k8c.io/api/v3@v3.0.0-20230904060738-b0a93889c0b6/pkg/apis/ee.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 kubermaticv1 "k8c.io/api/v3/pkg/apis/kubermatic/v1" 21 22 corev1 "k8s.io/api/core/v1" 23 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 "k8s.io/apimachinery/pkg/util/sets" 25 ) 26 27 const ( 28 // PresetNameAnnotation is key of the annotation used to hold preset name if was used for the cluster creation. 29 PresetNameAnnotation = "presetName" 30 31 // PresetInvalidatedAnnotation is key of the annotation used to indicate why the preset was invalidated. 32 PresetInvalidatedAnnotation = "presetInvalidated" 33 34 // ProjectIDLabelKey is the label on a Cluster resource that points to the project it belongs to. 35 ProjectIDLabelKey = "project-id" 36 37 IsCredentialPresetLabelKey = "is-credential-preset" 38 39 UpdatedByVPALabelKey = "updated-by-vpa" 40 41 ExternalClusterIDLabelKey = "external-cluster-id" 42 ) 43 44 const ( 45 // ClusterFeatureEncryptionAtRest enables the experimental "encryption-at-rest" feature, which allows encrypting 46 // Kubernetes data in etcd with a user-provided encryption key or KMS service. 47 ClusterFeatureEncryptionAtRest = "encryptionAtRest" 48 ) 49 50 // ProtectedClusterLabels is a set of labels that must not be set on clusters manually by users, 51 // as they are relevant for the correct functioning of and security in KKP. 52 var ProtectedClusterLabels = sets.New(ProjectIDLabelKey, IsCredentialPresetLabelKey) 53 54 // +kubebuilder:validation:Enum=deleted;changed 55 type PresetInvalidationReason string 56 57 const ( 58 PresetInvalidationReasonDeleted PresetInvalidationReason = "deleted" 59 PresetInvalidationReasonChanged PresetInvalidationReason = "changed" 60 ) 61 62 // +genclient 63 // +kubebuilder:resource:scope=Cluster 64 // +kubebuilder:object:generate=true 65 // +kubebuilder:object:root=true 66 // +kubebuilder:subresource:status 67 // +kubebuilder:printcolumn:JSONPath=".spec.humanReadableName",name="HumanReadableName",type="string" 68 // +kubebuilder:printcolumn:JSONPath=".status.userEmail",name="Owner",type="string" 69 // +kubebuilder:printcolumn:JSONPath=".spec.version",name="Version",type="string" 70 // +kubebuilder:printcolumn:JSONPath=".spec.cloud.providerName",name="Provider",type="string" 71 // +kubebuilder:printcolumn:JSONPath=".spec.cloud.datacenter",name="Datacenter",type="string" 72 // +kubebuilder:printcolumn:JSONPath=".status.phase",name="Phase",type="string" 73 // +kubebuilder:printcolumn:JSONPath=".spec.pause",name="Paused",type="boolean" 74 // +kubebuilder:printcolumn:JSONPath=".metadata.creationTimestamp",name="Age",type="date" 75 76 // Cluster represents a Kubermatic Kubernetes Platform user cluster. 77 // Cluster objects exist on Seed clusters and each user cluster consists 78 // of a namespace containing the Kubernetes control plane and additional 79 // pods (like Prometheus or the machine-controller). 80 type Cluster struct { 81 metav1.TypeMeta `json:",inline"` 82 metav1.ObjectMeta `json:"metadata,omitempty"` 83 84 // Spec describes the desired cluster state. 85 Spec ClusterSpec `json:"spec,omitempty"` 86 87 // Status contains reconciliation information for the cluster. 88 Status ClusterStatus `json:"status,omitempty"` 89 } 90 91 // IsEncryptionConfigurationEnabled returns whether encryption-at-rest is configured on this cluster. 92 func (cluster *Cluster) IsEncryptionEnabled() bool { 93 return cluster.Spec.Features[ClusterFeatureEncryptionAtRest] && cluster.Spec.EncryptionConfiguration != nil && cluster.Spec.EncryptionConfiguration.Enabled 94 } 95 96 // ClusterSpec describes the desired state of a user cluster. 97 type ClusterSpec struct { 98 kubermaticv1.ClusterSpec `json:",inline"` 99 100 // Optional: Deploys the UserSSHKeyAgent to the user cluster. This field is immutable. 101 // If enabled, the agent will be deployed and used to sync user ssh keys attached by users to the cluster. 102 // No SSH keys will be synced after node creation if this is disabled. 103 EnableUserSSHKeyAgent *bool `json:"enableUserSSHKeyAgent,omitempty"` 104 105 // Optional: AuditLogging configures Kubernetes API audit logging (https://kubernetes.io/docs/tasks/debug-application-cluster/audit/) 106 // for the user cluster. 107 AuditLogging *AuditLoggingSettings `json:"auditLogging,omitempty"` 108 109 // Optional: Configures encryption-at-rest for Kubernetes API data. This needs the `encryptionAtRest` feature gate. 110 EncryptionConfiguration *EncryptionConfiguration `json:"encryptionConfiguration,omitempty"` 111 } 112 113 // EncryptionConfiguration configures encryption-at-rest for Kubernetes API data. 114 type EncryptionConfiguration struct { 115 // Enables encryption-at-rest on this cluster. 116 Enabled bool `json:"enabled"` 117 118 // +kubebuilder:validation:MinItems=1 119 120 // List of resources that will be stored encrypted in etcd. 121 Resources []string `json:"resources"` 122 // Configuration for the `secretbox` static key encryption scheme as supported by Kubernetes. 123 // More info: https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/#providers 124 Secretbox *SecretboxEncryptionConfiguration `json:"secretbox,omitempty"` 125 } 126 127 // SecretboxEncryptionConfiguration defines static key encryption based on the 'secretbox' solution for Kubernetes. 128 type SecretboxEncryptionConfiguration struct { 129 // +kubebuilder:validation:MinItems=1 130 131 // List of 'secretbox' encryption keys. The first element of this list is considered 132 // the "primary" key which will be used for encrypting data while writing it. Additional 133 // keys will be used for decrypting data while reading it, if keys higher in the list 134 // did not succeed in decrypting it. 135 Keys []SecretboxKey `json:"keys"` 136 } 137 138 // SecretboxKey stores a key or key reference for encrypting Kubernetes API data at rest with a static key. 139 type SecretboxKey struct { 140 // Identifier of a key, used in various places to refer to the key. 141 Name string `json:"name"` 142 // Value contains a 32-byte random key that is base64 encoded. This is the key used 143 // for encryption. Can be generated via `head -c 32 /dev/urandom | base64`, for example. 144 Value string `json:"value,omitempty"` 145 // Instead of passing the sensitive encryption key via the `value` field, a secret can be 146 // referenced. The key of the secret referenced here needs to hold a key equivalent to the `value` field. 147 SecretRef *corev1.SecretKeySelector `json:"secretRef,omitempty"` 148 } 149 150 // ClusterStatus stores status information about a cluster. 151 type ClusterStatus struct { 152 kubermaticv1.ClusterStatus `json:",inline"` 153 154 // Encryption describes the status of the encryption-at-rest feature for encrypted data in etcd. 155 // +optional 156 Encryption *ClusterEncryptionStatus `json:"encryption,omitempty"` 157 158 // ResourceUsage shows the current usage of resources for the cluster. 159 ResourceUsage *ResourceDetails `json:"resourceUsage,omitempty"` 160 } 161 162 // ClusterEncryptionStatus holds status information about the encryption-at-rest feature on the user cluster. 163 type ClusterEncryptionStatus struct { 164 // The current "primary" key used to encrypt data written to etcd. Secondary keys that can be used for decryption 165 // (but not encryption) might be configured in the ClusterSpec. 166 ActiveKey string `json:"activeKey"` 167 168 // List of resources currently encrypted. 169 EncryptedResources []string `json:"encryptedResources"` 170 171 // The current phase of the encryption process. Can be one of `Pending`, `Failed`, `Active` or `EncryptionNeeded`. 172 // The `encryption_controller` logic will process the cluster based on the current phase and issue necessary changes 173 // to make sure encryption on the cluster is active and updated with what the ClusterSpec defines. 174 Phase ClusterEncryptionPhase `json:"phase,omitempty"` 175 } 176 177 // +kubebuilder:validation:Enum=Pending;Failed;Active;EncryptionNeeded 178 type ClusterEncryptionPhase string 179 180 const ( 181 ClusterEncryptionPhasePending ClusterEncryptionPhase = "Pending" 182 ClusterEncryptionPhaseFailed ClusterEncryptionPhase = "Failed" 183 ClusterEncryptionPhaseActive ClusterEncryptionPhase = "Active" 184 ClusterEncryptionPhaseEncryptionNeeded ClusterEncryptionPhase = "EncryptionNeeded" 185 ) 186 187 // +kubebuilder:validation:Enum=HealthStatusDown;HealthStatusUp;HealthStatusProvisioning 188 189 type HealthStatus string 190 191 const ( 192 HealthStatusDown HealthStatus = "HealthStatusDown" 193 HealthStatusUp HealthStatus = "HealthStatusUp" 194 HealthStatusProvisioning HealthStatus = "HealthStatusProvisioning" 195 ) 196 197 // ExtendedClusterHealth stores health information of a cluster. 198 type ExtendedClusterHealth struct { 199 Apiserver HealthStatus `json:"apiserver,omitempty"` 200 Scheduler HealthStatus `json:"scheduler,omitempty"` 201 Controller HealthStatus `json:"controller,omitempty"` 202 MachineController HealthStatus `json:"machineController,omitempty"` 203 Etcd HealthStatus `json:"etcd,omitempty"` 204 CloudProviderInfrastructure HealthStatus `json:"cloudProviderInfrastructure,omitempty"` 205 UserClusterControllerManager HealthStatus `json:"userClusterControllerManager,omitempty"` 206 ApplicationController HealthStatus `json:"applicationController,omitempty"` 207 OpenVPN *HealthStatus `json:"openvpn,omitempty"` 208 Konnectivity *HealthStatus `json:"konnectivity,omitempty"` 209 GatekeeperController *HealthStatus `json:"gatekeeperController,omitempty"` 210 GatekeeperAudit *HealthStatus `json:"gatekeeperAudit,omitempty"` 211 Monitoring *HealthStatus `json:"monitoring,omitempty"` 212 Logging *HealthStatus `json:"logging,omitempty"` 213 AlertmanagerConfig *HealthStatus `json:"alertmanagerConfig,omitempty"` 214 MLAGateway *HealthStatus `json:"mlaGateway,omitempty"` 215 OperatingSystemManager *HealthStatus `json:"operatingSystemManager,omitempty"` 216 KubernetesDashboard *HealthStatus `json:"kubernetesDashboard,omitempty"` 217 } 218 219 // ControlPlaneHealthy returns if all Kubernetes control plane components are healthy. 220 func (h *ExtendedClusterHealth) ControlPlaneHealthy() bool { 221 return h.Etcd == HealthStatusUp && 222 h.Controller == HealthStatusUp && 223 h.Apiserver == HealthStatusUp && 224 h.Scheduler == HealthStatusUp 225 } 226 227 // AllHealthy returns true if all components are healthy. Gatekeeper components not included as they are optional and not 228 // crucial for cluster functioning. 229 func (h *ExtendedClusterHealth) AllHealthy() bool { 230 return h.ControlPlaneHealthy() && 231 h.MachineController == HealthStatusUp && 232 h.CloudProviderInfrastructure == HealthStatusUp && 233 h.UserClusterControllerManager == HealthStatusUp 234 } 235 236 // ApplicationControllerHealthy checks for health of all essential components and the ApplicationController. 237 func (h *ExtendedClusterHealth) ApplicationControllerHealthy() bool { 238 return h.AllHealthy() && 239 h.ApplicationController == HealthStatusUp 240 } 241 242 // +kubebuilder:object:generate=true 243 // +kubebuilder:object:root=true 244 245 // ClusterList specifies a list of user clusters. 246 type ClusterList struct { 247 metav1.TypeMeta `json:",inline"` 248 metav1.ListMeta `json:"metadata,omitempty"` 249 250 Items []Cluster `json:"items"` 251 }