k8c.io/api/v3@v3.0.0-20230904060738-b0a93889c0b6/pkg/apis/kubermatic/v1/common.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 "net" 22 23 corev1 "k8s.io/api/core/v1" 24 "k8s.io/apimachinery/pkg/api/resource" 25 netutils "k8s.io/utils/net" 26 ) 27 28 // +kubebuilder:validation:Pattern:=`^((\d{1,3}\.){3}\d{1,3}\/([0-9]|[1-2][0-9]|3[0-2]))$` 29 type CIDR string 30 31 // +kubebuilder:validation:Pattern="((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))/([0-9]|[1-2][0-9]|3[0-2])$)|(^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))/([0-9]|[0-9][0-9]|1[0-1][0-9]|12[0-8])$))" 32 33 // SubnetCIDR is used to store IPv4/IPv6 CIDR. 34 type SubnetCIDR string 35 36 // Finalizers should be kept to their controllers. Only if a finalizer is 37 // used by multiple controllers should it be placed here. 38 39 const ( 40 // NodeDeletionFinalizer indicates that the nodes still need cleanup. 41 NodeDeletionFinalizer = "kubermatic.k8c.io/delete-nodes" 42 // NamespaceCleanupFinalizer indicates that the cluster namespace still exists and the owning Cluster object 43 // must not yet be deleted. 44 NamespaceCleanupFinalizer = "kubermatic.k8c.io/cleanup-namespace" 45 // InClusterPVCleanupFinalizer indicates that the PVs still need cleanup. 46 InClusterPVCleanupFinalizer = "kubermatic.k8c.io/cleanup-in-cluster-pv" 47 // InClusterLBCleanupFinalizer indicates that the LBs still need cleanup. 48 InClusterLBCleanupFinalizer = "kubermatic.k8c.io/cleanup-in-cluster-lb" 49 // CredentialsSecretsCleanupFinalizer indicates that secrets for credentials still need cleanup. 50 CredentialsSecretsCleanupFinalizer = "kubermatic.k8c.io/cleanup-credentials-secrets" 51 // ExternalClusterKubeOneNamespaceCleanupFinalizer indicates that kubeone cluster namespace still need cleanup. 52 ExternalClusterKubeOneNamespaceCleanupFinalizer = "kubermatic.k8c.io/cleanup-kubeone-namespace" 53 // ExternalClusterKubeconfigCleanupFinalizer indicates that secrets for kubeconfig still need cleanup. 54 ExternalClusterKubeconfigCleanupFinalizer = "kubermatic.k8c.io/cleanup-kubeconfig-secret" 55 // ExternalClusterKubeOneCleanupFinalizer indicates that secrets for kubeone cluster still need cleanup. 56 ExternalClusterKubeOneSecretsCleanupFinalizer = "kubermatic.k8c.io/cleanup-kubeone-secret" 57 // EtcdBackConfigCleanupFinalizer indicates that EtcdBackupConfigs for the cluster still need cleanup. 58 EtcdBackupConfigCleanupFinalizer = "kubermatic.k8c.io/cleanup-etcdbackupconfigs" 59 // GatekeeperConstraintCleanupFinalizer indicates that gatkeeper constraints on the user cluster need cleanup. 60 GatekeeperConstraintCleanupFinalizer = "kubermatic.k8c.io/cleanup-gatekeeper-constraints" 61 // KubermaticConstraintCleanupFinalizer indicates that Kubermatic constraints for the cluster need cleanup. 62 KubermaticConstraintCleanupFinalizer = "kubermatic.k8c.io/cleanup-kubermatic-constraints" 63 ) 64 65 const ( 66 InitialMachineDeploymentRequestAnnotation = "kubermatic.io/initial-machinedeployment-request" 67 InitialApplicationInstallationsRequestAnnotation = "kubermatic.io/initial-application-installations-request" 68 InitialCNIValuesRequestAnnotation = "kubermatic.io/initial-cni-values-request" 69 ) 70 71 type MachineFlavorFilter struct { 72 // +kubebuilder:default=0 73 // +kubebuilder:validation:Minimum:=0 74 75 // Minimum number of vCPU 76 MinCPU int `json:"minCPU"` 77 78 // +kubebuilder:default=0 79 // +kubebuilder:validation:Minimum:=0 80 81 // Maximum number of vCPU 82 MaxCPU int `json:"maxCPU"` 83 84 // +kubebuilder:default=0 85 // +kubebuilder:validation:Minimum:=0 86 87 // Minimum RAM size in GB 88 MinRAM int `json:"minRAM"` 89 90 // +kubebuilder:default=0 91 // +kubebuilder:validation:Minimum:=0 92 93 // Maximum RAM size in GB 94 MaxRAM int `json:"maxRAM"` 95 96 // Include VMs with GPU 97 EnableGPU bool `json:"enableGPU"` //nolint:tagliatelle 98 } 99 100 // NetworkRanges represents ranges of network addresses. 101 type NetworkRanges struct { 102 CIDRBlocks []string `json:"cidrBlocks,omitempty"` 103 } 104 105 // Validate validates the network ranges. Returns nil if valid, error otherwise. 106 func (r *NetworkRanges) Validate() error { 107 if r == nil { 108 return nil 109 } 110 111 for _, cidr := range r.CIDRBlocks { 112 if _, _, err := net.ParseCIDR(cidr); err != nil { 113 return fmt.Errorf("unable to parse CIDR %q: %w", cidr, err) 114 } 115 } 116 117 return nil 118 } 119 120 // GetIPv4CIDR returns the first found IPv4 CIDR in the network ranges, or an empty string if no IPv4 CIDR is found. 121 func (r *NetworkRanges) GetIPv4CIDR() string { 122 for _, cidr := range r.CIDRBlocks { 123 if netutils.IsIPv4CIDRString(cidr) { 124 return cidr 125 } 126 } 127 128 return "" 129 } 130 131 // GetIPv4CIDRs returns all IPv4 CIDRs in the network ranges, or an empty string if no IPv4 CIDR is found. 132 func (r *NetworkRanges) GetIPv4CIDRs() (res []string) { 133 for _, cidr := range r.CIDRBlocks { 134 if netutils.IsIPv4CIDRString(cidr) { 135 res = append(res, cidr) 136 } 137 } 138 139 return 140 } 141 142 // HasIPv4CIDR returns true if the network ranges contain any IPv4 CIDR, false otherwise. 143 func (r *NetworkRanges) HasIPv4CIDR() bool { 144 return r.GetIPv4CIDR() != "" 145 } 146 147 // GetIPv6CIDR returns the first found IPv6 CIDR in the network ranges, or an empty string if no IPv6 CIDR is found. 148 func (r *NetworkRanges) GetIPv6CIDR() string { 149 for _, cidr := range r.CIDRBlocks { 150 if netutils.IsIPv6CIDRString(cidr) { 151 return cidr 152 } 153 } 154 155 return "" 156 } 157 158 // GetIPv6CIDRs returns all IPv6 CIDRs in the network ranges, or an empty string if no IPv6 CIDR is found. 159 func (r *NetworkRanges) GetIPv6CIDRs() (res []string) { 160 for _, cidr := range r.CIDRBlocks { 161 if netutils.IsIPv6CIDRString(cidr) { 162 res = append(res, cidr) 163 } 164 } 165 166 return 167 } 168 169 // HasIPv6CIDR returns true if the network ranges contain any IPv6 CIDR, false otherwise. 170 func (r *NetworkRanges) HasIPv6CIDR() bool { 171 return r.GetIPv6CIDR() != "" 172 } 173 174 // ResourceDetails holds the CPU, Memory and Storage quantities. 175 type ResourceDetails struct { 176 // CPU holds the quantity of CPU. For the format, please check k8s.io/apimachinery/pkg/api/resource.Quantity. 177 CPU *resource.Quantity `json:"cpu,omitempty"` 178 // Memory represents the quantity of RAM size. For the format, please check k8s.io/apimachinery/pkg/api/resource.Quantity. 179 Memory *resource.Quantity `json:"memory,omitempty"` 180 // Storage represents the disk size. For the format, please check k8s.io/apimachinery/pkg/api/resource.Quantity. 181 Storage *resource.Quantity `json:"storage,omitempty"` 182 } 183 184 func emptyQuantity(q *resource.Quantity) bool { 185 return q == nil || q.IsZero() 186 } 187 188 func (r *ResourceDetails) IsEmpty() bool { 189 return r == nil || (emptyQuantity(r.CPU) && emptyQuantity(r.Memory) && emptyQuantity(r.Storage)) 190 } 191 192 // GlobalObjectKeySelector is needed as we can not use v1.SecretKeySelector 193 // because it is not cross namespace. 194 type GlobalObjectKeySelector struct { 195 corev1.ObjectReference `json:",inline"` 196 Key string `json:"key,omitempty"` 197 } 198 199 type GlobalSecretKeySelector GlobalObjectKeySelector 200 type GlobalConfigMapKeySelector GlobalObjectKeySelector 201 202 // ProxySettings allow configuring a HTTP proxy for the control planes and nodes. 203 type ProxySettings struct { 204 // Optional: If set, this proxy will be configured for both HTTP and HTTPS. 205 HTTPProxy *string `json:"httpProxy,omitempty"` 206 // Optional: If set this will be set as NO_PROXY environment variable on the node; 207 // The value must be a comma-separated list of domains for which no proxy 208 // should be used, e.g. "*.example.com,internal.dev". 209 // Note that the in-cluster apiserver URL will be automatically prepended 210 // to this value. 211 NoProxy *string `json:"noProxy,omitempty"` 212 } 213 214 func emptyStrPtr(s *string) bool { 215 return s == nil || *s == "" 216 } 217 218 // Empty returns true if p or all of its children are nil or empty strings. 219 func (p *ProxySettings) Empty() bool { 220 return p == nil || (emptyStrPtr(p.HTTPProxy) && emptyStrPtr(p.NoProxy)) 221 } 222 223 // Merge applies the settings from p into dst if the corresponding setting 224 // in dst is nil or an empty string. 225 func (p *ProxySettings) Merge(dst *ProxySettings) { 226 if emptyStrPtr(dst.HTTPProxy) { 227 dst.HTTPProxy = p.HTTPProxy 228 } 229 if emptyStrPtr(dst.NoProxy) { 230 dst.NoProxy = p.NoProxy 231 } 232 } 233 234 // ClusterReference is a struct that allows referencing a single Cluster object. 235 type ClusterReference struct { 236 // Name of the Cluster object. 237 Name string `json:"name"` 238 }