github.com/banzaicloud/operator-tools@v0.28.10/pkg/typeoverride/override.go (about)

     1  // Copyright © 2020 Banzai Cloud
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package typeoverride
    16  
    17  import (
    18  	appsv1 "k8s.io/api/apps/v1"
    19  	v1 "k8s.io/api/core/v1"
    20  	"k8s.io/api/extensions/v1beta1"
    21  	networkingv1beta1 "k8s.io/api/networking/v1beta1"
    22  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    23  )
    24  
    25  // Types in this package are the structural equivalent of their original Kubernetes counterparts with the difference,
    26  // that required fields are declared as optional using `omitempty` or in certain cases some fields are left off.
    27  //
    28  // The purpose of this is that now these types can be embedded into CRDs and can be used to provide a convenient override
    29  // mechanism for resources created inside an operator.
    30  //
    31  // For an example see tests in https://github.com/banzaicloud/operator-tools/tree/master/pkg/merge
    32  
    33  // +kubebuilder:object:generate=true
    34  
    35  // ObjectMeta contains only a [subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#objectmeta-v1-meta).
    36  type ObjectMeta struct {
    37  	Annotations map[string]string `json:"annotations,omitempty"`
    38  	Labels      map[string]string `json:"labels,omitempty"`
    39  }
    40  
    41  // Merge merges it's receivers values into the incoming ObjectMeta by overwriting values for existing keys and adding new ones.
    42  func (override *ObjectMeta) Merge(meta metav1.ObjectMeta) metav1.ObjectMeta {
    43  	if override == nil {
    44  		return meta
    45  	}
    46  	if len(override.Annotations) > 0 {
    47  		if meta.Annotations == nil {
    48  			meta.Annotations = make(map[string]string)
    49  		}
    50  		for key, val := range override.Annotations {
    51  			meta.Annotations[key] = val
    52  		}
    53  	}
    54  	if len(override.Labels) > 0 {
    55  		if meta.Labels == nil {
    56  			meta.Labels = make(map[string]string)
    57  		}
    58  		for key, val := range override.Labels {
    59  			meta.Labels[key] = val
    60  		}
    61  	}
    62  	return meta
    63  }
    64  
    65  // +kubebuilder:object:generate=true
    66  
    67  // Service is a subset of [Service in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#service-v1-core) for embedding.
    68  type Service struct {
    69  	ObjectMeta ObjectMeta `json:"metadata,omitempty"`
    70  	// Kubernetes [Service Specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#servicespec-v1-core)
    71  	Spec v1.ServiceSpec `json:"spec,omitempty"`
    72  }
    73  
    74  // +kubebuilder:object:generate=true
    75  
    76  // IngressExtensionsV1beta1 is a subset of Ingress k8s.io/api/extensions/v1beta1 but is already deprecated
    77  type IngressExtensionsV1beta1 struct {
    78  	ObjectMeta `json:"metadata,omitempty"`
    79  	Spec       v1beta1.IngressSpec `json:"spec,omitempty"`
    80  }
    81  
    82  // +kubebuilder:object:generate=true
    83  
    84  // IngressExtensionsV1beta1 is a subset of [Ingress in k8s.io/api/networking/v1beta1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#ingress-v1-networking-k8s-io).
    85  type IngressNetworkingV1beta1 struct {
    86  	ObjectMeta `json:"metadata,omitempty"`
    87  	// Kubernetes [Ingress Specification](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#ingressclassspec-v1-networking-k8s-io)
    88  	Spec networkingv1beta1.IngressSpec `json:"spec,omitempty"`
    89  }
    90  
    91  // +kubebuilder:object:generate=true
    92  
    93  // DaemonSet is a subset of [DaemonSet in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#daemonset-v1-apps), with [DaemonSetSpec replaced by the local variant](#daemonset-spec).
    94  type DaemonSet struct {
    95  	ObjectMeta `json:"metadata,omitempty"`
    96  	// [Local DaemonSet specification](#daemonset-spec)
    97  	Spec DaemonSetSpec `json:"spec,omitempty"`
    98  }
    99  
   100  // +kubebuilder:object:generate=true
   101  
   102  // DaemonSetSpec is a subset of [DaemonSetSpec in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#daemonsetspec-v1-apps) but with required fields declared as optional
   103  // and [PodTemplateSpec replaced by the local variant](#podtemplatespec).
   104  type DaemonSetSpec struct {
   105  	// A label query over pods that are managed by the daemon set.
   106  	Selector *metav1.LabelSelector `json:"selector,omitempty"`
   107  
   108  	// An object that describes the pod that will be created. Note that this is a [local PodTemplateSpec](#podtemplatespec)
   109  	Template PodTemplateSpec `json:"template,omitempty"`
   110  
   111  	// An update strategy to replace existing DaemonSet pods with new pods.
   112  	UpdateStrategy appsv1.DaemonSetUpdateStrategy `json:"updateStrategy,omitempty"`
   113  
   114  	// The minimum number of seconds for which a newly created DaemonSet pod should
   115  	// be ready without any of its container crashing, for it to be considered
   116  	// available. Defaults to 0 (pod will be considered available as soon as it
   117  	// is ready). (default: 0)
   118  	MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
   119  
   120  	// The number of old history to retain to allow rollback.
   121  	// This is a pointer to distinguish between explicit zero and not specified.
   122  	// Defaults to 10. (default: 10)
   123  	RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
   124  }
   125  
   126  // +kubebuilder:object:generate=true
   127  
   128  // Deployment is a subset of [Deployment in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deployment-v1-apps), with [DeploymentSpec replaced by the local variant](#deployment-spec).
   129  type Deployment struct {
   130  	ObjectMeta `json:"metadata,omitempty"`
   131  	// The desired behavior of [this deployment](#deploymentspec).
   132  	Spec DeploymentSpec `json:"spec,omitempty"`
   133  }
   134  
   135  // +kubebuilder:object:generate=true
   136  
   137  // DeploymentSpec is a subset of [DeploymentSpec in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deploymentspec-v1-apps) but with required fields declared as optional
   138  // and [PodTemplateSpec replaced by the local variant](#podtemplatespec).
   139  type DeploymentSpec struct {
   140  	// Number of desired pods. This is a pointer to distinguish between explicit
   141  	// zero and not specified. Defaults to 1. (default: 1)
   142  	Replicas *int32 `json:"replicas,omitempty"`
   143  
   144  	// Label selector for pods. Existing ReplicaSets whose pods are
   145  	// selected by this will be the ones affected by this deployment.
   146  	// It must match the pod template's labels.
   147  	Selector *metav1.LabelSelector `json:"selector,omitempty"`
   148  
   149  	// An object that describes the pod that will be created. Note that this is a [local PodTemplateSpec](#podtemplatespec)
   150  	Template PodTemplateSpec `json:"template,omitempty"`
   151  
   152  	// The deployment strategy to use to replace existing pods with new ones.
   153  	// +patchStrategy=retainKeys
   154  	Strategy appsv1.DeploymentStrategy `json:"strategy,omitempty"`
   155  
   156  	// Minimum number of seconds for which a newly created pod should be ready
   157  	// without any of its container crashing, for it to be considered available.
   158  	// Defaults to 0 (pod will be considered available as soon as it is ready) (default: 0)
   159  	MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
   160  
   161  	// The number of old ReplicaSets to retain to allow rollback.
   162  	// This is a pointer to distinguish between explicit zero and not specified.
   163  	// Defaults to 10. (default: 10)
   164  	RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
   165  
   166  	// Indicates that the deployment is paused.
   167  	Paused bool `json:"paused,omitempty"`
   168  
   169  	// The maximum time in seconds for a deployment to make progress before it
   170  	// is considered to be failed. The deployment controller will continue to
   171  	// process failed deployments and a condition with a ProgressDeadlineExceeded
   172  	// reason will be surfaced in the deployment status. Note that progress will
   173  	// not be estimated during the time a deployment is paused.
   174  	// Defaults to 600s. (default: 600)
   175  	ProgressDeadlineSeconds *int32 `json:"progressDeadlineSeconds,omitempty"`
   176  }
   177  
   178  // +kubebuilder:object:generate=true
   179  
   180  // StatefulSet is a subset of [StatefulSet in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#statefulset-v1-apps), with [StatefulSetSpec replaced by the local variant](#statefulset-spec).
   181  type StatefulSet struct {
   182  	ObjectMeta `json:"metadata,omitempty"`
   183  	Spec       StatefulSetSpec `json:"spec,omitempty"`
   184  }
   185  
   186  // +kubebuilder:object:generate=true
   187  
   188  // StatefulSetSpec is a subset of [StatefulSetSpec in k8s.io/api/apps/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#statefulsetspec-v1-apps) but with required fields declared as optional
   189  // and [PodTemplateSpec](#podtemplatespec) and [PersistentVolumeClaim replaced by the local variant](#persistentvolumeclaim).
   190  type StatefulSetSpec struct {
   191  	// Replicas is the desired number of replicas of the given Template.
   192  	// These are replicas in the sense that they are instantiations of the
   193  	// same Template, but individual replicas also have a consistent identity.
   194  	// If unspecified, defaults to 1. (default: 1)
   195  	// +optional
   196  	Replicas *int32 `json:"replicas,omitempty"`
   197  
   198  	// Selector is a label query over pods that should match the replica count.
   199  	// It must match the pod template's labels.
   200  	Selector *metav1.LabelSelector `json:"selector,omitempty"`
   201  
   202  	// template is the object that describes the pod that will be created if
   203  	// insufficient replicas are detected. Each pod stamped out by the StatefulSet
   204  	// will fulfill this Template, but have a unique identity from the rest
   205  	// of the StatefulSet.
   206  	Template PodTemplateSpec `json:"template,omitempty"`
   207  
   208  	// volumeClaimTemplates is a list of claims that pods are allowed to reference.
   209  	// The StatefulSet controller is responsible for mapping network identities to
   210  	// claims in a way that maintains the identity of a pod. Every claim in
   211  	// this list must have at least one matching (by name) volumeMount in one
   212  	// container in the template. A claim in this list takes precedence over
   213  	// any volumes in the template, with the same name.
   214  	// +optional
   215  	VolumeClaimTemplates []PersistentVolumeClaim `json:"volumeClaimTemplates,omitempty"`
   216  
   217  	// serviceName is the name of the service that governs this StatefulSet.
   218  	// This service must exist before the StatefulSet, and is responsible for
   219  	// the network identity of the set. Pods get DNS/hostnames that follow the
   220  	// pattern: pod-specific-string.serviceName.default.svc.cluster.local
   221  	// where "pod-specific-string" is managed by the StatefulSet controller.
   222  	ServiceName string `json:"serviceName,omitempty"`
   223  
   224  	// podManagementPolicy controls how pods are created during initial scale up,
   225  	// when replacing pods on nodes, or when scaling down. The default policy is
   226  	// `OrderedReady`, where pods are created in increasing order (pod-0, then
   227  	// pod-1, etc) and the controller will wait until each pod is ready before
   228  	// continuing. When scaling down, the pods are removed in the opposite order.
   229  	// The alternative policy is `Parallel` which will create pods in parallel
   230  	// to match the desired scale without waiting, and on scale down will delete
   231  	// all pods at once.
   232  	// (default: OrderedReady)
   233  	// +optional
   234  	PodManagementPolicy appsv1.PodManagementPolicyType `json:"podManagementPolicy,omitempty"`
   235  
   236  	// updateStrategy indicates the StatefulSetUpdateStrategy that will be
   237  	// employed to update Pods in the StatefulSet when a revision is made to
   238  	// Template.
   239  	UpdateStrategy appsv1.StatefulSetUpdateStrategy `json:"updateStrategy,omitempty"`
   240  
   241  	// revisionHistoryLimit is the maximum number of revisions that will
   242  	// be maintained in the StatefulSet's revision history. The revision history
   243  	// consists of all revisions not represented by a currently applied
   244  	// StatefulSetSpec version. The default value is 10. (default: 10)
   245  	RevisionHistoryLimit *int32 `json:"revisionHistoryLimit,omitempty"`
   246  }
   247  
   248  // +kubebuilder:object:generate=true
   249  
   250  // PersistentVolumeClaim is a subset of [PersistentVolumeClaim in k8s.io/api/core/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#persistentvolumeclaim-v1-core).
   251  type PersistentVolumeClaim struct {
   252  	EmbeddedPersistentVolumeClaimObjectMeta `json:"metadata,omitempty"`
   253  	Spec                                    v1.PersistentVolumeClaimSpec `json:"spec,omitempty"`
   254  }
   255  
   256  // +kubebuilder:object:generate=true
   257  
   258  // ObjectMeta contains only a subset of the fields included in k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta
   259  // Only fields which are relevant to embedded PVCs are included
   260  // controller-gen discards embedded ObjectMetadata type fields, so we have to overcome this.
   261  type EmbeddedPersistentVolumeClaimObjectMeta struct {
   262  	Name        string            `json:"name,omitempty"`
   263  	Annotations map[string]string `json:"annotations,omitempty"`
   264  	Labels      map[string]string `json:"labels,omitempty"`
   265  }
   266  
   267  // +kubebuilder:object:generate=true
   268  
   269  // PodTemplateSpec describes the data a pod should have when created from a template
   270  // It's the same as [PodTemplateSpec in k8s.io/api/core/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podtemplatespec-v1-core) but with the [local ObjectMeta](#objectmeta) and [PodSpec](#podspec) types embedded.
   271  type PodTemplateSpec struct {
   272  	ObjectMeta `json:"metadata,omitempty"`
   273  	Spec       PodSpec `json:"spec,omitempty"`
   274  }
   275  
   276  // +kubebuilder:object:generate=true
   277  
   278  // PodSpec is a subset of [PodSpec in k8s.io/api/corev1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core). It's the same as the original PodSpec expect it allows for containers to be missing.
   279  type PodSpec struct {
   280  	// List of volumes that can be mounted by containers belonging to the pod.
   281  	// +patchMergeKey=name
   282  	// +patchStrategy=merge,retainKeys
   283  	Volumes []v1.Volume `json:"volumes,omitempty" patchStrategy:"merge,retainKeys" patchMergeKey:"name"`
   284  	// List of initialization containers belonging to the pod.
   285  	// +patchMergeKey=name
   286  	// +patchStrategy=merge
   287  	InitContainers []v1.Container `json:"initContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
   288  	// List of containers belonging to the pod.
   289  	// +patchMergeKey=name
   290  	// +patchStrategy=merge
   291  	Containers []v1.Container `json:"containers,omitempty" patchStrategy:"merge" patchMergeKey:"name" `
   292  	// List of ephemeral containers run in this pod.
   293  	// +patchMergeKey=name
   294  	// +patchStrategy=merge
   295  	EphemeralContainers []v1.EphemeralContainer `json:"ephemeralContainers,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
   296  	// Restart policy for all containers within the pod.
   297  	// One of Always, OnFailure, Never.
   298  	// Default to Always. (default: Always)
   299  	RestartPolicy v1.RestartPolicy `json:"restartPolicy,omitempty"`
   300  	// Optional duration in seconds the pod needs to terminate gracefully.
   301  	// Defaults to 30 seconds. (default: 30)
   302  	TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
   303  	// Optional duration in seconds the pod may be active on the node relative to
   304  	ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
   305  	// Set DNS policy for the pod.
   306  	// Defaults to "ClusterFirst". (default: ClusterFirst)
   307  	// Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'.
   308  	DNSPolicy v1.DNSPolicy `json:"dnsPolicy,omitempty"`
   309  	// NodeSelector is a selector which must be true for the pod to fit on a node.
   310  	NodeSelector map[string]string `json:"nodeSelector,omitempty"`
   311  	// ServiceAccountName is the name of the ServiceAccount to use to run this pod.
   312  	ServiceAccountName string `json:"serviceAccountName,omitempty"`
   313  	// AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.
   314  	AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty"`
   315  	// NodeName is a request to schedule this pod onto a specific node.
   316  	NodeName string `json:"nodeName,omitempty"`
   317  	// Host networking requested for this pod. Use the host's network namespace.
   318  	// If this option is set, the ports that will be used must be specified.
   319  	// Default to false. (default: false)
   320  	HostNetwork bool `json:"hostNetwork,omitempty"`
   321  	// Use the host's pid namespace.
   322  	// Optional: Default to false. (default: false)
   323  	HostPID bool `json:"hostPID,omitempty"`
   324  	// Use the host's ipc namespace.
   325  	// Optional: Default to false. (default: false)
   326  	HostIPC bool `json:"hostIPC,omitempty"`
   327  	// Share a single process namespace between all of the containers in a pod.
   328  	// HostPID and ShareProcessNamespace cannot both be set.
   329  	// Optional: Default to false. (default: false)
   330  	ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty"`
   331  	// SecurityContext holds pod-level security attributes and common container settings.
   332  	// Optional: Defaults to empty.  See type description for default values of each field.
   333  	SecurityContext *v1.PodSecurityContext `json:"securityContext,omitempty"`
   334  	// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
   335  	// +patchMergeKey=name
   336  	// +patchStrategy=merge
   337  	ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
   338  	// Specifies the hostname of the Pod
   339  	// If not specified, the pod's hostname will be set to a system-defined value.
   340  	Hostname string `json:"hostname,omitempty"`
   341  	// If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
   342  	// If not specified, the pod will not have a domainname at all.
   343  	Subdomain string `json:"subdomain,omitempty"`
   344  	// If specified, the pod's scheduling constraints
   345  	Affinity *v1.Affinity `json:"affinity,omitempty"`
   346  	// If specified, the pod will be dispatched by specified scheduler.
   347  	// If not specified, the pod will be dispatched by default scheduler.
   348  	SchedulerName string `json:"schedulerName,omitempty"`
   349  	// If specified, the pod's tolerations.
   350  	Tolerations []v1.Toleration `json:"tolerations,omitempty"`
   351  	// HostAliases is an optional list of hosts and IPs that will be injected into the pod's hosts
   352  	// file if specified. This is only valid for non-hostNetwork pods.
   353  	// +patchMergeKey=ip
   354  	// +patchStrategy=merge
   355  	HostAliases []v1.HostAlias `json:"hostAliases,omitempty" patchStrategy:"merge" patchMergeKey:"ip"`
   356  	// If specified, indicates the pod's priority.
   357  	PriorityClassName string `json:"priorityClassName,omitempty"`
   358  	// The priority value. Various system components use this field to find the
   359  	// priority of the pod.
   360  	Priority *int32 `json:"priority,omitempty"`
   361  	// Specifies the DNS parameters of a pod.
   362  	DNSConfig *v1.PodDNSConfig `json:"dnsConfig,omitempty"`
   363  	// If specified, all readiness gates will be evaluated for pod readiness.
   364  	ReadinessGates []v1.PodReadinessGate `json:"readinessGates,omitempty"`
   365  	// RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used
   366  	// to run this pod.
   367  	RuntimeClassName *string `json:"runtimeClassName,omitempty"`
   368  	// EnableServiceLinks indicates whether information about services should be injected into pod's
   369  	// environment variables, matching the syntax of Docker links.
   370  	// Optional: Defaults to true. (default: true)
   371  	EnableServiceLinks *bool `json:"enableServiceLinks,omitempty"`
   372  	// PreemptionPolicy is the Policy for preempting pods with lower priority.
   373  	// One of Never, PreemptLowerPriority.
   374  	// Defaults to PreemptLowerPriority if unset. (default: PreemptLowerPriority)
   375  	PreemptionPolicy *v1.PreemptionPolicy `json:"preemptionPolicy,omitempty"`
   376  	// Overhead represents the resource overhead associated with running a pod for a given RuntimeClass.
   377  	Overhead v1.ResourceList `json:"overhead,omitempty"`
   378  	// TopologySpreadConstraints describes how a group of pods ought to spread across topology
   379  	// domains.
   380  	// +patchMergeKey=topologyKey
   381  	// +patchStrategy=merge
   382  	// +listType=map
   383  	// +listMapKey=topologyKey
   384  	// +listMapKey=whenUnsatisfiable
   385  	TopologySpreadConstraints []v1.TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty" patchStrategy:"merge" patchMergeKey:"topologyKey"`
   386  	// If true the pod's hostname will be configured as the pod's FQDN, rather than the leaf name (the default).
   387  	// Default to false. (default: false)
   388  	// +optional
   389  	SetHostnameAsFQDN *bool `json:"setHostnameAsFQDN,omitempty"`
   390  }
   391  
   392  // +kubebuilder:object:generate=true
   393  
   394  // ServiceAccount is a subset of [ServiceAccount in k8s.io/api/core/v1](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#serviceaccount-v1-core).
   395  type ServiceAccount struct {
   396  	// +optional
   397  	ObjectMeta `json:"metadata,omitempty"`
   398  
   399  	// +optional
   400  	// +patchMergeKey=name
   401  	// +patchStrategy=merge
   402  	Secrets []v1.ObjectReference `json:"secrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
   403  
   404  	// +optional
   405  	ImagePullSecrets []v1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
   406  
   407  	// +optional
   408  	AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty"`
   409  }