-
Notifications
You must be signed in to change notification settings - Fork 367
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
Secretsmanager: Implement LateInitialize of a K8s secret when AWS secret already exists #669
Secretsmanager: Implement LateInitialize of a K8s secret when AWS secret already exists #669
Conversation
0bbe08c
to
96a17f6
Compare
96a17f6
to
c2bbe99
Compare
@haarchri done |
c2bbe99
to
e523207
Compare
@haarchri 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.
We haven't done late-init for an input Secret
before but I think it makes sense given that it's very similar to other params except that it's stored differently. Thanks @MisterMX !
} | ||
|
||
payload := map[string][]byte{} | ||
if v, exists := parsed[awsclients.StringValue(ref.Key)]; exists { |
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.
We send the data as a string
if the key is given, I'd expect the reverse of this to happen in late-init, i.e. look for a string only if the key is given. If not, then we should always treat that the whole map is requested. So, I think we should only iterate here and not account for the case where there is a key, blob in AWS is a map and user actually meant a specific key in that whole blob in AWS.
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.
Oh in fact, it will never be non-nil anyway since we checked it in the beginning.
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, I think we can go for always iterating to keep the external and local data in sync.
Though it will be overwritten in the next reconcile if a ref.Key
is set (because payload will be different).
default: | ||
return nil, errors.New("neither binarySecretRef nor stringSecretRef is given") | ||
func (e *hooks) getPayload(ctx context.Context, cr *svcapitypes.SecretParameters) ([]byte, error) { | ||
ref, err := getSecretRef(cr) |
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 it's easier to follow what's happening if we have duplication for that switch case instead of calling another function.
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 would prefer to keep code encapsulated that is used more than once.
I modified the function so it will return an error in case StringSecretRef
and BinarySecretRef
are both set. Before that, StringSecretRef
took preference over BinarySecretRef
and I don't think that was intended. I also added a note to the API docs.
ref = cr.Spec.ForProvider.BinarySecretRef | ||
default: | ||
return nil, errors.New("neither binarySecretRef nor stringSecretRef is given") | ||
func (e *hooks) getPayload(ctx context.Context, cr *svcapitypes.SecretParameters) ([]byte, error) { |
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.
cr
seems to be used to point to the whole Secret
object in this file, i.e. as in (c)ustom (r)esource
. So, I'd suggest either keeping this line as is or use params
as variable name when it addresses SecretParameters
.
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.
Renamed to params
.
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 @muvaf for the review. I added (most of) your requested changes and rebased on current master.
One last proposal before bumping this to v1beta1
:
Currently we have a binarySecretRef
and stringSecretRef
next to each other. Wouldn't it be better if we'd have a single secretRef
and a format
property instead? This way we would be able to support different file formats, such as yaml
, json
etc.
} | ||
|
||
payload := map[string][]byte{} | ||
if v, exists := parsed[awsclients.StringValue(ref.Key)]; exists { |
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, I think we can go for always iterating to keep the external and local data in sync.
Though it will be overwritten in the next reconcile if a ref.Key
is set (because payload will be different).
default: | ||
return nil, errors.New("neither binarySecretRef nor stringSecretRef is given") | ||
func (e *hooks) getPayload(ctx context.Context, cr *svcapitypes.SecretParameters) ([]byte, error) { | ||
ref, err := getSecretRef(cr) |
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 would prefer to keep code encapsulated that is used more than once.
I modified the function so it will return an error in case StringSecretRef
and BinarySecretRef
are both set. Before that, StringSecretRef
took preference over BinarySecretRef
and I don't think that was intended. I also added a note to the API docs.
ref = cr.Spec.ForProvider.BinarySecretRef | ||
default: | ||
return nil, errors.New("neither binarySecretRef nor stringSecretRef is given") | ||
func (e *hooks) getPayload(ctx context.Context, cr *svcapitypes.SecretParameters) ([]byte, error) { |
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.
Renamed to params
.
9239fe4
to
baec13f
Compare
The controller now creates a K8s with the value from AWS if it does not already exist. Signed-off-by: Maximilian Blatt <maximilian.blatt-extern@deutschebahn.com> (external expert on behalf of DB Netz AG)
baec13f
to
26ea6cb
Compare
@@ -113,6 +121,79 @@ type hooks struct { | |||
kube client.Client | |||
} | |||
|
|||
func (e *hooks) lateInitialize(spec *svcapitypes.SecretParameters, resp *svcsdk.DescribeSecretOutput) error { | |||
payload, err := e.getPayload(context.TODO(), spec) | |||
if err := client.IgnoreNotFound(err); err != nil || payload == nil { |
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 err := client.IgnoreNotFound(err); err != nil || payload == nil { | |
if err := client.IgnoreNotFound(err); err != nil || payload != nil { |
I think my initial code suggestion was the opposite of what you're trying to do in that if statement, sorry about that. We should return nil
in case payload is full since we don't need to take any action.
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.
Description of your changes
Fixes #668
The controller now creates a K8s with the value from AWS if it does not already exist.
I have:
make reviewable test
to ensure this PR is ready for review.How has this code been tested
Manually