-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding secretsmanager support #305
base: master
Are you sure you want to change the base?
Adding secretsmanager support #305
Conversation
df61ffc
to
9f2f4f6
Compare
3704dd3
to
d369831
Compare
Signed-off-by: Harsh Thakur <[email protected]>
d369831
to
322384a
Compare
There was a problem hiding this comment.
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.
Signed-off-by: Harsh Thakur <[email protected]>
322384a
to
7da053a
Compare
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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
.
Parent string `json:"parent,omitempty"` | |
Parent string `json:"parent"` |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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.
Location string `json:"location,omitempty"` | |
Location *string `json:"location,omitempty"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SecretID *string `json:"secretid,omitempty"` | |
SecretID string `json:"secretid,omitempty"` |
We typically do not use pointer types in status.
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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?
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"` |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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 .
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
// Package type metadata. | ||
const ( | ||
Group = "secretsmanager.gcp.crossplane.io" | ||
Version = "v1alpha1" | ||
) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!
There was a problem hiding this comment.
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
// Package type metadata. | ||
const ( | ||
Group = "secretsmanager.gcp.crossplane.io" | ||
Version = "v1alpha1" | ||
) |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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"` |
There was a problem hiding this comment.
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 <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
Signed-off-by: Harsh Thakur <[email protected]>
c80d020
to
8fc8e3c
Compare
Signed-off-by: Harsh Thakur <[email protected]>
There was a problem hiding this comment.
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 👍
@RealHarshThakur what is your plan on this one? Do you have some time to revisit/rebase this PR? |
@RealHarshThakur I can help testing agains gcp API in my account if it would help. Would love to see this merged :) |
@knelasevero Awesome. Do you need any help from me? UPDATE: invited you to my fork. Feel free to push commits directly. |
@RealHarshThakur Thanks! I just accepted. I will be working on this next week. |
@knelasevero Great! JFYI: I did try to have a K8s secret reference in a separate PR. #317 . |
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 |
Sure, shoot me an email ( [email protected] ) or at crossplane slack so we can figure out a time |
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. |
Signed-off-by: Harsh Thakur [email protected]
Description of your changes
Fixes ##294
I have:
make reviewable test
to ensure this PR is ready for review.TODO:
How has this code been tested
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