k8c.io/api/v3@v3.0.0-20230904060738-b0a93889c0b6/pkg/apis/kubermatic/v1/cluster.go (about) 1 /* 2 Copyright 2023 The Kubermatic Kubernetes Platform contributors. 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 v1 18 19 import ( 20 "fmt" 21 "strings" 22 23 "k8c.io/api/v3/pkg/semver" 24 25 corev1 "k8s.io/api/core/v1" 26 "k8s.io/apimachinery/pkg/api/resource" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 "k8s.io/apimachinery/pkg/util/rand" 29 "k8s.io/apimachinery/pkg/util/sets" 30 netutils "k8s.io/utils/net" 31 ) 32 33 const ( 34 // PresetNameAnnotation is key of the annotation used to hold preset name if was used for the cluster creation. 35 PresetNameAnnotation = "presetName" 36 37 // PresetInvalidatedAnnotation is key of the annotation used to indicate why the preset was invalidated. 38 PresetInvalidatedAnnotation = "presetInvalidated" 39 40 // credentialPrefix is the prefix used for the secrets containing cloud provider credentials. 41 credentialPrefix = "credential" 42 43 // ProjectIDLabelKey is the label on a Cluster resource that points to the project it belongs to. 44 ProjectIDLabelKey = "project-id" 45 46 IsCredentialPresetLabelKey = "is-credential-preset" 47 ) 48 49 // ProtectedClusterLabels is a set of labels that must not be set on clusters manually by users, 50 // as they are relevant for the correct functioning of and security in KKP. 51 var ProtectedClusterLabels = sets.New(ProjectIDLabelKey, IsCredentialPresetLabelKey) 52 53 const ( 54 CCMMigrationNeededAnnotation = "ccm-migration.k8c.io/migration-needed" 55 CSIMigrationNeededAnnotation = "csi-migration.k8c.io/migration-needed" 56 ) 57 58 // +kubebuilder:validation:Enum=standard;basic 59 60 // Azure SKU for Load Balancers. Possible values are `basic` and `standard`. 61 type AzureLBSKU string 62 63 const ( 64 AzureLBSKUStandard AzureLBSKU = "standard" 65 AzureLBSKUBasic AzureLBSKU = "basic" 66 ) 67 68 // +kubebuilder:validation:Enum=deleted;changed 69 type PresetInvalidationReason string 70 71 const ( 72 PresetInvalidationReasonDeleted PresetInvalidationReason = "deleted" 73 PresetInvalidationReasonChanged PresetInvalidationReason = "changed" 74 ) 75 76 // +genclient 77 // +kubebuilder:resource:scope=Cluster 78 // +kubebuilder:object:generate=true 79 // +kubebuilder:object:root=true 80 // +kubebuilder:subresource:status 81 // +kubebuilder:printcolumn:JSONPath=".spec.humanReadableName",name="HumanReadableName",type="string" 82 // +kubebuilder:printcolumn:JSONPath=".status.userEmail",name="Owner",type="string" 83 // +kubebuilder:printcolumn:JSONPath=".spec.version",name="Version",type="string" 84 // +kubebuilder:printcolumn:JSONPath=".spec.cloud.providerName",name="Provider",type="string" 85 // +kubebuilder:printcolumn:JSONPath=".spec.cloud.datacenter",name="Datacenter",type="string" 86 // +kubebuilder:printcolumn:JSONPath=".status.phase",name="Phase",type="string" 87 // +kubebuilder:printcolumn:JSONPath=".spec.pause",name="Paused",type="boolean" 88 // +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name="Age",type="date" 89 90 // Cluster represents a Kubermatic Kubernetes Platform user cluster. 91 // Cluster objects exist on Seed clusters and each user cluster consists 92 // of a namespace containing the Kubernetes control plane and additional 93 // pods (like Prometheus or the machine-controller). 94 type Cluster struct { 95 metav1.TypeMeta `json:",inline"` 96 metav1.ObjectMeta `json:"metadata,omitempty"` 97 98 // Spec describes the desired cluster state. 99 Spec ClusterSpec `json:"spec,omitempty"` 100 101 // Status contains reconciliation information for the cluster. 102 Status ClusterStatus `json:"status,omitempty"` 103 } 104 105 // +kubebuilder:object:generate=true 106 // +kubebuilder:object:root=true 107 108 // ClusterList specifies a list of user clusters. 109 type ClusterList struct { 110 metav1.TypeMeta `json:",inline"` 111 metav1.ListMeta `json:"metadata,omitempty"` 112 113 Items []Cluster `json:"items"` 114 } 115 116 // ClusterSpec describes the desired state of a user cluster. 117 type ClusterSpec struct { 118 // HumanReadableName is the cluster name provided by the user. 119 HumanReadableName string `json:"humanReadableName"` 120 121 // Version defines the wanted version of the control plane. 122 Version semver.Semver `json:"version"` 123 124 // Cloud contains information regarding the cloud provider that 125 // is responsible for hosting the cluster's workload. 126 Cloud CloudSpec `json:"cloud"` 127 128 // +kubebuilder:validation:Enum=docker;containerd 129 // +kubebuilder:default=containerd 130 131 // ContainerRuntime to use, i.e. `docker` or `containerd`. By default `containerd` will be used. 132 ContainerRuntime string `json:"containerRuntime,omitempty"` 133 134 // Optional: ImagePullSecret references a secret with container registry credentials. This is 135 // passed to the machine-controller which sets the registry credentials on node level. 136 ImagePullSecret *corev1.SecretReference `json:"imagePullSecret,omitempty"` 137 138 CNIPlugin *CNIPluginSettings `json:"cniPlugin,omitempty"` 139 140 ClusterNetwork ClusterNetworkingConfig `json:"clusterNetwork"` 141 MachineNetworks []MachineNetworkingConfig `json:"machineNetworks,omitempty"` 142 143 // ExposeStrategy is the strategy used to expose a cluster control plane. 144 ExposeStrategy ExposeStrategy `json:"exposeStrategy"` 145 146 // Optional: APIServerAllowedIPRanges is a list of IP ranges allowed to access the API server. 147 // Applicable only if the expose strategy of the cluster is LoadBalancer. 148 // If not configured, access to the API server is unrestricted. 149 APIServerAllowedIPRanges *NetworkRanges `json:"apiServerAllowedIPRanges,omitempty"` 150 151 // Component specific overrides that allow customization of control plane components. 152 ComponentsOverride ComponentSettings `json:"componentsOverride,omitempty"` 153 154 OIDC *OIDCSettings `json:"oidc,omitempty"` 155 156 // A map of optional or early-stage features that can be enabled for the user cluster. 157 // Some feature gates cannot be disabled after being enabled. 158 // The available feature gates vary based on KKP version, Kubernetes version and Seed configuration. 159 // Please consult the KKP documentation for specific feature gates. 160 Features map[string]bool `json:"features,omitempty"` 161 162 // Optional: UpdateWindow configures automatic update systems to respect a maintenance window for 163 // applying OS updates to nodes. This is only respected on Flatcar nodes currently. 164 UpdateWindow *UpdateWindow `json:"updateWindow,omitempty"` 165 166 // Enables the admission plugin `PodSecurityPolicy`. This plugin is deprecated by Kubernetes. 167 UsePodSecurityPolicyAdmissionPlugin bool `json:"usePodSecurityPolicyAdmissionPlugin,omitempty"` 168 // Enables the admission plugin `PodNodeSelector`. Needs additional configuration via the `podNodeSelectorAdmissionPluginConfig` field. 169 UsePodNodeSelectorAdmissionPlugin bool `json:"usePodNodeSelectorAdmissionPlugin,omitempty"` 170 // Enables the admission plugin `EventRateLimit`. Needs additional configuration via the `eventRateLimitConfig` field. 171 // This plugin is considered "alpha" by Kubernetes. 172 UseEventRateLimitAdmissionPlugin bool `json:"useEventRateLimitAdmissionPlugin,omitempty"` 173 174 // A list of arbitrary admission plugin names that are passed to kube-apiserver. Must not include admission plugins 175 // that can be enabled via a separate setting. 176 AdmissionPlugins []string `json:"admissionPlugins,omitempty"` 177 178 // Optional: Provides configuration for the PodNodeSelector admission plugin (needs plugin enabled 179 // via `usePodNodeSelectorAdmissionPlugin`). It's used by the backend to create a configuration file for this plugin. 180 // The key:value from this map is converted to <namespace>:<node-selectors-labels> in the file. Use `clusterDefaultNodeSelector` 181 // as key to configure a default node selector. 182 PodNodeSelectorAdmissionPluginConfig map[string]string `json:"podNodeSelectorAdmissionPluginConfig,omitempty"` 183 184 // Optional: Configures the EventRateLimit admission plugin (if enabled via `useEventRateLimitAdmissionPlugin`) 185 // to create limits on Kubernetes event generation. The EventRateLimit plugin is capable of comparing and rate limiting incoming 186 // `Events` based on several configured buckets. 187 EventRateLimitConfig *EventRateLimitConfig `json:"eventRateLimitConfig,omitempty"` 188 189 // Optional: Enables operating-system-manager (OSM), which is responsible for creating and managing worker node configuration. 190 // This field is enabled(true) by default. 191 EnableOperatingSystemManager *bool `json:"enableOperatingSystemManager,omitempty"` 192 193 // KubernetesDashboard holds the configuration for the kubernetes-dashboard component. 194 KubernetesDashboard *KubernetesDashboard `json:"kubernetesDashboard,omitempty"` 195 196 // Optional: OPAIntegration is a preview feature that enables OPA integration for the cluster. 197 // Enabling it causes OPA Gatekeeper and its resources to be deployed on the user cluster. 198 // By default it is disabled. 199 OPAIntegration *OPAIntegrationSettings `json:"opaIntegration,omitempty"` 200 201 // Optional: ServiceAccount contains service account related settings for the user cluster's kube-apiserver. 202 ServiceAccount *ServiceAccountSettings `json:"serviceAccount,omitempty"` 203 204 // Optional: MLA contains monitoring, logging and alerting related settings for the user cluster. 205 MLA *MLASettings `json:"mla,omitempty"` 206 207 // Optional: ApplicationSettings contains the settings relative to the application feature. 208 ApplicationSettings *ApplicationSettings `json:"applicationSettings,omitempty"` 209 210 // If this is set to true, the cluster will not be reconciled by KKP. 211 // This indicates that the user needs to do some action to resolve the pause. 212 // +kubebuilder:default=false 213 Pause bool `json:"pause,omitempty"` 214 215 // PauseReason is the reason why the cluster is not being managed. This field is for informational 216 // purpose only and can be set by a user or a controller to communicate the reason for pausing the cluster. 217 PauseReason string `json:"pauseReason,omitempty"` 218 219 // Enables more verbose logging in KKP's user-cluster-controller-manager. 220 DebugLog bool `json:"debugLog,omitempty"` 221 } 222 223 func (c ClusterSpec) IsOperatingSystemManagerEnabled() bool { 224 return c.EnableOperatingSystemManager == nil || *c.EnableOperatingSystemManager 225 } 226 227 // KubernetesDashboard contains settings for the kubernetes-dashboard component as part of the cluster control plane. 228 type KubernetesDashboard struct { 229 // Controls whether kubernetes-dashboard is deployed to the user cluster or not. 230 // Enabled by default. 231 Enabled bool `json:"enabled,omitempty"` 232 } 233 234 func (c ClusterSpec) IsKubernetesDashboardEnabled() bool { 235 return c.KubernetesDashboard == nil || c.KubernetesDashboard.Enabled 236 } 237 238 // GetVersionConditions returns a kubermaticv1.ConditionType list that should be used when checking 239 // for available versions in a VersionManager instance. 240 func (c ClusterSpec) GetVersionConditions() []ConditionType { 241 conditions := []ConditionType{} 242 243 if c.Features[ClusterFeatureExternalCloudProvider] { 244 conditions = append(conditions, ConditionExternalCloudProvider) 245 } else { 246 conditions = append(conditions, ConditionInTreeCloudProvider) 247 } 248 249 return conditions 250 } 251 252 // CNIPluginSettings contains the spec of the CNI plugin used by the Cluster. 253 type CNIPluginSettings struct { 254 // Type is the CNI plugin type to be used. 255 Type CNIPluginType `json:"type"` 256 // Version defines the CNI plugin version to be used. This varies by chosen CNI plugin type. 257 Version string `json:"version"` 258 } 259 260 const ( 261 // ClusterFeatureExternalCloudProvider describes the external cloud provider feature. It is 262 // only supported on a limited set of providers for a specific set of Kube versions. It must 263 // not be set if its not supported. 264 ClusterFeatureExternalCloudProvider = "externalCloudProvider" 265 266 // ClusterFeatureCCMClusterName sets the cluster-name flag on the external CCM deployment. 267 // The cluster-name flag is often used for naming cloud resources, such as load balancers. 268 ClusterFeatureCCMClusterName = "ccmClusterName" 269 270 // ClusterFeatureVsphereCSIClusterID sets the cluster-id in the vSphere CSI config to 271 // the name of the user cluster. Originally, we have been setting cluster-id to the 272 // vSphere Compute Cluster name (provided via the Datacenter object), however, 273 // this is supposed to identify the Kubernetes cluster, therefore it must be unique. 274 // This feature flag is enabled by default for new vSphere clusters, while existing 275 // vSphere clusters must be migrated manually (preferably by following advice here: 276 // https://kb.vmware.com/s/article/84446). 277 ClusterFeatureVsphereCSIClusterID = "vsphereCSIClusterID" 278 279 // ClusterFeatureEtcdLauncher enables features related to the experimental etcd-launcher. This includes user-cluster 280 // etcd scaling, automatic volume recovery and new backup/restore contorllers. 281 ClusterFeatureEtcdLauncher = "etcdLauncher" 282 283 // ApiserverNetworkPolicy enables the deployment of network policies that 284 // restrict the egress traffic from Apiserver pods. 285 ApiserverNetworkPolicy = "apiserverNetworkPolicy" 286 287 // KubeSystemNetworkPolicies enables the deployment of network policies to kube-system namespace that 288 // restrict traffic from all pods in the namespace. 289 KubeSystemNetworkPolicies = "kubeSystemNetworkPolicies" 290 ) 291 292 // UpdateWindow allows defining windows for maintenance tasks related to OS updates. 293 // This is only applied to cluster nodes using Flatcar Linux. 294 // The reference time for this is the node system time and might differ from 295 // the user's timezone, which needs to be considered when configuring a window. 296 type UpdateWindow struct { 297 // Sets the start time of the update window. This can be a time of day in 24h format, e.g. `22:30`, 298 // or a day of week plus a time of day, for example `Mon 21:00`. Only short names for week days are supported, 299 // i.e. `Mon`, `Tue`, `Wed`, `Thu`, `Fri`, `Sat` and `Sun`. 300 Start string `json:"start,omitempty"` 301 // Sets the length of the update window beginning with the start time. This needs to be a valid duration 302 // as parsed by Go's time.ParseDuration (https://pkg.go.dev/time#ParseDuration), e.g. `2h`. 303 Length string `json:"length,omitempty"` 304 } 305 306 // EncryptionConfiguration configures encryption-at-rest for Kubernetes API data. 307 type EncryptionConfiguration struct { 308 // Enables encryption-at-rest on this cluster. 309 Enabled bool `json:"enabled"` 310 311 // +kubebuilder:validation:MinItems=1 312 313 // List of resources that will be stored encrypted in etcd. 314 Resources []string `json:"resources"` 315 // Configuration for the `secretbox` static key encryption scheme as supported by Kubernetes. 316 // More info: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers 317 Secretbox *SecretboxEncryptionConfiguration `json:"secretbox,omitempty"` 318 } 319 320 // SecretboxEncryptionConfiguration defines static key encryption based on the 'secretbox' solution for Kubernetes. 321 type SecretboxEncryptionConfiguration struct { 322 // +kubebuilder:validation:MinItems=1 323 324 // List of 'secretbox' encryption keys. The first element of this list is considered 325 // the "primary" key which will be used for encrypting data while writing it. Additional 326 // keys will be used for decrypting data while reading it, if keys higher in the list 327 // did not succeed in decrypting it. 328 Keys []SecretboxKey `json:"keys"` 329 } 330 331 // SecretboxKey stores a key or key reference for encrypting Kubernetes API data at rest with a static key. 332 type SecretboxKey struct { 333 // Identifier of a key, used in various places to refer to the key. 334 Name string `json:"name"` 335 // Value contains a 32-byte random key that is base64 encoded. This is the key used 336 // for encryption. Can be generated via `head -c 32 /dev/urandom | base64`, for example. 337 Value string `json:"value,omitempty"` 338 // Instead of passing the sensitive encryption key via the `value` field, a secret can be 339 // referenced. The key of the secret referenced here needs to hold a key equivalent to the `value` field. 340 SecretRef *corev1.SecretKeySelector `json:"secretRef,omitempty"` 341 } 342 343 // +kubebuilder:validation:Enum=SeedResourcesUpToDate;ClusterControllerReconciledSuccessfully;AddonControllerReconciledSuccessfully;AddonInstallerControllerReconciledSuccessfully;BackupControllerReconciledSuccessfully;CloudControllerReconciledSuccessfully;UpdateControllerReconciledSuccessfully;MonitoringControllerReconciledSuccessfully;MachineDeploymentReconciledSuccessfully;MLAControllerReconciledSuccessfully;ClusterInitialized;EtcdClusterInitialized;CSIKubeletMigrationCompleted;ClusterUpdateSuccessful;ClusterUpdateInProgress;CSIKubeletMigrationSuccess;CSIKubeletMigrationInProgress;EncryptionControllerReconciledSuccessfully;IPAMControllerReconciledSuccessfully; 344 345 // ClusterConditionType is used to indicate the type of a cluster condition. For all condition 346 // types, the `true` value must indicate success. All condition types must be registered within 347 // the `AllClusterConditionTypes` variable. 348 type ClusterConditionType string 349 350 const ( 351 // ClusterConditionSeedResourcesUpToDate indicates that all controllers have finished setting up the 352 // resources for a user clusters that run inside the seed cluster, i.e. this ignores 353 // the status of cloud provider resources for a given cluster. 354 ClusterConditionSeedResourcesUpToDate ClusterConditionType = "SeedResourcesUpToDate" 355 356 ClusterConditionClusterControllerReconcilingSuccess ClusterConditionType = "ClusterControllerReconciledSuccessfully" 357 ClusterConditionAddonControllerReconcilingSuccess ClusterConditionType = "AddonControllerReconciledSuccessfully" 358 ClusterConditionAddonInstallerControllerReconcilingSuccess ClusterConditionType = "AddonInstallerControllerReconciledSuccessfully" 359 ClusterConditionBackupControllerReconcilingSuccess ClusterConditionType = "BackupControllerReconciledSuccessfully" 360 ClusterConditionCloudControllerReconcilingSuccess ClusterConditionType = "CloudControllerReconciledSuccessfully" 361 ClusterConditionUpdateControllerReconcilingSuccess ClusterConditionType = "UpdateControllerReconciledSuccessfully" 362 ClusterConditionMonitoringControllerReconcilingSuccess ClusterConditionType = "MonitoringControllerReconciledSuccessfully" 363 ClusterConditionMachineDeploymentControllerReconcilingSuccess ClusterConditionType = "MachineDeploymentReconciledSuccessfully" 364 ClusterConditionApplicationInstallationControllerReconcilingSuccess ClusterConditionType = "ApplicationInstallationControllerReconciledSuccessfully" 365 ClusterConditionCNIControllerReconcilingSuccess ClusterConditionType = "CNIControllerReconciledSuccessfully" 366 ClusterConditionMLAControllerReconcilingSuccess ClusterConditionType = "MLAControllerReconciledSuccessfully" 367 ClusterConditionEncryptionControllerReconcilingSuccess ClusterConditionType = "EncryptionControllerReconciledSuccessfully" 368 ClusterConditionClusterInitialized ClusterConditionType = "ClusterInitialized" 369 ClusterConditionIPAMControllerReconcilingSuccess ClusterConditionType = "IPAMControllerReconciledSuccessfully" 370 371 ClusterConditionEtcdClusterInitialized ClusterConditionType = "EtcdClusterInitialized" 372 ClusterConditionEncryptionInitialized ClusterConditionType = "EncryptionInitialized" 373 374 ClusterConditionUpdateProgress ClusterConditionType = "UpdateProgress" 375 376 // ClusterConditionNone is a special value indicating that no cluster condition should be set. 377 ClusterConditionNone ClusterConditionType = "" 378 // This condition is met when a CSI migration is ongoing and the CSI 379 // migration feature gates are activated on the Kubelets of all the nodes. 380 // When this condition is `true` CSIMigration{provider}Complete can be 381 // enabled. 382 ClusterConditionCSIKubeletMigrationCompleted ClusterConditionType = "CSIKubeletMigrationCompleted" 383 384 ReasonClusterUpdateSuccessful = "ClusterUpdateSuccessful" 385 ReasonClusterUpdateInProgress = "ClusterUpdateInProgress" 386 ReasonClusterCSIKubeletMigrationCompleted = "CSIKubeletMigrationSuccess" 387 ReasonClusterCCMMigrationInProgress = "CSIKubeletMigrationInProgress" 388 ) 389 390 type ClusterCondition struct { 391 // Status of the condition, one of True, False, Unknown. 392 Status corev1.ConditionStatus `json:"status"` 393 // KubermaticVersion current kubermatic version. 394 KubermaticVersion string `json:"kubermaticVersion"` 395 // Last time we got an update on a given condition. 396 LastHeartbeatTime metav1.Time `json:"lastHeartbeatTime"` 397 // Last time the condition transit from one status to another. 398 // +optional 399 LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"` 400 // (brief) reason for the condition's last transition. 401 // +optional 402 Reason string `json:"reason,omitempty"` 403 // Human readable message indicating details about last transition. 404 // +optional 405 Message string `json:"message,omitempty"` 406 } 407 408 // +kubebuilder:validation:Enum=Creating;Updating;Running;Terminating 409 410 type ClusterPhase string 411 412 // These are the valid phases of a cluster. 413 const ( 414 ClusterPhaseCreating ClusterPhase = "Creating" 415 ClusterPhaseUpdating ClusterPhase = "Updating" 416 ClusterPhaseRunning ClusterPhase = "Running" 417 ClusterPhaseTerminating ClusterPhase = "Terminating" 418 ) 419 420 // ClusterStatus stores status information about a cluster. 421 type ClusterStatus struct { 422 // Address contains the IPs/URLs to access the cluster control plane. 423 // +optional 424 Address ClusterAddress `json:"address,omitempty"` 425 426 // +optional 427 LastUpdated metav1.Time `json:"lastUpdated,omitempty"` 428 // ExtendedHealth exposes information about the current health state. 429 // Extends standard health status for new states. 430 // +optional 431 ExtendedHealth ExtendedClusterHealth `json:"extendedHealth,omitempty"` 432 // LastProviderReconciliation is the time when the cloud provider resources 433 // were last fully reconciled (during normal cluster reconciliation, KKP does 434 // not re-check things like security groups, networks etc.). 435 // +optional 436 LastProviderReconciliation metav1.Time `json:"lastProviderReconciliation,omitempty"` 437 // NamespaceName defines the namespace the control plane of this cluster is deployed in. 438 // +optional 439 NamespaceName string `json:"namespaceName"` 440 441 // Versions contains information regarding the current and desired versions 442 // of the cluster control plane and worker nodes. 443 // +optional 444 Versions ClusterVersionsStatus `json:"versions,omitempty"` 445 446 // Deprecated: UserName contains the name of the owner of this cluster. 447 // This field is not actively used and will be removed in the future. 448 // +optional 449 UserName string `json:"userName,omitempty"` 450 // UserEmail contains the email of the owner of this cluster. 451 // During cluster creation only, this field will be used to bind the `cluster-admin` `ClusterRole` to a cluster owner. 452 // +optional 453 UserEmail string `json:"userEmail"` 454 455 // ErrorReason contains a error reason in case the controller encountered an error. Will be reset if the error was resolved. 456 // +optional 457 ErrorReason *ClusterStatusError `json:"errorReason,omitempty"` 458 // ErrorMessage contains a default error message in case the controller encountered an error. Will be reset if the error was resolved. 459 // +optional 460 ErrorMessage *string `json:"errorMessage,omitempty"` 461 462 // Conditions contains conditions the cluster is in, its primary use case is status signaling between controllers or between 463 // controllers and the API. 464 // +optional 465 Conditions map[ClusterConditionType]ClusterCondition `json:"conditions,omitempty"` 466 467 // Phase is a description of the current cluster status, summarizing the various conditions, 468 // possible active updates etc. This field is for informational purpose only and no logic 469 // should be tied to the phase. 470 Phase ClusterPhase `json:"phase,omitempty"` 471 472 // InheritedLabels are labels the cluster inherited from the project. They are read-only for users. 473 // +optional 474 InheritedLabels map[string]string `json:"inheritedLabels,omitempty"` 475 } 476 477 // ClusterVersionsStatus contains information regarding the current and desired versions 478 // of the cluster control plane and worker nodes. 479 type ClusterVersionsStatus struct { 480 // ControlPlane is the currently active cluster version. This can lag behind the apiserver 481 // version if an update is currently rolling out. 482 ControlPlane semver.Semver `json:"controlPlane"` 483 // Apiserver is the currently desired version of the kube-apiserver. During 484 // upgrades across multiple minor versions (e.g. from 1.20 to 1.23), this will gradually 485 // be increased by the update-controller until the desired cluster version (spec.version) 486 // is reached. 487 Apiserver semver.Semver `json:"apiserver"` 488 // ControllerManager is the currently desired version of the kube-controller-manager. This 489 // field behaves the same as the apiserver field. 490 ControllerManager semver.Semver `json:"controllerManager"` 491 // Scheduler is the currently desired version of the kube-scheduler. This field behaves the 492 // same as the apiserver field. 493 Scheduler semver.Semver `json:"scheduler"` 494 // OldestNodeVersion is the oldest node version currently in use inside the cluster. This can be 495 // nil if there are no nodes. This field is primarily for speeding up reconciling, so that 496 // the controller doesn't have to re-fetch to the usercluster and query its node on every 497 // reconciliation. 498 OldestNodeVersion *semver.Semver `json:"oldestNodeVersion,omitempty"` 499 } 500 501 // +kubebuilder:validation:Enum=InvalidConfiguration;UnsupportedChange;ReconcileError 502 503 type ClusterStatusError string 504 505 const ( 506 ClusterStatusErrorInvalidConfiguration ClusterStatusError = "InvalidConfiguration" 507 ClusterStatusErrorUnsupportedChange ClusterStatusError = "UnsupportedChange" 508 ClusterStatusErrorReconcile ClusterStatusError = "ReconcileError" 509 ) 510 511 type OIDCSettings struct { 512 IssuerURL string `json:"issuerURL,omitempty"` 513 ClientID string `json:"clientID,omitempty"` 514 ClientSecret string `json:"clientSecret,omitempty"` 515 UsernameClaim string `json:"usernameClaim,omitempty"` 516 GroupsClaim string `json:"groupsClaim,omitempty"` 517 RequiredClaim string `json:"requiredClaim,omitempty"` 518 ExtraScopes string `json:"extraScopes,omitempty"` 519 } 520 521 // EventRateLimitConfig configures the `EventRateLimit` admission plugin. 522 // More info: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#eventratelimit 523 type EventRateLimitConfig struct { 524 Server *EventRateLimitConfigItem `json:"server,omitempty"` 525 Namespace *EventRateLimitConfigItem `json:"namespace,omitempty"` 526 User *EventRateLimitConfigItem `json:"user,omitempty"` 527 SourceAndObject *EventRateLimitConfigItem `json:"sourceAndObject,omitempty"` 528 } 529 530 type EventRateLimitConfigItem struct { 531 QPS int32 `json:"qps"` 532 Burst int32 `json:"burst"` 533 CacheSize int32 `json:"cacheSize,omitempty"` 534 } 535 536 // OPAIntegrationSettings configures the usage of OPA (Open Policy Agent) Gatekeeper inside the user cluster. 537 type OPAIntegrationSettings struct { 538 // Enables OPA Gatekeeper integration. 539 Enabled bool `json:"enabled,omitempty"` 540 541 // +kubebuilder:default=10 542 543 // The timeout in seconds that is set for the Gatekeeper validating webhook admission review calls. 544 // Defaults to `10` (seconds). 545 WebhookTimeoutSeconds *int32 `json:"webhookTimeoutSeconds,omitempty"` 546 // Optional: Enables experimental mutation in Gatekeeper. 547 ExperimentalEnableMutation bool `json:"experimentalEnableMutation,omitempty"` 548 // Optional: ControllerResources is the resource requirements for user cluster gatekeeper controller. 549 ControllerResources *corev1.ResourceRequirements `json:"controllerResources,omitempty"` 550 // Optional: AuditResources is the resource requirements for user cluster gatekeeper audit. 551 AuditResources *corev1.ResourceRequirements `json:"auditResources,omitempty"` 552 } 553 554 type ServiceAccountSettings struct { 555 TokenVolumeProjectionEnabled bool `json:"tokenVolumeProjectionEnabled,omitempty"` 556 // Issuer is the identifier of the service account token issuer 557 // If this is not specified, it will be set to the URL of apiserver by default 558 Issuer string `json:"issuer,omitempty"` 559 // APIAudiences are the Identifiers of the API 560 // If this is not specified, it will be set to a single element list containing the issuer URL 561 APIAudiences []string `json:"apiAudiences,omitempty"` 562 } 563 564 type MLASettings struct { 565 // MonitoringEnabled is the flag for enabling monitoring in user cluster. 566 MonitoringEnabled bool `json:"monitoringEnabled,omitempty"` 567 // LoggingEnabled is the flag for enabling logging in user cluster. 568 LoggingEnabled bool `json:"loggingEnabled,omitempty"` 569 // MonitoringResources is the resource requirements for user cluster prometheus. 570 MonitoringResources *corev1.ResourceRequirements `json:"monitoringResources,omitempty"` 571 // LoggingResources is the resource requirements for user cluster promtail. 572 LoggingResources *corev1.ResourceRequirements `json:"loggingResources,omitempty"` 573 // MonitoringReplicas is the number of desired pods of user cluster prometheus deployment. 574 MonitoringReplicas *int32 `json:"monitoringReplicas,omitempty"` 575 } 576 577 type ApplicationSettings struct { 578 // CacheSize is the size of the cache used to download application's sources. 579 CacheSize *resource.Quantity `json:"cacheSize,omitempty"` 580 } 581 582 // +kubebuilder:validation:Enum=preferred;required 583 584 // AntiAffinityType is the type of anti-affinity that should be used. Can be "preferred" 585 // or "required". 586 type AntiAffinityType string 587 588 const ( 589 AntiAffinityTypePreferred = "preferred" 590 AntiAffinityTypeRequired = "required" 591 ) 592 593 type ComponentSettings struct { 594 // Apiserver configures kube-apiserver settings. 595 Apiserver APIServerSettings `json:"apiserver"` 596 // ControllerManager configures kube-controller-manager settings. 597 ControllerManager ControllerSettings `json:"controllerManager"` 598 // Scheduler configures kube-scheduler settings. 599 Scheduler ControllerSettings `json:"scheduler"` 600 // Etcd configures the etcd ring used to store Kubernetes data. 601 Etcd EtcdStatefulSetSettings `json:"etcd"` 602 // Prometheus configures the Prometheus instance deployed into the cluster control plane. 603 Prometheus *StatefulSetSettings `json:"prometheus,omitempty"` 604 // NodePortProxyEnvoy configures the per-cluster nodeport-proxy-envoy that is deployed if 605 // the `LoadBalancer` expose strategy is used. This is not effective if a different expose 606 // strategy is configured. 607 NodePortProxyEnvoy *NodeportProxyComponent `json:"nodePortProxyEnvoy,omitempty"` 608 // KonnectivityProxy configures konnectivity-server and konnectivity-agent components. 609 KonnectivityProxy *KonnectivityProxySettings `json:"konnectivityProxy,omitempty"` 610 // UserClusterController configures the KKP usercluster-controller deployed as part of the cluster control plane. 611 UserClusterController *ControllerSettings `json:"userClusterController,omitempty"` 612 } 613 614 type APIServerSettings struct { 615 DeploymentSettings `json:",inline"` 616 617 EndpointReconcilingDisabled *bool `json:"endpointReconcilingDisabled,omitempty"` 618 NodePortRange string `json:"nodePortRange,omitempty"` 619 } 620 621 type KonnectivityProxySettings struct { 622 // Resources configure limits/requests for Konnectivity components. 623 Resources *corev1.ResourceRequirements `json:"resources,omitempty"` 624 // KeepaliveTime represents a duration of time to check if the transport is still alive. 625 // The option is propagated to agents and server. 626 // Defaults to 1m. 627 KeepaliveTime string `json:"keepaliveTime,omitempty"` 628 } 629 630 type ControllerSettings struct { 631 DeploymentSettings `json:",inline"` 632 LeaderElectionSettings `json:"leaderElection,omitempty"` 633 } 634 635 type DeploymentSettings struct { 636 Replicas *int32 `json:"replicas,omitempty"` 637 Resources *corev1.ResourceRequirements `json:"resources,omitempty"` 638 Tolerations []corev1.Toleration `json:"tolerations,omitempty"` 639 } 640 641 type StatefulSetSettings struct { 642 Resources *corev1.ResourceRequirements `json:"resources,omitempty"` 643 } 644 645 type EtcdStatefulSetSettings struct { 646 // ClusterSize is the number of replicas created for etcd. This should be an 647 // odd number to guarantee consensus, e.g. 3, 5 or 7. 648 ClusterSize *int32 `json:"clusterSize,omitempty"` 649 // StorageClass is the Kubernetes StorageClass used for persistent storage 650 // which stores the etcd WAL and other data persisted across restarts. Defaults to 651 // `kubermatic-fast` (the global default). 652 StorageClass string `json:"storageClass,omitempty"` 653 // DiskSize is the volume size used when creating persistent storage from 654 // the configured StorageClass. This is inherited from KubermaticConfiguration 655 // if not set. Defaults to 5Gi. 656 DiskSize *resource.Quantity `json:"diskSize,omitempty"` 657 // Resources allows to override the resource requirements for etcd Pods. 658 Resources *corev1.ResourceRequirements `json:"resources,omitempty"` 659 // Tolerations allows to override the scheduling tolerations for etcd Pods. 660 Tolerations []corev1.Toleration `json:"tolerations,omitempty"` 661 // HostAntiAffinity allows to enforce a certain type of host anti-affinity on etcd 662 // pods. Options are "preferred" (default) and "required". Please note that 663 // enforcing anti-affinity via "required" can mean that pods are never scheduled. 664 HostAntiAffinity AntiAffinityType `json:"hostAntiAffinity,omitempty"` 665 // ZoneAntiAffinity allows to enforce a certain type of availability zone anti-affinity on etcd 666 // pods. Options are "preferred" (default) and "required". Please note that 667 // enforcing anti-affinity via "required" can mean that pods are never scheduled. 668 ZoneAntiAffinity AntiAffinityType `json:"zoneAntiAffinity,omitempty"` 669 } 670 671 type LeaderElectionSettings struct { 672 // LeaseDurationSeconds is the duration in seconds that non-leader candidates 673 // will wait to force acquire leadership. This is measured against time of 674 // last observed ack. 675 // +optional 676 LeaseDurationSeconds *int32 `json:"leaseDurationSeconds,omitempty"` 677 // RenewDeadlineSeconds is the duration in seconds that the acting controlplane 678 // will retry refreshing leadership before giving up. 679 // +optional 680 RenewDeadlineSeconds *int32 `json:"renewDeadlineSeconds,omitempty"` 681 // RetryPeriodSeconds is the duration in seconds the LeaderElector clients 682 // should wait between tries of actions. 683 // +optional 684 RetryPeriodSeconds *int32 `json:"retryPeriodSeconds,omitempty"` 685 } 686 687 // +kubebuilder:validation:Enum="";IPv4;IPv4+IPv6 688 type IPFamily string 689 690 const ( 691 // IPFamilyUnspecified represents unspecified IP address family, which is interpreted as IPv4. 692 IPFamilyUnspecified IPFamily = "" 693 // IPFamilyIPv4 represents IPv4-only address family. 694 IPFamilyIPv4 IPFamily = "IPv4" 695 // IPFamilyDualStack represents dual-stack address family with IPv4 as the primary address family. 696 IPFamilyDualStack IPFamily = "IPv4+IPv6" 697 ) 698 699 // ClusterNetworkingConfig specifies the different networking 700 // parameters for a cluster. 701 type ClusterNetworkingConfig struct { 702 // Optional: IP family used for cluster networking. Supported values are "", "IPv4" or "IPv4+IPv6". 703 // Can be omitted / empty if pods and services network ranges are specified. 704 // In that case it defaults according to the IP families of the provided network ranges. 705 // If neither ipFamily nor pods & services network ranges are specified, defaults to "IPv4". 706 // +optional 707 IPFamily IPFamily `json:"ipFamily,omitempty"` 708 709 // The network ranges from which service VIPs are allocated. 710 // It can contain one IPv4 and/or one IPv6 CIDR. 711 // If both address families are specified, the first one defines the primary address family. 712 Services NetworkRanges `json:"services"` 713 714 // The network ranges from which POD networks are allocated. 715 // It can contain one IPv4 and/or one IPv6 CIDR. 716 // If both address families are specified, the first one defines the primary address family. 717 Pods NetworkRanges `json:"pods"` 718 719 // NodeCIDRMaskSizeIPv4 is the mask size used to address the nodes within provided IPv4 Pods CIDR. 720 // It has to be larger than the provided IPv4 Pods CIDR. Defaults to 24. 721 // +optional 722 NodeCIDRMaskSizeIPv4 *int32 `json:"nodeCidrMaskSizeIPv4,omitempty"` 723 724 // NodeCIDRMaskSizeIPv6 is the mask size used to address the nodes within provided IPv6 Pods CIDR. 725 // It has to be larger than the provided IPv6 Pods CIDR. Defaults to 64. 726 // +optional 727 NodeCIDRMaskSizeIPv6 *int32 `json:"nodeCidrMaskSizeIPv6,omitempty"` 728 729 // Domain name for services. 730 DNSDomain string `json:"dnsDomain"` 731 732 // +kubebuilder:validation:Enum=ipvs;iptables;ebpf 733 // +kubebuilder:default=ipvs 734 735 // ProxyMode defines the kube-proxy mode ("ipvs" / "iptables" / "ebpf"). 736 // Defaults to "ipvs". "ebpf" disables kube-proxy and requires CNI support. 737 ProxyMode string `json:"proxyMode"` 738 739 // IPVS defines kube-proxy ipvs configuration options 740 IPVS *IPVSConfiguration `json:"ipvs,omitempty"` 741 742 // +kubebuilder:default=true 743 744 // NodeLocalDNSCacheEnabled controls whether the NodeLocal DNS Cache feature is enabled. 745 // Defaults to true. 746 NodeLocalDNSCacheEnabled *bool `json:"nodeLocalDNSCacheEnabled,omitempty"` 747 748 // CoreDNSReplicas is the number of desired pods of user cluster coredns deployment. 749 CoreDNSReplicas *int32 `json:"coreDNSReplicas,omitempty"` 750 751 // KonnectivityEnabled enables konnectivity for controlplane to node network communication. 752 KonnectivityEnabled *bool `json:"konnectivityEnabled,omitempty"` 753 754 // TunnelingAgentIP is the address used by the tunneling agents 755 TunnelingAgentIP string `json:"tunnelingAgentIP,omitempty"` 756 } 757 758 // IsIPv4Only returns true if the cluster networking is IPv4-only. 759 func (c *ClusterNetworkingConfig) IsIPv4Only() bool { 760 return len(c.Pods.CIDRBlocks) == 1 && netutils.IsIPv4CIDRString(c.Pods.CIDRBlocks[0]) 761 } 762 763 // IsIPv6Only returns true if the cluster networking is IPv6-only. 764 func (c *ClusterNetworkingConfig) IsIPv6Only() bool { 765 return len(c.Pods.CIDRBlocks) == 1 && netutils.IsIPv6CIDRString(c.Pods.CIDRBlocks[0]) 766 } 767 768 // IsDualStack returns true if the cluster networking is dual-stack (IPv4 + IPv6). 769 func (c *ClusterNetworkingConfig) IsDualStack() bool { 770 res, err := netutils.IsDualStackCIDRStrings(c.Pods.CIDRBlocks) 771 772 return err == nil && res 773 } 774 775 // MachineNetworkingConfig specifies the networking parameters used for IPAM. 776 type MachineNetworkingConfig struct { 777 CIDR string `json:"cidr"` 778 Gateway string `json:"gateway"` 779 DNSServers []string `json:"dnsServers"` 780 } 781 782 // ClusterAddress stores access and address information of a cluster. 783 type ClusterAddress struct { 784 // URL under which the Apiserver is available 785 // +optional 786 URL string `json:"url"` 787 // Port is the port the API server listens on 788 // +optional 789 Port int32 `json:"port"` 790 // ExternalName is the DNS name for this cluster 791 // +optional 792 ExternalName string `json:"externalName"` 793 // InternalName is the seed cluster internal absolute DNS name to the API server 794 // +optional 795 InternalName string `json:"internalURL"` 796 // AdminToken is the token for the kubeconfig, the user can download 797 // +optional 798 AdminToken string `json:"adminToken"` 799 // IP is the external IP under which the apiserver is available 800 // +optional 801 IP string `json:"ip"` 802 } 803 804 // IPVSConfiguration contains ipvs-related configuration details for kube-proxy. 805 type IPVSConfiguration struct { 806 // +kubebuilder:default=true 807 808 // StrictArp configure arp_ignore and arp_announce to avoid answering ARP queries from kube-ipvs0 interface. 809 // defaults to true. 810 StrictArp *bool `json:"strictArp,omitempty"` 811 } 812 813 // CloudSpec stores configuration options for a given cloud provider. Provider specs are mutually exclusive. 814 type CloudSpec struct { 815 // DatacenterName states the name of a cloud provider "datacenter" (defined in `Seed` resources) 816 // this cluster should be deployed into. 817 DatacenterName string `json:"datacenter"` 818 819 // ProviderName is the name of the cloud provider used for this cluster. 820 // This must match the given provider spec (e.g. if the providerName is 821 // "aws", then the `aws` field must be set). 822 ProviderName CloudProvider `json:"providerName"` 823 824 Fake *FakeCloudSpec `json:"fake,omitempty"` 825 Digitalocean *DigitaloceanCloudSpec `json:"digitalocean,omitempty"` 826 BringYourOwn *BringYourOwnCloudSpec `json:"bringyourown,omitempty"` 827 AWS *AWSCloudSpec `json:"aws,omitempty"` 828 Azure *AzureCloudSpec `json:"azure,omitempty"` 829 OpenStack *OpenStackCloudSpec `json:"openstack,omitempty"` 830 Packet *PacketCloudSpec `json:"packet,omitempty"` 831 Hetzner *HetznerCloudSpec `json:"hetzner,omitempty"` 832 VSphere *VSphereCloudSpec `json:"vsphere,omitempty"` 833 GCP *GCPCloudSpec `json:"gcp,omitempty"` 834 KubeVirt *KubeVirtCloudSpec `json:"kubevirt,omitempty"` 835 Alibaba *AlibabaCloudSpec `json:"alibaba,omitempty"` 836 Anexia *AnexiaCloudSpec `json:"anexia,omitempty"` 837 Nutanix *NutanixCloudSpec `json:"nutanix,omitempty"` 838 VMwareCloudDirector *VMwareCloudDirectorCloudSpec `json:"vmwareclouddirector,omitempty"` 839 } 840 841 // FakeCloudSpec specifies access data for a fake cloud. 842 type FakeCloudSpec struct { 843 Token string `json:"token,omitempty"` 844 } 845 846 // DigitaloceanCloudSpec specifies access data to DigitalOcean. 847 type DigitaloceanCloudSpec struct { 848 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 849 850 Token string `json:"token,omitempty"` // Token is used to authenticate with the DigitalOcean API. 851 } 852 853 // HetznerCloudSpec specifies access data to hetzner cloud. 854 type HetznerCloudSpec struct { 855 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 856 857 // Token is used to authenticate with the Hetzner cloud API. 858 Token string `json:"token,omitempty"` 859 // Network is the pre-existing Hetzner network in which the machines are running. 860 // While machines can be in multiple networks, a single one must be chosen for the 861 // HCloud CCM to work. 862 // If this is empty, the network configured on the datacenter will be used. 863 Network string `json:"network,omitempty"` 864 } 865 866 // AzureCloudSpec defines cloud resource references for Microsoft Azure. 867 type AzureCloudSpec struct { 868 // CredentialsReference allows referencing a `Secret` resource instead of passing secret data in this spec. 869 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 870 871 // TenantID is the Azure Active Directory Tenant used for this cluster. 872 // Can be read from `credentialsReference` instead. 873 TenantID string `json:"tenantID,omitempty"` 874 // SubscriptionID is the Azure Subscription used for this cluster. 875 // Can be read from `credentialsReference` instead. 876 SubscriptionID string `json:"subscriptionID,omitempty"` 877 // ClientID is the service principal used to access Azure. 878 // Can be read from `credentialsReference` instead. 879 ClientID string `json:"clientID,omitempty"` 880 // ClientSecret is the client secret corresponding to the given service principal. 881 // Can be read from `credentialsReference` instead. 882 ClientSecret string `json:"clientSecret,omitempty"` 883 884 // The resource group that will be used to look up and create resources for the cluster in. 885 // If set to empty string at cluster creation, a new resource group will be created and this field will be updated to 886 // the generated resource group's name. 887 ResourceGroup string `json:"resourceGroup"` 888 // Optional: VNetResourceGroup optionally defines a second resource group that will be used for VNet related resources instead. 889 // If left empty, NO additional resource group will be created and all VNet related resources use the resource group defined by `resourceGroup`. 890 VNetResourceGroup string `json:"vnetResourceGroup"` 891 // The name of the VNet resource used for setting up networking in. 892 // If set to empty string at cluster creation, a new VNet will be created and this field will be updated to 893 // the generated VNet's name. 894 VNetName string `json:"vnet"` 895 // The name of a subnet in the VNet referenced by `vnet`. 896 // If set to empty string at cluster creation, a new subnet will be created and this field will be updated to 897 // the generated subnet's name. If no VNet is defined at cluster creation, this field should be empty as well. 898 SubnetName string `json:"subnet"` 899 // The name of a route table associated with the subnet referenced by `subnet`. 900 // If set to empty string at cluster creation, a new route table will be created and this field will be updated to 901 // the generated route table's name. If no subnet is defined at cluster creation, this field should be empty as well. 902 RouteTableName string `json:"routeTable"` 903 // The name of a security group associated with the subnet referenced by `subnet`. 904 // If set to empty string at cluster creation, a new security group will be created and this field will be updated to 905 // the generated security group's name. If no subnet is defined at cluster creation, this field should be empty as well. 906 SecurityGroup string `json:"securityGroup"` 907 // A CIDR range that will be used to allow access to the node port range in the security group to. Only applies if 908 // the security group is generated by KKP and not preexisting. 909 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 910 NodePortsAllowedIPRange string `json:"nodePortsAllowedIPRange,omitempty"` 911 // Optional: CIDR ranges that will be used to allow access to the node port range in the security group to. Only applies if 912 // the security group is generated by KKP and not preexisting. 913 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 914 NodePortsAllowedIPRanges *NetworkRanges `json:"nodePortsAllowedIPRanges,omitempty"` 915 // Optional: AssignAvailabilitySet determines whether KKP creates and assigns an AvailabilitySet to machines. 916 // Defaults to `true` internally if not set. 917 AssignAvailabilitySet *bool `json:"assignAvailabilitySet,omitempty"` 918 // An availability set that will be associated with nodes created for this cluster. If this field is set to empty string 919 // at cluster creation and `AssignAvailabilitySet` is set to `true`, a new availability set will be created and this field 920 // will be updated to the generated availability set's name. 921 AvailabilitySet string `json:"availabilitySet"` 922 923 LoadBalancerSKU AzureLBSKU `json:"loadBalancerSKU"` //nolint:tagliatelle 924 } 925 926 // VSphereCredentials credentials represents a credential for accessing vSphere. 927 type VSphereCredentials struct { 928 Username string `json:"username,omitempty"` 929 Password string `json:"password,omitempty"` 930 } 931 932 // VSphereCloudSpec specifies access data to VSphere cloud. 933 type VSphereCloudSpec struct { 934 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 935 936 // Username is the vSphere user name. 937 // +optional 938 Username string `json:"username"` 939 // Password is the vSphere user password. 940 // +optional 941 Password string `json:"password"` 942 // VMNetName is the name of the vSphere network. 943 VMNetName string `json:"vmNetName"` 944 // Folder is the folder to be used to group the provisioned virtual 945 // machines. 946 // +optional 947 Folder string `json:"folder"` 948 // If both Datastore and DatastoreCluster are not specified the virtual 949 // machines are stored in the `DefaultDatastore` specified for the 950 // Datacenter. 951 952 // Datastore to be used for storing virtual machines and as a default for 953 // dynamic volume provisioning, it is mutually exclusive with 954 // DatastoreCluster. 955 // +optional 956 Datastore string `json:"datastore,omitempty"` 957 // DatastoreCluster to be used for storing virtual machines, it is mutually 958 // exclusive with Datastore. 959 // +optional 960 DatastoreCluster string `json:"datastoreCluster,omitempty"` 961 962 // StoragePolicy to be used for storage provisioning 963 StoragePolicy string `json:"storagePolicy"` 964 965 // ResourcePool is used to manage resources such as cpu and memory for vSphere virtual machines. The resource pool 966 // should be defined on vSphere cluster level. 967 // +optional 968 ResourcePool string `json:"resourcePool,omitempty"` 969 970 // This user will be used for everything except cloud provider functionality 971 InfraManagementUser VSphereCredentials `json:"infraManagementUser"` 972 973 // Tags represents the tags that are attached or created on the cluster level, that are then propagated down to the 974 // MachineDeployments. In order to attach tags on MachineDeployment, users must create the tag on a cluster level first 975 // then attach that tag on the MachineDeployment. 976 Tags *VSphereTag `json:"tags,omitempty"` 977 } 978 979 // VSphereTag represents the tags that are attached or created on the cluster level, that are then propagated down to the 980 // MachineDeployments. In order to attach tags on MachineDeployment, users must create the tag on a cluster level first 981 // then attach that tag on the MachineDeployment. 982 type VSphereTag struct { 983 // Tags represents the name of the created tags. 984 Tags []string `json:"tags"` 985 // CategoryID is the id of the vsphere category that the tag belongs to. If the category id is left empty, the default 986 // category id for the cluster will be used. 987 CategoryID string `json:"categoryID,omitempty"` 988 } 989 990 // VMwareCloudDirectorCloudSpec specifies access data to VMware Cloud Director cloud. 991 type VMwareCloudDirectorCloudSpec struct { 992 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 993 994 // Username is the VMware Cloud Director user name. 995 // +optional 996 Username string `json:"username,omitempty"` 997 // Password is the VMware Cloud Director user password. 998 // +optional 999 Password string `json:"password,omitempty"` 1000 1001 // APIToken is the VMware Cloud Director API token. 1002 // +optional 1003 APIToken string `json:"apiToken,omitempty"` 1004 1005 // Organization is the name of organization to use. 1006 // +optional 1007 Organization string `json:"organization,omitempty"` 1008 1009 // VDC is the organizational virtual data center. 1010 // +optional 1011 VDC string `json:"vdc,omitempty"` 1012 1013 // Network is the name of organizational virtual data center network that will be associated with the VMs and vApp. 1014 OVDCNetwork string `json:"ovdcNetwork"` 1015 1016 // VApp used for isolation of VMs and their associated network 1017 // +optional 1018 VApp string `json:"vapp,omitempty"` 1019 1020 // Config for CSI driver 1021 CSI *VMwareCloudDirectorCSIConfig `json:"csi"` 1022 } 1023 1024 type VMwareCloudDirectorCSIConfig struct { 1025 // The name of the storage profile to use for disks created by CSI driver 1026 StorageProfile string `json:"storageProfile"` 1027 1028 // Filesystem to use for named disks, defaults to "ext4" 1029 // +optional 1030 Filesystem string `json:"filesystem,omitempty"` 1031 } 1032 1033 // BringYourOwnCloudSpec specifies access data for a bring your own cluster. 1034 type BringYourOwnCloudSpec struct{} 1035 1036 // AWSCloudSpec specifies access data to Amazon Web Services. 1037 type AWSCloudSpec struct { 1038 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1039 1040 AccessKeyID string `json:"accessKeyID,omitempty"` 1041 SecretAccessKey string `json:"secretAccessKey,omitempty"` 1042 AssumeRoleARN string `json:"assumeRoleARN,omitempty"` //nolint:tagliatelle 1043 AssumeRoleExternalID string `json:"assumeRoleExternalID,omitempty"` 1044 VPCID string `json:"vpcID"` 1045 // The IAM role, the control plane will use. The control plane will perform an assume-role 1046 ControlPlaneRoleARN string `json:"roleARN"` //nolint:tagliatelle 1047 RouteTableID string `json:"routeTableID"` 1048 InstanceProfileName string `json:"instanceProfileName"` 1049 SecurityGroupID string `json:"securityGroupID"` 1050 // A CIDR range that will be used to allow access to the node port range in the security group to. Only applies if 1051 // the security group is generated by KKP and not preexisting. 1052 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1053 NodePortsAllowedIPRange string `json:"nodePortsAllowedIPRange,omitempty"` 1054 // Optional: CIDR ranges that will be used to allow access to the node port range in the security group to. Only applies if 1055 // the security group is generated by KKP and not preexisting. 1056 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1057 NodePortsAllowedIPRanges *NetworkRanges `json:"nodePortsAllowedIPRanges,omitempty"` 1058 // DisableIAMReconciling is used to disable reconciliation for IAM related configuration. This is useful in air-gapped 1059 // setups where access to IAM service is not possible. 1060 DisableIAMReconciling bool `json:"disableIAMReconciling,omitempty"` //nolint:tagliatelle 1061 } 1062 1063 // OpenStackCloudSpec specifies access data to an OpenStack cloud. 1064 type OpenStackCloudSpec struct { 1065 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1066 1067 Username string `json:"username,omitempty"` 1068 Password string `json:"password,omitempty"` 1069 1070 // project, formally known as tenant. 1071 Project string `json:"project,omitempty"` 1072 // project id, formally known as tenantID. 1073 ProjectID string `json:"projectID,omitempty"` 1074 1075 Domain string `json:"domain,omitempty"` 1076 ApplicationCredentialID string `json:"applicationCredentialID,omitempty"` 1077 ApplicationCredentialSecret string `json:"applicationCredentialSecret,omitempty"` 1078 UseToken bool `json:"useToken,omitempty"` 1079 // Used internally during cluster creation 1080 Token string `json:"token,omitempty"` 1081 1082 // Network holds the name of the internal network 1083 // When specified, all worker nodes will be attached to this network. If not specified, a network, subnet & router will be created 1084 // 1085 // Note that the network is internal if the "External" field is set to false 1086 Network string `json:"network"` 1087 SecurityGroups string `json:"securityGroups"` 1088 // A CIDR range that will be used to allow access to the node port range in the security group to. Only applies if 1089 // the security group is generated by KKP and not preexisting. 1090 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1091 NodePortsAllowedIPRange string `json:"nodePortsAllowedIPRange,omitempty"` 1092 // Optional: CIDR ranges that will be used to allow access to the node port range in the security group to. Only applies if 1093 // the security group is generated by KKP and not preexisting. 1094 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1095 NodePortsAllowedIPRanges *NetworkRanges `json:"nodePortsAllowedIPRanges,omitempty"` 1096 // FloatingIPPool holds the name of the public network 1097 // The public network is reachable from the outside world 1098 // and should provide the pool of IP addresses to choose from. 1099 // 1100 // When specified, all worker nodes will receive a public ip from this floating ip pool 1101 // 1102 // Note that the network is external if the "External" field is set to true 1103 FloatingIPPool string `json:"floatingIPPool"` 1104 RouterID string `json:"routerID"` 1105 SubnetID string `json:"subnetID"` 1106 // IPv6SubnetID holds the ID of the subnet used for IPv6 networking. 1107 // If not provided, a new subnet will be created if IPv6 is enabled. 1108 // +optional 1109 IPv6SubnetID string `json:"ipv6SubnetID,omitempty"` 1110 // IPv6SubnetPool holds the name of the subnet pool used for creating new IPv6 subnets. 1111 // If not provided, the default IPv6 subnet pool will be used. 1112 // +optional 1113 IPv6SubnetPool string `json:"ipv6SubnetPool,omitempty"` 1114 // Whether or not to use Octavia for LoadBalancer type of Service 1115 // implementation instead of using Neutron-LBaaS. 1116 // Attention:OpenStack CCM use Octavia as default load balancer 1117 // implementation since v1.17.0 1118 // 1119 // Takes precedence over the 'use_octavia' flag provided at datacenter 1120 // level if both are specified. 1121 // +optional 1122 UseOctavia *bool `json:"useOctavia,omitempty"` 1123 1124 // Enable the `enable-ingress-hostname` cloud provider option on the OpenStack CCM. Can only be used with the 1125 // external CCM and might be deprecated and removed in future versions as it is considered a workaround for the PROXY 1126 // protocol to preserve client IPs. 1127 // +optional 1128 EnableIngressHostname *bool `json:"enableIngressHostname,omitempty"` 1129 // Set a specific suffix for the hostnames used for the PROXY protocol workaround that is enabled by EnableIngressHostname. 1130 // The suffix is set to `nip.io` by default. Can only be used with the external CCM and might be deprecated and removed in 1131 // future versions as it is considered a workaround only. 1132 IngressHostnameSuffix *string `json:"ingressHostnameSuffix,omitempty"` 1133 } 1134 1135 // PacketCloudSpec specifies access data to a Packet cloud. 1136 type PacketCloudSpec struct { 1137 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1138 1139 APIKey string `json:"apiKey,omitempty"` 1140 ProjectID string `json:"projectID,omitempty"` 1141 BillingCycle string `json:"billingCycle"` 1142 } 1143 1144 // GCPCloudSpec specifies access data to GCP. 1145 type GCPCloudSpec struct { 1146 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1147 1148 // The Google Service Account (JSON format), encoded with base64. 1149 ServiceAccount string `json:"serviceAccount,omitempty"` 1150 Network string `json:"network"` 1151 Subnetwork string `json:"subnetwork"` 1152 // A CIDR range that will be used to allow access to the node port range in the firewall rules to. 1153 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1154 NodePortsAllowedIPRange string `json:"nodePortsAllowedIPRange,omitempty"` 1155 // Optional: CIDR ranges that will be used to allow access to the node port range in the firewall rules to. 1156 // If NodePortsAllowedIPRange nor NodePortsAllowedIPRanges is set, the node port range can be accessed from anywhere. 1157 NodePortsAllowedIPRanges *NetworkRanges `json:"nodePortsAllowedIPRanges,omitempty"` 1158 } 1159 1160 // KubeVirtCloudSpec specifies the access data to KubeVirt. 1161 type KubeVirtCloudSpec struct { 1162 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1163 1164 // The cluster's kubeconfig file, encoded with base64. 1165 Kubeconfig string `json:"kubeconfig,omitempty"` 1166 CSIKubeconfig string `json:"csiKubeconfig,omitempty"` 1167 // Custom Images are a good example of this use case. 1168 PreAllocatedDataVolumes []PreAllocatedDataVolume `json:"preAllocatedDataVolumes,omitempty"` 1169 // Deprecated: in favor of StorageClasses. 1170 // InfraStorageClasses is a list of storage classes from KubeVirt infra cluster that are used for 1171 // initialization of user cluster storage classes by the CSI driver kubevirt (hot pluggable disks) 1172 InfraStorageClasses []string `json:"infraStorageClasses,omitempty"` 1173 // StorageClasses is a list of storage classes from KubeVirt infra cluster that are used for 1174 // initialization of user cluster storage classes by the CSI driver kubevirt (hot pluggable disks. 1175 // It contains also some flag specifying which one is the default one. 1176 StorageClasses []KubeVirtInfraStorageClass `json:"storageClasses,omitempty"` 1177 // ImageCloningEnabled flag enable/disable cloning for a cluster. 1178 ImageCloningEnabled bool `json:"imageCloningEnabled,omitempty"` 1179 } 1180 1181 type PreAllocatedDataVolume struct { 1182 Name string `json:"name"` 1183 Annotations map[string]string `json:"annotations,omitempty"` 1184 URL string `json:"url"` 1185 Size string `json:"size"` 1186 StorageClass string `json:"storageClass"` 1187 } 1188 1189 // AlibabaCloudSpec specifies the access data to Alibaba. 1190 type AlibabaCloudSpec struct { 1191 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1192 1193 AccessKeyID string `json:"accessKeyID,omitempty"` 1194 AccessKeySecret string `json:"accessKeySecret,omitempty"` 1195 } 1196 1197 // AnexiaCloudSpec specifies the access data to Anexia. 1198 type AnexiaCloudSpec struct { 1199 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1200 1201 Token string `json:"token,omitempty"` 1202 } 1203 1204 // NutanixCSIConfig contains credentials and the endpoint for the Nutanix Prism Element to which the CSI driver connects. 1205 type NutanixCSIConfig struct { 1206 // Prism Element Username for csi driver 1207 Username string `json:"username,omitempty"` 1208 1209 // Prism Element Password for csi driver 1210 Password string `json:"password,omitempty"` 1211 1212 // Prism Element Endpoint to access Nutanix Prism Element for csi driver 1213 Endpoint string `json:"endpoint"` 1214 1215 // Optional: Port to use when connecting to the Nutanix Prism Element endpoint (defaults to 9440) 1216 // +optional 1217 Port *int32 `json:"port,omitempty"` 1218 1219 // Storage Class options 1220 1221 // Optional: defaults to "SelfServiceContainer" 1222 // +optional 1223 StorageContainer string `json:"storageContainer,omitempty"` 1224 1225 // Optional: defaults to "xfs" 1226 // +optional 1227 Fstype string `json:"fstype,omitempty"` 1228 1229 // Optional: defaults to "false" 1230 // +optional 1231 SsSegmentedIscsiNetwork *bool `json:"ssSegmentedIscsiNetwork,omitempty"` 1232 } 1233 1234 // NutanixCloudSpec specifies the access data to Nutanix. 1235 type NutanixCloudSpec struct { 1236 CredentialsReference *GlobalSecretKeySelector `json:"credentialsReference,omitempty"` 1237 1238 // ClusterName is the Nutanix cluster that this user cluster will be deployed to. 1239 ClusterName string `json:"clusterName"` 1240 1241 // ProjectName is the project that this cluster is deployed into. If none is given, no project will be used. 1242 // +optional 1243 ProjectName string `json:"projectName,omitempty"` 1244 1245 ProxyURL string `json:"proxyURL,omitempty"` 1246 Username string `json:"username,omitempty"` 1247 Password string `json:"password,omitempty"` 1248 1249 // NutanixCSIConfig for csi driver that connects to a prism element 1250 // +optional 1251 CSI *NutanixCSIConfig `json:"csi,omitempty"` 1252 } 1253 1254 // +kubebuilder:validation:Enum=HealthStatusDown;HealthStatusUp;HealthStatusProvisioning 1255 1256 type HealthStatus string 1257 1258 const ( 1259 HealthStatusDown HealthStatus = "HealthStatusDown" 1260 HealthStatusUp HealthStatus = "HealthStatusUp" 1261 HealthStatusProvisioning HealthStatus = "HealthStatusProvisioning" 1262 ) 1263 1264 // ExtendedClusterHealth stores health information of a cluster. 1265 type ExtendedClusterHealth struct { 1266 KubernetesApiserver HealthStatus `json:"kubernetesApiserver,omitempty"` 1267 KubernetesScheduler HealthStatus `json:"kubernetesScheduler,omitempty"` 1268 KubernetesControllerManager HealthStatus `json:"kubernetesControllerManager,omitempty"` 1269 MachineController HealthStatus `json:"machineController,omitempty"` 1270 Etcd HealthStatus `json:"etcd,omitempty"` 1271 CloudProviderInfrastructure HealthStatus `json:"cloudProviderInfrastructure,omitempty"` 1272 UserClusterControllerManager HealthStatus `json:"userClusterControllerManager,omitempty"` 1273 ApplicationController HealthStatus `json:"applicationController,omitempty"` 1274 OpenVPN *HealthStatus `json:"openvpn,omitempty"` 1275 Konnectivity *HealthStatus `json:"konnectivity,omitempty"` 1276 GatekeeperController *HealthStatus `json:"gatekeeperController,omitempty"` 1277 GatekeeperAudit *HealthStatus `json:"gatekeeperAudit,omitempty"` 1278 Monitoring *HealthStatus `json:"monitoring,omitempty"` 1279 Logging *HealthStatus `json:"logging,omitempty"` 1280 AlertmanagerConfig *HealthStatus `json:"alertmanagerConfig,omitempty"` 1281 MLAGateway *HealthStatus `json:"mlaGateway,omitempty"` 1282 OperatingSystemManager *HealthStatus `json:"operatingSystemManager,omitempty"` 1283 KubernetesDashboard *HealthStatus `json:"kubernetesDashboard,omitempty"` 1284 } 1285 1286 // ControlPlaneHealthy returns if all Kubernetes control plane components are healthy. 1287 func (h *ExtendedClusterHealth) ControlPlaneHealthy() bool { 1288 return h.Etcd == HealthStatusUp && 1289 h.KubernetesControllerManager == HealthStatusUp && 1290 h.KubernetesApiserver == HealthStatusUp && 1291 h.KubernetesScheduler == HealthStatusUp 1292 } 1293 1294 // AllHealthy returns true if all components are healthy. Gatekeeper components not included as they are optional and not 1295 // crucial for cluster functioning. 1296 func (h *ExtendedClusterHealth) AllHealthy() bool { 1297 return h.ControlPlaneHealthy() && 1298 h.MachineController == HealthStatusUp && 1299 h.CloudProviderInfrastructure == HealthStatusUp && 1300 h.UserClusterControllerManager == HealthStatusUp 1301 } 1302 1303 // ApplicationControllerHealthy checks for health of all essential components and the ApplicationController. 1304 func (h *ExtendedClusterHealth) ApplicationControllerHealthy() bool { 1305 return h.AllHealthy() && 1306 h.ApplicationController == HealthStatusUp 1307 } 1308 1309 // TODO: Remove this in KKP 3.x and replace it with a field in the ClusterStatus. 1310 func (cluster *Cluster) GetSecretName() string { 1311 // new clusters might not have a name yet (if the user used GenerateName), 1312 // so we must be careful when constructing the Secret name 1313 clusterName := cluster.Name 1314 if clusterName == "" { 1315 clusterName = rand.String(5) 1316 1317 if cluster.GenerateName != "" { 1318 clusterName = fmt.Sprintf("%s-%s", strings.TrimSuffix(cluster.GenerateName, "-"), clusterName) 1319 } 1320 } 1321 1322 if cluster.Spec.Cloud.AWS != nil { 1323 return fmt.Sprintf("%s-aws-%s", credentialPrefix, clusterName) 1324 } 1325 if cluster.Spec.Cloud.Azure != nil { 1326 return fmt.Sprintf("%s-azure-%s", credentialPrefix, clusterName) 1327 } 1328 if cluster.Spec.Cloud.Digitalocean != nil { 1329 return fmt.Sprintf("%s-digitalocean-%s", credentialPrefix, clusterName) 1330 } 1331 if cluster.Spec.Cloud.GCP != nil { 1332 return fmt.Sprintf("%s-gcp-%s", credentialPrefix, clusterName) 1333 } 1334 if cluster.Spec.Cloud.Hetzner != nil { 1335 return fmt.Sprintf("%s-hetzner-%s", credentialPrefix, clusterName) 1336 } 1337 if cluster.Spec.Cloud.OpenStack != nil { 1338 return fmt.Sprintf("%s-openstack-%s", credentialPrefix, clusterName) 1339 } 1340 if cluster.Spec.Cloud.Packet != nil { 1341 return fmt.Sprintf("%s-packet-%s", credentialPrefix, clusterName) 1342 } 1343 if cluster.Spec.Cloud.KubeVirt != nil { 1344 return fmt.Sprintf("%s-kubevirt-%s", credentialPrefix, clusterName) 1345 } 1346 if cluster.Spec.Cloud.VSphere != nil { 1347 return fmt.Sprintf("%s-vsphere-%s", credentialPrefix, clusterName) 1348 } 1349 if cluster.Spec.Cloud.Alibaba != nil { 1350 return fmt.Sprintf("%s-alibaba-%s", credentialPrefix, clusterName) 1351 } 1352 if cluster.Spec.Cloud.Anexia != nil { 1353 return fmt.Sprintf("%s-anexia-%s", credentialPrefix, clusterName) 1354 } 1355 if cluster.Spec.Cloud.Nutanix != nil { 1356 return fmt.Sprintf("%s-nutanix-%s", credentialPrefix, clusterName) 1357 } 1358 if cluster.Spec.Cloud.VMwareCloudDirector != nil { 1359 return fmt.Sprintf("%s-vmware-cloud-director-%s", credentialPrefix, clusterName) 1360 } 1361 return "" 1362 }