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*/