Skip to content

Commit

Permalink
Merge pull request #3282 from yuwenma/sm-version-alias
Browse files Browse the repository at this point in the history
feat: add secretManager version alias
  • Loading branch information
google-oss-prow[bot] authored Dec 5, 2024
2 parents 7d2b4a7 + d75b3db commit 2c92427
Show file tree
Hide file tree
Showing 22 changed files with 675 additions and 11 deletions.
1 change: 1 addition & 0 deletions apis/secretmanager/v1beta1/secret_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ type SecretManagerSecretStatus struct {
// SecretManagerSecretSpec defines the desired state of SecretManagerSecret
// +kcc:proto=google.cloud.secretmanager.v1.Secret
type SecretManagerSecretObservedState struct {
VersionAliases map[string]string `json:"versionAliases,omitempty"`
}

// +genclient
Expand Down
9 changes: 8 additions & 1 deletion apis/secretmanager/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,11 @@ spec:
observedState:
description: ObservedState is the state of the resource as most recently
observed in GCP.
properties:
versionAliases:
additionalProperties:
type: string
type: object
type: object
type: object
type: object
Expand Down
12 changes: 10 additions & 2 deletions pkg/controller/direct/secretmanager/secret_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,8 @@ func (a *Adapter) Create(ctx context.Context, op *directbase.CreateOperation) er
}
resource.Annotations = ComputeAnnotations(desired)
resource.Labels = common.ComputeGCPLabels(desired.GetLabels())

// GCP service does not allow setting version aliases during Secret creation.
resource.VersionAliases = nil
req := &secretmanagerpb.CreateSecretRequest{
Parent: a.id.Parent().String(),
SecretId: a.id.ID(),
Expand All @@ -203,7 +204,14 @@ func (a *Adapter) Create(ctx context.Context, op *directbase.CreateOperation) er
external := a.id.String()
status.ExternalRef = &external
status.Name = created.Name
return op.UpdateStatus(ctx, status, nil)
if err = op.UpdateStatus(ctx, status, nil); err != nil {
return err
}
// VersionAliases cannot be set in Creation, requeing the result to update the versionAlias without waiting for the reconciliation interval.
if a.desired.Spec.VersionAliases != nil {
op.RequeueRequested = true
}
return nil
}

func topicsEqual(desired []*krm.TopicRef, actual []*secretmanagerpb.Topic) bool {
Expand Down
32 changes: 29 additions & 3 deletions pkg/controller/direct/secretmanager/secret_mapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
package secretmanager

import (
"strconv"

krm "github.com/GoogleCloudPlatform/k8s-config-connector/apis/secretmanager/v1beta1"

pb "cloud.google.com/go/secretmanager/apiv1/secretmanagerpb"
Expand All @@ -23,7 +25,12 @@ import (
)

func SecretManagerSecretStatusObservedState_FromProto(mapCtx *direct.MapContext, in *pb.Secret) *krm.SecretManagerSecretObservedState {
return &krm.SecretManagerSecretObservedState{}
if in == nil {
return nil
}
out := &krm.SecretManagerSecretObservedState{}
out.VersionAliases = MapStringInt64_ToMapStringString(mapCtx, in.VersionAliases)
return out
}

func CustomerManagedEncryption_FromProto(mapCtx *direct.MapContext, in *pb.CustomerManagedEncryption) *krm.CustomerManagedEncryption {
Expand Down Expand Up @@ -96,8 +103,7 @@ func SecretManagerSecretSpec_ToProto(mapCtx *direct.MapContext, in *krm.SecretMa
}
// MISSING: Etag
out.Rotation = Rotation_ToProto(mapCtx, in.Rotation)
// MISSING: VersionAliases
// out.VersionAliases = in.VersionAliases
out.VersionAliases = MapStringString_ToMapStringInt64(mapCtx, in.VersionAliases)
out.Annotations = in.Annotations
// MISSING: Labels
// MISSING: VersionDestroyTtl
Expand All @@ -122,3 +128,23 @@ func Topic_ToProto(mapCtx *direct.MapContext, in *krm.Topic) *pb.Topic {
out.Name = direct.ValueOf(in.Name)
return out
}

func MapStringString_ToMapStringInt64(mapCtx *direct.MapContext, in map[string]string) map[string]int64 {
out := map[string]int64{}
for k, v := range in {
stringV, err := strconv.ParseInt(v, 10, 64)
if err != nil {
mapCtx.Errorf("%s has invalid value, expect int64, got %s", k, v)
}
out[k] = stringV
}
return out
}

func MapStringInt64_ToMapStringString(mapCtx *direct.MapContext, in map[string]int64) map[string]string {
out := map[string]string{}
for k, v := range in {
out[k] = strconv.FormatInt(v, 10)
}
return out
}
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ func (a *SecretVersionAdapter) Delete(ctx context.Context, deleteOp *directbase.
Name: a.id.String(), Etag: a.actual.Etag}
_, err := a.gcpClient.DestroySecretVersion(ctx, req)
if err != nil {
if direct.IsNotFound(err) {
return false, nil
}
return false, fmt.Errorf("deleting SecretVersion %s: %w", a.id, err)
}
log.Info("destroyed SecretVersion", "name", a.id)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: secretmanager.cnrm.cloud.google.com/v1beta1
kind: SecretManagerSecret
metadata:
annotations:
cnrm.cloud.google.com/project-id: ${projectId}
labels:
cnrm-test: "true"
label-one: value-one
managed-by-cnrm: "true"
name: secretmanagersecret-${uniqueId}
spec:
replication:
userManaged:
replicas:
- location: us-central1
resourceID: secretmanagersecret-${uniqueId}
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,43 @@ X-Xss-Protection: 0

---

GET https://secretmanager.googleapis.com/v1/projects/${projectId}/secrets/secretmanagersecret-${uniqueId}?alt=json
Content-Type: application/json
User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager

200 OK
Cache-Control: private
Content-Type: application/json; charset=UTF-8
Server: ESF
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
"createTime": "2024-04-01T12:34:56.123456Z",
"etag": "abcdef0123A=",
"labels": {
"cnrm-test": "true",
"label-one": "value-one",
"managed-by-cnrm": "true"
},
"name": "projects/${projectNumber}/secrets/secretmanagersecret-${uniqueId}",
"replication": {
"userManaged": {
"replicas": [
{
"location": "us-central1"
}
]
}
}
}

---

GET https://secretmanager.googleapis.com/v1/projects/${projectId}/secrets/secretmanagersecret-${uniqueId}?%24alt=json%3Benum-encoding%3Dint
Content-Type: application/json
User-Agent: kcc/controller-manager
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
apiVersion: secretmanager.cnrm.cloud.google.com/v1beta1
kind: SecretManagerSecret
metadata:
annotations:
cnrm.cloud.google.com/project-id: ${projectId}
labels:
cnrm-test: "true"
label-one: value-one
label-two: value-two
managed-by-cnrm: "true"
name: secretmanagersecret-${uniqueId}
spec:
annotations:
bar: secretmanagersecret-bar
foo: secretmanagersecret
expireTime: "2025-10-03T15:01:23Z"
replication:
auto:
customerManagedEncryption:
kmsKeyRef:
external: projects/${projectId}/locations/global/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}
resourceID: secretmanagersecret-${uniqueId}
rotation:
nextRotationTime: "2025-10-03T15:01:23Z"
rotationPeriod: 7200s
topics:
- topicRef:
external: projects/${projectId}/topics/topic-2-${uniqueId}
Original file line number Diff line number Diff line change
Expand Up @@ -892,6 +892,56 @@ X-Xss-Protection: 0

---

GET https://secretmanager.googleapis.com/v1/projects/${projectId}/secrets/secretmanagersecret-${uniqueId}?alt=json
Content-Type: application/json
User-Agent: Terraform/ (+https://www.terraform.io) Terraform-Plugin-SDK/2.10.1 terraform-provider-google-beta/kcc/controller-manager

200 OK
Cache-Control: private
Content-Type: application/json; charset=UTF-8
Server: ESF
Vary: Origin
Vary: X-Origin
Vary: Referer
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 0

{
"annotations": {
"bar": "secretmanagersecret-bar",
"foo": "secretmanagersecret"
},
"createTime": "2024-04-01T12:34:56.123456Z",
"etag": "abcdef0123A=",
"expireTime": "2025-10-03T15:01:23Z",
"labels": {
"cnrm-test": "true",
"label-one": "value-one",
"label-two": "value-two",
"managed-by-cnrm": "true"
},
"name": "projects/${projectNumber}/secrets/secretmanagersecret-${uniqueId}",
"replication": {
"automatic": {
"customerManagedEncryption": {
"kmsKeyName": "projects/${projectId}/locations/global/keyRings/kmskeyring-${uniqueId}/cryptoKeys/kmscryptokey-${uniqueId}"
}
}
},
"rotation": {
"nextRotationTime": "2025-10-03T15:01:23Z",
"rotationPeriod": "7200s"
},
"topics": [
{
"name": "projects/${projectId}/topics/topic-2-${uniqueId}"
}
]
}

---

GET https://secretmanager.googleapis.com/v1/projects/${projectId}/secrets/secretmanagersecret-${uniqueId}?%24alt=json%3Benum-encoding%3Dint
Content-Type: application/json
User-Agent: kcc/controller-manager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,9 @@ conditions:
externalRef: string
name: string
observedGeneration: integer
observedState: {}
observedState:
versionAliases:
string: string
```

<table class="properties responsive">
Expand Down Expand Up @@ -642,6 +644,13 @@ observedState: {}
<p>{% verbatim %}ObservedState is the state of the resource as most recently observed in GCP.{% endverbatim %}</p>
</td>
</tr>
<tr>
<td><code>observedState.versionAliases</code></td>
<td>
<p><code class="apitype">map (key: string, value: string)</code></p>
<p>{% verbatim %}{% endverbatim %}</p>
</td>
</tr>
</tbody>
</table>

Expand Down
18 changes: 14 additions & 4 deletions tests/e2e/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func exportResource(h *create.Harness, obj *unstructured.Unstructured, expectati
case schema.GroupKind{Group: "cloudbuild.cnrm.cloud.google.com", Kind: "CloudBuildWorkerPool"}:
exportURI = "//cloudbuild.googleapis.com/projects/" + projectID + "/locations/" + location + "/workerPools/" + resourceID

case schema.GroupKind{Group: "secretmanager.cnrm.cloud.google.com", Kind: "SecretManagerSecret"}:
exportURI = "//secretmanager.googleapis.com/projects/" + projectID + "/secrets/" + resourceID

}

if exportURI == "" {
Expand Down Expand Up @@ -103,17 +106,24 @@ func exportResource(h *create.Harness, obj *unstructured.Unstructured, expectati
}
exportURI = strings.ReplaceAll(exportURI, "{.spec.collection}", collection)
}

exportParams := h.ExportParams()
exportParams.IAMFormat = "partialpolicy"
exportParams.ResourceFormat = "krm"
outputDir := h.TempDir()
outputPath := filepath.Join(outputDir, "export.yaml")
exportParams.Output = outputPath
exportParams.URI = exportURI
if err := export.Execute(h.Ctx, &exportParams); err != nil {
h.Errorf("error from export.Execute: %v", err)
return ""
switch gvk.Kind {
case "SecretManagerSecretVersion":
// Skip run export.Execute because the SecretVersion servicemappings has a broken marker
// that the `idTemplateCanBeUsedToMatchResourceName` is false so the Execute always fails.
// https://github.com/GoogleCloudPlatform/k8s-config-connector/blob/3530c83a5e0d331640ec2160675d80336fad9c53/config/servicemappings/secretmanager.yaml#L79
break
default:
if err := export.Execute(h.Ctx, &exportParams); err != nil {
h.Errorf("error from export.Execute: %v", err)
return ""
}
}

output := h.MustReadFile(outputPath)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: secretmanager.cnrm.cloud.google.com/v1beta1
kind: SecretManagerSecret
metadata:
annotations:
cnrm.cloud.google.com/project-id: ${projectId}
name: secret-${uniqueId}
spec:
replication:
userManaged:
replicas:
- location: us-central1
resourceID: secret-${uniqueId}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: secretmanager.cnrm.cloud.google.com/v1beta1
kind: SecretManagerSecret
metadata:
annotations:
cnrm.cloud.google.com/project-id: ${projectId}
name: secret-${uniqueId}
spec:
replication:
userManaged:
replicas:
- location: us-central1
resourceID: secret-${uniqueId}
versionAliases:
foo: "1"
Loading

0 comments on commit 2c92427

Please sign in to comment.