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  }