Secrets: Save owner reference fields in secure value db table (#108905)

* Secrets: Save owner reference fields in secure value db table

* Save api group and version separately
This commit is contained in:
Matheus Macabu
2025-07-31 10:42:19 +02:00
committed by GitHub
parent 66bebe94e0
commit 80d7892d6a
19 changed files with 243 additions and 67 deletions
@@ -20,6 +20,18 @@ INSERT INTO {{ .Ident "secret_secure_value" }} (
{{ if .Row.Ref.Valid }}
{{ .Ident "ref" }},
{{ end }}
{{ if .Row.OwnerReferenceAPIGroup.Valid }}
{{ .Ident "owner_reference_api_group" }},
{{ end }}
{{ if .Row.OwnerReferenceAPIVersion.Valid }}
{{ .Ident "owner_reference_api_version" }},
{{ end }}
{{ if .Row.OwnerReferenceKind.Valid }}
{{ .Ident "owner_reference_kind" }},
{{ end }}
{{ if .Row.OwnerReferenceName.Valid }}
{{ .Ident "owner_reference_name" }},
{{ end }}
{{ .Ident "external_id" }}
) VALUES (
{{ .Arg .Row.GUID }},
@@ -43,5 +55,17 @@ INSERT INTO {{ .Ident "secret_secure_value" }} (
{{ if .Row.Ref.Valid }}
{{ .Arg .Row.Ref.String }},
{{ end }}
{{ if .Row.OwnerReferenceAPIGroup.Valid }}
{{ .Arg .Row.OwnerReferenceAPIGroup.String }},
{{ end }}
{{ if .Row.OwnerReferenceAPIVersion.Valid }}
{{ .Arg .Row.OwnerReferenceAPIVersion.String }},
{{ end }}
{{ if .Row.OwnerReferenceKind.Valid }}
{{ .Arg .Row.OwnerReferenceKind.String }},
{{ end }}
{{ if .Row.OwnerReferenceName.Valid }}
{{ .Arg .Row.OwnerReferenceName.String }},
{{ end }}
{{ .Arg .Row.ExternalID }}
);
@@ -14,7 +14,11 @@ SELECT
{{ .Ident "ref" }},
{{ .Ident "external_id" }},
{{ .Ident "version" }},
{{ .Ident "active" }}
{{ .Ident "active" }},
{{ .Ident "owner_reference_api_group" }},
{{ .Ident "owner_reference_api_version" }},
{{ .Ident "owner_reference_kind" }},
{{ .Ident "owner_reference_name" }}
FROM
{{ .Ident "secret_secure_value" }}
WHERE
@@ -14,7 +14,11 @@ SELECT
{{ .Ident "ref" }},
{{ .Ident "external_id" }},
{{ .Ident "active" }},
{{ .Ident "version" }}
{{ .Ident "version" }},
{{ .Ident "owner_reference_api_group" }},
{{ .Ident "owner_reference_api_version" }},
{{ .Ident "owner_reference_kind" }},
{{ .Ident "owner_reference_name" }}
FROM
{{ .Ident "secret_secure_value" }}
WHERE
+38 -30
View File
@@ -177,21 +177,25 @@ func TestSecureValueQueries(t *testing.T) {
Data: &createSecureValue{
SQLTemplate: mocks.NewTestingSQLTemplate(),
Row: &secureValueDB{
GUID: "abc",
Name: "name",
Namespace: "ns",
Annotations: `{"x":"XXXX"}`,
Labels: `{"a":"AAA", "b", "BBBB"}`,
Created: 1234,
CreatedBy: "user:ryan",
Updated: 5678,
UpdatedBy: "user:cameron",
Version: 1,
Description: "description",
Keeper: toNullString(nil),
Decrypters: toNullString(nil),
Ref: toNullString(nil),
ExternalID: "extId",
GUID: "abc",
Name: "name",
Namespace: "ns",
Annotations: `{"x":"XXXX"}`,
Labels: `{"a":"AAA", "b", "BBBB"}`,
Created: 1234,
CreatedBy: "user:ryan",
Updated: 5678,
UpdatedBy: "user:cameron",
Version: 1,
Description: "description",
Keeper: toNullString(nil),
Decrypters: toNullString(nil),
Ref: toNullString(nil),
ExternalID: "extId",
OwnerReferenceAPIGroup: toNullString(nil),
OwnerReferenceAPIVersion: toNullString(nil),
OwnerReferenceKind: toNullString(nil),
OwnerReferenceName: toNullString(nil),
},
},
},
@@ -200,21 +204,25 @@ func TestSecureValueQueries(t *testing.T) {
Data: &createSecureValue{
SQLTemplate: mocks.NewTestingSQLTemplate(),
Row: &secureValueDB{
GUID: "abc",
Name: "name",
Namespace: "ns",
Annotations: `{"x":"XXXX"}`,
Labels: `{"a":"AAA", "b", "BBBB"}`,
Created: 1234,
CreatedBy: "user:ryan",
Updated: 5678,
UpdatedBy: "user:cameron",
Version: 1,
Description: "description",
Keeper: toNullString(ptr.To("keeper_test")),
Decrypters: toNullString(ptr.To("decrypters_test")),
Ref: toNullString(ptr.To("ref_test")),
ExternalID: "extId",
GUID: "abc",
Name: "name",
Namespace: "ns",
Annotations: `{"x":"XXXX"}`,
Labels: `{"a":"AAA", "b", "BBBB"}`,
Created: 1234,
CreatedBy: "user:ryan",
Updated: 5678,
UpdatedBy: "user:cameron",
Version: 1,
Description: "description",
Keeper: toNullString(ptr.To("keeper_test")),
Decrypters: toNullString(ptr.To("decrypters_test")),
Ref: toNullString(ptr.To("ref_test")),
ExternalID: "extId",
OwnerReferenceAPIGroup: toNullString(ptr.To("prometheus.datasource.grafana.app")),
OwnerReferenceAPIVersion: toNullString(ptr.To("v0alpha1")),
OwnerReferenceKind: toNullString(ptr.To("DataSource")),
OwnerReferenceName: toNullString(ptr.To("prom-config")),
},
},
},
@@ -10,22 +10,26 @@ import (
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/apimachinery/utils"
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
"github.com/grafana/grafana/pkg/storage/secret/migrator"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
)
type secureValueDB struct {
// Kubernetes Metadata
GUID string
Name string
Namespace string
Annotations string // map[string]string
Labels string // map[string]string
Created int64
CreatedBy string
Updated int64
UpdatedBy string
GUID string
Name string
Namespace string
Annotations string // map[string]string
Labels string // map[string]string
Created int64
CreatedBy string
Updated int64
UpdatedBy string
OwnerReferenceAPIGroup sql.NullString
OwnerReferenceAPIVersion sql.NullString
OwnerReferenceKind sql.NullString
OwnerReferenceName sql.NullString
// Kubernetes Status
Active bool
@@ -39,10 +43,6 @@ type secureValueDB struct {
ExternalID string
}
func (*secureValueDB) TableName() string {
return migrator.TableNameSecureValue
}
// toKubernetes maps a DB row into a Kubernetes resource (metadata + spec).
func (sv *secureValueDB) toKubernetes() (*secretv1beta1.SecureValue, error) {
annotations := make(map[string]string, 0)
@@ -85,8 +85,6 @@ func (sv *secureValueDB) toKubernetes() (*secretv1beta1.SecureValue, error) {
resource.Spec.Ref = &sv.Ref.String
}
resource.Status.ExternalID = sv.ExternalID
// Set all meta fields here for consistency.
meta, err := utils.MetaAccessor(resource)
if err != nil {
@@ -106,6 +104,20 @@ func (sv *secureValueDB) toKubernetes() (*secretv1beta1.SecureValue, error) {
meta.SetUpdatedTimestamp(&updated)
meta.SetResourceVersionInt64(sv.Updated)
hasOwnerReference := sv.OwnerReferenceAPIGroup.Valid && sv.OwnerReferenceAPIGroup.String != "" &&
sv.OwnerReferenceAPIVersion.Valid && sv.OwnerReferenceAPIVersion.String != "" &&
sv.OwnerReferenceKind.Valid && sv.OwnerReferenceKind.String != "" &&
sv.OwnerReferenceName.Valid && sv.OwnerReferenceName.String != ""
if hasOwnerReference {
meta.SetOwnerReferences([]metav1.OwnerReference{
{
APIVersion: schema.GroupVersion{Group: sv.OwnerReferenceAPIGroup.String, Version: sv.OwnerReferenceAPIVersion.String}.String(),
Kind: sv.OwnerReferenceKind.String,
Name: sv.OwnerReferenceName.String,
},
})
}
return resource, nil
}
@@ -179,16 +191,48 @@ func toRow(sv *secretv1beta1.SecureValue, externalID string) (*secureValueDB, er
return nil, fmt.Errorf("failed to get resource version: %w", err)
}
var (
ownerReferenceAPIGroup sql.NullString
ownerReferenceAPIVersion sql.NullString
ownerReferenceKind sql.NullString
ownerReferenceName sql.NullString
)
ownerReferences := meta.GetOwnerReferences()
if len(ownerReferences) > 1 {
return nil, fmt.Errorf("only one owner reference is supported, found %d", len(ownerReferences))
}
if len(ownerReferences) == 1 {
ownerReference := ownerReferences[0]
gv, err := schema.ParseGroupVersion(ownerReference.APIVersion)
if err != nil {
return nil, fmt.Errorf("failed to parse owner reference API version %s: %w", ownerReference.APIVersion, err)
}
if gv.Group == "" {
return nil, fmt.Errorf("malformed api version %s requires <group>/<version> format", ownerReference.APIVersion)
}
ownerReferenceAPIGroup = toNullString(&gv.Group)
ownerReferenceAPIVersion = toNullString(&gv.Version)
ownerReferenceKind = toNullString(&ownerReference.Kind)
ownerReferenceName = toNullString(&ownerReference.Name)
}
return &secureValueDB{
GUID: string(sv.UID),
Name: sv.Name,
Namespace: sv.Namespace,
Annotations: annotations,
Labels: labels,
Created: meta.GetCreationTimestamp().UnixMilli(),
CreatedBy: meta.GetCreatedBy(),
Updated: updatedTimestamp,
UpdatedBy: meta.GetUpdatedBy(),
GUID: string(sv.UID),
Name: sv.Name,
Namespace: sv.Namespace,
Annotations: annotations,
Labels: labels,
Created: meta.GetCreationTimestamp().UnixMilli(),
CreatedBy: meta.GetCreatedBy(),
Updated: updatedTimestamp,
UpdatedBy: meta.GetUpdatedBy(),
OwnerReferenceAPIGroup: ownerReferenceAPIGroup,
OwnerReferenceAPIVersion: ownerReferenceAPIVersion,
OwnerReferenceKind: ownerReferenceKind,
OwnerReferenceName: ownerReferenceName,
Version: sv.Status.Version,
@@ -243,7 +243,9 @@ func (s *secureValueMetadataStorage) readActiveVersion(ctx context.Context, name
&secureValue.Annotations, &secureValue.Labels,
&secureValue.Created, &secureValue.CreatedBy,
&secureValue.Updated, &secureValue.UpdatedBy,
&secureValue.Description, &secureValue.Keeper, &secureValue.Decrypters, &secureValue.Ref, &secureValue.ExternalID, &secureValue.Active, &secureValue.Version); err != nil {
&secureValue.Description, &secureValue.Keeper, &secureValue.Decrypters, &secureValue.Ref, &secureValue.ExternalID, &secureValue.Active, &secureValue.Version,
&secureValue.OwnerReferenceAPIGroup, &secureValue.OwnerReferenceAPIVersion, &secureValue.OwnerReferenceKind, &secureValue.OwnerReferenceName,
); err != nil {
return secureValueDB{}, fmt.Errorf("failed to scan secure value row: %w", err)
}
@@ -320,6 +322,7 @@ func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.N
&row.Updated, &row.UpdatedBy,
&row.Description, &row.Keeper, &row.Decrypters,
&row.Ref, &row.ExternalID, &row.Version, &row.Active,
&row.OwnerReferenceAPIGroup, &row.OwnerReferenceAPIVersion, &row.OwnerReferenceKind, &row.OwnerReferenceName,
)
if err != nil {
@@ -14,6 +14,10 @@ INSERT INTO `secret_secure_value` (
`keeper`,
`decrypters`,
`ref`,
`owner_reference_api_group`,
`owner_reference_api_version`,
`owner_reference_kind`,
`owner_reference_name`,
`external_id`
) VALUES (
'abc',
@@ -31,5 +35,9 @@ INSERT INTO `secret_secure_value` (
'keeper_test',
'decrypters_test',
'ref_test',
'prometheus.datasource.grafana.app',
'v0alpha1',
'DataSource',
'prom-config',
'extId'
);
@@ -14,7 +14,11 @@ SELECT
`ref`,
`external_id`,
`version`,
`active`
`active`,
`owner_reference_api_group`,
`owner_reference_api_version`,
`owner_reference_kind`,
`owner_reference_name`
FROM
`secret_secure_value`
WHERE
@@ -14,7 +14,11 @@ SELECT
`ref`,
`external_id`,
`active`,
`version`
`version`,
`owner_reference_api_group`,
`owner_reference_api_version`,
`owner_reference_kind`,
`owner_reference_name`
FROM
`secret_secure_value`
WHERE
@@ -14,7 +14,11 @@ SELECT
`ref`,
`external_id`,
`active`,
`version`
`version`,
`owner_reference_api_group`,
`owner_reference_api_version`,
`owner_reference_kind`,
`owner_reference_name`
FROM
`secret_secure_value`
WHERE
@@ -14,6 +14,10 @@ INSERT INTO "secret_secure_value" (
"keeper",
"decrypters",
"ref",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name",
"external_id"
) VALUES (
'abc',
@@ -31,5 +35,9 @@ INSERT INTO "secret_secure_value" (
'keeper_test',
'decrypters_test',
'ref_test',
'prometheus.datasource.grafana.app',
'v0alpha1',
'DataSource',
'prom-config',
'extId'
);
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"version",
"active"
"active",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"active",
"version"
"version",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"active",
"version"
"version",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
@@ -14,6 +14,10 @@ INSERT INTO "secret_secure_value" (
"keeper",
"decrypters",
"ref",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name",
"external_id"
) VALUES (
'abc',
@@ -31,5 +35,9 @@ INSERT INTO "secret_secure_value" (
'keeper_test',
'decrypters_test',
'ref_test',
'prometheus.datasource.grafana.app',
'v0alpha1',
'DataSource',
'prom-config',
'extId'
);
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"version",
"active"
"active",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"active",
"version"
"version",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
@@ -14,7 +14,11 @@ SELECT
"ref",
"external_id",
"active",
"version"
"version",
"owner_reference_api_group",
"owner_reference_api_version",
"owner_reference_kind",
"owner_reference_name"
FROM
"secret_secure_value"
WHERE
+29
View File
@@ -152,4 +152,33 @@ func (*SecretDB) AddMigration(mg *migrator.Migrator) {
Cols: []string{"namespace", "label", "active"},
Type: migrator.IndexType,
}))
// Owner Reference columns
mg.AddMigration("add owner_reference_api_group column to "+TableNameSecureValue, migrator.NewAddColumnMigration(secureValueTable, &migrator.Column{
Name: "owner_reference_api_group",
Type: migrator.DB_NVarchar,
Length: 253, // Limit enforced by K8s.
Nullable: true,
}))
mg.AddMigration("add owner_reference_api_version column to "+TableNameSecureValue, migrator.NewAddColumnMigration(secureValueTable, &migrator.Column{
Name: "owner_reference_api_version",
Type: migrator.DB_NVarchar,
Length: 253, // Limit enforced by K8s.
Nullable: true,
}))
mg.AddMigration("add owner_reference_kind column to "+TableNameSecureValue, migrator.NewAddColumnMigration(secureValueTable, &migrator.Column{
Name: "owner_reference_kind",
Type: migrator.DB_NVarchar,
Length: 253, // Limit enforced by K8s.
Nullable: true,
}))
mg.AddMigration("add owner_reference_name column to "+TableNameSecureValue, migrator.NewAddColumnMigration(secureValueTable, &migrator.Column{
Name: "owner_reference_name",
Type: migrator.DB_NVarchar,
Length: 253, // Limit enforced by K8s.
Nullable: true,
}))
}