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