-
Notifications
You must be signed in to change notification settings - Fork 59
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
Create default passwords when dev mode is set. #441 #442
base: main
Are you sure you want to change the base?
Conversation
cmoulliard
commented
Nov 8, 2024
- Add new parameter to enable/disable: dev mode
- Set the default password for gitea
- [Feature] Have a --dev parameter able to configure gitea and argocd with default: username/password #441
Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
…a new password. cnoe-io#441 Signed-off-by: cmoulliard <[email protected]>
Question: Is it the best place to add the code able to generate a new password (= developer) when devMode is enabled -
|
Yeah after install() comes back with no errors. |
… - developer. Create a kubeClient part of the k8s util package. cnoe-io#441 Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
This comment was marked as resolved.
This comment was marked as resolved.
Signed-off-by: cmoulliard <[email protected]>
If what I did cannot work, we have 2 options:
|
I am still not sure if the flag name is what we want to go with. Is proving static password the only thing needed for dev mode? Does it describe what it does? If we add more config changes for dev mode in the future, do we want to provide ways to control each change? If the names I proposed in the issue are too long, can we get away with a short flag? I do like the idea of having a static default passwords for sure. |
If we continue to develop idpbuilder, having a devMode help a lot as we do for quarkus |
Let's review that later when we have a PR which is working as |
I will make a try to see if that works |
This comment was marked as resolved.
This comment was marked as resolved.
I was able to play with a user RBAC
ConfigMap
As the following secret is created on the flight by argocd when Argocd Secret
|
…veloper's password. cnoe-io#441 Signed-off-by: cmoulliard <[email protected]>
The PR supports now to log on to the UI of Argocd using (developer/developer) with RBAC Can you please review it ? |
Signed-off-by: cmoulliard <[email protected]>
…oper Signed-off-by: cmoulliard <[email protected]>
Apparently we cannot use for gitea
I will then revert to the user |
… fails Signed-off-by: cmoulliard <[email protected]>
…for argocd Signed-off-by: cmoulliard <[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.
If you are having problems setting passwords on install, we can change them through APIs after install.
namespace: argocd | ||
data: | ||
policy.csv: | | ||
p, role:developer, applications, *, *, allow |
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.
What's the purpose of having a separate account that has a very similar permissions as admin?
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 is an account for the developers and it only allows to handle applications
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 you tell me if this is inline with what you are thinking?
- Use a random password for the developer and admin account if the dev password flag is unset.
- Use a static, known password for the developer and admin account if the dev password flag is set.
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.
Option 2 => Use a known password for the developer and admin account if the dev password flag is set
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.
Ok that sounds good to me. Looks like Gitea static password isn't working for some reason?
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.
Ok that sounds good to me. Looks like Gitea static password isn't working for some reason?
For gitea when using dev-mode, we should still use as user: giteaAdmin and password = developer
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.
Since you are adding a user called developer to argocd, we may as well add the developer user in Gitea.
pkg/controllers/localbuild/argo.go
Outdated
return ctrl.Result{}, fmt.Errorf("Error marshalling patch data: %w", err) | ||
} | ||
|
||
kubeClient, err := k8s.GetKubeClient() |
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 reconciler has client already. You can just use that instead. e.g. r.Client.
. You can also change passwords through ArgoCD api.
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.
You can also change passwords through ArgoCD api.
That will require to be done in a 2nd step while here the idea is to have the account developer/developer available when packages are installed 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.
r.Client
fixed. See: 7d81b27
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.
You can also change passwords through ArgoCD api.
That will require to be done in a 2nd step while here the idea is to have the account developer/developer available when packages are installed too
Yeah I am starting to think we should set them through API for both Gitea and ArgoCD in every invocation of idpbuilder. Instead of relying on manifests.
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 should then (maybe) create some job(s) which are applied post installation of the core package like gitea or argocd and able to execute some additional steps based on parameters passed.
Until now, the first action could be to create a new user: developer able to log on using as user/pwd => developer/developer or idpbuilder/developer if the parameter passed is --dev-mode
.
A second job could also patch existing resources if by example we pass a different DNS domain = --host
etc
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.
flag renamed from "dev" to "dev-mode". See: a8c3016
pkg/controllers/localbuild/argo.go
Outdated
err = kubeClient.Get(ctx, client.ObjectKey{Name: argocdAdminSecretName, Namespace: argocdNamespace}, &s) | ||
if err != nil { | ||
return ctrl.Result{}, fmt.Errorf("getting argocd secret: %w", err) | ||
} | ||
|
||
// Patching the argocd-secret with the user's hashed password | ||
err = kubeClient.Patch(ctx, &s, client.RawPatch(types.StrategicMergePatchType, patchBytes)) | ||
if err != nil { | ||
return ctrl.Result{}, fmt.Errorf("Error patching the Secret: %w", err) | ||
} |
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.
You can use server side apply instead here to simplify this process.
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.
Ok. I will review
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.
What do you mean by "server side" ? My code is similar to what we do here with the Gitea -
return r.Client.Patch(ctx, &u, client.Apply, client.ForceOwnership, client.FieldOwner(v1alpha1.FieldManager)) |
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 way it's done in Gitea is server side apply. If you look further up, you'll see it's working with unstructured object to avoid having ownership of fields we do not care about. Sometimes we see errors like "object has been updated and version doesn't match". Server side apply avoids that.
This talks about it: https://eng.d2iq.com/blog/conflict-resolution-kubernetes-server-side-apply/
Here's where unstructured object is used:
idpbuilder/pkg/controllers/localbuild/gitea.go
Lines 163 to 166 in f31a08e
u := unstructured.Unstructured{} | |
u.SetName(giteaAdminSecret) | |
u.SetNamespace(giteaNamespace) | |
u.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Secret")) |
Here's another example:
Lines 78 to 86 in d14289a
func ApplyAnnotation(ctx context.Context, kubeClient client.Client, obj client.Object, annotations map[string]string, opts ...client.PatchOption) error { | |
// MUST be unstructured to avoid managing fields we do not care about. | |
u := unstructured.Unstructured{} | |
u.SetAnnotations(annotations) | |
u.SetName(obj.GetName()) | |
u.SetNamespace(obj.GetNamespace()) | |
u.SetGroupVersionKind(obj.GetObjectKind().GroupVersionKind()) | |
return kubeClient.Patch(ctx, &u, client.Apply, opts...) | |
} |
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.
Fixed. See: 80a785b
pkg/controllers/localbuild/argo.go
Outdated
argocdDevModePassword = "developer" | ||
argocdAdminSecretName = "argocd-secret" | ||
argocdInitialAdminSecretName = "argocd-initial-admin-secret" | ||
argocdInitialAdminPasswordKey = "argocd-initial-admin-secret" | ||
argocdNamespace = "argocd" |
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.
These are already defined in other packages I think. Either export them or move them to globals or APIs
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.
Ok. I will review
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 removed 2 non used constants and others are non declared in another go file or package. See: 78e1e40
@@ -20,6 +20,7 @@ import ( | |||
const ( | |||
recreateClusterUsage = "Delete cluster first if it already exists." | |||
buildNameUsage = "Name for build (Prefix for kind cluster name, pod names, etc)." | |||
devModeUsage = "When enabled, the platform will run the core packages with developer password." |
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 just not sold on the name
dev mode
. idpbuilder is primary used for development and testing purposes already. I think we should use more explicit name with a short flag. - Even if we accept dev mode, we shouldn't limit the flag name to just passwords. dev mode could mean a lot of different things. This should be a meta flag.
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.
- idpbuilder is primary used for development and testing purposes already. I think we should use more explicit name with a short flag.
If this is the case, then we should install gitea and argocd using a non generated password ;-)
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.
2. Even if we accept dev mode, we shouldn't limit the flag name to just passwords. dev mode could mean a lot of different things. This should be a meta flag.
What about using the the parameter: --devPwd
or --devPassword
as boolean @nabuskey
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 ok with dev-pwd
or dev-password
since we use snake case for our flags. We can also have --dev-mode flag that is essentially a convenient flag that enables dev passwords and any other QOL stuff for dev purposes.
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.
Finally we aligned our paths => I will then use --dev-mode
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.
To be clear, I meant to have two flags. (--dev-password
OR --dev-pwd
) AND --dev-mode
because we could enable other QOL features under --dev-mode
other than static passwords.
pkg/k8s/util.go
Outdated
|
||
"github.com/cnoe-io/idpbuilder/pkg/util" | ||
"k8s.io/apimachinery/pkg/runtime" | ||
"sigs.k8s.io/controller-runtime/pkg/client" | ||
) | ||
|
||
var ( | ||
setupLog = ctrl.Log.WithName("k8s") |
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 rather not produce log messages in utility functions. Let's wrap the error instead. e.g. fmt.Errorf("Error creating kubernetes client: %w"
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.
ok
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.
Fixed with: 8158551
…orf() Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
…out. Signed-off-by: cmoulliard <[email protected]>
Signed-off-by: cmoulliard <[email protected]>
I pushed a commit: 3c3511d to show the Remark: This code should be reviewed and improved as the secret containing the developer username/password is argocd-secret where the password has been bcrypted and by consequence we cannot get and decode it from the secret |
// TODO: The following code should be reviewed and improved as the secret containing the developer username/password is argocd-secret | ||
// where the password has been bcrypted and by consequence we cannot get and decode it from the secret | ||
// This is why we are going to add it here BUT it will be displayed every time no matter if --dev-mode has been used or not | ||
if strings.Contains(s.Name, "gitea") { | ||
data.Data["username-developer"] = "giteAdmin" | ||
data.Data["password-developer"] = "developer" | ||
} else if strings.Contains(s.Name, "argocd") { | ||
data.Data["username-developer"] = "developer" | ||
data.Data["password-developer"] = "developer" | ||
} | ||
|
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 can get the localbuild object from K8s since it's essentially our way of storing configurations. You added the DevMode
field so you can just check the value. We should change that field name btw. devPassword
makes sense. There's a typo: giteAdmin
-> giteaAdmin
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 can get the localbuild object from K8s since it's essentially our way of storing configurations.
Yes but the flag --dev-mode
or --dev-password
is not passed at all to the command: idp get secrets
and users will not like to perform such a command idp get secrets --dev-mode
.
The more I think about it, I think it's cleaner to change passwords and add users post install. This enables flows like:
|
I'm also in favor to go down that road as I mentioned also in a different comments where we could use job or something else able to perform additional config steps or let's say post install steps. 2 remarks:
|
As the result about what I did and also what I discovered imply that finally we hack the existing code to support to generate a WDYT ? @nabuskey |
What I meant was to do this in post-install (e.g. the core packages are ready) during the reconciliation loop. Essentially around here:
Instead of using manifests to set initial passwords, change them to a known value if the dev password flag is set.
I agree with this. We should have a separate command to configure / reconfigure things.
|
I dont follow you
I don't set initial password using manifests. Can you then elaborate a bit here ? @nabuskey |
So here's the flow I am thinking.
|
This is perhaps doable for gitea but not for argocd as there is no argocd Go Lib that we could use for that purpose, the Argocd CLI don't offer such an option to create new account except to update an existing account The gitea go client allows to create a user (which is perhaps an admin user - to be verified)
I confirm that we can create a gitea user using such a code
|
https://cd.apps.argoproj.io/swagger-ui#operation/AccountService_UpdatePassword It's available through the rest api. We should be able to make a request for this I think. |
This is the request used by the argocd CLI but there is no command or REST API to create a new user. |