k8s_cluster_api/v1beta1/bootstrap/kubeadm.rs
1use super::*;
2
3pub use kubeadmconfig::KubeadmConfigSpec;
4pub use kubeadmconfig::KubeadmConfigTemplate;
5pub use kubeadmconfig::KubeadmConfigTemplateSpec;
6
7mod kubeadmconfig;
8
9/// InitConfiguration contains a list of elements that is specific "kubeadm init"-only runtime
10/// information.
11#[skip_serializing_none]
12#[derive(Clone, Debug, Default, Serialize, Deserialize)]
13#[serde(rename_all = "camelCase")]
14pub struct InitConfiguration {
15 #[serde(flatten)]
16 pub meta: TypeMeta,
17
18 /// BootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create.
19 /// This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature
20 // +optional
21 #[serde(default, skip_serializing_if = "Vec::is_empty")]
22 pub bootstrap_tokens: Vec<BootstrapToken>, // `json:"bootstrapTokens,omitempty"`
23
24 /// NodeRegistration holds fields that relate to registering the new control-plane node to the cluster.
25 /// When used in the context of control plane nodes, NodeRegistration should remain consistent
26 /// across both InitConfiguration and JoinConfiguration
27 // +optional
28 pub node_registration: Option<NodeRegistrationOptions>, // `json:"nodeRegistration,omitempty"`
29
30 // LocalAPIEndpoint represents the endpoint of the API server instance that's deployed on this control plane node
31 // In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint in the sense that ControlPlaneEndpoint
32 // is the global endpoint for the cluster, which then loadbalances the requests to each individual API server. This
33 // configuration object lets you customize what IP/DNS name and port the local API server advertises it's accessible
34 // on. By default, kubeadm tries to auto-detect the IP of the default interface and use that, but in case that process
35 // fails you may set the desired value here.
36 // +optional
37 #[serde(rename = "localAPIEndpoint")]
38 pub local_api_endpoint: Option<APIEndpoint>, // `json:"localAPIEndpoint,omitempty"`
39}
40
41// ClusterConfiguration contains cluster-wide configuration for a kubeadm cluster.
42#[skip_serializing_none]
43#[derive(Clone, Debug, Default, Serialize, Deserialize)]
44#[serde(rename_all = "camelCase")]
45pub struct ClusterConfiguration {
46 #[serde(flatten)]
47 pub meta: TypeMeta,
48
49 /// Etcd holds configuration for etcd.
50 /// NB: This value defaults to a Local (stacked) etcd
51 // +optional
52 pub etcd: Option<Etcd>, // `json:"etcd,omitempty"`
53
54 /// Networking holds configuration for the networking topology of the cluster.
55 /// NB: This value defaults to the Cluster object spec.clusterNetwork.
56 // +optional
57 pub networking: Option<Networking>, // `json:"networking,omitempty"`
58
59 // KubernetesVersion is the target version of the control plane.
60 // NB: This value defaults to the Machine object spec.version
61 // +optional
62 pub kubernetes_version: Option<String>, // `json:"kubernetesVersion,omitempty"`
63
64 /// ControlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it
65 /// can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port.
66 /// In case the ControlPlaneEndpoint is not specified, the AdvertiseAddress + BindPort
67 /// are used; in case the ControlPlaneEndpoint is specified but without a TCP port,
68 /// the BindPort is used.
69 /// Possible usages are:
70 /// e.g. In a cluster with more than one control plane instances, this field should be
71 /// assigned the address of the external load balancer in front of the
72 /// control plane instances.
73 /// e.g. in environments with enforced node recycling, the ControlPlaneEndpoint
74 /// could be used for assigning a stable DNS to the control plane.
75 /// NB: This value defaults to the first value in the Cluster object status.apiEndpoints array.
76 // +optional
77 pub control_plane_endpoint: Option<String>, // `json:"controlPlaneEndpoint,omitempty"`
78
79 /// APIServer contains extra settings for the API server control plane component
80 // +optional
81 pub api_server: Option<APIServer>, // `json:"apiServer,omitempty"`
82
83 /// ControllerManager contains extra settings for the controller manager control plane component
84 // +optional
85 pub controller_manager: Option<ControlPlaneComponent>, // `json:"controllerManager,omitempty"`
86
87 /// Scheduler contains extra settings for the scheduler control plane component
88 // +optional
89 pub scheduler: Option<ControlPlaneComponent>, // `json:"scheduler,omitempty"`
90
91 /// DNS defines the options for the DNS add-on installed in the cluster.
92 // +optional
93 pub dns: Option<DNS>, // `json:"dns,omitempty"`
94
95 /// CertificatesDir specifies where to store or look for all required certificates.
96 /// NB: if not provided, this will default to `/etc/kubernetes/pki`
97 // +optional
98 pub certificates_dir: Option<String>, // `json:"certificatesDir,omitempty"`
99
100 /// ImageRepository sets the container registry to pull images from.
101 /// If empty, `k8s.gcr.io` will be used by default; in case of kubernetes version is a CI build (kubernetes version starts with `ci/` or `ci-cross/`)
102 /// `gcr.io/k8s-staging-ci-images` will be used as a default for control plane components and for kube-proxy, while `k8s.gcr.io`
103 /// will be used for all the other images.
104 // +optional
105 pub image_repository: Option<String>, // `json:"imageRepository,omitempty"`
106
107 /// FeatureGates enabled by the user.
108 // +optional
109 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
110 pub feature_gates: BTreeMap<String, bool>, // `json:"featureGates,omitempty"`
111
112 /// The cluster name
113 // +optional
114 pub cluster_name: Option<String>, // `json:"clusterName,omitempty"`
115}
116
117/// JoinConfiguration contains elements describing a particular node.
118#[skip_serializing_none]
119#[derive(Clone, Debug, Default, Serialize, Deserialize)]
120#[serde(rename_all = "camelCase")]
121pub struct JoinConfiguration {
122 #[serde(flatten)]
123 pub meta: TypeMeta, // metav1.TypeMeta `json:",inline"`
124
125 /// NodeRegistration holds fields that relate to registering the new control-plane node to the cluster.
126 /// When used in the context of control plane nodes, NodeRegistration should remain consistent
127 /// across both InitConfiguration and JoinConfiguration
128 // +optional
129 pub node_registration: Option<NodeRegistrationOptions>, // `json:"nodeRegistration,omitempty"`
130
131 /// CACertPath is the path to the SSL certificate authority used to
132 /// secure comunications between node and control-plane.
133 /// Defaults to "/etc/kubernetes/pki/ca.crt".
134 // +optional
135 // TODO: revisit when there is defaulting from k/k
136 pub ca_cert_path: Option<String>, // `json:"caCertPath,omitempty"`
137
138 /// Discovery specifies the options for the kubelet to use during the TLS Bootstrap process
139 // +optional
140 // TODO: revisit when there is defaulting from k/k
141 pub discovery: Option<Discovery>, // `json:"discovery,omitempty"`
142
143 /// ControlPlane defines the additional control plane instance to be deployed on the joining node.
144 /// If nil, no additional control plane instance will be deployed.
145 // +optional
146 pub control_plane: Option<JoinControlPlane>, // `json:"controlPlane,omitempty"`
147}
148
149/// BootstrapToken describes one bootstrap token, stored as a Secret in the cluster.
150#[skip_serializing_none]
151#[derive(Clone, Debug, Default, Serialize, Deserialize)]
152#[serde(rename_all = "camelCase")]
153pub struct BootstrapToken {
154 /// Token is used for establishing bidirectional trust between nodes and control-planes.
155 /// Used for joining nodes in the cluster.
156 pub token: String, // `json:"token"`
157 /// Description sets a human-friendly message why this token exists and what it's used
158 /// for, so other administrators can know its purpose.
159 // +optional
160 pub description: Option<String>, // `json:"description,omitempty"`
161 /// TTL defines the time to live for this token. Defaults to 24h.
162 /// Expires and TTL are mutually exclusive.
163 // +optional
164 // pub ttl: *metav1.Duration `json:"ttl,omitempty"`
165 pub ttl: Option<i64>, // `json:"ttl,omitempty"`
166 /// Expires specifies the timestamp when this token expires. Defaults to being set
167 /// dynamically at runtime based on the TTL. Expires and TTL are mutually exclusive.
168 // +optional
169 pub expires: Option<metav1::Time>, // `json:"expires,omitempty"`
170 /// Usages describes the ways in which this token can be used. Can by default be used
171 /// for establishing bidirectional trust, but that can be changed here.
172 // +optional
173 #[serde(default, skip_serializing_if = "Vec::is_empty")]
174 pub usages: Vec<String>, // `json:"usages,omitempty"`
175 /// Groups specifies the extra groups that this token will authenticate as when/if
176 /// used for authentication
177 // +optional
178 #[serde(default, skip_serializing_if = "Vec::is_empty")]
179 pub groups: Vec<String>, // `json:"groups,omitempty"`
180}
181
182/// NodeRegistrationOptions holds fields that relate to registering a new control-plane or node to the cluster, either via "kubeadm init" or "kubeadm join".
183#[skip_serializing_none]
184#[derive(Clone, Debug, Default, Serialize, Deserialize)]
185#[serde(rename_all = "camelCase")]
186pub struct NodeRegistrationOptions {
187 /// Name is the `.Metadata.Name` field of the Node API object that will be created in this `kubeadm init` or `kubeadm join` operation.
188 /// This field is also used in the CommonName field of the kubelet's client certificate to the API server.
189 /// Defaults to the hostname of the node if not provided.
190 // +optional
191 pub name: Option<String>, // `json:"name,omitempty"`
192
193 /// CRISocket is used to retrieve container runtime info. This information will be annotated to the Node API object, for later re-use
194 // +optional
195 pub cri_socket: Option<String>, // `json:"criSocket,omitempty"`
196
197 /// Taints specifies the taints the Node API object should be registered with. If this field is unset, i.e. nil, in the `kubeadm init` process
198 /// it will be defaulted to []v1.Taint{'node-role.kubernetes.io/master=""'}. If you don't want to taint your control-plane node, set this field to an
199 /// empty slice, i.e. `taints: {}` in the YAML file. This field is solely used for Node registration.
200 // +optional
201 #[serde(default, skip_serializing_if = "Vec::is_empty")]
202 pub taints: Vec<corev1::Taint>, // `json:"taints,omitempty"`
203
204 /// KubeletExtraArgs passes through extra arguments to the kubelet. The arguments here are passed to the kubelet command line via the environment file
205 /// kubeadm writes at runtime for the kubelet to source. This overrides the generic base-level configuration in the kubelet-config-1.X ConfigMap
206 /// Flags have higher priority when parsing. These values are local and specific to the node kubeadm is executing on.
207 // +optional
208 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
209 pub kubelet_extra_args: BTreeMap<String, String>, // `json:"kubeletExtraArgs,omitempty"`
210
211 /// IgnorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered.
212 // +optional
213 #[serde(default, skip_serializing_if = "Vec::is_empty")]
214 pub ignore_preflight_errors: Vec<String>, // `json:"ignorePreflightErrors,omitempty"`
215}
216
217// APIEndpoint struct contains elements of API server instance deployed on a node.
218#[skip_serializing_none]
219#[derive(Clone, Debug, Default, Serialize, Deserialize)]
220#[serde(rename_all = "camelCase")]
221pub struct APIEndpoint {
222 /// AdvertiseAddress sets the IP address for the API server to advertise.
223 // +optional
224 pub advertise_address: Option<String>, // `json:"advertiseAddress,omitempty"`
225
226 /// BindPort sets the secure port for the API Server to bind to.
227 /// Defaults to 6443.
228 // +optional
229 pub bind_port: Option<i32>, // `json:"bindPort,omitempty"`
230}
231
232/// Etcd contains elements describing Etcd configuration.
233#[skip_serializing_none]
234#[derive(Clone, Debug, Default, Serialize, Deserialize)]
235#[serde(rename_all = "camelCase")]
236pub struct Etcd {
237 /// Local provides configuration knobs for configuring the local etcd instance
238 /// Local and External are mutually exclusive
239 // +optional
240 pub local: Option<LocalEtcd>, // `json:"local,omitempty"`
241
242 // External describes how to connect to an external etcd cluster
243 // Local and External are mutually exclusive
244 // +optional
245 pub external: Option<ExternalEtcd>, // `json:"external,omitempty"`
246}
247
248/// LocalEtcd describes that kubeadm should run an etcd cluster locally.
249#[skip_serializing_none]
250#[derive(Clone, Debug, Default, Serialize, Deserialize)]
251#[serde(rename_all = "camelCase")]
252pub struct LocalEtcd {
253 /// ImageMeta allows to customize the container used for etcd
254 #[serde(flatten)]
255 pub image_meta: ImageMeta, // `json:",inline"`
256
257 /// DataDir is the directory etcd will place its data.
258 /// Defaults to "/var/lib/etcd".
259 // +optional
260 pub data_dir: Option<String>, // `json:"dataDir,omitempty"`
261
262 /// ExtraArgs are extra arguments provided to the etcd binary
263 /// when run inside a static pod.
264 // +optional
265 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
266 pub extra_args: BTreeMap<String, String>, // `json:"extraArgs,omitempty"`
267
268 /// ServerCertSANs sets extra Subject Alternative Names for the etcd server signing cert.
269 // +optional
270 #[serde(
271 rename = "serverCertSANs",
272 default,
273 skip_serializing_if = "Vec::is_empty"
274 )]
275 pub server_cert_sans: Vec<String>, // `json:"serverCertSANs,omitempty"`
276 /// PeerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert.
277 // +optional
278 #[serde(
279 rename = "peerCertSANs",
280 default,
281 skip_serializing_if = "Vec::is_empty"
282 )]
283 pub peer_cert_sans: Vec<String>, // `json:"peerCertSANs,omitempty"`
284}
285
286/// ExternalEtcd describes an external etcd cluster.
287/// Kubeadm has no knowledge of where certificate files live and they must be supplied.
288#[skip_serializing_none]
289#[derive(Clone, Debug, Serialize, Deserialize)]
290#[serde(rename_all = "camelCase")]
291pub struct ExternalEtcd {
292 /// Endpoints of etcd members. Required for ExternalEtcd.
293 pub endpoints: Vec<String>, // `json:"endpoints"`
294
295 /// CAFile is an SSL Certificate Authority file used to secure etcd communication.
296 /// Required if using a TLS connection.
297 pub ca_file: String, // `json:"caFile"`
298
299 /// CertFile is an SSL certification file used to secure etcd communication.
300 /// Required if using a TLS connection.
301 pub cert_file: String, // `json:"certFile"`
302
303 /// KeyFile is an SSL key file used to secure etcd communication.
304 /// Required if using a TLS connection.
305 pub key_file: String, // `json:"keyFile"`
306}
307
308/// ImageMeta allows to customize the image used for components that are not
309/// originated from the Kubernetes/Kubernetes release process.
310#[skip_serializing_none]
311#[derive(Clone, Debug, Default, Serialize, Deserialize)]
312#[serde(rename_all = "camelCase")]
313pub struct ImageMeta {
314 /// ImageRepository sets the container registry to pull images from.
315 /// if not set, the ImageRepository defined in ClusterConfiguration will be used instead.
316 // +optional
317 pub image_repository: Option<String>, // `json:"imageRepository,omitempty"`
318
319 /// ImageTag allows to specify a tag for the image.
320 /// In case this value is set, kubeadm does not change automatically the version of the above components during upgrades.
321 // +optional
322 pub image_tag: Option<String>, // `json:"imageTag,omitempty"`
323
324 //TODO: evaluate if we need also a ImageName based on user feedbacks
325}
326
327/// Networking contains elements describing cluster's networking configuration.
328#[skip_serializing_none]
329#[derive(Clone, Debug, Serialize, Deserialize)]
330#[serde(rename_all = "camelCase")]
331pub struct Networking {
332 // ServiceSubnet is the subnet used by k8s services.
333 // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.pods.cidrBlocks, or
334 // to "10.96.0.0/12" if that's unset.
335 // +optional
336 pub service_subnet: Option<String>, // `json:"serviceSubnet,omitempty"`
337 // PodSubnet is the subnet used by pods.
338 // If unset, the API server will not allocate CIDR ranges for every node.
339 // Defaults to a comma-delimited string of the Cluster object's spec.clusterNetwork.services.cidrBlocks if that is set
340 // +optional
341 pub pod_subnet: Option<String>, // `json:"podSubnet,omitempty"`
342 // DNSDomain is the dns domain used by k8s services. Defaults to "cluster.local".
343 // +optional
344 pub dns_domain: Option<String>, // `json:"dnsDomain,omitempty"`
345}
346
347/// ControlPlaneComponent holds settings common to control plane component of the cluster.
348#[skip_serializing_none]
349#[derive(Clone, Debug, Default, Serialize, Deserialize)]
350#[serde(rename_all = "camelCase")]
351pub struct ControlPlaneComponent {
352 /// ExtraArgs is an extra set of flags to pass to the control plane component.
353 /// TODO: This is temporary and ideally we would like to switch all components to
354 /// use ComponentConfig + ConfigMaps.
355 // +optional
356 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
357 pub extra_args: BTreeMap<String, String>, // `json:"extraArgs,omitempty"`
358
359 /// ExtraVolumes is an extra set of host volumes, mounted to the control plane component.
360 // +optional
361 #[serde(default, skip_serializing_if = "Vec::is_empty")]
362 pub extra_volumes: Vec<HostPathMount>, // `json:"extraVolumes,omitempty"`
363}
364
365// APIServer holds settings necessary for API server deployments in the cluster.
366#[skip_serializing_none]
367#[derive(Clone, Debug, Default, Serialize, Deserialize)]
368#[serde(rename_all = "camelCase")]
369pub struct APIServer {
370 #[serde(flatten)]
371 pub control_plane: ControlPlaneComponent, // `json:",inline"`
372
373 /// CertSANs sets extra Subject Alternative Names for the API Server signing cert.
374 // +optional
375 #[serde(rename = "certSANs", default, skip_serializing_if = "Vec::is_empty")]
376 pub cert_sans: Vec<String>, // `json:"certSANs,omitempty"`
377
378 // TimeoutForControlPlane controls the timeout that we use for API server to appear
379 // +optional
380 pub timeout_for_control_plane: Option<i64>, // metav1.Duration `json:"timeoutForControlPlane,omitempty"`
381}
382
383// DNS defines the DNS addon that should be used in the cluster.
384#[skip_serializing_none]
385#[derive(Clone, Debug, Serialize, Deserialize)]
386#[serde(rename_all = "camelCase")]
387pub struct DNS {
388 /// ImageMeta allows to customize the image used for the DNS component
389 #[serde(flatten)]
390 pub image_meta: ImageMeta, // ImageMeta `json:",inline"`
391}
392
393/// Discovery specifies the options for the kubelet to use during the TLS Bootstrap process.
394#[skip_serializing_none]
395#[derive(Clone, Debug, Serialize, Deserialize)]
396#[serde(rename_all = "camelCase")]
397pub struct Discovery {
398 /// BootstrapToken is used to set the options for bootstrap token based discovery
399 /// BootstrapToken and File are mutually exclusive
400 // +optional
401 pub bootstrap_token: Option<BootstrapTokenDiscovery>, // `json:"bootstrapToken,omitempty"`
402
403 /// File is used to specify a file or URL to a kubeconfig file from which to load cluster information
404 /// BootstrapToken and File are mutually exclusive
405 // +optional
406 pub file: Option<FileDiscovery>, // `json:"file,omitempty"`
407
408 /// TLSBootstrapToken is a token used for TLS bootstrapping.
409 /// If .BootstrapToken is set, this field is defaulted to .BootstrapToken.Token, but can be overridden.
410 /// If .File is set, this field **must be set** in case the KubeConfigFile does not contain any other authentication information
411 // +optional
412 pub tls_bootstrap_token: Option<String>, // `json:"tlsBootstrapToken,omitempty"`
413
414 /// Timeout modifies the discovery timeout
415 // +optional
416 pub timeout: Option<i64>, // *metav1.Duration `json:"timeout,omitempty"`
417}
418
419/// JoinControlPlane contains elements describing an additional control plane instance to be deployed on the joining node.
420#[skip_serializing_none]
421#[derive(Clone, Debug, Serialize, Deserialize)]
422#[serde(rename_all = "camelCase")]
423pub struct JoinControlPlane {
424 /// LocalAPIEndpoint represents the endpoint of the API server instance to be deployed on this node.
425 // +optional
426 #[serde(rename = "localAPIEndpoint")]
427 pub local_api_endpoint: Option<APIEndpoint>, // `json:"localAPIEndpoint,omitempty"`
428}
429
430/// HostPathMount contains elements describing volumes that are mounted from the
431/// host.
432#[skip_serializing_none]
433#[derive(Clone, Debug, Serialize, Deserialize)]
434#[serde(rename_all = "camelCase")]
435pub struct HostPathMount {
436 /// Name of the volume inside the pod template.
437 pub name: String, // `json:"name"`
438 /// HostPath is the path in the host that will be mounted inside
439 /// the pod.
440 pub host_path: String, // `json:"hostPath"`
441 /// MountPath is the path inside the pod where hostPath will be mounted.
442 pub mount_path: String, // `json:"mountPath"`
443 /// ReadOnly controls write access to the volume
444 // +optional
445 pub read_only: Option<bool>, // `json:"readOnly,omitempty"`
446 /// PathType is the type of the HostPath.
447 // +optional
448 pub path_type: Option<String>, // corev1.HostPathType> `json:"pathType,omitempty"`
449}
450
451/// FileDiscovery is used to specify a file or URL to a kubeconfig file from which to load cluster information.
452#[skip_serializing_none]
453#[derive(Clone, Debug, Serialize, Deserialize)]
454#[serde(rename_all = "camelCase")]
455pub struct FileDiscovery {
456 /// KubeConfigPath is used to specify the actual file path or URL to the kubeconfig file from which to load cluster information
457 pub kube_config_path: String, // `json:"kubeConfigPath"`
458}
459
460/// BootstrapTokenDiscovery is used to set the options for bootstrap token based discovery.
461#[skip_serializing_none]
462#[derive(Clone, Debug, Serialize, Deserialize)]
463#[serde(rename_all = "camelCase")]
464pub struct BootstrapTokenDiscovery {
465 /// Token is a token used to validate cluster information
466 /// fetched from the control-plane.
467 pub token: String, // `json:"token"`
468
469 /// APIServerEndpoint is an IP or domain name to the API server from which info will be fetched.
470 // +optional
471 pub api_server_endpoint: Option<String>, // `json:"apiServerEndpoint,omitempty"`
472
473 /// CACertHashes specifies a set of public key pins to verify
474 /// when token-based discovery is used. The root CA found during discovery
475 /// must match one of these values. Specifying an empty set disables root CA
476 /// pinning, which can be unsafe. Each hash is specified as "<type>:<value>",
477 /// where the only currently supported type is "sha256". This is a hex-encoded
478 /// SHA-256 hash of the Subject Public Key Info (SPKI) object in DER-encoded
479 /// ASN.1. These hashes can be calculated using, for example, OpenSSL:
480 /// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
481 // +optional
482 #[serde(default, skip_serializing_if = "Vec::is_empty")]
483 pub ca_cert_hashes: Vec<String>, // `json:"caCertHashes,omitempty"`
484
485 // UnsafeSkipCAVerification allows token-based discovery
486 // without CA verification via CACertHashes. This can weaken
487 // the security of kubeadm since other nodes can impersonate the control-plane.
488 // +optional
489 #[serde(rename = "unsafeSkipCAVerification")]
490 pub unsafe_skip_ca_verification: Option<bool>, // `json:"unsafeSkipCAVerification,omitempty"`
491}
492
493/*
494
495package v1beta1
496
497import (
498 "fmt"
499 "strings"
500
501 "github.com/pkg/errors"
502 corev1 "k8s.io/api/core/v1"
503 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
504 bootstrapapi "k8s.io/cluster-bootstrap/token/api"
505 bootstraputil "k8s.io/cluster-bootstrap/token/util"
506)
507
508// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
509
510// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
511
512
513
514// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
515
516// ClusterStatus contains the cluster status. The ClusterStatus will be stored in the kubeadm-config
517// ConfigMap in the cluster, and then updated by kubeadm when additional control plane instance joins or leaves the cluster.
518// Deprecated: ClusterStatus has been removed from kubeadm v1beta3 API; This type is preserved only to support
519// conversion to older versions of the kubeadm API.
520type ClusterStatus struct {
521 metav1.TypeMeta `json:",inline"`
522
523 // APIEndpoints currently available in the cluster, one for each control plane/api server instance.
524 // The key of the map is the IP of the host's default interface
525 APIEndpoints map[string]APIEndpoint `json:"apiEndpoints"`
526}
527
528
529
530// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
531
532
533
534// BootstrapTokenString is a token of the format abcdef.abcdef0123456789 that is used
535// for both validation of the practically of the API server from a joining node's point
536// of view and as an authentication method for the node in the bootstrap phase of
537// "kubeadm join". This token is and should be short-lived.
538//
539// +kubebuilder:validation:Type=string
540type BootstrapTokenString struct {
541 ID string `json:"-"`
542 Secret string `json:"-"`
543}
544
545// MarshalJSON implements the json.Marshaler interface.
546func (bts BootstrapTokenString) MarshalJSON() ([]byte, error) {
547 return []byte(fmt.Sprintf(`"%s"`, bts.String())), nil
548}
549
550// UnmarshalJSON implements the json.Unmarshaller interface.
551func (bts *BootstrapTokenString) UnmarshalJSON(b []byte) error {
552 // If the token is represented as "", just return quickly without an error
553 if len(b) == 0 {
554 return nil
555 }
556
557 // Remove unnecessary " characters coming from the JSON parser
558 token := strings.ReplaceAll(string(b), `"`, ``)
559 // Convert the string Token to a BootstrapTokenString object
560 newbts, err := NewBootstrapTokenString(token)
561 if err != nil {
562 return err
563 }
564 bts.ID = newbts.ID
565 bts.Secret = newbts.Secret
566 return nil
567}
568
569// String returns the string representation of the BootstrapTokenString.
570func (bts BootstrapTokenString) String() string {
571 if len(bts.ID) > 0 && len(bts.Secret) > 0 {
572 return bootstraputil.TokenFromIDAndSecret(bts.ID, bts.Secret)
573 }
574 return ""
575}
576
577// NewBootstrapTokenString converts the given Bootstrap Token as a string
578// to the BootstrapTokenString object used for serialization/deserialization
579// and internal usage. It also automatically validates that the given token
580// is of the right format.
581func NewBootstrapTokenString(token string) (*BootstrapTokenString, error) {
582 substrs := bootstraputil.BootstrapTokenRegexp.FindStringSubmatch(token)
583 // TODO: Add a constant for the 3 value here, and explain better why it's needed (other than because how the regexp parsin works)
584 if len(substrs) != 3 {
585 return nil, errors.Errorf("the bootstrap token %q was not of the form %q", token, bootstrapapi.BootstrapTokenPattern)
586 }
587
588 return &BootstrapTokenString{ID: substrs[1], Secret: substrs[2]}, nil
589}
590
591*/