Skip to content
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

[repository] fixes and enhancements for repository update support #5763

Merged
merged 9 commits into from Dec 15, 2022

Conversation

dlaloue-vmware
Copy link
Collaborator

@dlaloue-vmware dlaloue-vmware commented Nov 30, 2022

Description of the change

This PR contains changes for two purposes:

  • improve feature parity between plugins
  • enable update support in UI

Feature parity:

  • flux: description support
  • flux: support changing to/from auth provider
  • carvel: description support
  • carvel: support changing auth type

Bug fixes to support update support in UI:

  • auth updates were not possible
  • fixed conditions for fields enablement
  • form fields data were sent incorrectly as a group, instead of only sending what applied
  • errors handling 'undefined' values
  • fixed which auth types are valid per plugin+type combination
  • fixed issue with helm plugins image pull secrets

helm/flux bug fixes:

  • fixed handling of redacted fields leading to secrets not being updated as expected or secret data being overwritten with 'redacted' as value.

(note: the PR has many small changes, but i was fixing issues as i was testing, hence the list)

Benefits

With the changes, users should see more commonality between plugin features, as well as a more robust UI experience regarding repository creation/updates.

Applicable issues

fixes issues #5745, #5746 and #5747

Additional information

The issue 1 in # 5746 could not be reproduce with the latest bits, so no change were made for it.

@netlify
Copy link

netlify bot commented Nov 30, 2022

Deploy Preview for kubeapps-dev canceled.

Built without sensitive environment variables

Name Link
🔨 Latest commit 459dfd3
🔍 Latest deploy log https://app.netlify.com/sites/kubeapps-dev/deploys/6390dbb0a5d4290009fa38cc

@gfichtenholt
Copy link
Contributor

just curious, is there a similar issue in flux plugin?

@dlaloue-vmware
Copy link
Collaborator Author

just curious, is there a similar issue in flux plugin?
yes, issue #5747

@gfichtenholt
Copy link
Contributor

just curious, is there a similar issue in flux plugin?
yes, issue #5747

would it be ok to ask you to fix both as long as you're at it? Code should be similar

@dlaloue-vmware
Copy link
Collaborator Author

dlaloue-vmware commented Dec 1, 2022

would it be ok to ask you to fix both as long as you're at it? Code should be similar

I don't mind.
but can it be 2 separate PRs, or you prefer me to do it in the same PR?

@gfichtenholt
Copy link
Contributor

would it be ok to ask you to fix both as long as you're at it? Code should be similar

I don't mind. but can it be 2 separate PRs, or you prefer me to do it in the same PR?

just do it here, its like 2 more files for a grand total of 5 or 6

Copy link
Contributor

@gfichtenholt gfichtenholt left a comment

Choose a reason for hiding this comment

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

I am ok with this. I think there are just some linter error(s) to clean up, then you're set

@dlaloue-vmware dlaloue-vmware marked this pull request as draft December 2, 2022 06:54
@dlaloue-vmware
Copy link
Collaborator Author

moved to draft, as additional changes will be added

@dlaloue-vmware dlaloue-vmware changed the title Issue5746 - secrets not properly updated if auth is partially redacted [repository] fixes and enhancements for repository update support Dec 6, 2022
@dlaloue-vmware dlaloue-vmware marked this pull request as ready for review December 6, 2022 06:37
Copy link
Contributor

@absoludity absoludity left a comment

Choose a reason for hiding this comment

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

Hi Dimitri

(note: the PR has many small changes, but i was fixing issues as i was testing, hence the list)

Yeah - I don't think I did a good job of reviewing this past the first 400 lines or so. I think it's pretty well established that code reviews degrade as the diff gets bigger beyond a certain point... certainly true for me. If possible in the future, try to push a PR whenever you have a small unit that can be reviewed (ie. 200-400 lines).

Anyway, I've left a few thoughts, but none of it blocking.

Please don't land this until we've cut the release - it's the kind of larger change that could have unseen impact that I'd prefer to have us dogfood for a while in dev before releasing.

Thanks!

@@ -40,6 +40,9 @@ const (
// see docs at https://fluxcd.io/docs/components/source/ and
// https://fluxcd.io/docs/components/helm/api/
fluxHelmRepositories = "helmrepositories"

// description support
Annotation_Description_Key = "kubeapps.dev/description"
Copy link
Contributor

Choose a reason for hiding this comment

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

Not important, but any reason to use snake-case here? The Go convention is to always use MixedCaps (public) or mixedCaps (private) for all identifiers (with a few exceptions).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

no particular reason.
this was copied from the carvel plugin, where i introduced them that way - i think the reason is that the code already had constants with underscore though all caps.
i can easily fix that.

Comment on lines 975 to 977
func getDescription(fluxRepo *sourcev1.HelmRepository) string {
return fluxRepo.Annotations[Annotation_Description_Key]
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Did you mean to remove these and use the same function defined in utils? (or vice-versa?)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i don't think we have those functions in a utils file in flux plugin or in a shared utils

Copy link
Contributor

Choose a reason for hiding this comment

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

It's in the kapp_controller/server_utils.go that you've added below (I hadn't noticed earlier that that was specific to kapp_controller). Just wondering if it should be DRY'd up and used just once... perhaps in plugins/pkg/k8sutils/k8sutils.go? Fine either way.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I will make the code common, that is the right thing to do.

Comment on lines +482 to +492
if provider != "" && provider != "generic" {
if request.Auth != nil && request.Auth.Type != corev1.PackageRepositoryAuth_PACKAGE_REPOSITORY_AUTH_TYPE_UNSPECIFIED {
return nil, status.Errorf(codes.InvalidArgument, "Auth provider cannot be configured in combination with another auth method")
}
if repo.Spec.Provider != "" && repo.Spec.Provider != "generic" && repo.Spec.Provider != provider {
return nil, status.Errorf(codes.InvalidArgument, "Auth provider cannot be changed.")
}
repo.Spec.Provider = provider
} else {
repo.Spec.Provider = ""
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm just trying to understand some of the logic here: on lines 487 we explicitly disallow the provider from being changed if it has been set, but on line 491 we allow it to be set to empty. So, unless I'm missing something, users can change the auth provider, they just need to first set it to empty then set it?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The idea was that changing the provider did not really make sense (the original code was completely ignoring the new value) so we are explicitly rejecting such change.
The main reason to allow to unset the provider is that the user may have tried with the provider and it did not work and as such is switching back to using basic auth for example.
But yes, a side effect would be that you could unset the provider and switch to another one in the next update.

Comment on lines +133 to +137
if existingSecret != nil {
if err = secretInterface.Delete(ctx, existingSecret.Name, metav1.DeleteOptions{}); err != nil {
log.Errorf("Error deleting existing secret: [%s] due to %v", err)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't remember how the discussions ended, but I thought in the past we'd talked about the fact that we should not delete a secret unless it was created by kubeapps? That is, if I create a repo in Kubeapps (perhaps via the CLI, not relevant) and associate an existing secret with that repo, what should happen if I then update the repo credentials via the Kubeapps UI.

Also wondering, in what case should the error when deleting the secret here not be raised? Why is it not raised here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It is only deleting it because this is a secret created by kubeapps. we are not deleting secrets that kubeapps has not created.
As per the spec, there is a validation that ensures that we are not switching 'mode' between user managed and kubeapps managed secrets. So in this code path, we know this is a kubeapps managed secret.

Comment on lines +392 to +394
if (ck.Cert == redactedString && !hadSecretTlsCert) || (ck.Key == redactedString && !hadSecretTlsKey) {
return nil, false, status.Errorf(codes.InvalidArgument, "Invalid configuration, unexpected REDACTED content")
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for all these checks - ensuring that we'll know if the UX sends the incorrect redacted content (I assume?).

Comment on lines +608 to +616
for server, entry := range config.Auths {
docker := &corev1.DockerCredentials{
Server: server,
Username: entry.Username,
Password: entry.Password,
Email: entry.Email,
}
return docker, nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why you're using a for loop over the range of config.Auths here? It reads as though you're just returning after using the first of config.Auths always? But even then, there is no concept of "first" for a map in go (config.Auths is a map[string]DockerConfigEntry I think?) - the order when you iterate a map in go is explicitly random.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I reused existing code. i.e. that is how Kubeapps has been handling AppRepository image pull secrets and docker config, assuming there was only one even though the struct is a collection.
is there a better way to take one item from a map than this kind of loop?

Copy link
Contributor

Choose a reason for hiding this comment

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

The normal way to get ordered output from a map would be to get the keys and order those, but yeah, not much point if the assumption here is that there's only a single credential. It'd be worth a comment so that it's clear what the assumption is (here and in the other code where you found it, if it's not already commented there, it should be).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i will add a comment.
I will try to find the other code assuming a single credentials, but i don't want to bloat the PR even more :-)

Comment on lines -323 to +324
finalHeader = `Bearer ${bearerToken}`;
finalHeader = bearerToken;
Copy link
Contributor

Choose a reason for hiding this comment

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

This change is surprising? Was it a bug currently, or why is the Bearer not included now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

i think this was a left-over bug from when the UI was switched to the new API.
The UI code was not changed to comply with what the spec says. The UI was sending the token prefixed with Bearer, and the backend would strip the prefix if present, only (for helm) to add it back before putting it in the secret.
On a read, the backend would always send the token only, without the Bearer prefix (as per the spec). So the UI was inconsistent between its read and write operations.
this is double defensive and inconsistent code that makes things so hard to read and understand, so i cleaned it up.

@dlaloue-vmware
Copy link
Collaborator Author

to avoid making even more changes to this PR, is it ok to push the cleanups to another PR?

@absoludity
Copy link
Contributor

to avoid making even more changes to this PR, is it ok to push the cleanups to another PR?

Doesn't matter to me either way (it's already huge - but whatever works for you). It'd just be helpful not to land anything until we're confident the current release is good. So if it's not landing, it might be simpler just to update this one with any small cleanups (and anyway, the DRYing up of your two functions will reduce the diff :) )

@dlaloue-vmware dlaloue-vmware merged commit ed020ef into vmware-tanzu:main Dec 15, 2022
@dlaloue-vmware dlaloue-vmware deleted the issue5746 branch December 15, 2022 19:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants