Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.

Adding secretsmanager support - #305

Open
RealHarshThakur wants to merge 13 commits into
crossplane-contrib:masterfrom
RealHarshThakur:secrets-manager
Open

Adding secretsmanager support#305
RealHarshThakur wants to merge 13 commits into
crossplane-contrib:masterfrom
RealHarshThakur:secrets-manager

Conversation

@RealHarshThakur

@RealHarshThakur RealHarshThakur commented Feb 21, 2021

Copy link
Copy Markdown
Contributor

Signed-off-by: Harsh Thakur harshthakur9030@gmail.com

Description of your changes

Fixes ##294

I have:

  • Read and followed Crossplane's contribution process.
  • [] Run make reviewable test to ensure this PR is ready for review.

TODO:

  • Implement type SecretVersion . This is where data is going to reside
  • Add Kubernetes SecretRef

How has this code been tested

  • Add unit tests

Manually tried creating, updating, syncing and deleting the secret(GCP) resource.
Manually tried creating a secret version , changed it's states and deleting the secret version

@RealHarshThakur
RealHarshThakur marked this pull request as draft February 21, 2021 19:09
@RealHarshThakur RealHarshThakur changed the title Adding resource : secret Adding secretsmanager support Feb 21, 2021
@RealHarshThakur
RealHarshThakur force-pushed the secrets-manager branch 2 times, most recently from 3704dd3 to d369831 Compare February 25, 2021 21:51
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>

@hasheddan hasheddan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RealHarshThakur thanks for working on this and apologies for the review delay! I think we should be offering two different CRDs here to match the GCP API (Secret and SecretVersion).

Some helpful references could be the similar implementation in provider-aws as well as the terraform docs for this API.

Comment thread apis/secretsmanager/v1alpha1/secret_types.go Outdated
Comment thread apis/secretsmanager/v1alpha1/secret_types.go Outdated
Comment thread apis/secretsmanager/v1alpha1/secret_types.go Outdated
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
@RealHarshThakur
RealHarshThakur marked this pull request as ready for review March 22, 2021 18:16
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>

@hasheddan hasheddan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for working on this @RealHarshThakur! Let me know if you have any questions :)


// Required. The resource name of the project to associate with the
// [Secret][google.cloud.secretmanager.v1.Secret], in the format `projects/*`.
Parent string `json:"parent,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If required we don't need omitempty.

Suggested change
Parent string `json:"parent,omitempty"`
Parent string `json:"parent"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also be a cross resource reference to the Secret type.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't understand the cross resource reference part . Is it possible to reference just the field Secret.ObjectMeta.Name ?

}

// ReplicationAutomatic has fields for automatic replication of secrets
type ReplicationAutomatic struct {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be fields here?

@RealHarshThakur RealHarshThakur Apr 4, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version of google SDK doesn't have any but there are new fields in the latest versions. Shall I add a comment to mention it's intentionally empty?

type ReplicationUserManagedReplica struct {
// Location of the secret.
// +immutable
Location string `json:"location,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be pointer type if optional, though if it is the only field in this embedded struct we could consider making it required and just the parent struct optional.

Suggested change
Location string `json:"location,omitempty"`
Location *string `json:"location,omitempty"`

@RealHarshThakur RealHarshThakur Apr 5, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, making the struct optional reflects what GCP expects. If user has started filling the struct, Location should be a required field. Also, newer GCP SDK does have additional fields . I have already marked this as optional in ReplicationType struct at L67


// Output only. This must be unique within the project. External name of the object is set to this field, hence making it optional
// +optional
SecretID *string `json:"secretid,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
SecretID *string `json:"secretid,omitempty"`
SecretID string `json:"secretid,omitempty"`

We typically do not use pointer types in status.

@RealHarshThakur RealHarshThakur Apr 5, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if I should remove this field as it doesn't provide much value anyway. It's the same as external name of the CR


const (
// SecretVersionSTATEUNSPECIFIED represents that SecretVersion state is not specified. This value is unused and invalid.
SecretVersionSTATEUNSPECIFIED SecretVersionState = 0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this camel case?

Suggested change
SecretVersionSTATEUNSPECIFIED SecretVersionState = 0
SecretVersionStateUnspecified SecretVersionState = 0

type SecretVersionParameters struct {
// SecretRef refers to the secret object(GCP) created in Kubernetes
// Required
SecretRef string `json:"secretRef,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be optional if payload is provided?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the comment is misleading, SecretRef is the name of the secret created within GCP . Basically, the secrets manager expects us to create a Secret and then it can have multiple SecretVersion . It won't be possible to create a SecretVersion without the Secret . End users can choose to create the Secret manually and just manage SecretVersion through crossplane

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For referencing K8s secret, I am continuing the work here : #317 .

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I wonder if there's a way to enforce the following validation: it is mandatory to pass in either Payload or KubeSecretRef . Right now, I have kept them both optional

// SecretVersionDESTROYED represents that SecretVersion state is destroyed and the secret data is no longer
// stored. A version may not leave this state once entered.
// SecretVersionDESTROYED SecretVersionState = 3
// +kubebuilder:validation:Enum=1;2;3

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should instead make this ENABLED,DISABLED,... as that would likely map to the experience folks would expect here.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

"github.com/crossplane/provider-gcp/apis/secretversion/v1alpha1"
"github.com/google/go-cmp/cmp"
"github.com/googleapis/gax-go"
"google.golang.org/genproto/googleapis/cloud/secretmanager/v1"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think both Secret and SecretVersion should be in secretmanager group, just be different types within it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

Comment on lines +26 to +30
// Package type metadata.
const (
Group = "secretsmanager.gcp.crossplane.io"
Version = "v1alpha1"
)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left the same comment below in the client packages, but I think both Secret and SecretVersion should be in the secretsmanager.gcp.crossplane.io group and just be different types, rather than in different groups.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I should probably change the project structure too in clients and controllers too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

@RealHarshThakur RealHarshThakur left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hasheddan Thanks for reviewing . Will work on the suggestions and start with writing tests

Comment on lines +26 to +30
// Package type metadata.
const (
Group = "secretsmanager.gcp.crossplane.io"
Version = "v1alpha1"
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, I should probably change the project structure too in clients and controllers too.


// Required. The resource name of the project to associate with the
// [Secret][google.cloud.secretmanager.v1.Secret], in the format `projects/*`.
Parent string `json:"parent,omitempty"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I didn't understand the cross resource reference part . Is it possible to reference just the field Secret.ObjectMeta.Name ?

}

// ReplicationAutomatic has fields for automatic replication of secrets
type ReplicationAutomatic struct {

@RealHarshThakur RealHarshThakur Apr 4, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current version of google SDK doesn't have any but there are new fields in the latest versions. Shall I add a comment to mention it's intentionally empty?

type ReplicationUserManagedReplica struct {
// Location of the secret.
// +immutable
Location string `json:"location,omitempty"`

@RealHarshThakur RealHarshThakur Apr 5, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, making the struct optional reflects what GCP expects. If user has started filling the struct, Location should be a required field. Also, newer GCP SDK does have additional fields . I have already marked this as optional in ReplicationType struct at L67


// Output only. This must be unique within the project. External name of the object is set to this field, hence making it optional
// +optional
SecretID *string `json:"secretid,omitempty"`

@RealHarshThakur RealHarshThakur Apr 5, 2021

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if I should remove this field as it doesn't provide much value anyway. It's the same as external name of the CR

type SecretVersionParameters struct {
// SecretRef refers to the secret object(GCP) created in Kubernetes
// Required
SecretRef string `json:"secretRef,omitempty"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, the comment is misleading, SecretRef is the name of the secret created within GCP . Basically, the secrets manager expects us to create a Secret and then it can have multiple SecretVersion . It won't be possible to create a SecretVersion without the Secret . End users can choose to create the Secret manually and just manage SecretVersion through crossplane

type SecretVersionParameters struct {
// SecretRef refers to the secret object(GCP) created in Kubernetes
// Required
SecretRef string `json:"secretRef,omitempty"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For referencing K8s secret, I am continuing the work here : #317 .

type SecretVersionParameters struct {
// SecretRef refers to the secret object(GCP) created in Kubernetes
// Required
SecretRef string `json:"secretRef,omitempty"`

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I wonder if there's a way to enforce the following validation: it is mandatory to pass in either Payload or KubeSecretRef . Right now, I have kept them both optional

Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>
Signed-off-by: Harsh Thakur <harshthakur9030@gmail.com>

@hasheddan hasheddan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RealHarshThakur thanks for your patience here and my apologies on the long review cycle 😞 We have made a number of changes in this repo in #308 which will require a rebase here. Please let me know if you have any questions and I will be more than happy to help :)

I also noticed you are using the genproto GCP library here. I recently moved a few of our types off of it because it was somewhat difficult to work with (you may have noticed this in the steps required in the controller implementation). It may be easier to work with https://github.com/googleapis/google-api-go-client/blob/d82b0a56bb37a94bfd6d885bc7c3e1761de7b509/secretmanager/v1/secretmanager-gen.go#L1187 instead. I believe we are now on the latest version of this package 👍

@turkenh

turkenh commented Sep 6, 2021

Copy link
Copy Markdown
Contributor

@RealHarshThakur what is your plan on this one? Do you have some time to revisit/rebase this PR?

@RealHarshThakur

Copy link
Copy Markdown
Contributor Author

Hey @turkenh , the PR is almost ready. I need to add bits to reference K8s secrets, but I was doing in a separate PR. Sure, I can rebase it but I can't test it against GCP API anymore due to weird billing issue.

@knelasevero

Copy link
Copy Markdown

@RealHarshThakur I can help testing agains gcp API in my account if it would help. Would love to see this merged :)

@RealHarshThakur

RealHarshThakur commented Oct 27, 2021

Copy link
Copy Markdown
Contributor Author

@knelasevero Awesome. Do you need any help from me?
I could give you access to this branch.(I don't know if there's a better way to collaborate)

UPDATE: invited you to my fork. Feel free to push commits directly.

@knelasevero

Copy link
Copy Markdown

@RealHarshThakur Thanks! I just accepted. I will be working on this next week.

@RealHarshThakur

Copy link
Copy Markdown
Contributor Author

@knelasevero Great! JFYI: I did try to have a K8s secret reference in a separate PR. #317 .
I think there are some bits in it which still need thinking as there's no direct way to enforce immutability of fields but would love to hear your experience/opinion on it.

@knelasevero

Copy link
Copy Markdown

Hey, sorry to have vanished. I've been on sick leave for a while.

@RealHarshThakur do you think we can pair on this when I am back? I think we can close this one quicker that way

@RealHarshThakur

Copy link
Copy Markdown
Contributor Author

Sure, shoot me an email ( harshthakur9030@gmail.com ) or at crossplane slack so we can figure out a time

@knelasevero

Copy link
Copy Markdown

Ok, I thought I would have more time, but client work will get most of my slots. Would you have time to rebase yourself and tweak whatever is needed? Then you can let me know and I test this in my account.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants