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  }