-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
✨Support reset password for machine #5885
Conversation
Welcome @ruifaling! |
Hi @ruifaling. Thanks for your PR. I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here.
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
:sparkles:
Support reset password for machine
:sparkles:
Support reset password for machine@@ -62,6 +63,9 @@ func NewInitControlPlane(input *ControlPlaneInput) ([]byte, error) { | |||
input.WriteFiles = input.Certificates.AsFiles() | |||
input.WriteFiles = append(input.WriteFiles, input.AdditionalFiles...) | |||
input.SentinelFileCommand = sentinelFileCommand | |||
if input.AdminPass != "" { | |||
input.ResetPwd = "- '(echo " + input.AdminPass + ";sleep 1;echo " + input.AdminPass + ") | passwd root' " |
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 not expert in this area
not sure this is the right way to input?
do we have any reference of the usage 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.
If you mean the script:[(https://linuxhandbook.com/passwd-command/;)]
Of course, there are different ways to implement it through cloudinit, but I think it's enough to execute this script once by runcmd https://github.com/madorn/cloud-init-guide/blob/master/13-run_commands.txt
|
||
//adminPass is the admin pass to inject to the machine | ||
// +optional | ||
AdminPass string `json:"adminPass"` |
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 I'm not wrong, according to https://cloudinit.readthedocs.io/en/latest/topics/examples.html#including-users-and-groups this is already doable with
Passwd *string `json:"passwd,omitempty"` |
Have you considered this option?
/hold
Also, I have some concerns about this approach given that it requires to specify the admin password in plain text into the KubeadmConfig object, and then the same password will be repeated without encryption into the generated data secret that gets passed to machines.
@randomvariable opinions?
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.
After testing, we can use user group to update the password .,and we can put the hashed passwd in the kubeadmConfig.If It is the right way ,I will continue to modify this pr
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.
not sure I got your comment. if you can use users, then no changes are required, or am I missing something?
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.
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.
There need some changes, As the cloudinit remind(and verified by my test), we should use plain_text_passwd or hashed_passwd for already users
So If I'm reading this correctly I think I'd expect the KubeadmConfigSpec.users user input to satisfy and behave accordingly to the above docs without capi adding any additional magic, would that cover your use case?
Please note this feature has security caveats as stated in the cloud init docs. I'd expect this OS tuning to be configured as a day two thing out of band beyond capi for most scenarios. Also this might be good to discuss as part of #5294 about how much we want to get into providing automated management for this and the appropriate UX.
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.
Just an additional data point, maybe it helps.
CAPO uses the existing passwd
and lockPassword
fields to set a password: (for debugging purposes in e2e tests)
- name: "capi"
sudo: "ALL=(ALL) NOPASSWD:ALL"
# user: capi, passwd: capi
passwd: "$6$rounds=4096$yKTFKL6RmN128$a7cGMiNjeTSd091s6QzZcUNrMTgm3HhML5rVmpDFlCfgD7scTW7ZHr0OChcXCaeiO/kbhdn0XzIzWk63nSqRH1"
lockPassword: false
Not sure if I follow the discussion correctly. Is your use case different / do the existing fields don't work in your case?
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 only suit for new users not for already users
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.
not sure I got your comment. if you can use users, then no changes are required, or am I missing something?
There are some changes here. Please re-check,Thanks.
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.
Ah got it.
In my opinion it should be fine to add the new HashedPasswd
field, but we cannot just drop the Passwd
field from the v1beta1 API as it's a breaking change. So I would suggest to modify the PR to keep the Passwd
field.
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.
Ah got it.
In my opinion it should be fine to add the new
HashedPasswd
field, but we cannot just drop thePasswd
field from the v1beta1 API as it's a breaking change. So I would suggest to modify the PR to keep thePasswd
field.
so you mean we keep both Passwd
and HashedPasswd
fileds
/ok-to-test |
/retest |
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'm not a cloud-init expert, but the proposed change violates API deprecation guidelines; it also introduces a regression when creating users.
As suggested by @sbueringer, HashedPasswd should be a new, additional field; also comments should be updated describing when to use one or the other
@@ -279,7 +279,7 @@ type User struct { | |||
|
|||
// Passwd specifies a hashed password for the user | |||
// +optional | |||
Passwd *string `json:"passwd,omitempty"` | |||
HashedPasswd *string `json:"hashedPasswd,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.
Renaming an existing field is an API-breaking change and it cannot be implemented without following deprecation guidelines.
Also, given my understanding of the cloud-init code, passwd
is used for setting the password of new users, which is a use case we want to continue to support.
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 have some modify
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 ,passwd is used only for new users,and hashed_passwd could used for new users and already exist users.If we want to distinguish them,we can keep both passwd and hashed_passwd field
{{- if .Passwd }} | ||
passwd: {{ .Passwd }} | ||
{{- if .HashedPasswd }} | ||
hashed_passwd: {{ .HashedPasswd }} |
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.
See comment above about the need of preserving passwd
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.
Thx, looks great. One suggestion for godocs.
@@ -296,6 +296,10 @@ type User struct { | |||
// SSHAuthorizedKeys specifies a list of ssh authorized keys for the user | |||
// +optional | |||
SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty"` | |||
|
|||
// HashedPasswd specifies a hashed password for the already exist user |
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.
Just to emphasize it a bit more.
// HashedPasswd specifies a hashed password for the already exist user | |
// HashedPasswd specifies a hashed password for the user. | |
// NOTE: HashedPasswd can be used for existing and new users. |
// Passwd specifies a hashed password for the user.
// NOTE: Passwd can be only used for new users.
// +optional
Passwd *string `json:"passwd,omitempty"`
About the failed tests: pull-cluster-api-verify-main Looks like you just have to run pull-cluster-api-test-main Some context: we have to ensure the API types are roundtrip-able, which means we're able to convert between different versions of a type (via a conversion webhook). This is necessary to avoid losing some fields when e.g. a controller which is implemented with the v1alpha3 types writes an object of that type and we don't want to lose a field introduced in v1beta1. The conversions are implemented in
Concrete: To fix for i, _ := range restored.Spec.Users {
dst.Spec.Users[i].HashedPasswd = restored.Spec.Users[i].HashedPasswd
} There might be other cases where we didn't already implement the backup/restore with the annotation, but those cases should be implemented similarly. Feel free to ask if you have further questions, the conversion is not exactly the most trivial thing in our codebase :) |
/retest |
/retest |
1 similar comment
/retest |
Thanks very much for your suggestions.Now I really have some question.Firstly, when I run make generate,the conversion.go will remove the method Convert_v1beta1_User_To_v1alpha4_User and Convert_v1beta1_User_To_v1alpha3_User,and it will bring some errors,so what makes it remove the method ? Secondly,because the removal of this method caused some errors, I added this method back manually, now the failed test about 'pull-cluster-api-verify-main' is that what caused it ?https://storage.googleapis.com/kubernetes-jenkins/pr-logs/pull/kubernetes-sigs_cluster-api/5885/pull-cluster-api-verify-main/1481189478797152256/build-log.txt |
Adding the method manually won't work as the zz_generated files are just overwritten again by the generation. I'll take a closer look locally and come back to you. |
You have to use the zz_generated files generated by the conversion target. Essentially the conversion tells us that it doesn't know if the generated conversion in That's why manual intervention is necessary. You have to do the following:
func Convert_v1beta1_User_To_v1alpha3_User(in *bootstrapv1.User, out *User, s apiconversion.Scope) error {
// User.HashedPasswd does not exist in kubeadm v1alpha3 API.
return autoConvert_v1beta1_User_To_v1alpha3_User(in, out, s)
}
func Convert_v1beta1_User_To_v1alpha4_User(in *bootstrapv1.User, out *User, s apiconversion.Scope) error {
// User.HashedPasswd does not exist in kubeadm v1alpha4 API.
return autoConvert_v1beta1_User_To_v1alpha4_User(in, out, s)
} Our version of these funcs just ignores the HasedPasswd field, which is the only thing we can do in that case. Then the verify job should be happy :) |
The problem is really solved! Thank you very much for your help. This time PR I learned a lot. As a newcomer to this project, I benefited a lot from your help. Thanks again!! |
You're welcome and thank you for the feedback, that's always nice to hear :) Can you please squash the commits? We're running Prow in merge-mode which means the commits are preserved when merging (this is done so we're able to generate release notes correctly). Otherwise lgtm from my side. |
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.
Only one nit on naming (naming i hard 😉) otherwise lgtm
@@ -296,6 +297,11 @@ type User struct { | |||
// SSHAuthorizedKeys specifies a list of ssh authorized keys for the user | |||
// +optional | |||
SSHAuthorizedKeys []string `json:"sshAuthorizedKeys,omitempty"` | |||
|
|||
// HashedPasswd specifies a hashed password for the user. | |||
// NOTE: HashedPasswd can be used for existing and new users. |
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 I got it right from the cloud-init codebase, HashedPasswd must be used only for existing users, or am I word
Also:
- could you kindly move this below Passwd, given that they are logically related
- should this be
changePasswd
or something that makes it more explicit its intended usage
@vincepri @sbueringer @enxebre @CecileRobertMichon opinions?
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 could only find the following doc:
Most of these configuration options will not be honored if the user already exists. The following options are the exceptions; they are applied to already-existing users: plain_text_passwd, hashed_passwd, lock_passwd, sudo, ssh_authorized_keys, ssh_redirect_user.
https://cloudinit.readthedocs.io/en/latest/topics/modules.html?highlight=hashed_passwd#users-and-groups
Based on that I would guess that they also work on new users, but it's not clear.
Based on this comment #5885 (comment) it works on new and existing comments (I assume this part was tested @ruifaling?)
Regarding naming, I was under the impression that we're trying to keep our fields roughly in sync with the field names of cloud-init, but I agree their name is not great. I assume the format of passwd and hashedpasswd in cloud-init is the same? If yes and if we don't necessarily want to mirror cloud-init names, +1 to ChangePasswd
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.
HashedPasswd
The result of my test is that hashed_passwd could be used for new users and existing users
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 could only find the following doc:
Most of these configuration options will not be honored if the user already exists. The following options are the exceptions; they are applied to already-existing users: plain_text_passwd, hashed_passwd, lock_passwd, sudo, ssh_authorized_keys, ssh_redirect_user.
https://cloudinit.readthedocs.io/en/latest/topics/modules.html?highlight=hashed_passwd#users-and-groupsBased on that I would guess that they also work on new users, but it's not clear.
Based on this comment #5885 (comment) it works on new and existing comments (I assume this part was tested @ruifaling?)
Regarding naming, I was under the impression that we're trying to keep our fields roughly in sync with the field names of cloud-init, but I agree their name is not great. I assume the format of passwd and hashedpasswd in cloud-init is the same? If yes and if we don't necessarily want to mirror cloud-init names, +1 to
ChangePasswd
Yes ,I have tested it,hashedpasswd could be used for new users and existing users.
And yes, the format of passwd and hashedpasswd in cloud-init is the same, and the representative field of HashedPasswd in cloudinit is hashed_ passwd.
And HashedPasswd may be a little better than ChangePasswd based on the fact that it is suitable for both new users and existing users?
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 me there are two options with different underlying assumptions:
- CABPK tries to mirror cloud-init APIs => HashedPasswd would be the right name, to make clear that we're setting the cloud-init hashed_passwd field
- CABPK provides a user-friendly API with the ideal field names independent of cloud-init => I think we could:
- either keep only
Passwd
, document that the passwd is hashed (which it already is today) and usePasswd
to set (only) the cloud-inithashed_passwd
- add
HashedPasswd
and deprecatePasswd
, as it doesn't seem especially useful to have both - => tl;dr I would try to get eventually to only one field, for which the ideal field name might be
Passwd
orHashedPasswd
- either keep only
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.
hashed_passwd
will not work for Windows - so do that only if that's acceptable for that user group (it better be).
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.
hashed_passwd will not work for Windows - so do that only if that's acceptable for that user group (it better be).
Okay, not sure I got that right :). We shouldn't break Windows user and I think that would be not acceptable for them.
Just that I got it right:
- we need cloud-init passwd for Windows because hashed_passwd does not work
- we want cloud-init hashed_passwd for Linux users to be able to also set pw's of existing users.
Correct?
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.
It should probably be in a secret, especially if there is going to support a non hashed variant? That way it can be encrypted at rest.
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, thanks all for the quick feedback.
I will try to reach out on people working on windows next week after MLK day, but
WRT to "there is going to support a non hashed variant", this is not an option being considered in this PR
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.
@jayunit100 if you have some time could you give an opinion from windows land?
@ruifaling: PR needs rebase. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
Closing due to inactivity. Due to the lengthy discussions inline I'd suggest to follow-up in an issue first before a new PR is opened. /close |
@vincepri: Closed this PR. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
What this PR does / why we need it:
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #5883