-
Notifications
You must be signed in to change notification settings - Fork 1.4k
🐛 Make joinConfiguration.discovery.bootstrapToken.token optional #12107
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
Conversation
/cc @Karthik-K-N |
@@ -585,7 +585,7 @@ type BootstrapTokenDiscovery struct { | |||
// token is a token used to validate cluster information | |||
// fetched from the control-plane. | |||
// +required | |||
// +kubebuilder:validation:MinLength=1 | |||
// +kubebuilder:validation:MinLength=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.
I looked into #12019 that fixed a similar issue by making the field optional and adding omit empty, which seems a cleaner option to allow users to not set a field.
@JoelSpeed WDYT?
Also, Is this a non-breaking change? (I assume it is not breaking, but I would like to double check)
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 looked into #12019 that fixed a similar issue by making the field optional and adding omit empty, which seems a cleaner option to allow users to not set a field.
Right, making it optional would be better, will wait for @JoelSpeed's response.
Also, Is this a non-breaking change? (I assume it is not breaking, but I would like to double check)
It should be a non breaking change.
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.
Technically any change we would make here could be considered breaking.
Adding a min length of 0 to a required field is odd and I would avoid personally. A required field where the zero value is valid does not actually behave as a required field for those using structured clients. For those using unstructured clients, it's even weirder, they have to specify the key, and possibly then set the zero value.
The lesser of two evils here, if there needs to be a case where this field is empty, it to make the field optional with omitempty.
Who consumes this API? Do we understand what the consumers will do if they see an empty string 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.
Thank you for the response, Token is being currently used in kubeadm_config controller and we have logic written to handle both the cases, that is to respect the value if set or generate one. Reference
cluster-api/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
Lines 1270 to 1284 in 3e6bc6a
// if BootstrapToken already contains a token, respect it; otherwise create a new bootstrap token for the node to join | |
if config.Spec.JoinConfiguration.Discovery.BootstrapToken.Token == "" { | |
remoteClient, err := r.ClusterCache.GetClient(ctx, util.ObjectKey(cluster)) | |
if err != nil { | |
return ctrl.Result{}, err | |
} | |
token, err := createToken(ctx, remoteClient, r.TokenTTL) | |
if err != nil { | |
return ctrl.Result{}, errors.Wrapf(err, "failed to create new bootstrap token") | |
} | |
config.Spec.JoinConfiguration.Discovery.BootstrapToken.Token = token | |
log.V(3).Info("Altering JoinConfiguration.Discovery.BootstrapToken.Token") | |
} |
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.
As per suggestions, changed to field to optional
. PTAL.
ec3058e
to
2426f1d
Compare
c1f3b94
to
fadadca
Compare
@fabriziopandini @JoelSpeed, PTAL if the change is okay? |
@@ -584,10 +584,10 @@ type Discovery struct { | |||
type BootstrapTokenDiscovery 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.
This object now has no required field, so there will be difference in behaviour between not specifying the object, and specifying bootstrapToken: {}
.
This is generally not desirable.
Is it valid to have an empty bootstrapToken
? In the current use case, which alternative field would be used instead?
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.
From code reading what I can see is that the both the scenario's are handled currently, If boostStrapToken
is not set and its nil, its being initialized first.
Also we have necessary checks for respecting the already set values as well.
Reference:
cluster-api/bootstrap/kubeadm/internal/controllers/kubeadmconfig_controller.go
Lines 1242 to 1284 in 3e6bc6a
// otherwise it is necessary to ensure token discovery is properly configured | |
if config.Spec.JoinConfiguration.Discovery.BootstrapToken == nil { | |
config.Spec.JoinConfiguration.Discovery.BootstrapToken = &bootstrapv1.BootstrapTokenDiscovery{} | |
} | |
// calculate the ca cert hashes if they are not already set | |
if len(config.Spec.JoinConfiguration.Discovery.BootstrapToken.CACertHashes) == 0 { | |
hashes, err := certificates.GetByPurpose(secret.ClusterCA).Hashes() | |
if err != nil { | |
log.Error(err, "Unable to generate Cluster CA certificate hashes") | |
return ctrl.Result{}, err | |
} | |
config.Spec.JoinConfiguration.Discovery.BootstrapToken.CACertHashes = hashes | |
} | |
// if BootstrapToken already contains an APIServerEndpoint, respect it; otherwise inject the APIServerEndpoint endpoint defined in cluster status | |
apiServerEndpoint := config.Spec.JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint | |
if apiServerEndpoint == "" { | |
if !cluster.Spec.ControlPlaneEndpoint.IsValid() { | |
log.V(1).Info("Waiting for Cluster Controller to set Cluster.Spec.ControlPlaneEndpoint") | |
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil | |
} | |
apiServerEndpoint = cluster.Spec.ControlPlaneEndpoint.String() | |
config.Spec.JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint = apiServerEndpoint | |
log.V(3).Info("Altering JoinConfiguration.Discovery.BootstrapToken.APIServerEndpoint", "apiServerEndpoint", apiServerEndpoint) | |
} | |
// if BootstrapToken already contains a token, respect it; otherwise create a new bootstrap token for the node to join | |
if config.Spec.JoinConfiguration.Discovery.BootstrapToken.Token == "" { | |
remoteClient, err := r.ClusterCache.GetClient(ctx, util.ObjectKey(cluster)) | |
if err != nil { | |
return ctrl.Result{}, err | |
} | |
token, err := createToken(ctx, remoteClient, r.TokenTTL) | |
if err != nil { | |
return ctrl.Result{}, errors.Wrapf(err, "failed to create new bootstrap token") | |
} | |
config.Spec.JoinConfiguration.Discovery.BootstrapToken.Token = token | |
log.V(3).Info("Altering JoinConfiguration.Discovery.BootstrapToken.Token") | |
} |
Please correct If I missed anything @chrischdi @fabriziopandini
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 we are ok
Discovery has two mutually exclusive options, FileDiscovery and TokenDiscovery.
If File discovery is set, TokenDiscovery must not be set
If File discovery is not set, TokenDiscovery is used, either with the values specified by the users or, if those value are missing, with defaults.
Considering this, there wont be any difference in behaviour between not specifying the object, and specifying empty bootstrapToken: in both cases you accept all the defaults for TokenDiscovery
I'm merging to get this fix in tomorrow's patch release |
LGTM label has been added. Git tree hash: 1732d327cb8bccf3fed135e106cbf19d668447cf
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: fabriziopandini The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
/area bootstrap |
/cherry-pick release-1.10 |
@fabriziopandini: #12107 failed to apply on top of branch "release-1.10":
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-sigs/prow repository. |
@Amulyam24 @Karthik-K-N looks like it is required a manual cherry pick for the 1.10 branch |
🐛 Make joinConfiguration.discovery.bootstrapToken.token optional
What this PR does / why we need it:
In the cluster-api provider for IBM cloud, we set the API server endpoint explicitly in the join configuration. With the recent change via #11949, it has become mandatory to set the token value and cluster deployment fails with
This PR adds the change to not set a hard validation for token and use the one generated by bootstrap provider in case it is empty.
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 #