diff --git a/CHANGELOG.md b/CHANGELOG.md index bdcd41206..79de9162f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) - (Feature) Add Core fields to the Scheduler Container Spec +- (Feature) Add Metadata fields to the Scheduler Pod Spec ## [1.2.39](https://github.com/arangodb/kube-arangodb/tree/1.2.39) (2024-03-11) - (Feature) Extract Scheduler API diff --git a/Makefile b/Makefile index 7d9bfc2d1..0cc05c7dd 100644 --- a/Makefile +++ b/Makefile @@ -317,7 +317,7 @@ license-range: fmt: @echo ">> Ensuring style of files" @$(GOPATH)/bin/goimports -w $(SOURCES) - @$(GOPATH)/bin/gci write -s "standard" -s "default" -s "prefix(github.com/arangodb)" -s "prefix(github.com/arangodb/kube-arangodb)" $(SOURCES) + @$(GOPATH)/bin/gci write -s "standard" -s "default" -s "prefix(github.com/arangodb)" -s "prefix(github.com/arangodb/kube-arangodb)" $(SOURCES) .PHONY: yamlfmt yamlfmt: @@ -337,7 +337,7 @@ license: .PHONY: fmt-verify fmt-verify: license-verify @echo ">> Verify files style" - @if [ X"$$($(GOPATH)/bin/goimports -l $(SOURCES) | wc -l)" != X"0" ]; then echo ">> Style errors"; $(GOPATH)/bin/goimports -l $(SOURCES); exit 1; fi + @if $(GOPATH)/bin/goimports -l $(SOURCES) | grep -v "^$$"; then echo ">> Style errors"; exit 1; fi .PHONY: linter linter: @@ -729,7 +729,7 @@ tools-min: update-vendor @echo ">> Fetching golangci-lint linter" @GOBIN=$(GOPATH)/bin go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.56.2 @echo ">> Fetching goimports" - @GOBIN=$(GOPATH)/bin go install golang.org/x/tools/cmd/goimports@0bb7e5c47b1a31f85d4f173edc878a8e049764a5 + @GOBIN=$(GOPATH)/bin go install golang.org/x/tools/cmd/goimports@v0.19.0 @echo ">> Fetching license check" @GOBIN=$(GOPATH)/bin go install github.com/google/addlicense@6d92264d717064f28b32464f0f9693a5b4ef0239 @echo ">> Fetching yamlfmt" diff --git a/docs/api/ArangoMLExtension.V1Alpha1.md b/docs/api/ArangoMLExtension.V1Alpha1.md index 86968e35a..7e122cd82 100644 --- a/docs/api/ArangoMLExtension.V1Alpha1.md +++ b/docs/api/ArangoMLExtension.V1Alpha1.md @@ -19,6 +19,27 @@ Links: *** +### .spec.deployment.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + +### .spec.deployment.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.deployment.hostIPC Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L42) @@ -50,6 +71,19 @@ Default Value: `false` *** +### .spec.deployment.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.deployment.nodeSelector Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L39) @@ -61,6 +95,17 @@ Links: *** +### .spec.deployment.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.deployment.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -506,6 +551,17 @@ Possible Values: *** +### .spec.deployment.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.deployment.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -739,40 +795,27 @@ Links: *** -### .spec.image - -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/image.go#L37) - -Image define image details - -*** - -### .spec.imagePullPolicy - -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/image.go#L41) - -ImagePullPolicy define Image pull policy - -Default Value: `IfNotPresent` - -*** +### .spec.init.affinity -### .spec.imagePullSecrets +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44) -Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/image.go#L44) +Affinity defines scheduling constraints for workload -ImagePullSecrets define Secrets used to pull Image from registry +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) *** -### .spec.init.affinity +### .spec.init.annotations -Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/scheduling.go#L44) +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) -Affinity defines scheduling constraints for workload +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. Links: -* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) *** @@ -793,6 +836,14 @@ Links: *** +### .spec.init.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.init.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -889,6 +940,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.init.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.init.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -920,6 +984,17 @@ Links: *** +### .spec.init.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.init.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -987,6 +1062,17 @@ Links: *** +### .spec.init.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.init.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -1066,6 +1152,19 @@ Links: *** +### .spec.jobsTemplates.featurization.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.featurization.cpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -1083,6 +1182,14 @@ Links: *** +### .spec.jobsTemplates.featurization.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.featurization.cpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -1179,6 +1286,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.featurization.cpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.featurization.cpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -1210,6 +1330,17 @@ Links: *** +### .spec.jobsTemplates.featurization.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.featurization.cpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -1277,6 +1408,17 @@ Links: *** +### .spec.jobsTemplates.featurization.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.featurization.cpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -1356,6 +1498,19 @@ Links: *** +### .spec.jobsTemplates.featurization.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.featurization.gpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -1373,6 +1528,14 @@ Links: *** +### .spec.jobsTemplates.featurization.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.featurization.gpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -1469,6 +1632,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.featurization.gpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.featurization.gpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -1500,6 +1676,17 @@ Links: *** +### .spec.jobsTemplates.featurization.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.featurization.gpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -1567,6 +1754,17 @@ Links: *** +### .spec.jobsTemplates.featurization.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.featurization.gpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -1646,6 +1844,19 @@ Links: *** +### .spec.jobsTemplates.prediction.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.prediction.cpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -1663,6 +1874,14 @@ Links: *** +### .spec.jobsTemplates.prediction.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.prediction.cpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -1759,6 +1978,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.prediction.cpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.prediction.cpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -1790,6 +2022,17 @@ Links: *** +### .spec.jobsTemplates.prediction.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.prediction.cpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -1857,6 +2100,17 @@ Links: *** +### .spec.jobsTemplates.prediction.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.prediction.cpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -1936,6 +2190,19 @@ Links: *** +### .spec.jobsTemplates.prediction.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.prediction.gpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -1953,6 +2220,14 @@ Links: *** +### .spec.jobsTemplates.prediction.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.prediction.gpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -2049,6 +2324,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.prediction.gpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.prediction.gpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -2080,6 +2368,17 @@ Links: *** +### .spec.jobsTemplates.prediction.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.prediction.gpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -2147,6 +2446,17 @@ Links: *** +### .spec.jobsTemplates.prediction.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.prediction.gpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -2226,6 +2536,19 @@ Links: *** +### .spec.jobsTemplates.training.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.training.cpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -2243,6 +2566,14 @@ Links: *** +### .spec.jobsTemplates.training.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.training.cpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -2339,6 +2670,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.training.cpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.training.cpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -2370,6 +2714,17 @@ Links: *** +### .spec.jobsTemplates.training.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.training.cpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -2437,6 +2792,17 @@ Links: *** +### .spec.jobsTemplates.training.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.training.cpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) @@ -2516,6 +2882,19 @@ Links: *** +### .spec.jobsTemplates.training.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L45) + +Annotations is an unstructured key value map stored with a resource that may be +set by external tools to store and retrieve arbitrary metadata. They are not +queryable and should be preserved when modifying objects. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations) + +*** + ### .spec.jobsTemplates.training.gpu.args Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L50) @@ -2533,6 +2912,14 @@ Links: *** +### .spec.jobsTemplates.training.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + ### .spec.jobsTemplates.training.gpu.command Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/core.go#L40) @@ -2629,6 +3016,19 @@ ImagePullSecrets define Secrets used to pull Image from registry *** +### .spec.jobsTemplates.training.gpu.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L39) + +Map of string keys and values that can be used to organize and categorize +(scope and select) objects. May match selectors of replication controllers +and services. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels) + +*** + ### .spec.jobsTemplates.training.gpu.lifecycle Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/container/resources/lifecycle.go#L35) @@ -2660,6 +3060,17 @@ Links: *** +### .spec.jobsTemplates.training.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go#L52) + +List of objects depended by this object. If ALL objects in the list have +been deleted, this object will be garbage collected. If this object is managed by a controller, +then an entry in this list will point to this controller, with the controller field set to true. +There cannot be more than one managing controller. + +*** + ### .spec.jobsTemplates.training.gpu.podSecurityContext Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/security.go#L35) @@ -2727,6 +3138,17 @@ Links: *** +### .spec.jobsTemplates.training.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go#L35) + +ServiceAccountName is the name of the ServiceAccount to use to run this pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/) + +*** + ### .spec.jobsTemplates.training.gpu.shareProcessNamespace Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.39/pkg/apis/scheduler/v1alpha1/pod/resources/namespace.go#L48) diff --git a/pkg/apis/ml/v1alpha1/extension_spec.go b/pkg/apis/ml/v1alpha1/extension_spec.go index 4722e198e..f055534a4 100644 --- a/pkg/apis/ml/v1alpha1/extension_spec.go +++ b/pkg/apis/ml/v1alpha1/extension_spec.go @@ -21,7 +21,6 @@ package v1alpha1 import ( - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" ) @@ -34,9 +33,6 @@ type ArangoMLExtensionSpec struct { // Storage specifies the ArangoMLStorage used within Extension Storage *sharedApi.Object `json:"storage,omitempty"` - // Image defines default image used for the extension - *schedulerContainerResourcesApi.Image `json:",inline"` - // ArangoMLExtensionTemplate define Init job specification Init *ArangoMLExtensionTemplate `json:"init,omitempty"` @@ -55,14 +51,6 @@ func (a *ArangoMLExtensionSpec) GetMetadataService() *ArangoMLExtensionSpecMetad return a.MetadataService } -func (a *ArangoMLExtensionSpec) GetImage() *schedulerContainerResourcesApi.Image { - if a == nil || a.Image == nil { - return nil - } - - return a.Image -} - func (a *ArangoMLExtensionSpec) GetInit() *ArangoMLExtensionTemplate { if a == nil || a.Init == nil { return nil @@ -101,9 +89,7 @@ func (a *ArangoMLExtensionSpec) Validate() error { return shared.WithErrors(shared.PrefixResourceErrors("spec", shared.PrefixResourceErrors("metadataService", a.GetMetadataService().Validate()), shared.PrefixResourceErrors("storage", shared.ValidateRequired(a.GetStorage(), func(obj sharedApi.Object) error { return obj.Validate() })), - a.GetImage().Validate(), shared.PrefixResourceErrors("init", a.GetInit().Validate()), - shared.ValidateAnyNotNil(".image or .init.image needs to be specified", a.GetImage(), a.GetInit().GetContainer().GetImage()), shared.PrefixResourceErrors("deployment", a.GetDeployment().Validate()), shared.PrefixResourceErrors("jobsTemplates", a.GetJobsTemplates().Validate()), )) diff --git a/pkg/apis/ml/v1alpha1/extension_spec_job.go b/pkg/apis/ml/v1alpha1/extension_spec_job.go index 15fda1bf6..b281e4a4b 100644 --- a/pkg/apis/ml/v1alpha1/extension_spec_job.go +++ b/pkg/apis/ml/v1alpha1/extension_spec_job.go @@ -21,9 +21,11 @@ package v1alpha1 import ( + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" ) type JobType string @@ -139,6 +141,32 @@ func (a *ArangoMLExtensionTemplate) GetContainer() *schedulerContainerApi.Contai return a.Container } +func (a *ArangoMLExtensionTemplate) AsTemplate(name string) *schedulerApi.ProfileTemplate { + if a == nil { + return nil + } + + if a.Pod == nil && a.Container == nil { + return nil + } + + t := &schedulerApi.ProfileTemplate{} + + if p := a.Pod; p != nil { + t.Pod = p.DeepCopy() + } + + if p := a.Container; p != nil { + t.Container = &schedulerApi.ProfileContainerTemplate{ + Containers: schedulerContainerApi.Containers{ + name: util.TypeOrDefault(p.DeepCopy()), + }, + } + } + + return t +} + func (a *ArangoMLExtensionTemplate) Validate() error { if a == nil { return nil diff --git a/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go index 98219a607..0299777a4 100644 --- a/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/ml/v1alpha1/zz_generated.deepcopy.go @@ -28,7 +28,6 @@ package v1alpha1 import ( deploymentv1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" container "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - resources "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" pod "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod" sharedv1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" v1 "k8s.io/api/batch/v1" @@ -340,11 +339,6 @@ func (in *ArangoMLExtensionSpec) DeepCopyInto(out *ArangoMLExtensionSpec) { *out = new(sharedv1.Object) (*in).DeepCopyInto(*out) } - if in.Image != nil { - in, out := &in.Image, &out.Image - *out = new(resources.Image) - (*in).DeepCopyInto(*out) - } if in.Init != nil { in, out := &in.Init, &out.Init *out = new(ArangoMLExtensionTemplate) diff --git a/pkg/apis/scheduler/v1alpha1/container/definition.go b/pkg/apis/scheduler/v1alpha1/container/definition.go index faf2ac4f8..bcd7c56a3 100644 --- a/pkg/apis/scheduler/v1alpha1/container/definition.go +++ b/pkg/apis/scheduler/v1alpha1/container/definition.go @@ -33,6 +33,28 @@ import ( type Containers map[string]Container +func (c *Containers) ExtendContainers(spec *Container, names ...string) { + if c == nil { + return + } + + r := c.DeepCopy() + + if r == nil { + r = Containers{} + } + + for _, n := range names { + if v, ok := r[n]; ok { + r[n] = util.TypeOrDefault(v.With(spec)) + } else { + r[n] = util.TypeOrDefault(spec.DeepCopy()) + } + } + + *c = r +} + func (c Containers) Apply(template *core.PodTemplateSpec) error { if len(c) == 0 { return nil diff --git a/pkg/apis/scheduler/v1alpha1/pod/definition.go b/pkg/apis/scheduler/v1alpha1/pod/definition.go index 7daa08615..faf1448da 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/definition.go +++ b/pkg/apis/scheduler/v1alpha1/pod/definition.go @@ -31,6 +31,9 @@ import ( var _ interfaces.Pod[Pod] = &Pod{} type Pod struct { + // Metadata keeps the metadata settings for Pod + *schedulerPodResourcesApi.Metadata `json:",inline"` + // Scheduling keeps the scheduling information *schedulerPodResourcesApi.Scheduling `json:",inline"` @@ -42,6 +45,9 @@ type Pod struct { // Volumes keeps the volumes settings for Pod *schedulerPodResourcesApi.Volumes `json:",inline"` + + // ServiceAccount keeps the service account settings for Pod + *schedulerPodResourcesApi.ServiceAccount `json:",inline"` } func (a *Pod) With(other *Pod) *Pod { @@ -58,10 +64,12 @@ func (a *Pod) With(other *Pod) *Pod { } return &Pod{ - Scheduling: a.Scheduling.With(other.Scheduling), - Namespace: a.Namespace.With(other.Namespace), - Security: a.Security.With(other.Security), - Volumes: a.Volumes.With(other.Volumes), + Scheduling: a.Scheduling.With(other.Scheduling), + Namespace: a.Namespace.With(other.Namespace), + Security: a.Security.With(other.Security), + Volumes: a.Volumes.With(other.Volumes), + ServiceAccount: a.ServiceAccount.With(other.ServiceAccount), + Metadata: a.Metadata.With(other.Metadata), } } @@ -75,6 +83,8 @@ func (a *Pod) Apply(template *core.PodTemplateSpec) error { a.Namespace.Apply(template), a.Security.Apply(template), a.Volumes.Apply(template), + a.ServiceAccount.Apply(template), + a.Metadata.Apply(template), ) } @@ -110,6 +120,22 @@ func (a *Pod) GetVolumes() *schedulerPodResourcesApi.Volumes { return a.Volumes } +func (a *Pod) GetServiceAccount() *schedulerPodResourcesApi.ServiceAccount { + if a == nil { + return nil + } + + return a.ServiceAccount +} + +func (a *Pod) GetMetadata() *schedulerPodResourcesApi.Metadata { + if a == nil { + return nil + } + + return a.Metadata +} + func (a *Pod) Validate() error { if a == nil { return nil @@ -119,5 +145,7 @@ func (a *Pod) Validate() error { a.Namespace.Validate(), a.Security.Validate(), a.Volumes.Validate(), + a.ServiceAccount.Validate(), + a.Metadata.Validate(), ) } diff --git a/pkg/apis/scheduler/v1alpha1/pod/definition_test.go b/pkg/apis/scheduler/v1alpha1/pod/definition_test.go index 1c8835f64..b9a40c5c7 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/definition_test.go +++ b/pkg/apis/scheduler/v1alpha1/pod/definition_test.go @@ -78,12 +78,14 @@ func Test_Pod(t *testing.T) { applyPod(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec, _ *Pod) { require.Nil(t, pod.Spec.SecurityContext) require.Nil(t, pod.Spec.Affinity) + require.Empty(t, pod.Spec.ServiceAccountName) }) }) t.Run("Empty template", func(t *testing.T) { applyPod(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec, _ *Pod) { require.Nil(t, pod.Spec.SecurityContext) require.Nil(t, pod.Spec.Affinity) + require.Empty(t, pod.Spec.ServiceAccountName) }) }) t.Run("Add scheduling", func(t *testing.T) { @@ -128,12 +130,16 @@ func Test_Pod_YAML(t *testing.T) { require.Nil(t, spec.Security) require.Nil(t, spec.Scheduling) require.Nil(t, spec.Namespace) + require.Nil(t, spec.ServiceAccount) + require.Nil(t, spec.Metadata) }) }) t.Run("Empty template", func(t *testing.T) { applyPodYAML(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec, _ *Pod) { require.Nil(t, pod.Spec.SecurityContext) require.Nil(t, pod.Spec.Affinity) + require.Empty(t, pod.Spec.ServiceAccountName) + require.Nil(t, pod.Labels) }) }) t.Run("Add nodeSelector", func(t *testing.T) { @@ -182,6 +188,9 @@ nodeSelector: podSecurityContext: runAsUser: 10 hostPID: true +serviceAccountName: test +labels: + A: B volumes: - name: test emptyDir: {} @@ -202,6 +211,11 @@ volumes: require.Len(t, spec.Volumes.Volumes, 1) require.EqualValues(t, "test", spec.Volumes.Volumes[0].Name) require.NotNil(t, spec.Volumes.Volumes[0].EmptyDir) + require.NotNil(t, spec.ServiceAccount) + require.EqualValues(t, "test", spec.ServiceAccount.ServiceAccountName) + require.NotNil(t, spec.Labels) + require.Contains(t, spec.Labels, "A") + require.EqualValues(t, "B", spec.Labels["A"]) // Pod require.NotNil(t, pod.Spec.SecurityContext) @@ -217,6 +231,9 @@ volumes: require.Len(t, pod.Spec.Volumes, 1) require.EqualValues(t, "test", pod.Spec.Volumes[0].Name) require.NotNil(t, pod.Spec.Volumes[0].EmptyDir) + require.NotNil(t, pod.Labels) + require.Contains(t, pod.Labels, "A") + require.EqualValues(t, "B", spec.Labels["A"]) }) }) } diff --git a/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go b/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go new file mode 100644 index 000000000..bb557305d --- /dev/null +++ b/pkg/apis/scheduler/v1alpha1/pod/resources/metadata.go @@ -0,0 +1,91 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import ( + core "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces" + "github.com/arangodb/kube-arangodb/pkg/util" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Pod[Metadata] = &Metadata{} + +type Metadata struct { + // Map of string keys and values that can be used to organize and categorize + // (scope and select) objects. May match selectors of replication controllers + // and services. + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/overview/working-with-objects/labels + Labels map[string]string `json:"labels,omitempty"` + + // Annotations is an unstructured key value map stored with a resource that may be + // set by external tools to store and retrieve arbitrary metadata. They are not + // queryable and should be preserved when modifying objects. + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations + Annotations map[string]string `json:"annotations,omitempty"` + + // List of objects depended by this object. If ALL objects in the list have + // been deleted, this object will be garbage collected. If this object is managed by a controller, + // then an entry in this list will point to this controller, with the controller field set to true. + // There cannot be more than one managing controller. + // +doc/type: meta.OwnerReference + OwnerReferences []meta.OwnerReference `json:"ownerReferences,omitempty"` +} + +func (m *Metadata) Apply(template *core.PodTemplateSpec) error { + if m == nil { + return nil + } + + z := m.DeepCopy() + + template.Labels = z.Labels + template.Annotations = z.Annotations + template.OwnerReferences = z.OwnerReferences + + return nil +} + +func (m *Metadata) With(other *Metadata) *Metadata { + if m == nil && other == nil { + return nil + } + + if m == nil { + return other.DeepCopy() + } + + if other == nil { + return m.DeepCopy() + } + + return &Metadata{ + Labels: util.MergeMaps(true, m.Labels, other.Labels), + Annotations: util.MergeMaps(true, m.Annotations, other.Annotations), + OwnerReferences: kresources.MergeOwnerReferences(m.OwnerReferences, other.OwnerReferences), + } +} + +func (m *Metadata) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1alpha1/pod/resources/metadata_test.go b/pkg/apis/scheduler/v1alpha1/pod/resources/metadata_test.go new file mode 100644 index 000000000..ad4558078 --- /dev/null +++ b/pkg/apis/scheduler/v1alpha1/pod/resources/metadata_test.go @@ -0,0 +1,139 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func applyMetadata(t *testing.T, template *core.PodTemplateSpec, ns ...*Metadata) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Metadata + + for _, n := range ns { + require.NoError(t, n.Validate()) + + i = i.With(n) + + require.NoError(t, i.Validate()) + } + + template = template.DeepCopy() + + if template == nil { + template = &core.PodTemplateSpec{} + } + + require.NoError(t, i.Apply(template)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec)) { + t.Run("Validate", func(t *testing.T) { + in(t, template) + }) + } +} + +func Test_Metadata(t *testing.T) { + t.Run("Apply", func(t *testing.T) { + applyMetadata(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Labels, 0) + require.Len(t, pod.Annotations, 0) + require.Len(t, pod.OwnerReferences, 0) + }) + }) + t.Run("Apply nil", func(t *testing.T) { + applyMetadata(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Labels, 0) + require.Len(t, pod.Annotations, 0) + require.Len(t, pod.OwnerReferences, 0) + }) + }) + t.Run("One", func(t *testing.T) { + applyMetadata(t, nil, &Metadata{ + Labels: map[string]string{ + "A": "1", + }, + Annotations: map[string]string{ + "B": "2", + }, + OwnerReferences: []meta.OwnerReference{ + { + UID: "test", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Labels, 1) + require.Contains(t, pod.Labels, "A") + require.EqualValues(t, "1", pod.Labels["A"]) + + require.Len(t, pod.Annotations, 1) + require.Contains(t, pod.Annotations, "B") + require.EqualValues(t, "2", pod.Annotations["B"]) + + require.Len(t, pod.OwnerReferences, 1) + require.EqualValues(t, "test", pod.OwnerReferences[0].UID) + }) + }) + t.Run("Update", func(t *testing.T) { + applyMetadata(t, nil, &Metadata{ + Labels: map[string]string{ + "A": "1", + }, + Annotations: map[string]string{ + "B": "2", + }, + OwnerReferences: []meta.OwnerReference{ + { + UID: "test", + }, + }, + }, &Metadata{ + Labels: map[string]string{ + "A": "3", + }, + Annotations: map[string]string{ + "B2": "4", + }, + OwnerReferences: []meta.OwnerReference{ + { + UID: "test2", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Labels, 1) + require.Contains(t, pod.Labels, "A") + require.EqualValues(t, "3", pod.Labels["A"]) + + require.Len(t, pod.Annotations, 2) + require.Contains(t, pod.Annotations, "B") + require.EqualValues(t, "2", pod.Annotations["B"]) + require.Contains(t, pod.Annotations, "B2") + require.EqualValues(t, "4", pod.Annotations["B2"]) + + require.Len(t, pod.OwnerReferences, 2) + require.EqualValues(t, "test", pod.OwnerReferences[0].UID) + require.EqualValues(t, "test2", pod.OwnerReferences[1].UID) + }) + }) +} diff --git a/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go b/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go new file mode 100644 index 000000000..c8cea0b22 --- /dev/null +++ b/pkg/apis/scheduler/v1alpha1/pod/resources/service_account.go @@ -0,0 +1,72 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import ( + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces" +) + +var _ interfaces.Pod[ServiceAccount] = &ServiceAccount{} + +type ServiceAccount struct { + + // ServiceAccountName is the name of the ServiceAccount to use to run this pod. + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + ServiceAccountName string `json:"serviceAccountName,omitempty"` + + // AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty"` +} + +func (s *ServiceAccount) Apply(template *core.PodTemplateSpec) error { + if s == nil { + return nil + } + + c := s.DeepCopy() + + template.Spec.ServiceAccountName = c.ServiceAccountName + template.Spec.AutomountServiceAccountToken = c.AutomountServiceAccountToken + + return nil +} + +func (s *ServiceAccount) With(newResources *ServiceAccount) *ServiceAccount { + if s == nil && newResources == nil { + return nil + } + + if s == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return s.DeepCopy() + } + + return newResources.DeepCopy() +} + +func (s *ServiceAccount) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1alpha1/pod/resources/service_account_test.go b/pkg/apis/scheduler/v1alpha1/pod/resources/service_account_test.go new file mode 100644 index 000000000..6097c58d1 --- /dev/null +++ b/pkg/apis/scheduler/v1alpha1/pod/resources/service_account_test.go @@ -0,0 +1,94 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func applyServiceAccount(t *testing.T, template *core.PodTemplateSpec, ns ...*ServiceAccount) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *ServiceAccount + + for _, n := range ns { + require.NoError(t, n.Validate()) + + i = i.With(n) + + require.NoError(t, i.Validate()) + } + + template = template.DeepCopy() + + if template == nil { + template = &core.PodTemplateSpec{} + } + + require.NoError(t, i.Apply(template)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec)) { + t.Run("Validate", func(t *testing.T) { + in(t, template) + }) + } +} + +func Test_ServiceAccount(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyServiceAccount(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Empty(t, pod.Spec.ServiceAccountName) + require.Nil(t, pod.Spec.AutomountServiceAccountToken) + }) + }) + t.Run("Empty", func(t *testing.T) { + applyServiceAccount(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Empty(t, pod.Spec.ServiceAccountName) + require.Nil(t, pod.Spec.AutomountServiceAccountToken) + }) + }) + t.Run("One Provided", func(t *testing.T) { + applyServiceAccount(t, &core.PodTemplateSpec{}, &ServiceAccount{ + ServiceAccountName: "test", + AutomountServiceAccountToken: util.NewType(true), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "test", pod.Spec.ServiceAccountName) + + require.NotNil(t, pod.Spec.AutomountServiceAccountToken) + require.True(t, *pod.Spec.AutomountServiceAccountToken) + }) + }) + t.Run("Override", func(t *testing.T) { + applyServiceAccount(t, &core.PodTemplateSpec{}, &ServiceAccount{ + ServiceAccountName: "test", + AutomountServiceAccountToken: util.NewType(true), + }, &ServiceAccount{ + ServiceAccountName: "test2", + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "test2", pod.Spec.ServiceAccountName) + + require.Nil(t, pod.Spec.AutomountServiceAccountToken) + }) + }) +} diff --git a/pkg/apis/scheduler/v1alpha1/pod/resources/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1alpha1/pod/resources/zz_generated.deepcopy.go index 22c16a422..7e833e994 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/resources/zz_generated.deepcopy.go +++ b/pkg/apis/scheduler/v1alpha1/pod/resources/zz_generated.deepcopy.go @@ -26,9 +26,47 @@ package resources import ( - v1 "k8s.io/api/core/v1" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Metadata) DeepCopyInto(out *Metadata) { + *out = *in + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Annotations != nil { + in, out := &in.Annotations, &out.Annotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.OwnerReferences != nil { + in, out := &in.OwnerReferences, &out.OwnerReferences + *out = make([]v1.OwnerReference, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Metadata. +func (in *Metadata) DeepCopy() *Metadata { + if in == nil { + return nil + } + out := new(Metadata) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Namespace) DeepCopyInto(out *Namespace) { *out = *in @@ -77,7 +115,7 @@ func (in *Scheduling) DeepCopyInto(out *Scheduling) { } if in.Affinity != nil { in, out := &in.Affinity, &out.Affinity - *out = new(v1.Affinity) + *out = new(corev1.Affinity) (*in).DeepCopyInto(*out) } if in.Tolerations != nil { @@ -110,7 +148,7 @@ func (in *Security) DeepCopyInto(out *Security) { *out = *in if in.PodSecurityContext != nil { in, out := &in.PodSecurityContext, &out.PodSecurityContext - *out = new(v1.PodSecurityContext) + *out = new(corev1.PodSecurityContext) (*in).DeepCopyInto(*out) } return @@ -126,6 +164,27 @@ func (in *Security) DeepCopy() *Security { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServiceAccount) DeepCopyInto(out *ServiceAccount) { + *out = *in + if in.AutomountServiceAccountToken != nil { + in, out := &in.AutomountServiceAccountToken, &out.AutomountServiceAccountToken + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceAccount. +func (in *ServiceAccount) DeepCopy() *ServiceAccount { + if in == nil { + return nil + } + out := new(ServiceAccount) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in Tolerations) DeepCopyInto(out *Tolerations) { { @@ -153,7 +212,7 @@ func (in *Volumes) DeepCopyInto(out *Volumes) { *out = *in if in.Volumes != nil { in, out := &in.Volumes, &out.Volumes - *out = make([]v1.Volume, len(*in)) + *out = make([]corev1.Volume, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/pkg/apis/scheduler/v1alpha1/pod/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1alpha1/pod/zz_generated.deepcopy.go index f61d14ab0..49c6f6a90 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/zz_generated.deepcopy.go +++ b/pkg/apis/scheduler/v1alpha1/pod/zz_generated.deepcopy.go @@ -32,6 +32,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Pod) DeepCopyInto(out *Pod) { *out = *in + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = new(resources.Metadata) + (*in).DeepCopyInto(*out) + } if in.Scheduling != nil { in, out := &in.Scheduling, &out.Scheduling *out = new(resources.Scheduling) @@ -52,6 +57,11 @@ func (in *Pod) DeepCopyInto(out *Pod) { *out = new(resources.Volumes) (*in).DeepCopyInto(*out) } + if in.ServiceAccount != nil { + in, out := &in.ServiceAccount, &out.ServiceAccount + *out = new(resources.ServiceAccount) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/apis/scheduler/v1alpha1/profile_templates.go b/pkg/apis/scheduler/v1alpha1/profile_templates.go index 3e72bc7f4..30bd5d8bc 100644 --- a/pkg/apis/scheduler/v1alpha1/profile_templates.go +++ b/pkg/apis/scheduler/v1alpha1/profile_templates.go @@ -29,7 +29,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util/errors" ) -type ProfileTemplates []ProfileTemplate +type ProfileTemplates []*ProfileTemplate func (p ProfileTemplates) Sort() ProfileTemplates { sort.Slice(p, func(i, j int) bool { @@ -43,29 +43,27 @@ func (p ProfileTemplates) Sort() ProfileTemplates { return p } -func (p ProfileTemplates) Render() (*core.PodTemplateSpec, error) { - var pod core.PodTemplateSpec - +func (p ProfileTemplates) RenderOnTemplate(pod *core.PodTemplateSpec) error { // Apply Pod Spec for id := range p { - if err := p[id].Pod.Apply(&pod); err != nil { - return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id) + if err := p[id].Pod.Apply(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod for %d", id) } } // Apply Generic Containers Spec for id := range p { - if err := p[id].Container.ApplyGeneric(&pod); err != nil { - return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id) + if err := p[id].Container.ApplyGeneric(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod for %d", id) } } // Apply Containers Spec for id := range p { - if err := p[id].Container.ApplyContainers(&pod); err != nil { - return nil, errors.Wrapf(err, "Error while rendering Pod for %d", id) + if err := p[id].Container.ApplyContainers(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod for %d", id) } } - return pod.DeepCopy(), nil + return nil } diff --git a/pkg/apis/scheduler/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1alpha1/zz_generated.deepcopy.go index 3fbf82417..8a9c4ebba 100644 --- a/pkg/apis/scheduler/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/scheduler/v1alpha1/zz_generated.deepcopy.go @@ -95,7 +95,11 @@ func (in ProfileTemplates) DeepCopyInto(out *ProfileTemplates) { in := &in *out = make(ProfileTemplates, len(*in)) for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ProfileTemplate) + (*in).DeepCopyInto(*out) + } } return } diff --git a/pkg/crd/crds/ml-extension.schema.generated.yaml b/pkg/crd/crds/ml-extension.schema.generated.yaml index 57a01fd6d..2dbfcb115 100644 --- a/pkg/crd/crds/ml-extension.schema.generated.yaml +++ b/pkg/crd/crds/ml-extension.schema.generated.yaml @@ -337,16 +337,43 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object + automountServiceAccountToken: + type: boolean hostIPC: type: boolean hostNetwork: type: boolean hostPID: type: boolean + labels: + additionalProperties: + type: string + type: object nodeSelector: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -1414,6 +1441,8 @@ v1alpha1: - ExternalName type: string type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean tolerations: @@ -2608,14 +2637,6 @@ v1alpha1: type: object type: array type: object - image: - type: string - imagePullPolicy: - type: string - imagePullSecrets: - items: - type: string - type: array init: description: ArangoMLExtensionTemplate define Init job specification properties: @@ -2950,10 +2971,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -3039,6 +3066,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -3201,6 +3232,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -3421,6 +3469,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -4544,10 +4594,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -4633,6 +4689,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -4795,6 +4855,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -5015,6 +5092,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -6132,10 +6211,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -6221,6 +6306,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -6383,6 +6472,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -6603,6 +6709,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -7724,10 +7832,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -7813,6 +7927,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -7975,6 +8093,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -8195,6 +8330,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -9312,10 +9449,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -9401,6 +9544,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -9563,6 +9710,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -9783,6 +9947,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -10904,10 +11070,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -10993,6 +11165,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -11155,6 +11331,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -11375,6 +11568,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: @@ -12492,10 +12687,16 @@ v1alpha1: type: array type: object type: object + annotations: + additionalProperties: + type: string + type: object args: items: type: string type: array + automountServiceAccountToken: + type: boolean command: items: type: string @@ -12581,6 +12782,10 @@ v1alpha1: items: type: string type: array + labels: + additionalProperties: + type: string + type: object lifecycle: properties: postStart: @@ -12743,6 +12948,23 @@ v1alpha1: additionalProperties: type: string type: object + ownerReferences: + items: + properties: + apiVersion: + type: string + blockOwnerDeletion: + type: boolean + controller: + type: boolean + kind: + type: string + name: + type: string + uid: + type: string + type: object + type: array podSecurityContext: properties: fsGroup: @@ -12963,6 +13185,8 @@ v1alpha1: type: string type: object type: object + serviceAccountName: + type: string shareProcessNamespace: type: boolean startupProbe: diff --git a/pkg/util/dict.go b/pkg/util/dict.go index fa138e97b..c356b246a 100644 --- a/pkg/util/dict.go +++ b/pkg/util/dict.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -55,6 +55,24 @@ func CopyFullMap[K comparable, V any](src map[K]V) map[K]V { return r } +func MergeMaps[K comparable, V any](override bool, maps ...map[K]V) map[K]V { + r := map[K]V{} + + for _, m := range maps { + for k, v := range m { + if !override { + if _, ok := r[k]; ok { + continue + } + } + + r[k] = v + } + } + + return r +} + func CopyMap[K comparable, V any](dst, src map[K]V) { // TODO: replace with maps.Copy when switching to go1.21 for k, v := range src { diff --git a/pkg/util/k8sutil/resources/metadata.go b/pkg/util/k8sutil/resources/metadata.go new file mode 100644 index 000000000..3d7ff7a99 --- /dev/null +++ b/pkg/util/k8sutil/resources/metadata.go @@ -0,0 +1,36 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import meta "k8s.io/apimachinery/pkg/apis/meta/v1" + +func MergeOwnerReferences(refs ...[]meta.OwnerReference) []meta.OwnerReference { + var ret []meta.OwnerReference + for _, ref := range refs { + for _, r := range ref { + var o meta.OwnerReference + r.DeepCopyInto(&o) + ret = append(ret, o) + } + } + + return ret +}