From ccdf309abfcc4cbde65d6c45a92cf3067b6e5430 Mon Sep 17 00:00:00 2001 From: Adam Janikowski <12255597+ajanikow@users.noreply.github.com> Date: Mon, 6 May 2024 14:32:52 +0200 Subject: [PATCH] [Feature] [ML] Release V1Beta1 API (#1658) --- .golangci.yaml | 28 +- CHANGELOG.md | 1 + Makefile | 5 +- chart/kube-arangodb/crds/ml-extension.yaml | 9 + chart/kube-arangodb/crds/ml-storage.yaml | 9 + .../kube-arangodb/crds/scheduler-profile.yaml | 9 + docs/api/ArangoMLExtension.V1Beta1.md | 3233 ++++ docs/api/ArangoMLStorage.V1Beta1.md | 320 + docs/api/ArangoProfile.V1Beta1.md | 398 + integrations/scheduler/v1/batch_job_test.go | 2 +- integrations/scheduler/v1/cron_job_test.go | 2 +- internal/cr_validation_test.go | 19 +- internal/docs_test.go | 58 +- .../ml/v1alpha1/extension_spec_deployment.go | 12 +- pkg/apis/ml/v1alpha1/extension_spec_job.go | 22 +- .../ml/v1alpha1/storage_spec_mode_sidecar.go | 6 +- pkg/apis/ml/v1alpha1/storage_spec_test.go | 10 +- pkg/apis/ml/v1beta1/conditions.go | 39 + pkg/apis/ml/v1beta1/doc.go | 23 + pkg/apis/ml/v1beta1/extension.go | 69 + pkg/apis/ml/v1beta1/extension_spec.go | 96 + .../ml/v1beta1/extension_spec_deployment.go | 127 + .../extension_spec_deployment_service.go | 57 + .../v1beta1/extension_spec_deployment_tls.go | 45 + pkg/apis/ml/v1beta1/extension_spec_job.go | 187 + .../extension_spec_metadata_service.go | 99 + pkg/apis/ml/v1beta1/extension_status.go | 44 + .../v1beta1/extension_status_arangodb_ref.go | 30 + .../extension_status_metadata_service.go | 39 + .../extension_status_reconciliation.go | 42 + pkg/apis/ml/v1beta1/register.go | 57 + pkg/apis/ml/v1beta1/storage.go | 69 + pkg/apis/ml/v1beta1/storage_spec.go | 84 + pkg/apis/ml/v1beta1/storage_spec_backend.go | 50 + .../ml/v1beta1/storage_spec_backend_s3.go | 109 + pkg/apis/ml/v1beta1/storage_spec_mode.go | 45 + .../ml/v1beta1/storage_spec_mode_sidecar.go | 82 + pkg/apis/ml/v1beta1/storage_spec_test.go | 95 + pkg/apis/ml/v1beta1/storage_status.go | 29 + pkg/apis/ml/v1beta1/zz_generated.deepcopy.go | 736 + .../v1alpha1/container/definition.go | 38 +- .../container/definition_container_test.go | 20 +- .../container/definition_containers_test.go | 10 +- .../scheduler/v1alpha1/container/generic.go | 10 +- .../v1alpha1/container/generic_test.go | 6 +- pkg/apis/scheduler/v1alpha1/pod/definition.go | 30 +- .../scheduler/v1alpha1/pod/definition_test.go | 8 +- .../v1alpha1/profile_container_template.go | 6 +- .../scheduler/v1alpha1/profile_template.go | 6 +- .../environments.container.kubernetes.go | 16 +- .../environments.container.resources.go | 16 +- .../scheduler/v1beta1/container/definition.go | 289 + .../container/definition_container_test.go | 371 + .../container/definition_containers_test.go | 205 + pkg/apis/scheduler/v1beta1/container/doc.go | 23 + .../scheduler/v1beta1/container/generic.go | 102 + .../v1beta1/container/generic_test.go | 190 + .../v1beta1/container/resources/core.go | 86 + .../v1beta1/container/resources/core_test.go | 107 + .../v1beta1/container/resources/doc.go | 23 + .../container/resources/environments.go | 76 + .../container/resources/environments_test.go | 221 + .../v1beta1/container/resources/image.go | 82 + .../v1beta1/container/resources/image_test.go | 109 + .../v1beta1/container/resources/lifecycle.go | 68 + .../container/resources/lifecycle_test.go | 181 + .../v1beta1/container/resources/networking.go | 86 + .../container/resources/networking_test.go | 140 + .../v1beta1/container/resources/probes.go | 87 + .../container/resources/probes_test.go | 271 + .../v1beta1/container/resources/resources.go | 83 + .../container/resources/resources_test.go | 210 + .../v1beta1/container/resources/security.go | 70 + .../container/resources/security_test.go | 96 + .../container/resources/volume_mounts.go | 70 + .../container/resources/volume_mounts_test.go | 145 + .../resources/zz_generated.deepcopy.go | 250 + .../container/zz_generated.deepcopy.go | 139 + pkg/apis/scheduler/v1beta1/doc.go | 23 + .../v1beta1/interfaces/interfaces.go | 38 + pkg/apis/scheduler/v1beta1/pod/definition.go | 165 + .../scheduler/v1beta1/pod/definition_test.go | 239 + pkg/apis/scheduler/v1beta1/pod/doc.go | 23 + .../scheduler/v1beta1/pod/resources/doc.go | 23 + .../scheduler/v1beta1/pod/resources/image.go | 87 + .../v1beta1/pod/resources/image_test.go | 88 + .../v1beta1/pod/resources/metadata.go | 91 + .../v1beta1/pod/resources/metadata_test.go | 139 + .../v1beta1/pod/resources/namespace.go | 123 + .../v1beta1/pod/resources/namespace_test.go | 136 + .../v1beta1/pod/resources/scheduling.go | 166 + .../v1beta1/pod/resources/scheduling_test.go | 844 + .../v1beta1/pod/resources/security.go | 74 + .../v1beta1/pod/resources/security_test.go | 87 + .../v1beta1/pod/resources/service_account.go | 74 + .../pod/resources/service_account_test.go | 94 + .../v1beta1/pod/resources/volumes.go | 71 + .../v1beta1/pod/resources/volumes_test.go | 149 + .../pod/resources/zz_generated.deepcopy.go | 272 + .../v1beta1/pod/zz_generated.deepcopy.go | 81 + pkg/apis/scheduler/v1beta1/profile.go | 45 + .../v1beta1/profile_container_template.go | 80 + .../scheduler/v1beta1/profile_selectors.go | 49 + pkg/apis/scheduler/v1beta1/profile_spec.go | 44 + pkg/apis/scheduler/v1beta1/profile_status.go | 24 + .../scheduler/v1beta1/profile_template.go | 90 + .../scheduler/v1beta1/profile_templates.go | 74 + .../environments.container.kubernetes.go | 76 + .../environments.container.resources.go | 86 + pkg/apis/scheduler/v1beta1/register.go | 56 + .../v1beta1/zz_generated.deepcopy.go | 242 + .../crds/ml-extension.schema.generated.yaml | 12995 ++++++++++++++++ pkg/crd/crds/ml-extension.yaml | 9 + pkg/crd/crds/ml-storage.schema.generated.yaml | 546 + pkg/crd/crds/ml-storage.yaml | 9 + .../scheduler-profile.schema.generated.yaml | 1748 +++ pkg/crd/crds/scheduler-profile.yaml | 9 + .../kubernetes/arango_ml_batch_job.go | 12 +- .../kubernetes/arango_ml_cron_job.go | 12 +- .../kubernetes/arango_ml_extension.go | 6 +- .../kubernetes/arango_ml_storage.go | 6 +- .../kubernetes/arango_scheduler_profile.go | 4 +- .../clientset/versioned/clientset.go | 26 + .../versioned/fake/clientset_generated.go | 14 + .../clientset/versioned/fake/register.go | 4 + .../clientset/versioned/scheme/register.go | 4 + .../typed/ml/v1beta1/arangomlextension.go | 199 + .../typed/ml/v1beta1/arangomlstorage.go | 199 + .../versioned/typed/ml/v1beta1/doc.go | 24 + .../versioned/typed/ml/v1beta1/fake/doc.go | 24 + .../ml/v1beta1/fake/fake_arangomlextension.go | 145 + .../ml/v1beta1/fake/fake_arangomlstorage.go | 145 + .../typed/ml/v1beta1/fake/fake_ml_client.go | 48 + .../typed/ml/v1beta1/generated_expansion.go | 27 + .../versioned/typed/ml/v1beta1/ml_client.go | 116 + .../typed/scheduler/v1beta1/arangoprofile.go | 199 + .../versioned/typed/scheduler/v1beta1/doc.go | 24 + .../typed/scheduler/v1beta1/fake/doc.go | 24 + .../v1beta1/fake/fake_arangoprofile.go | 145 + .../v1beta1/fake/fake_scheduler_client.go | 44 + .../scheduler/v1beta1/generated_expansion.go | 25 + .../scheduler/v1beta1/scheduler_client.go | 111 + .../informers/externalversions/generic.go | 12 + .../externalversions/ml/interface.go | 8 + .../ml/v1beta1/arangomlextension.go | 94 + .../ml/v1beta1/arangomlstorage.go | 94 + .../externalversions/ml/v1beta1/interface.go | 56 + .../externalversions/scheduler/interface.go | 8 + .../scheduler/v1beta1/arangoprofile.go | 94 + .../scheduler/v1beta1/interface.go | 49 + .../listers/ml/v1beta1/arangomlextension.go | 103 + .../listers/ml/v1beta1/arangomlstorage.go | 103 + .../listers/ml/v1beta1/expansion_generated.go | 39 + .../scheduler/v1beta1/arangoprofile.go | 103 + .../scheduler/v1beta1/expansion_generated.go | 31 + pkg/operatorV2/update_wraps.go | 13 +- pkg/scheduler/input.go | 10 +- pkg/scheduler/scheduler.go | 4 +- pkg/scheduler/scheduler_test.go | 6 +- pkg/util/k8sutil/images.go | 2 +- pkg/util/k8sutil/pods.go | 4 +- pkg/util/tests/kubernetes.go | 220 +- pkg/util/tests/kubernetes_test.go | 9 +- 163 files changed, 32040 insertions(+), 220 deletions(-) create mode 100644 docs/api/ArangoMLExtension.V1Beta1.md create mode 100644 docs/api/ArangoMLStorage.V1Beta1.md create mode 100644 docs/api/ArangoProfile.V1Beta1.md create mode 100644 pkg/apis/ml/v1beta1/conditions.go create mode 100644 pkg/apis/ml/v1beta1/doc.go create mode 100644 pkg/apis/ml/v1beta1/extension.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec_deployment.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec_deployment_service.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec_job.go create mode 100644 pkg/apis/ml/v1beta1/extension_spec_metadata_service.go create mode 100644 pkg/apis/ml/v1beta1/extension_status.go create mode 100644 pkg/apis/ml/v1beta1/extension_status_arangodb_ref.go create mode 100644 pkg/apis/ml/v1beta1/extension_status_metadata_service.go create mode 100644 pkg/apis/ml/v1beta1/extension_status_reconciliation.go create mode 100644 pkg/apis/ml/v1beta1/register.go create mode 100644 pkg/apis/ml/v1beta1/storage.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec_backend.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec_backend_s3.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec_mode.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go create mode 100644 pkg/apis/ml/v1beta1/storage_spec_test.go create mode 100644 pkg/apis/ml/v1beta1/storage_status.go create mode 100644 pkg/apis/ml/v1beta1/zz_generated.deepcopy.go create mode 100644 pkg/apis/scheduler/v1beta1/container/definition.go create mode 100644 pkg/apis/scheduler/v1beta1/container/definition_container_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/definition_containers_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/doc.go create mode 100644 pkg/apis/scheduler/v1beta1/container/generic.go create mode 100644 pkg/apis/scheduler/v1beta1/container/generic_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/core.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/core_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/doc.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/environments.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/environments_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/image.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/image_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/lifecycle_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/networking.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/networking_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/probes.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/probes_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/resources.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/resources_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/security.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/security_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/volume_mounts_test.go create mode 100644 pkg/apis/scheduler/v1beta1/container/resources/zz_generated.deepcopy.go create mode 100644 pkg/apis/scheduler/v1beta1/container/zz_generated.deepcopy.go create mode 100644 pkg/apis/scheduler/v1beta1/doc.go create mode 100644 pkg/apis/scheduler/v1beta1/interfaces/interfaces.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/definition.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/definition_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/doc.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/doc.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/image.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/image_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/metadata.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/metadata_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/namespace.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/namespace_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/scheduling_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/security.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/security_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/service_account.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/service_account_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/volumes.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/volumes_test.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/resources/zz_generated.deepcopy.go create mode 100644 pkg/apis/scheduler/v1beta1/pod/zz_generated.deepcopy.go create mode 100644 pkg/apis/scheduler/v1beta1/profile.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_container_template.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_selectors.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_spec.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_status.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_template.go create mode 100644 pkg/apis/scheduler/v1beta1/profile_templates.go create mode 100644 pkg/apis/scheduler/v1beta1/profiles/environments.container.kubernetes.go create mode 100644 pkg/apis/scheduler/v1beta1/profiles/environments.container.resources.go create mode 100644 pkg/apis/scheduler/v1beta1/register.go create mode 100644 pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlextension.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlstorage.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlextension.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlstorage.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_ml_client.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/generated_expansion.go create mode 100644 pkg/generated/clientset/versioned/typed/ml/v1beta1/ml_client.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoprofile.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/doc.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoprofile.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_scheduler_client.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go create mode 100644 pkg/generated/informers/externalversions/ml/v1beta1/arangomlextension.go create mode 100644 pkg/generated/informers/externalversions/ml/v1beta1/arangomlstorage.go create mode 100644 pkg/generated/informers/externalversions/ml/v1beta1/interface.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/arangoprofile.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go create mode 100644 pkg/generated/listers/ml/v1beta1/arangomlextension.go create mode 100644 pkg/generated/listers/ml/v1beta1/arangomlstorage.go create mode 100644 pkg/generated/listers/ml/v1beta1/expansion_generated.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/arangoprofile.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/expansion_generated.go diff --git a/.golangci.yaml b/.golangci.yaml index 414b5ed1e..55d481725 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -41,26 +41,40 @@ linters-settings: alias: policy - pkg: github.com/arangodb/kube-arangodb/pkg/apis/shared/v1 alias: sharedApi - - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1 + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1 alias: schedulerApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/profiles + alias: schedulerProfilesv1beta1 + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container + alias: schedulerContainerApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources + alias: schedulerContainerResourcesApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod + alias: schedulerPodApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod/resources + alias: schedulerPodResourcesApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1 + alias: schedulerApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/profiles - alias: schedulerProfiles + alias: schedulerProfilesv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container - alias: schedulerContainerApi + alias: schedulerContainerApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources - alias: schedulerContainerResourcesApi + alias: schedulerContainerResourcesApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod - alias: schedulerPodApi + alias: schedulerPodApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources - alias: schedulerPodResourcesApi + alias: schedulerPodResourcesApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/pkg/apis/shared alias: shared - pkg: github.com/arangodb/kube-arangodb/pkg/handlers/enterprise/ml/shared alias: mlShared - pkg: github.com/arangodb/kube-arangodb/pkg/handlers/enterprise/ml/shared/test alias: mlSharedTests - - pkg: github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1 + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1 alias: mlApi + - pkg: github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1 + alias: mlApiv1alpha1 - pkg: github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition alias: pbSchedulerV1 - pkg: github.com/arangodb/kube-arangodb/integrations/scheduler/v1 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3fd94e394..3a34f0e77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - (Feature) (ML) Add TLS Secrets - (Feature) (ML) Allow to change API port - (Feature) (ML) Enable TLS +- (Feature) (ML) Release V1Beta1 API ## [1.2.40](https://github.com/arangodb/kube-arangodb/tree/1.2.40) (2024-04-10) - (Feature) Add Core fields to the Scheduler Container Spec diff --git a/Makefile b/Makefile index 74a34e9c2..bf3d2043e 100644 --- a/Makefile +++ b/Makefile @@ -431,14 +431,15 @@ update-generated: "client lister informer deepcopy" \ "github.com/arangodb/kube-arangodb/pkg/generated" \ "github.com/arangodb/kube-arangodb/pkg/apis" \ - "deployment:v1 replication:v1 storage:v1alpha backup:v1 deployment:v2alpha1 replication:v2alpha1 apps:v1 ml:v1alpha1 scheduler:v1alpha1" \ + "deployment:v1 replication:v1 storage:v1alpha backup:v1 deployment:v2alpha1 replication:v2alpha1 apps:v1 ml:v1alpha1 ml:v1beta1 scheduler:v1alpha1 scheduler:v1beta1" \ --go-header-file "./tools/codegen/boilerplate.go.txt" \ $(VERIFYARGS) GOPATH=$(GOBUILDDIR) $(VENDORDIR)/k8s.io/code-generator/generate-groups.sh \ "deepcopy" \ "github.com/arangodb/kube-arangodb/pkg/generated" \ "github.com/arangodb/kube-arangodb/pkg/apis" \ - "shared:v1 scheduler:v1alpha1/container scheduler:v1alpha1/container/resources scheduler:v1alpha1/pod scheduler:v1alpha1/pod/resources" \ + "shared:v1 scheduler:v1alpha1/container scheduler:v1alpha1/container/resources scheduler:v1alpha1/pod scheduler:v1alpha1/pod/resources\ + shared:v1 scheduler:v1beta1/container scheduler:v1beta1/container/resources scheduler:v1beta1/pod scheduler:v1beta1/pod/resources" \ --go-header-file "./tools/codegen/boilerplate.go.txt" \ $(VERIFYARGS) diff --git a/chart/kube-arangodb/crds/ml-extension.yaml b/chart/kube-arangodb/crds/ml-extension.yaml index 776be6000..1ba50dd8c 100644 --- a/chart/kube-arangodb/crds/ml-extension.yaml +++ b/chart/kube-arangodb/crds/ml-extension.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/chart/kube-arangodb/crds/ml-storage.yaml b/chart/kube-arangodb/crds/ml-storage.yaml index 77303d266..01b23a672 100644 --- a/chart/kube-arangodb/crds/ml-storage.yaml +++ b/chart/kube-arangodb/crds/ml-storage.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/chart/kube-arangodb/crds/scheduler-profile.yaml b/chart/kube-arangodb/crds/scheduler-profile.yaml index 685448169..2be38f32a 100644 --- a/chart/kube-arangodb/crds/scheduler-profile.yaml +++ b/chart/kube-arangodb/crds/scheduler-profile.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/docs/api/ArangoMLExtension.V1Beta1.md b/docs/api/ArangoMLExtension.V1Beta1.md new file mode 100644 index 000000000..93278a7da --- /dev/null +++ b/docs/api/ArangoMLExtension.V1Beta1.md @@ -0,0 +1,3233 @@ +--- +layout: page +parent: CRD reference +title: ArangoMLExtension V1Beta1 +--- + +# API Reference for ArangoMLExtension V1Beta1 + +## Spec + +### .spec.deployment.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.deployment.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.args + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.deployment.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + +### .spec.deployment.command + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.deployment.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.deployment.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.deployment.gpu + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment.go#L55) + +GPU defined if GPU Jobs are enabled. + +Default Value: `false` + +*** + +### .spec.deployment.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.deployment.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.deployment.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.deployment.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.deployment.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.deployment.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +ImagePullSecrets define Secrets used to pull Image from registry + +*** + +### .spec.deployment.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.lifecycle + +Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.deployment.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.deployment.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.deployment.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.deployment.port + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment.go#L58) + +Port defines on which port the container will be listening for connections + +*** + +### .spec.deployment.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.deployment.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.deployment.replicas + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment.go#L39) + +Replicas defines the number of replicas running specified components. No replicas created if no components are defined. + +Default Value: `1` + +*** + +### .spec.deployment.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.deployment.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.deployment.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.deployment.service.type + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment_service.go#L37) + +Type determines how the Service is exposed + +Links: +* [Kubernetes Documentation](https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types) + +Possible Values: +* `"ClusterIP"` (default) - service will only be accessible inside the cluster, via the cluster IP +* `"NodePort"` - service will be exposed on one port of every node, in addition to 'ClusterIP' type +* `"LoadBalancer"` - service will be exposed via an external load balancer (if the cloud provider supports it), in addition to 'NodePort' type +* `"ExternalName"` - service consists of only a reference to an external name that kubedns or equivalent will return as a CNAME record, with no exposing or proxying of any pods involved + +*** + +### .spec.deployment.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.deployment.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.deployment.tls.altNames + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go#L28) + +AltNames define TLS AltNames used when TLS on the ArangoDB is enabled + +*** + +### .spec.deployment.tls.enabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go#L25) + +Enabled define if TLS Should be enabled. If is not set then default is taken from ArangoDeployment settings + +*** + +### .spec.deployment.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.deployment.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.deployment.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.deployment.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.init.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.init.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.init.args + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.init.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.init.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.init.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.init.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.init.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.init.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.init.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.init.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.init.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +ImagePullSecrets define Secrets used to pull Image from registry + +*** + +### .spec.init.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.init.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.init.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.init.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.init.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.init.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.init.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.init.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.init.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.init.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.init.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.init.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.init.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.init.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.init.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.featurization.cpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.featurization.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.featurization.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.featurization.cpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.featurization.cpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.featurization.cpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.cpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.cpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.cpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.featurization.cpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.featurization.cpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.featurization.cpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.cpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.featurization.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.featurization.cpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.featurization.cpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.cpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.featurization.cpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.featurization.cpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.featurization.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.cpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.cpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.featurization.cpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.featurization.cpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.featurization.cpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.featurization.gpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.featurization.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.featurization.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.featurization.gpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.featurization.gpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.featurization.gpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.gpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.gpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.gpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.featurization.gpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.featurization.gpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.featurization.gpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.gpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.featurization.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.featurization.gpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.featurization.gpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.gpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.featurization.gpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.featurization.gpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.featurization.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.featurization.gpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.featurization.gpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.featurization.gpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.featurization.gpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.featurization.gpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.prediction.cpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.prediction.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.prediction.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.prediction.cpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.prediction.cpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.prediction.cpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.cpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.cpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.cpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.prediction.cpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.prediction.cpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.prediction.cpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.cpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.prediction.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.prediction.cpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.prediction.cpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.cpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.prediction.cpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.prediction.cpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.prediction.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.cpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.cpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.prediction.cpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.prediction.cpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.prediction.cpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.prediction.gpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.prediction.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.prediction.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.prediction.gpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.prediction.gpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.prediction.gpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.gpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.gpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.gpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.prediction.gpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.prediction.gpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.prediction.gpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.gpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.prediction.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.prediction.gpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.prediction.gpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.gpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.prediction.gpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.prediction.gpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.prediction.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.prediction.gpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.prediction.gpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.prediction.gpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.prediction.gpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.prediction.gpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.training.cpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.training.cpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.training.cpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.training.cpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.training.cpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.training.cpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.cpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.cpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.cpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.training.cpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.training.cpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.training.cpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.cpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.training.cpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.training.cpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.training.cpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.cpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.training.cpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.training.cpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.training.cpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.cpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.cpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.training.cpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.training.cpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.training.cpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.jobsTemplates.training.gpu.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.jobsTemplates.training.gpu.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.training.gpu.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.jobsTemplates.training.gpu.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.jobsTemplates.training.gpu.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.jobsTemplates.training.gpu.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.gpu.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.gpu.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.gpu.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.jobsTemplates.training.gpu.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.jobsTemplates.training.gpu.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +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.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.jobsTemplates.training.gpu.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.gpu.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.jobsTemplates.training.gpu.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.training.gpu.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.jobsTemplates.training.gpu.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.gpu.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.jobsTemplates.training.gpu.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.jobsTemplates.training.gpu.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.jobsTemplates.training.gpu.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.jobsTemplates.training.gpu.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.jobsTemplates.training.gpu.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.jobsTemplates.training.gpu.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.jobsTemplates.training.gpu.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.jobsTemplates.training.gpu.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.metadataService.local.arangoMLFeatureStore + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_metadata_service.go#L65) + +ArangoMLFeatureStoreDatabase define Database name to be used as MetadataService Backend in ArangoMLFeatureStoreDatabase + +Default Value: `arangomlfeaturestore` + +*** + +### .spec.metadataService.local.arangoPipeDatabase + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_spec_metadata_service.go#L61) + +ArangoPipeDatabase define Database name to be used as MetadataService Backend in ArangoPipe + +Default Value: `arangopipe` + +*** + +### .spec.storage.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .spec.storage.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .spec.storage.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .spec.storage.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +## Status + +### .status.arangoDB.secret.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.arangoDB.secret.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.arangoDB.secret.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.arangoDB.secret.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.arangoDB.tls.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.arangoDB.tls.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.arangoDB.tls.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.arangoDB.tls.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.conditions + +Type: `api.Conditions` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_status.go#L31) + +Conditions specific to the entire extension + +*** + +### .status.metadataService.local.arangoMLFeatureStore + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_status_metadata_service.go#L38) + +ArangoMLFeatureStoreDatabase define Database name to be used as MetadataService Backend + +*** + +### .status.metadataService.local.arangoPipe + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/extension_status_metadata_service.go#L35) + +ArangoPipeDatabase define Database name to be used as MetadataService Backend + +*** + +### .status.metadataService.secret.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.metadataService.secret.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.metadataService.secret.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.metadataService.secret.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.reconciliation.service.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.reconciliation.service.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.reconciliation.service.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.reconciliation.service.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.reconciliation.statefulSet.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.reconciliation.statefulSet.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.reconciliation.statefulSet.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.reconciliation.statefulSet.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.serviceAccount.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.serviceAccount.cluster.binding.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.serviceAccount.cluster.binding.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.serviceAccount.cluster.binding.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.serviceAccount.cluster.binding.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.serviceAccount.cluster.role.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.serviceAccount.cluster.role.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.serviceAccount.cluster.role.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.serviceAccount.cluster.role.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.serviceAccount.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.serviceAccount.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.serviceAccount.namespaced.binding.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.serviceAccount.namespaced.binding.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.serviceAccount.namespaced.binding.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.serviceAccount.namespaced.binding.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.serviceAccount.namespaced.role.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .status.serviceAccount.namespaced.role.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .status.serviceAccount.namespaced.role.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .status.serviceAccount.namespaced.role.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .status.serviceAccount.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + diff --git a/docs/api/ArangoMLStorage.V1Beta1.md b/docs/api/ArangoMLStorage.V1Beta1.md new file mode 100644 index 000000000..01e4fd2c7 --- /dev/null +++ b/docs/api/ArangoMLStorage.V1Beta1.md @@ -0,0 +1,320 @@ +--- +layout: page +parent: CRD reference +title: ArangoMLStorage V1Beta1 +--- + +# API Reference for ArangoMLStorage V1Beta1 + +## Spec + +### .spec.backend.s3.allowInsecure + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go#L40) + +AllowInsecure if set to true, the Endpoint certificates won't be checked + +Default Value: `false` + +*** + +### .spec.backend.s3.caSecret.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .spec.backend.s3.caSecret.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .spec.backend.s3.caSecret.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .spec.backend.s3.caSecret.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .spec.backend.s3.credentialsSecret.checksum + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L61) + +UID keeps the information about object Checksum + +*** + +### .spec.backend.s3.credentialsSecret.name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L52) + +Name of the object + +*** + +### .spec.backend.s3.credentialsSecret.namespace + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L55) + +Namespace of the object. Should default to the namespace of the parent object + +*** + +### .spec.backend.s3.credentialsSecret.uid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/shared/v1/object.go#L58) + +UID keeps the information about object UID + +*** + +### .spec.backend.s3.endpoint + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go#L34) + +Endpoint specifies the S3 API-compatible endpoint which implements storage +Required + +*** + +### .spec.backend.s3.region + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go#L49) + +Region defines the availability zone name. + +Default Value: `""` + +*** + +### .spec.bucketName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec.go#L30) + +BucketName specifies the name of the bucket +Required + +*** + +### .spec.bucketPath + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec.go#L34) + +BucketPath specifies the path within the bucket + +Default Value: `/` + +*** + +### .spec.mode.sidecar.args + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.mode.sidecar.command + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.mode.sidecar.controllerListenPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go#L36) + +ControllerListenPort defines on which port the sidecar container will be listening for controller requests + +Default Value: `9202` + +*** + +### .spec.mode.sidecar.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.mode.sidecar.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.mode.sidecar.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.mode.sidecar.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.mode.sidecar.lifecycle + +Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.mode.sidecar.listenPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go#L32) + +ListenPort defines on which port the sidecar container will be listening for connections + +Default Value: `9201` + +*** + +### .spec.mode.sidecar.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.mode.sidecar.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.mode.sidecar.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.mode.sidecar.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.mode.sidecar.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.mode.sidecar.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.mode.sidecar.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.mode.sidecar.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +## Status + +### .status.conditions + +Type: `api.Conditions` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/ml/v1beta1/storage_status.go#L28) + +Conditions specific to the entire storage + diff --git a/docs/api/ArangoProfile.V1Beta1.md b/docs/api/ArangoProfile.V1Beta1.md new file mode 100644 index 000000000..84b956420 --- /dev/null +++ b/docs/api/ArangoProfile.V1Beta1.md @@ -0,0 +1,398 @@ +--- +layout: page +parent: CRD reference +title: ArangoProfile V1Beta1 +--- + +# API Reference for ArangoProfile V1Beta1 + +## Spec + +### .spec.selectors.label + +Type: `meta.LabelSelector` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/profile_selectors.go#L32) + +Label keeps information about label selector + +*** + +### .spec.template.container.all.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.template.container.all.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.template.container.all.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.template.container.containers.\.args + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L50) + +Arguments to the entrypoint. +The container image's CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.template.container.containers.\.command + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L40) + +Entrypoint array. Not executed within a shell. +The container image's ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container's environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will +produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell) + +*** + +### .spec.template.container.containers.\.env + +Type: `core.EnvVar` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L36) + +Env keeps the information about environment variables provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core) + +*** + +### .spec.template.container.containers.\.envFrom + +Type: `core.EnvFromSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/environments.go#L41) + +EnvFrom keeps the information about environment variable sources provided to the container + +Links: +* [Kubernetes Docs](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core) + +*** + +### .spec.template.container.containers.\.image + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L35) + +Image define image details + +*** + +### .spec.template.container.containers.\.imagePullPolicy + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/image.go#L39) + +ImagePullPolicy define Image pull policy + +Default Value: `IfNotPresent` + +*** + +### .spec.template.container.containers.\.lifecycle + +Type: `core.Lifecycle` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go#L35) + +Lifecycle keeps actions that the management system should take in response to container lifecycle events. + +*** + +### .spec.template.container.containers.\.livenessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L37) + +LivenessProbe keeps configuration of periodic probe of container liveness. +Container will be restarted if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.template.container.containers.\.ports + +Type: `[]core.ContainerPort` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/networking.go#L39) + +Ports contains list of ports to expose from the container. Not specifying a port here +DOES NOT prevent that port from being exposed. Any port which is +listening on the default "0.0.0.0" address inside a container will be +accessible from the network. + +*** + +### .spec.template.container.containers.\.readinessProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L42) + +ReadinessProbe keeps configuration of periodic probe of container service readiness. +Container will be removed from service endpoints if the probe fails. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.template.container.containers.\.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/resources.go#L37) + +Resources holds resource requests & limits for container + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.template.container.containers.\.securityContext + +Type: `core.SecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/security.go#L35) + +SecurityContext holds container-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.template.container.containers.\.startupProbe + +Type: `core.Probe` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/probes.go#L50) + +StartupProbe indicates that the Pod has successfully initialized. +If specified, no other probes are executed until this completes successfully. +If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. +This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, +when it might take a long time to load data or warm a cache, than during steady-state operation. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes) + +*** + +### .spec.template.container.containers.\.volumeMounts + +Type: `[]core.VolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go#L35) + +VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + +*** + +### .spec.template.container.containers.\.workingDir + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/container/resources/core.go#L55) + +Container's working directory. +If not specified, the container runtime's default will be used, which +might be configured in the container image. + +*** + +### .spec.template.pod.affinity + +Type: `core.Affinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L44) + +Affinity defines scheduling constraints for workload + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity) + +*** + +### .spec.template.pod.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.template.pod.automountServiceAccountToken + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/service_account.go#L38) + +AutomountServiceAccountToken indicates whether a service account token should be automatically mounted. + +*** + +### .spec.template.pod.hostIPC + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L42) + +HostIPC defines to use the host's ipc namespace. + +Default Value: `false` + +*** + +### .spec.template.pod.hostNetwork + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L36) + +HostNetwork requests Host network for this pod. Use the host's network namespace. +If this option is set, the ports that will be used must be specified. + +Default Value: `false` + +*** + +### .spec.template.pod.hostPID + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L39) + +HostPID define to use the host's pid namespace. + +Default Value: `false` + +*** + +### .spec.template.pod.imagePullSecrets + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/image.go#L36) + +ImagePullSecrets define Secrets used to pull Image from registry + +*** + +### .spec.template.pod.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.template.pod.nodeSelector + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L39) + +NodeSelector is a selector that must be true for the workload to fit on a node. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector) + +*** + +### .spec.template.pod.ownerReferences + +Type: `meta.OwnerReference` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.template.pod.podSecurityContext + +Type: `core.PodSecurityContext` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/security.go#L35) + +PodSecurityContext holds pod-level security attributes and common container settings. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) + +*** + +### .spec.template.pod.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L54) + +SchedulerName specifies, the pod will be dispatched by specified scheduler. +If not specified, the pod will be dispatched by default scheduler. + +Default Value: `""` + +*** + +### .spec.template.pod.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/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.template.pod.shareProcessNamespace + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go#L48) + +ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. +When this is set containers will be able to view and signal processes from other containers +in the same pod, and the first process in each container will not be assigned PID 1. +HostPID and ShareProcessNamespace cannot both be set. + +Default Value: `false` + +*** + +### .spec.template.pod.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go#L49) + +Tolerations defines tolerations + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/) + +*** + +### .spec.template.pod.volumes + +Type: `[]core.Volume` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go#L36) + +Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + +Links: +* [Kubernetes docs](https://kubernetes.io/docs/concepts/storage/volumes) + +*** + +### .spec.template.priority + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.40/pkg/apis/scheduler/v1beta1/profile_template.go#L30) + diff --git a/integrations/scheduler/v1/batch_job_test.go b/integrations/scheduler/v1/batch_job_test.go index 1ae84af99..368bee751 100644 --- a/integrations/scheduler/v1/batch_job_test.go +++ b/integrations/scheduler/v1/batch_job_test.go @@ -29,7 +29,7 @@ import ( meta "k8s.io/apimachinery/pkg/apis/meta/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/kclient" "github.com/arangodb/kube-arangodb/pkg/util/tests" diff --git a/integrations/scheduler/v1/cron_job_test.go b/integrations/scheduler/v1/cron_job_test.go index acbb2565c..ecddcdac2 100644 --- a/integrations/scheduler/v1/cron_job_test.go +++ b/integrations/scheduler/v1/cron_job_test.go @@ -30,7 +30,7 @@ import ( meta "k8s.io/apimachinery/pkg/apis/meta/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/kclient" "github.com/arangodb/kube-arangodb/pkg/util/tests" diff --git a/internal/cr_validation_test.go b/internal/cr_validation_test.go index a4eb8dddc..1b17b6203 100644 --- a/internal/cr_validation_test.go +++ b/internal/cr_validation_test.go @@ -37,10 +37,12 @@ import ( backupv1 "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" deploymentv1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" deploymentv2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v2alpha1" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" replicationv1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v2alpha1" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -183,6 +185,9 @@ func Test_GenerateCRValidationSchemas(t *testing.T) { "scheduler-profile": { fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { "v1alpha1": { + schedulerApiv1alpha1.ArangoProfile{}.Spec, + }, + "v1beta1": { schedulerApi.ArangoProfile{}.Spec, }, }, @@ -190,6 +195,9 @@ func Test_GenerateCRValidationSchemas(t *testing.T) { "ml-extension": { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { "v1alpha1": { + mlApiv1alpha1.ArangoMLExtension{}.Spec, + }, + "v1beta1": { mlApi.ArangoMLExtension{}.Spec, }, }, @@ -197,6 +205,9 @@ func Test_GenerateCRValidationSchemas(t *testing.T) { "ml-storage": { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { "v1alpha1": { + mlApiv1alpha1.ArangoMLStorage{}.Spec, + }, + "v1beta1": { mlApi.ArangoMLStorage{}.Spec, }, }, @@ -204,14 +215,14 @@ func Test_GenerateCRValidationSchemas(t *testing.T) { "ml-job-cron": { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { "v1alpha1": { - mlApi.ArangoMLCronJob{}.Spec, + mlApiv1alpha1.ArangoMLCronJob{}.Spec, }, }, }, "ml-job-batch": { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { "v1alpha1": { - mlApi.ArangoMLBatchJob{}.Spec, + mlApiv1alpha1.ArangoMLBatchJob{}.Spec, }, }, }, diff --git a/internal/docs_test.go b/internal/docs_test.go index 37b9a7285..dc33a7cc5 100644 --- a/internal/docs_test.go +++ b/internal/docs_test.go @@ -39,9 +39,11 @@ import ( appsApi "github.com/arangodb/kube-arangodb/pkg/apis/apps/v1" backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" deploymentApi "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" replicationApi "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" storageApi "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -200,20 +202,20 @@ func Test_GenerateAPIDocs(t *testing.T) { "v1alpha1": { Types: inputPackageTypes{ "ArangoMLExtension.V1Alpha1": { - "Spec": mlApi.ArangoMLExtension{}.Spec, - "Status": mlApi.ArangoMLExtension{}.Status, + "Spec": mlApiv1alpha1.ArangoMLExtension{}.Spec, + "Status": mlApiv1alpha1.ArangoMLExtension{}.Status, }, "ArangoMLStorage.V1Alpha1": { - "Spec": mlApi.ArangoMLStorage{}.Spec, - "Status": mlApi.ArangoMLStorage{}.Status, + "Spec": mlApiv1alpha1.ArangoMLStorage{}.Spec, + "Status": mlApiv1alpha1.ArangoMLStorage{}.Status, }, "ArangoMLCronJob.V1Alpha1": { - "Spec": mlApi.ArangoMLCronJob{}.Spec, - "Status": mlApi.ArangoMLCronJob{}.Status, + "Spec": mlApiv1alpha1.ArangoMLCronJob{}.Spec, + "Status": mlApiv1alpha1.ArangoMLCronJob{}.Status, }, "ArangoMLBatchJob.V1Alpha1": { - "Spec": mlApi.ArangoMLBatchJob{}.Spec, - "Status": mlApi.ArangoMLBatchJob{}.Status, + "Spec": mlApiv1alpha1.ArangoMLBatchJob{}.Spec, + "Status": mlApiv1alpha1.ArangoMLBatchJob{}.Status, }, }, Shared: []string{ @@ -225,6 +227,26 @@ func Test_GenerateAPIDocs(t *testing.T) { "scheduler/v1alpha1/pod/resources", }, }, + "v1beta1": { + Types: inputPackageTypes{ + "ArangoMLExtension.V1Beta1": { + "Spec": mlApi.ArangoMLExtension{}.Spec, + "Status": mlApi.ArangoMLExtension{}.Status, + }, + "ArangoMLStorage.V1Beta1": { + "Spec": mlApi.ArangoMLStorage{}.Spec, + "Status": mlApi.ArangoMLStorage{}.Status, + }, + }, + Shared: []string{ + "shared/v1", + "scheduler/v1beta1", + "scheduler/v1beta1/container", + "scheduler/v1beta1/container/resources", + "scheduler/v1beta1/pod", + "scheduler/v1beta1/pod/resources", + }, + }, }, "replication": map[string]inputPackage{ "v1": { @@ -239,7 +261,7 @@ func Test_GenerateAPIDocs(t *testing.T) { "v1alpha1": { Types: inputPackageTypes{ "ArangoProfile.V1Alpha1": { - "Spec": schedulerApi.ArangoProfile{}.Spec, + "Spec": schedulerApiv1alpha1.ArangoProfile{}.Spec, }, }, Shared: []string{ @@ -250,6 +272,20 @@ func Test_GenerateAPIDocs(t *testing.T) { "scheduler/v1alpha1/pod/resources", }, }, + "v1beta1": { + Types: inputPackageTypes{ + "ArangoProfile.V1Beta1": { + "Spec": schedulerApi.ArangoProfile{}.Spec, + }, + }, + Shared: []string{ + "shared/v1", + "scheduler/v1beta1/container", + "scheduler/v1beta1/container/resources", + "scheduler/v1beta1/pod", + "scheduler/v1beta1/pod/resources", + }, + }, }, "storage": map[string]inputPackage{ "v1alpha": { diff --git a/pkg/apis/ml/v1alpha1/extension_spec_deployment.go b/pkg/apis/ml/v1alpha1/extension_spec_deployment.go index 809f0e04a..2573eeeb5 100644 --- a/pkg/apis/ml/v1alpha1/extension_spec_deployment.go +++ b/pkg/apis/ml/v1alpha1/extension_spec_deployment.go @@ -21,8 +21,8 @@ package v1alpha1 import ( - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerPodApiv1alpha1 "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/errors" ) @@ -45,10 +45,10 @@ type ArangoMLExtensionSpecDeployment struct { TLS *ArangoMLExtensionSpecDeploymentTLS `json:"tls,omitempty"` // Pod defines base template for pods - *schedulerPodApi.Pod + *schedulerPodApiv1alpha1.Pod // Container Keeps the information about Container configuration - *schedulerContainerApi.Container `json:",inline"` + *schedulerContainerApiv1alpha1.Container `json:",inline"` // GPU defined if GPU Jobs are enabled. // +doc/default: false @@ -65,7 +65,7 @@ func (s *ArangoMLExtensionSpecDeployment) GetReplicas() int32 { return *s.Replicas } -func (s *ArangoMLExtensionSpecDeployment) GetPodTemplate() *schedulerPodApi.Pod { +func (s *ArangoMLExtensionSpecDeployment) GetPodTemplate() *schedulerPodApiv1alpha1.Pod { if s == nil || s.Pod == nil { return nil } @@ -87,7 +87,7 @@ func (s *ArangoMLExtensionSpecDeployment) GetPort(def int32) int32 { return *s.Port } -func (s *ArangoMLExtensionSpecDeployment) GetContainer() *schedulerContainerApi.Container { +func (s *ArangoMLExtensionSpecDeployment) GetContainer() *schedulerContainerApiv1alpha1.Container { if s == nil || s.Container == nil { return nil } diff --git a/pkg/apis/ml/v1alpha1/extension_spec_job.go b/pkg/apis/ml/v1alpha1/extension_spec_job.go index 8f13c3eae..de92176a4 100644 --- a/pkg/apis/ml/v1alpha1/extension_spec_job.go +++ b/pkg/apis/ml/v1alpha1/extension_spec_job.go @@ -21,9 +21,9 @@ 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" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerPodApiv1alpha1 "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" ) @@ -127,13 +127,13 @@ func (a *ArangoMLJobTemplates) Validate() error { type ArangoMLExtensionTemplate struct { // Pod keeps the information about Pod configuration - *schedulerPodApi.Pod `json:",inline"` + *schedulerPodApiv1alpha1.Pod `json:",inline"` // Container Keeps the information about Container configuration - *schedulerContainerApi.Container `json:",inline"` + *schedulerContainerApiv1alpha1.Container `json:",inline"` } -func (a *ArangoMLExtensionTemplate) GetPodTemplate() *schedulerPodApi.Pod { +func (a *ArangoMLExtensionTemplate) GetPodTemplate() *schedulerPodApiv1alpha1.Pod { if a == nil || a.Pod == nil { return nil } @@ -141,7 +141,7 @@ func (a *ArangoMLExtensionTemplate) GetPodTemplate() *schedulerPodApi.Pod { return a.Pod } -func (a *ArangoMLExtensionTemplate) GetContainer() *schedulerContainerApi.Container { +func (a *ArangoMLExtensionTemplate) GetContainer() *schedulerContainerApiv1alpha1.Container { if a == nil || a.Container == nil { return nil } @@ -149,7 +149,7 @@ func (a *ArangoMLExtensionTemplate) GetContainer() *schedulerContainerApi.Contai return a.Container } -func (a *ArangoMLExtensionTemplate) AsTemplate(name string) *schedulerApi.ProfileTemplate { +func (a *ArangoMLExtensionTemplate) AsTemplate(name string) *schedulerApiv1alpha1.ProfileTemplate { if a == nil { return nil } @@ -158,15 +158,15 @@ func (a *ArangoMLExtensionTemplate) AsTemplate(name string) *schedulerApi.Profil return nil } - t := &schedulerApi.ProfileTemplate{} + t := &schedulerApiv1alpha1.ProfileTemplate{} if p := a.Pod; p != nil { t.Pod = p.DeepCopy() } if p := a.Container; p != nil { - t.Container = &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ + t.Container = &schedulerApiv1alpha1.ProfileContainerTemplate{ + Containers: schedulerContainerApiv1alpha1.Containers{ name: util.TypeOrDefault(p.DeepCopy()), }, } diff --git a/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go b/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go index 81f00ebdf..36cfd280f 100644 --- a/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go +++ b/pkg/apis/ml/v1alpha1/storage_spec_mode_sidecar.go @@ -21,7 +21,7 @@ package v1alpha1 import ( - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" ) @@ -36,10 +36,10 @@ type ArangoMLStorageSpecModeSidecar struct { ControllerListenPort *uint16 `json:"controllerListenPort,omitempty"` // Container Keeps the information about Container configuration - *schedulerContainerApi.Container `json:",inline"` + *schedulerContainerApiv1alpha1.Container `json:",inline"` } -func (s *ArangoMLStorageSpecModeSidecar) GetContainer() *schedulerContainerApi.Container { +func (s *ArangoMLStorageSpecModeSidecar) GetContainer() *schedulerContainerApiv1alpha1.Container { if s == nil || s.Container == nil { return nil } diff --git a/pkg/apis/ml/v1alpha1/storage_spec_test.go b/pkg/apis/ml/v1alpha1/storage_spec_test.go index ea64ba131..b06a11296 100644 --- a/pkg/apis/ml/v1alpha1/storage_spec_test.go +++ b/pkg/apis/ml/v1alpha1/storage_spec_test.go @@ -27,8 +27,8 @@ import ( core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -68,8 +68,8 @@ func Test_ArangoMLStorageSpec(t *testing.T) { core.ResourceMemory: resource.MustParse("128Mi"), }, } - s.Mode.Sidecar.Container = &schedulerContainerApi.Container{} - s.Mode.Sidecar.Resources = &schedulerContainerResourcesApi.Resources{Resources: &assignedRequirements} + s.Mode.Sidecar.Container = &schedulerContainerApiv1alpha1.Container{} + s.Mode.Sidecar.Resources = &schedulerContainerResourcesApiv1alpha1.Resources{Resources: &assignedRequirements} expectedRequirements := core.ResourceRequirements{ Requests: assignedRequirements.Requests, @@ -79,7 +79,7 @@ func Test_ArangoMLStorageSpec(t *testing.T) { }, } - actualRequirements := s.Mode.Sidecar.GetResources().With(&schedulerContainerResourcesApi.Resources{Resources: &core.ResourceRequirements{ + actualRequirements := s.Mode.Sidecar.GetResources().With(&schedulerContainerResourcesApiv1alpha1.Resources{Resources: &core.ResourceRequirements{ Limits: core.ResourceList{ core.ResourceCPU: resource.MustParse("200m"), core.ResourceMemory: resource.MustParse("256Mi"), diff --git a/pkg/apis/ml/v1beta1/conditions.go b/pkg/apis/ml/v1beta1/conditions.go new file mode 100644 index 000000000..7667d0835 --- /dev/null +++ b/pkg/apis/ml/v1beta1/conditions.go @@ -0,0 +1,39 @@ +// +// 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 v1beta1 + +import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + +const ( + ReadyCondition api.ConditionType = "Ready" + SpecValidCondition api.ConditionType = "SpecValid" + ExtensionFoundCondition api.ConditionType = "ExtensionFound" + ExtensionStorageFoundCondition api.ConditionType = "StorageFound" + ExtensionDeploymentFoundCondition api.ConditionType = "DeploymentFound" + ExtensionBootstrapCompletedCondition api.ConditionType = "BootstrapCompleted" + ExtensionMetadataServiceValidCondition api.ConditionType = "MetadataServiceValid" + ExtensionServiceAccountReadyCondition api.ConditionType = "ServiceAccountReady" + ExtensionStatefulSetReadyCondition api.ConditionType = "ExtensionDeploymentReady" + ExtensionTLSEnabledCondition api.ConditionType = "TLSEnabled" + LicenseValidCondition api.ConditionType = "LicenseValid" + CronJobSyncedCondition api.ConditionType = "CronJobSynced" + BatchJobSyncedCondition api.ConditionType = "BatchJobSynced" +) diff --git a/pkg/apis/ml/v1beta1/doc.go b/pkg/apis/ml/v1beta1/doc.go new file mode 100644 index 000000000..db462df18 --- /dev/null +++ b/pkg/apis/ml/v1beta1/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=ml.arangodb.com +package v1beta1 diff --git a/pkg/apis/ml/v1beta1/extension.go b/pkg/apis/ml/v1beta1/extension.go new file mode 100644 index 000000000..2b35f36aa --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension.go @@ -0,0 +1,69 @@ +// +// 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 v1beta1 + +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/ml" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoMLExtensionList is a list of ArangoML Extensions. +type ArangoMLExtensionList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoMLExtension `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoMLExtension contains definition and status of the ArangoML Extension. +type ArangoMLExtension struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoMLExtensionSpec `json:"spec"` + Status ArangoMLExtensionStatus `json:"status"` +} + +// AsOwner creates an OwnerReference for the given Extension +func (d *ArangoMLExtension) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: ml.ArangoMLExtensionResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (a *ArangoMLExtension) GetStatus() ArangoMLExtensionStatus { + return a.Status +} + +func (a *ArangoMLExtension) SetStatus(status ArangoMLExtensionStatus) { + a.Status = status +} diff --git a/pkg/apis/ml/v1beta1/extension_spec.go b/pkg/apis/ml/v1beta1/extension_spec.go new file mode 100644 index 000000000..042f92634 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec.go @@ -0,0 +1,96 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" +) + +type ArangoMLExtensionSpec struct { + // MetadataService keeps the MetadataService configuration + // +doc/immutable: This setting cannot be changed after the MetadataService has been created. + MetadataService *ArangoMLExtensionSpecMetadataService `json:"metadataService,omitempty"` + + // Storage specifies the ArangoMLStorage used within Extension + Storage *sharedApi.Object `json:"storage,omitempty"` + + // ArangoMLExtensionTemplate define Init job specification + Init *ArangoMLExtensionTemplate `json:"init,omitempty"` + + // Deployment specifies how the ML extension will be deployed into cluster + Deployment *ArangoMLExtensionSpecDeployment `json:"deployment,omitempty"` + + // JobsTemplates defines templates for jobs + JobsTemplates *ArangoMLJobsTemplates `json:"jobsTemplates,omitempty"` +} + +func (a *ArangoMLExtensionSpec) GetMetadataService() *ArangoMLExtensionSpecMetadataService { + if a == nil || a.MetadataService == nil { + return nil + } + + return a.MetadataService +} + +func (a *ArangoMLExtensionSpec) GetInit() *ArangoMLExtensionTemplate { + if a == nil || a.Init == nil { + return nil + } + + return a.Init +} + +func (a *ArangoMLExtensionSpec) GetStorage() *sharedApi.Object { + if a == nil || a.Storage == nil { + return nil + } + + return a.Storage +} + +func (a *ArangoMLExtensionSpec) GetDeployment() *ArangoMLExtensionSpecDeployment { + if a == nil || a.Deployment == nil { + return nil + } + return a.Deployment +} + +func (a *ArangoMLExtensionSpec) GetJobsTemplates() *ArangoMLJobsTemplates { + if a == nil || a.JobsTemplates == nil { + return nil + } + return a.JobsTemplates +} + +func (a *ArangoMLExtensionSpec) Validate() error { + if a == nil { + a = &ArangoMLExtensionSpec{} + } + + 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() })), + shared.PrefixResourceErrors("init", a.GetInit().Validate()), + shared.PrefixResourceErrors("deployment", a.GetDeployment().Validate()), + shared.PrefixResourceErrors("jobsTemplates", a.GetJobsTemplates().Validate()), + )) +} diff --git a/pkg/apis/ml/v1beta1/extension_spec_deployment.go b/pkg/apis/ml/v1beta1/extension_spec_deployment.go new file mode 100644 index 000000000..56a8745a0 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec_deployment.go @@ -0,0 +1,127 @@ +// +// 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 v1beta1 + +import ( + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +const ( + ArangoMLExtensionSpecDeploymentApi = "api" + + ArangoMLExtensionSpecDeploymentComponentDefaultPort = 8502 +) + +type ArangoMLExtensionSpecDeployment struct { + // Replicas defines the number of replicas running specified components. No replicas created if no components are defined. + // +doc/default: 1 + Replicas *int32 `json:"replicas,omitempty"` + + // Service defines how components will be exposed + Service *ArangoMLExtensionSpecDeploymentService `json:"service,omitempty"` + + // TLS defined TLS Settings for extension + TLS *ArangoMLExtensionSpecDeploymentTLS `json:"tls,omitempty"` + + // Pod defines base template for pods + *schedulerPodApi.Pod + + // Container Keeps the information about Container configuration + *schedulerContainerApi.Container `json:",inline"` + + // GPU defined if GPU Jobs are enabled. + // +doc/default: false + GPU *bool `json:"gpu,omitempty"` + + // Port defines on which port the container will be listening for connections + Port *int32 `json:"port,omitempty"` +} + +func (s *ArangoMLExtensionSpecDeployment) GetReplicas() int32 { + if s == nil || s.Replicas == nil { + return 1 + } + return *s.Replicas +} + +func (s *ArangoMLExtensionSpecDeployment) GetPodTemplate() *schedulerPodApi.Pod { + if s == nil || s.Pod == nil { + return nil + } + + return s.Pod +} + +func (s *ArangoMLExtensionSpecDeployment) GetGPU() bool { + if s == nil || s.GPU == nil { + return false + } + return *s.GPU +} + +func (s *ArangoMLExtensionSpecDeployment) GetPort(def int32) int32 { + if s == nil || s.Port == nil { + return def + } + return *s.Port +} + +func (s *ArangoMLExtensionSpecDeployment) GetContainer() *schedulerContainerApi.Container { + if s == nil || s.Container == nil { + return nil + } + + return s.Container +} + +func (s *ArangoMLExtensionSpecDeployment) GetService() *ArangoMLExtensionSpecDeploymentService { + if s == nil { + return nil + } + return s.Service +} + +func (s *ArangoMLExtensionSpecDeployment) GetTLS() *ArangoMLExtensionSpecDeploymentTLS { + if s == nil { + return nil + } + return s.TLS +} + +func (s *ArangoMLExtensionSpecDeployment) Validate() error { + if s == nil { + return nil + } + + errs := []error{ + shared.PrefixResourceErrors("service", shared.ValidateOptional(s.GetService(), func(s ArangoMLExtensionSpecDeploymentService) error { return s.Validate() })), + s.GetPodTemplate().Validate(), + s.GetContainer().Validate(), + } + + if s.GetReplicas() < 0 || s.GetReplicas() > 10 { + errs = append(errs, shared.PrefixResourceErrors("replicas", errors.Errorf("out of range [0, 10]"))) + } + return shared.WithErrors(errs...) +} diff --git a/pkg/apis/ml/v1beta1/extension_spec_deployment_service.go b/pkg/apis/ml/v1beta1/extension_spec_deployment_service.go new file mode 100644 index 000000000..9d2c9beb6 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec_deployment_service.go @@ -0,0 +1,57 @@ +// +// 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 v1beta1 + +import ( + core "k8s.io/api/core/v1" + + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +type ArangoMLExtensionSpecDeploymentService struct { + // Type determines how the Service is exposed + // +doc/enum: ClusterIP|service will only be accessible inside the cluster, via the cluster IP + // +doc/enum: NodePort|service will be exposed on one port of every node, in addition to 'ClusterIP' type + // +doc/enum: LoadBalancer|service will be exposed via an external load balancer (if the cloud provider supports it), in addition to 'NodePort' type + // +doc/enum: ExternalName|service consists of only a reference to an external name that kubedns or equivalent will return as a CNAME record, with no exposing or proxying of any pods involved + // +doc/default: ClusterIP + // +doc/link: Kubernetes Documentation|https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + Type *core.ServiceType `json:"type,omitempty"` +} + +func (s *ArangoMLExtensionSpecDeploymentService) GetType() core.ServiceType { + if s == nil || s.Type == nil { + return core.ServiceTypeClusterIP + } + + return *s.Type +} + +func (s *ArangoMLExtensionSpecDeploymentService) Validate() error { + if s == nil { + return nil + } + + errs := []error{ + shared.PrefixResourceErrors("type", shared.ValidateServiceType(s.GetType())), + } + return shared.WithErrors(errs...) +} diff --git a/pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go b/pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go new file mode 100644 index 000000000..2e663247f --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec_deployment_tls.go @@ -0,0 +1,45 @@ +// +// 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 v1beta1 + +type ArangoMLExtensionSpecDeploymentTLS struct { + // Enabled define if TLS Should be enabled. If is not set then default is taken from ArangoDeployment settings + Enabled *bool `json:"enabled,omitempty"` + + // AltNames define TLS AltNames used when TLS on the ArangoDB is enabled + AltNames []string `json:"altNames,omitempty"` +} + +func (a *ArangoMLExtensionSpecDeploymentTLS) IsEnabled() bool { + if a == nil || a.Enabled == nil { + return true + } + + return *a.Enabled +} + +func (a *ArangoMLExtensionSpecDeploymentTLS) GetAltNames() []string { + if a == nil || a.AltNames == nil { + return nil + } + + return a.AltNames +} diff --git a/pkg/apis/ml/v1beta1/extension_spec_job.go b/pkg/apis/ml/v1beta1/extension_spec_job.go new file mode 100644 index 000000000..5b0590d5c --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec_job.go @@ -0,0 +1,187 @@ +// +// 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 v1beta1 + +import ( + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +type JobType string + +const ( + MLJobTrainingType JobType = "training" + MLJobPredictionType JobType = "prediction" + MLJobFeaturizationType JobType = "featurization" +) + +func MLJobTypes() []JobType { + return []JobType{ + MLJobTrainingType, + MLJobPredictionType, + MLJobFeaturizationType, + } +} + +type ArangoMLJobsTemplates struct { + // Prediction defines template for the prediction job + Prediction *ArangoMLJobTemplates `json:"prediction,omitempty"` + + // Training defines template for the training job + Training *ArangoMLJobTemplates `json:"training,omitempty"` + + // Featurization defines template for the featurization job + Featurization *ArangoMLJobTemplates `json:"featurization,omitempty"` +} + +func (a *ArangoMLJobsTemplates) GetJobTemplates(jobType JobType) *ArangoMLJobTemplates { + if a == nil { + return nil + } + + switch jobType { + case MLJobTrainingType: + return a.Training + case MLJobPredictionType: + return a.Prediction + case MLJobFeaturizationType: + return a.Featurization + default: + return nil + } +} + +func (a *ArangoMLJobsTemplates) Validate() error { + if a == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("prediction", a.Prediction.Validate()), + shared.PrefixResourceErrors("training", a.Training.Validate()), + shared.PrefixResourceErrors("featurization", a.Featurization.Validate()), + ) +} + +type JobScheduleType string + +const ( + MLJobScheduleCPU JobScheduleType = "cpu" + MLJobScheduleGPU JobScheduleType = "gpu" +) + +type ArangoMLJobTemplates struct { + // CPU defines templates for CPU jobs + CPU *ArangoMLExtensionTemplate `json:"cpu,omitempty"` + + // GPU defines templates for GPU jobs + GPU *ArangoMLExtensionTemplate `json:"gpu,omitempty"` +} + +func (a *ArangoMLJobTemplates) GetJobTemplateSpec(scheduleType JobScheduleType) *ArangoMLExtensionTemplate { + if a == nil { + return nil + } + + switch scheduleType { + case MLJobScheduleCPU: + return a.CPU + case MLJobScheduleGPU: + return a.GPU + default: + return nil + } +} + +func (a *ArangoMLJobTemplates) Validate() error { + if a == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("cpu", a.CPU.Validate()), + shared.PrefixResourceErrors("gpu", a.GPU.Validate()), + ) +} + +type ArangoMLExtensionTemplate struct { + // Pod keeps the information about Pod configuration + *schedulerPodApi.Pod `json:",inline"` + + // Container Keeps the information about Container configuration + *schedulerContainerApi.Container `json:",inline"` +} + +func (a *ArangoMLExtensionTemplate) GetPodTemplate() *schedulerPodApi.Pod { + if a == nil || a.Pod == nil { + return nil + } + + return a.Pod +} + +func (a *ArangoMLExtensionTemplate) GetContainer() *schedulerContainerApi.Container { + if a == nil || a.Container == nil { + return nil + } + + 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 + } + + return shared.WithErrors( + a.GetPodTemplate().Validate(), + a.GetContainer().Validate(), + ) +} diff --git a/pkg/apis/ml/v1beta1/extension_spec_metadata_service.go b/pkg/apis/ml/v1beta1/extension_spec_metadata_service.go new file mode 100644 index 000000000..779d6ab2e --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_spec_metadata_service.go @@ -0,0 +1,99 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +const ( + ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoPipeDatabase = "arangopipe" + ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoMLFeatureStoreDatabase = "arangoml_feature_store" +) + +type ArangoMLExtensionSpecMetadataService struct { + // Local define to use Local ArangoDeployment as the Metadata Service + Local *ArangoMLExtensionSpecMetadataServiceLocal `json:"local,omitempty"` +} + +func (a *ArangoMLExtensionSpecMetadataService) GetLocal() *ArangoMLExtensionSpecMetadataServiceLocal { + if a == nil || a.Local == nil { + return nil + } + + return a.Local +} + +func (a *ArangoMLExtensionSpecMetadataService) Validate() error { + // If Nil then we use default + if a == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("local", a.GetLocal().Validate()), + ) +} + +type ArangoMLExtensionSpecMetadataServiceLocal struct { + // ArangoPipeDatabase define Database name to be used as MetadataService Backend in ArangoPipe + // +doc/default: arangopipe + ArangoPipeDatabase *string `json:"arangoPipeDatabase,omitempty"` + + // ArangoMLFeatureStoreDatabase define Database name to be used as MetadataService Backend in ArangoMLFeatureStoreDatabase + // +doc/default: arangomlfeaturestore + ArangoMLFeatureStoreDatabase *string `json:"arangoMLFeatureStore,omitempty"` +} + +func (a *ArangoMLExtensionSpecMetadataServiceLocal) GetArangoPipeDatabase() string { + if a == nil { + return ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoPipeDatabase + } + + if d := a.ArangoPipeDatabase; d == nil { + return ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoPipeDatabase + } else { + return *d + } +} + +func (a *ArangoMLExtensionSpecMetadataServiceLocal) GetArangoMLFeatureStoreDatabase() string { + if a == nil { + return ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoMLFeatureStoreDatabase + } + + if d := a.ArangoMLFeatureStoreDatabase; d == nil { + return ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoMLFeatureStoreDatabase + } else { + return *d + } +} + +func (a *ArangoMLExtensionSpecMetadataServiceLocal) Validate() error { + // If Nil then we use default + + return shared.WithErrors( + shared.PrefixResourceErrors("arangoPipeDatabase", util.BoolSwitch(a.GetArangoPipeDatabase() != ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoPipeDatabase, errors.Errorf("Database name is hardcoded"), nil)), + shared.PrefixResourceErrors("arangoMLFeatureStore", util.BoolSwitch(a.GetArangoMLFeatureStoreDatabase() != ArangoMLExtensionSpecMetadataServiceLocalDefaultArangoMLFeatureStoreDatabase, errors.Errorf("Database name is hardcoded"), nil)), + ) +} diff --git a/pkg/apis/ml/v1beta1/extension_status.go b/pkg/apis/ml/v1beta1/extension_status.go new file mode 100644 index 000000000..6200c8f5b --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_status.go @@ -0,0 +1,44 @@ +// +// 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 v1beta1 + +import ( + api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" +) + +type ArangoMLExtensionStatus struct { + // Conditions specific to the entire extension + // +doc/type: api.Conditions + Conditions api.ConditionList `json:"conditions,omitempty"` + + // MetadataService keeps the MetadataService configuration + MetadataService *ArangoMLExtensionStatusMetadataService `json:"metadataService,omitempty"` + + // ServiceAccount keeps the information about ServiceAccount + ServiceAccount *sharedApi.ServiceAccount `json:"serviceAccount,omitempty"` + + // ArangoDB keeps the information about local arangodb reference + ArangoDB *ArangoMLExtensionStatusArangoDBRef `json:"arangoDB,omitempty"` + + // Reconciliation keeps the information about reconciliation process. For internal use. + Reconciliation *ArangoMLExtensionStatusReconciliation `json:"reconciliation"` +} diff --git a/pkg/apis/ml/v1beta1/extension_status_arangodb_ref.go b/pkg/apis/ml/v1beta1/extension_status_arangodb_ref.go new file mode 100644 index 000000000..efac70f77 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_status_arangodb_ref.go @@ -0,0 +1,30 @@ +// +// 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 v1beta1 + +import sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + +type ArangoMLExtensionStatusArangoDBRef struct { + // Secret keeps the information about ArangoDB deployment + Secret *sharedApi.Object `json:"secret,omitempty"` + // TLS keeps information about TLS Secret rendered from ArangoDB deployment + TLS *sharedApi.Object `json:"tls,omitempty"` +} diff --git a/pkg/apis/ml/v1beta1/extension_status_metadata_service.go b/pkg/apis/ml/v1beta1/extension_status_metadata_service.go new file mode 100644 index 000000000..e94530833 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_status_metadata_service.go @@ -0,0 +1,39 @@ +// +// 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 v1beta1 + +import sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + +type ArangoMLExtensionStatusMetadataService struct { + // Local define the Local ArangoDeployment Metadata Service configuration + Local *ArangoMLExtensionStatusMetadataServiceLocal `json:"local,omitempty"` + + // Secret define the Secret specification to store all the details + Secret *sharedApi.Object `json:"secret,omitempty"` +} + +type ArangoMLExtensionStatusMetadataServiceLocal struct { + // ArangoPipeDatabase define Database name to be used as MetadataService Backend + ArangoPipeDatabase string `json:"arangoPipe"` + + // ArangoMLFeatureStoreDatabase define Database name to be used as MetadataService Backend + ArangoMLFeatureStoreDatabase string `json:"arangoMLFeatureStore,omitempty"` +} diff --git a/pkg/apis/ml/v1beta1/extension_status_reconciliation.go b/pkg/apis/ml/v1beta1/extension_status_reconciliation.go new file mode 100644 index 000000000..b7dc80e42 --- /dev/null +++ b/pkg/apis/ml/v1beta1/extension_status_reconciliation.go @@ -0,0 +1,42 @@ +// +// 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 v1beta1 + +import sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + +type ArangoMLExtensionStatusReconciliation struct { + StatefulSet *sharedApi.Object `json:"statefulSet,omitempty"` + Service *sharedApi.Object `json:"service,omitempty"` +} + +func (r *ArangoMLExtensionStatusReconciliation) GetStatefulSet() *sharedApi.Object { + if r == nil { + return nil + } + return r.StatefulSet +} + +func (r *ArangoMLExtensionStatusReconciliation) GetService() *sharedApi.Object { + if r == nil { + return nil + } + return r.Service +} diff --git a/pkg/apis/ml/v1beta1/register.go b/pkg/apis/ml/v1beta1/register.go new file mode 100644 index 000000000..7387e1b28 --- /dev/null +++ b/pkg/apis/ml/v1beta1/register.go @@ -0,0 +1,57 @@ +// +// 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 v1beta1 + +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/ml" +) + +const ( + ArangoMLVersion = "v1beta1" +) + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme + + SchemeGroupVersion = schema.GroupVersion{Group: ml.ArangoMLGroupName, Version: ArangoMLVersion} +) + +// Resource gets an ArangoCluster GroupResource for a specified resource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// addKnownTypes adds the set of types defined in this package to the supplied scheme. +func addKnownTypes(s *runtime.Scheme) error { + s.AddKnownTypes(SchemeGroupVersion, + &ArangoMLStorage{}, + &ArangoMLStorageList{}, + &ArangoMLExtension{}, + &ArangoMLExtensionList{}, + ) + meta.AddToGroupVersion(s, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/ml/v1beta1/storage.go b/pkg/apis/ml/v1beta1/storage.go new file mode 100644 index 000000000..313ecbace --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage.go @@ -0,0 +1,69 @@ +// +// 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 v1beta1 + +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/ml" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoMLStorageList is a list of ArangoML Storages. +type ArangoMLStorageList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoMLStorage `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoMLStorage contains definition and status of the ArangoML Storage. +type ArangoMLStorage struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoMLStorageSpec `json:"spec"` + Status ArangoMLStorageStatus `json:"status"` +} + +// AsOwner creates an OwnerReference for the given Storage +func (d *ArangoMLStorage) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: ml.ArangoMLStorageResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (a *ArangoMLStorage) GetStatus() ArangoMLStorageStatus { + return a.Status +} + +func (a *ArangoMLStorage) SetStatus(status ArangoMLStorageStatus) { + a.Status = status +} diff --git a/pkg/apis/ml/v1beta1/storage_spec.go b/pkg/apis/ml/v1beta1/storage_spec.go new file mode 100644 index 000000000..192bf866c --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec.go @@ -0,0 +1,84 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +type ArangoMLStorageSpec struct { + // BucketName specifies the name of the bucket + // Required + BucketName *string `json:"bucketName,omitempty"` + + // BucketPath specifies the path within the bucket + // +doc/default: / + BucketPath *string `json:"bucketPath,omitempty"` + + // Mode defines how storage implementation should be deployed + Mode *ArangoMLStorageSpecMode `json:"mode,omitempty"` + // Backend defines how storage is implemented + Backend *ArangoMLStorageSpecBackend `json:"backend,omitempty"` +} + +func (s *ArangoMLStorageSpec) GetBucketName() string { + if s == nil || s.BucketName == nil { + return "" + } + return *s.BucketName +} + +func (s *ArangoMLStorageSpec) GetBucketPath() string { + if s == nil || s.BucketPath == nil { + return "/" + } + return *s.BucketPath +} + +func (s *ArangoMLStorageSpec) GetMode() *ArangoMLStorageSpecMode { + if s == nil || s.Mode == nil { + return nil + } + return s.Mode +} + +func (s *ArangoMLStorageSpec) GetBackend() *ArangoMLStorageSpecBackend { + if s == nil || s.Backend == nil { + return nil + } + return s.Backend +} + +func (s *ArangoMLStorageSpec) Validate() error { + if s == nil { + s = &ArangoMLStorageSpec{} + } + + if err := shared.WithErrors(shared.PrefixResourceErrors("spec", + shared.PrefixResourceError("backend", s.Backend.Validate()), + shared.PrefixResourceError("mode", s.Mode.Validate()), + shared.PrefixResourceError("bucket", shared.ValidateRequired(s.BucketName, shared.ValidateResourceName)), + )); err != nil { + return err + } + + return nil +} diff --git a/pkg/apis/ml/v1beta1/storage_spec_backend.go b/pkg/apis/ml/v1beta1/storage_spec_backend.go new file mode 100644 index 000000000..393495bed --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec_backend.go @@ -0,0 +1,50 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ArangoMLStorageSpecBackend struct { + // S3 backend implements storage as a proxy to the provided S3 API endpoint + S3 *ArangoMLStorageSpecBackendS3 `json:"s3,omitempty"` +} + +func (s *ArangoMLStorageSpecBackend) GetS3() *ArangoMLStorageSpecBackendS3 { + if s == nil || s.S3 == nil { + return nil + } + return s.S3 +} + +func (s *ArangoMLStorageSpecBackend) Validate() error { + if s == nil { + return errors.Errorf("Backend is not specified") + } + + if s.S3 == nil { + return errors.Errorf("At least one backend needs to be defined") + } + + return shared.WithErrors(shared.PrefixResourceError("s3", s.S3.Validate())) +} diff --git a/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go b/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go new file mode 100644 index 000000000..c205a7269 --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec_backend_s3.go @@ -0,0 +1,109 @@ +// +// 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 v1beta1 + +import ( + "net/url" + + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ArangoMLStorageSpecBackendS3 struct { + // Endpoint specifies the S3 API-compatible endpoint which implements storage + // Required + Endpoint *string `json:"endpoint"` + // CredentialsSecret specifies the Kubernetes Secret containing AccessKey and SecretKey for S3 API authorization + // Required + CredentialsSecret *sharedApi.Object `json:"credentialsSecret"` + // AllowInsecure if set to true, the Endpoint certificates won't be checked + // +doc/default: false + AllowInsecure *bool `json:"allowInsecure,omitempty"` + // CASecret if not empty, the given Kubernetes Secret will be used to check the authenticity of Endpoint + // The specified Secret, must contain the following data fields: + // - `ca.crt` PEM encoded public key of the CA certificate + // - `ca.key` PEM encoded private key of the CA certificate + // +doc/default: nil + CASecret *sharedApi.Object `json:"caSecret,omitempty"` + // Region defines the availability zone name. + // +doc/default: "" + Region *string `json:"region,omitempty"` +} + +func (s *ArangoMLStorageSpecBackendS3) Validate() error { + if s == nil { + s = &ArangoMLStorageSpecBackendS3{} + } + + var errs []error + + if s.GetEndpoint() == "" { + errs = append(errs, shared.PrefixResourceErrors("endpoint", errors.New("must be not empty"))) + } + + if _, err := url.Parse(s.GetEndpoint()); err != nil { + errs = append(errs, shared.PrefixResourceErrors("endpoint", errors.Errorf("invalid URL: %s", err.Error()))) + } + + errs = append(errs, shared.PrefixResourceErrors("credentialsSecret", s.GetCredentialsSecret().Validate())) + + if caSecret := s.GetCASecret(); !caSecret.IsEmpty() { + errs = append(errs, shared.PrefixResourceErrors("caSecret", caSecret.Validate())) + } + + return shared.WithErrors(errs...) +} + +func (s *ArangoMLStorageSpecBackendS3) GetEndpoint() string { + if s == nil || s.Endpoint == nil { + return "" + } + return *s.Endpoint +} + +func (s *ArangoMLStorageSpecBackendS3) GetCredentialsSecret() *sharedApi.Object { + if s == nil || s.CredentialsSecret == nil { + return &sharedApi.Object{} + } + return s.CredentialsSecret +} + +func (s *ArangoMLStorageSpecBackendS3) GetAllowInsecure() bool { + if s == nil || s.AllowInsecure == nil { + return false + } + return *s.AllowInsecure +} + +func (s *ArangoMLStorageSpecBackendS3) GetCASecret() *sharedApi.Object { + if s == nil || s.CASecret == nil { + return &sharedApi.Object{} + } + return s.CASecret +} + +func (s *ArangoMLStorageSpecBackendS3) GetRegion() string { + if s == nil || s.Region == nil { + return "" + } + return *s.Region +} diff --git a/pkg/apis/ml/v1beta1/storage_spec_mode.go b/pkg/apis/ml/v1beta1/storage_spec_mode.go new file mode 100644 index 000000000..ea000b2cb --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec_mode.go @@ -0,0 +1,45 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ArangoMLStorageSpecMode struct { + // Sidecar mode runs the storage implementation as a sidecar + Sidecar *ArangoMLStorageSpecModeSidecar `json:"sidecar,omitempty"` +} + +func (s *ArangoMLStorageSpecMode) GetSidecar() *ArangoMLStorageSpecModeSidecar { + if s == nil || s.Sidecar == nil { + return nil + } + return s.Sidecar +} + +func (s *ArangoMLStorageSpecMode) Validate() error { + if s == nil { + return errors.Errorf("Mode is not defined") + } + return shared.WithErrors(shared.PrefixResourceError("sidecar", s.Sidecar.Validate())) +} diff --git a/pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go b/pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go new file mode 100644 index 000000000..4288d23b9 --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec_mode_sidecar.go @@ -0,0 +1,82 @@ +// +// 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 v1beta1 + +import ( + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ArangoMLStorageSpecModeSidecar struct { + // ListenPort defines on which port the sidecar container will be listening for connections + // +doc/default: 9201 + ListenPort *uint16 `json:"listenPort,omitempty"` + + // ControllerListenPort defines on which port the sidecar container will be listening for controller requests + // +doc/default: 9202 + ControllerListenPort *uint16 `json:"controllerListenPort,omitempty"` + + // Container Keeps the information about Container configuration + *schedulerContainerApi.Container `json:",inline"` +} + +func (s *ArangoMLStorageSpecModeSidecar) GetContainer() *schedulerContainerApi.Container { + if s == nil || s.Container == nil { + return nil + } + + return s.Container +} + +func (s *ArangoMLStorageSpecModeSidecar) Validate() error { + if s == nil { + s = &ArangoMLStorageSpecModeSidecar{} + } + + var err []error + + if s.GetListenPort() < 1 { + err = append(err, shared.PrefixResourceErrors("listenPort", errors.Errorf("must be positive"))) + } + + if s.GetControllerListenPort() < 1 { + err = append(err, shared.PrefixResourceErrors("controllerListenPort", errors.Errorf("must be positive"))) + } + + err = append(err, s.GetContainer().Validate()) + + return shared.WithErrors(err...) +} + +func (s *ArangoMLStorageSpecModeSidecar) GetListenPort() uint16 { + if s == nil || s.ListenPort == nil { + return 9201 + } + return *s.ListenPort +} + +func (s *ArangoMLStorageSpecModeSidecar) GetControllerListenPort() uint16 { + if s == nil || s.ControllerListenPort == nil { + return 9202 + } + return *s.ControllerListenPort +} diff --git a/pkg/apis/ml/v1beta1/storage_spec_test.go b/pkg/apis/ml/v1beta1/storage_spec_test.go new file mode 100644 index 000000000..3092ecaef --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_spec_test.go @@ -0,0 +1,95 @@ +// +// 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 v1beta1 + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func Test_ArangoMLStorageSpec(t *testing.T) { + s := ArangoMLStorageSpec{} + require.Nil(t, s.GetMode()) + require.Nil(t, s.GetBackend()) + require.Error(t, s.Validate()) + + s.Mode = &ArangoMLStorageSpecMode{} + require.Nil(t, s.Mode.GetSidecar()) + + s.Backend = &ArangoMLStorageSpecBackend{} + require.Nil(t, s.Backend.GetS3()) + require.Error(t, s.Validate()) + + s.Mode.Sidecar = &ArangoMLStorageSpecModeSidecar{} + require.Nil(t, s.Mode.Sidecar.GetResources()) + require.NotNil(t, s.Mode.Sidecar.GetListenPort()) + + require.Error(t, s.Backend.S3.Validate()) + s.Backend.S3 = &ArangoMLStorageSpecBackendS3{ + Endpoint: util.NewType("http://test.s3.example.com"), + CredentialsSecret: &sharedApi.Object{ + Name: "a-secret", + Namespace: nil, + }, + } + s.BucketName = util.NewType("bucket") + require.NoError(t, s.Validate()) + + t.Run("default requests and limits assigned", func(t *testing.T) { + assignedRequirements := core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("128Mi"), + }, + } + s.Mode.Sidecar.Container = &schedulerContainerApi.Container{} + s.Mode.Sidecar.Resources = &schedulerContainerResourcesApi.Resources{Resources: &assignedRequirements} + + expectedRequirements := core.ResourceRequirements{ + Requests: assignedRequirements.Requests, + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse("200m"), + core.ResourceMemory: resource.MustParse("256Mi"), + }, + } + + actualRequirements := s.Mode.Sidecar.GetResources().With(&schedulerContainerResourcesApi.Resources{Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: resource.MustParse("200m"), + core.ResourceMemory: resource.MustParse("256Mi"), + }, + Requests: core.ResourceList{ + core.ResourceCPU: resource.MustParse("100m"), + core.ResourceMemory: resource.MustParse("128Mi"), + }, + }}) + + require.Equal(t, expectedRequirements, actualRequirements.GetResources()) + }) +} diff --git a/pkg/apis/ml/v1beta1/storage_status.go b/pkg/apis/ml/v1beta1/storage_status.go new file mode 100644 index 000000000..3d774064d --- /dev/null +++ b/pkg/apis/ml/v1beta1/storage_status.go @@ -0,0 +1,29 @@ +// +// 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 v1beta1 + +import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + +type ArangoMLStorageStatus struct { + // Conditions specific to the entire storage + // +doc/type: api.Conditions + Conditions api.ConditionList `json:"conditions,omitempty"` +} diff --git a/pkg/apis/ml/v1beta1/zz_generated.deepcopy.go b/pkg/apis/ml/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..b7d876368 --- /dev/null +++ b/pkg/apis/ml/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,736 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + deploymentv1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + container "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + pod "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + v1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + corev1 "k8s.io/api/core/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtension) DeepCopyInto(out *ArangoMLExtension) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtension. +func (in *ArangoMLExtension) DeepCopy() *ArangoMLExtension { + if in == nil { + return nil + } + out := new(ArangoMLExtension) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoMLExtension) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionList) DeepCopyInto(out *ArangoMLExtensionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoMLExtension, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionList. +func (in *ArangoMLExtensionList) DeepCopy() *ArangoMLExtensionList { + if in == nil { + return nil + } + out := new(ArangoMLExtensionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoMLExtensionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpec) DeepCopyInto(out *ArangoMLExtensionSpec) { + *out = *in + if in.MetadataService != nil { + in, out := &in.MetadataService, &out.MetadataService + *out = new(ArangoMLExtensionSpecMetadataService) + (*in).DeepCopyInto(*out) + } + if in.Storage != nil { + in, out := &in.Storage, &out.Storage + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.Init != nil { + in, out := &in.Init, &out.Init + *out = new(ArangoMLExtensionTemplate) + (*in).DeepCopyInto(*out) + } + if in.Deployment != nil { + in, out := &in.Deployment, &out.Deployment + *out = new(ArangoMLExtensionSpecDeployment) + (*in).DeepCopyInto(*out) + } + if in.JobsTemplates != nil { + in, out := &in.JobsTemplates, &out.JobsTemplates + *out = new(ArangoMLJobsTemplates) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpec. +func (in *ArangoMLExtensionSpec) DeepCopy() *ArangoMLExtensionSpec { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpecDeployment) DeepCopyInto(out *ArangoMLExtensionSpecDeployment) { + *out = *in + if in.Replicas != nil { + in, out := &in.Replicas, &out.Replicas + *out = new(int32) + **out = **in + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(ArangoMLExtensionSpecDeploymentService) + (*in).DeepCopyInto(*out) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(ArangoMLExtensionSpecDeploymentTLS) + (*in).DeepCopyInto(*out) + } + if in.Pod != nil { + in, out := &in.Pod, &out.Pod + *out = new(pod.Pod) + (*in).DeepCopyInto(*out) + } + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(container.Container) + (*in).DeepCopyInto(*out) + } + if in.GPU != nil { + in, out := &in.GPU, &out.GPU + *out = new(bool) + **out = **in + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new(int32) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpecDeployment. +func (in *ArangoMLExtensionSpecDeployment) DeepCopy() *ArangoMLExtensionSpecDeployment { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpecDeployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpecDeploymentService) DeepCopyInto(out *ArangoMLExtensionSpecDeploymentService) { + *out = *in + if in.Type != nil { + in, out := &in.Type, &out.Type + *out = new(corev1.ServiceType) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpecDeploymentService. +func (in *ArangoMLExtensionSpecDeploymentService) DeepCopy() *ArangoMLExtensionSpecDeploymentService { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpecDeploymentService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpecDeploymentTLS) DeepCopyInto(out *ArangoMLExtensionSpecDeploymentTLS) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.AltNames != nil { + in, out := &in.AltNames, &out.AltNames + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpecDeploymentTLS. +func (in *ArangoMLExtensionSpecDeploymentTLS) DeepCopy() *ArangoMLExtensionSpecDeploymentTLS { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpecDeploymentTLS) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpecMetadataService) DeepCopyInto(out *ArangoMLExtensionSpecMetadataService) { + *out = *in + if in.Local != nil { + in, out := &in.Local, &out.Local + *out = new(ArangoMLExtensionSpecMetadataServiceLocal) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpecMetadataService. +func (in *ArangoMLExtensionSpecMetadataService) DeepCopy() *ArangoMLExtensionSpecMetadataService { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpecMetadataService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionSpecMetadataServiceLocal) DeepCopyInto(out *ArangoMLExtensionSpecMetadataServiceLocal) { + *out = *in + if in.ArangoPipeDatabase != nil { + in, out := &in.ArangoPipeDatabase, &out.ArangoPipeDatabase + *out = new(string) + **out = **in + } + if in.ArangoMLFeatureStoreDatabase != nil { + in, out := &in.ArangoMLFeatureStoreDatabase, &out.ArangoMLFeatureStoreDatabase + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionSpecMetadataServiceLocal. +func (in *ArangoMLExtensionSpecMetadataServiceLocal) DeepCopy() *ArangoMLExtensionSpecMetadataServiceLocal { + if in == nil { + return nil + } + out := new(ArangoMLExtensionSpecMetadataServiceLocal) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionStatus) DeepCopyInto(out *ArangoMLExtensionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(deploymentv1.ConditionList, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.MetadataService != nil { + in, out := &in.MetadataService, &out.MetadataService + *out = new(ArangoMLExtensionStatusMetadataService) + (*in).DeepCopyInto(*out) + } + if in.ServiceAccount != nil { + in, out := &in.ServiceAccount, &out.ServiceAccount + *out = new(v1.ServiceAccount) + (*in).DeepCopyInto(*out) + } + if in.ArangoDB != nil { + in, out := &in.ArangoDB, &out.ArangoDB + *out = new(ArangoMLExtensionStatusArangoDBRef) + (*in).DeepCopyInto(*out) + } + if in.Reconciliation != nil { + in, out := &in.Reconciliation, &out.Reconciliation + *out = new(ArangoMLExtensionStatusReconciliation) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionStatus. +func (in *ArangoMLExtensionStatus) DeepCopy() *ArangoMLExtensionStatus { + if in == nil { + return nil + } + out := new(ArangoMLExtensionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionStatusArangoDBRef) DeepCopyInto(out *ArangoMLExtensionStatusArangoDBRef) { + *out = *in + if in.Secret != nil { + in, out := &in.Secret, &out.Secret + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.TLS != nil { + in, out := &in.TLS, &out.TLS + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionStatusArangoDBRef. +func (in *ArangoMLExtensionStatusArangoDBRef) DeepCopy() *ArangoMLExtensionStatusArangoDBRef { + if in == nil { + return nil + } + out := new(ArangoMLExtensionStatusArangoDBRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionStatusMetadataService) DeepCopyInto(out *ArangoMLExtensionStatusMetadataService) { + *out = *in + if in.Local != nil { + in, out := &in.Local, &out.Local + *out = new(ArangoMLExtensionStatusMetadataServiceLocal) + **out = **in + } + if in.Secret != nil { + in, out := &in.Secret, &out.Secret + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionStatusMetadataService. +func (in *ArangoMLExtensionStatusMetadataService) DeepCopy() *ArangoMLExtensionStatusMetadataService { + if in == nil { + return nil + } + out := new(ArangoMLExtensionStatusMetadataService) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionStatusMetadataServiceLocal) DeepCopyInto(out *ArangoMLExtensionStatusMetadataServiceLocal) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionStatusMetadataServiceLocal. +func (in *ArangoMLExtensionStatusMetadataServiceLocal) DeepCopy() *ArangoMLExtensionStatusMetadataServiceLocal { + if in == nil { + return nil + } + out := new(ArangoMLExtensionStatusMetadataServiceLocal) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionStatusReconciliation) DeepCopyInto(out *ArangoMLExtensionStatusReconciliation) { + *out = *in + if in.StatefulSet != nil { + in, out := &in.StatefulSet, &out.StatefulSet + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.Service != nil { + in, out := &in.Service, &out.Service + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionStatusReconciliation. +func (in *ArangoMLExtensionStatusReconciliation) DeepCopy() *ArangoMLExtensionStatusReconciliation { + if in == nil { + return nil + } + out := new(ArangoMLExtensionStatusReconciliation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLExtensionTemplate) DeepCopyInto(out *ArangoMLExtensionTemplate) { + *out = *in + if in.Pod != nil { + in, out := &in.Pod, &out.Pod + *out = new(pod.Pod) + (*in).DeepCopyInto(*out) + } + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(container.Container) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLExtensionTemplate. +func (in *ArangoMLExtensionTemplate) DeepCopy() *ArangoMLExtensionTemplate { + if in == nil { + return nil + } + out := new(ArangoMLExtensionTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLJobTemplates) DeepCopyInto(out *ArangoMLJobTemplates) { + *out = *in + if in.CPU != nil { + in, out := &in.CPU, &out.CPU + *out = new(ArangoMLExtensionTemplate) + (*in).DeepCopyInto(*out) + } + if in.GPU != nil { + in, out := &in.GPU, &out.GPU + *out = new(ArangoMLExtensionTemplate) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLJobTemplates. +func (in *ArangoMLJobTemplates) DeepCopy() *ArangoMLJobTemplates { + if in == nil { + return nil + } + out := new(ArangoMLJobTemplates) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLJobsTemplates) DeepCopyInto(out *ArangoMLJobsTemplates) { + *out = *in + if in.Prediction != nil { + in, out := &in.Prediction, &out.Prediction + *out = new(ArangoMLJobTemplates) + (*in).DeepCopyInto(*out) + } + if in.Training != nil { + in, out := &in.Training, &out.Training + *out = new(ArangoMLJobTemplates) + (*in).DeepCopyInto(*out) + } + if in.Featurization != nil { + in, out := &in.Featurization, &out.Featurization + *out = new(ArangoMLJobTemplates) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLJobsTemplates. +func (in *ArangoMLJobsTemplates) DeepCopy() *ArangoMLJobsTemplates { + if in == nil { + return nil + } + out := new(ArangoMLJobsTemplates) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorage) DeepCopyInto(out *ArangoMLStorage) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorage. +func (in *ArangoMLStorage) DeepCopy() *ArangoMLStorage { + if in == nil { + return nil + } + out := new(ArangoMLStorage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoMLStorage) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageList) DeepCopyInto(out *ArangoMLStorageList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoMLStorage, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageList. +func (in *ArangoMLStorageList) DeepCopy() *ArangoMLStorageList { + if in == nil { + return nil + } + out := new(ArangoMLStorageList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoMLStorageList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageSpec) DeepCopyInto(out *ArangoMLStorageSpec) { + *out = *in + if in.BucketName != nil { + in, out := &in.BucketName, &out.BucketName + *out = new(string) + **out = **in + } + if in.BucketPath != nil { + in, out := &in.BucketPath, &out.BucketPath + *out = new(string) + **out = **in + } + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(ArangoMLStorageSpecMode) + (*in).DeepCopyInto(*out) + } + if in.Backend != nil { + in, out := &in.Backend, &out.Backend + *out = new(ArangoMLStorageSpecBackend) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageSpec. +func (in *ArangoMLStorageSpec) DeepCopy() *ArangoMLStorageSpec { + if in == nil { + return nil + } + out := new(ArangoMLStorageSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageSpecBackend) DeepCopyInto(out *ArangoMLStorageSpecBackend) { + *out = *in + if in.S3 != nil { + in, out := &in.S3, &out.S3 + *out = new(ArangoMLStorageSpecBackendS3) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageSpecBackend. +func (in *ArangoMLStorageSpecBackend) DeepCopy() *ArangoMLStorageSpecBackend { + if in == nil { + return nil + } + out := new(ArangoMLStorageSpecBackend) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageSpecBackendS3) DeepCopyInto(out *ArangoMLStorageSpecBackendS3) { + *out = *in + if in.Endpoint != nil { + in, out := &in.Endpoint, &out.Endpoint + *out = new(string) + **out = **in + } + if in.CredentialsSecret != nil { + in, out := &in.CredentialsSecret, &out.CredentialsSecret + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.AllowInsecure != nil { + in, out := &in.AllowInsecure, &out.AllowInsecure + *out = new(bool) + **out = **in + } + if in.CASecret != nil { + in, out := &in.CASecret, &out.CASecret + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.Region != nil { + in, out := &in.Region, &out.Region + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageSpecBackendS3. +func (in *ArangoMLStorageSpecBackendS3) DeepCopy() *ArangoMLStorageSpecBackendS3 { + if in == nil { + return nil + } + out := new(ArangoMLStorageSpecBackendS3) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageSpecMode) DeepCopyInto(out *ArangoMLStorageSpecMode) { + *out = *in + if in.Sidecar != nil { + in, out := &in.Sidecar, &out.Sidecar + *out = new(ArangoMLStorageSpecModeSidecar) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageSpecMode. +func (in *ArangoMLStorageSpecMode) DeepCopy() *ArangoMLStorageSpecMode { + if in == nil { + return nil + } + out := new(ArangoMLStorageSpecMode) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageSpecModeSidecar) DeepCopyInto(out *ArangoMLStorageSpecModeSidecar) { + *out = *in + if in.ListenPort != nil { + in, out := &in.ListenPort, &out.ListenPort + *out = new(uint16) + **out = **in + } + if in.ControllerListenPort != nil { + in, out := &in.ControllerListenPort, &out.ControllerListenPort + *out = new(uint16) + **out = **in + } + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(container.Container) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageSpecModeSidecar. +func (in *ArangoMLStorageSpecModeSidecar) DeepCopy() *ArangoMLStorageSpecModeSidecar { + if in == nil { + return nil + } + out := new(ArangoMLStorageSpecModeSidecar) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoMLStorageStatus) DeepCopyInto(out *ArangoMLStorageStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make(deploymentv1.ConditionList, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoMLStorageStatus. +func (in *ArangoMLStorageStatus) DeepCopy() *ArangoMLStorageStatus { + if in == nil { + return nil + } + out := new(ArangoMLStorageStatus) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/scheduler/v1alpha1/container/definition.go b/pkg/apis/scheduler/v1alpha1/container/definition.go index 3a3b32101..789c133da 100644 --- a/pkg/apis/scheduler/v1alpha1/container/definition.go +++ b/pkg/apis/scheduler/v1alpha1/container/definition.go @@ -23,7 +23,7 @@ package container import ( core "k8s.io/api/core/v1" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" "github.com/arangodb/kube-arangodb/pkg/util" @@ -127,31 +127,31 @@ var _ interfaces.Container[Container] = &Container{} type Container struct { // Core keeps the core settings for Container - *schedulerContainerResourcesApi.Core `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Core `json:",inline"` // Security keeps the security settings for Container - *schedulerContainerResourcesApi.Security `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Security `json:",inline"` // Environments keeps the environment variables for Container - *schedulerContainerResourcesApi.Environments `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Environments `json:",inline"` // Image define default image used for the Container - *schedulerContainerResourcesApi.Image `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Image `json:",inline"` // Resources define resources assigned to the Container - *schedulerContainerResourcesApi.Resources `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Resources `json:",inline"` // VolumeMounts define volume mounts assigned to the Container - *schedulerContainerResourcesApi.VolumeMounts `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.VolumeMounts `json:",inline"` // Probes define probes assigned to the Container - *schedulerContainerResourcesApi.Probes `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Probes `json:",inline"` // Networking define networking assigned to the Container - *schedulerContainerResourcesApi.Networking `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Networking `json:",inline"` // Lifecycle define lifecycle assigned to the Container - *schedulerContainerResourcesApi.Lifecycle `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Lifecycle `json:",inline"` } func (c *Container) Apply(template *core.PodTemplateSpec, container *core.Container) error { @@ -172,7 +172,7 @@ func (c *Container) Apply(template *core.PodTemplateSpec, container *core.Contai ) } -func (c *Container) GetCore() *schedulerContainerResourcesApi.Core { +func (c *Container) GetCore() *schedulerContainerResourcesApiv1alpha1.Core { if c == nil || c.Core == nil { return nil } @@ -180,7 +180,7 @@ func (c *Container) GetCore() *schedulerContainerResourcesApi.Core { return c.Core } -func (c *Container) GetImage() *schedulerContainerResourcesApi.Image { +func (c *Container) GetImage() *schedulerContainerResourcesApiv1alpha1.Image { if c == nil || c.Image == nil { return nil } @@ -188,7 +188,7 @@ func (c *Container) GetImage() *schedulerContainerResourcesApi.Image { return c.Image } -func (c *Container) GetResources() *schedulerContainerResourcesApi.Resources { +func (c *Container) GetResources() *schedulerContainerResourcesApiv1alpha1.Resources { if c == nil || c.Resources == nil { return nil } @@ -196,7 +196,7 @@ func (c *Container) GetResources() *schedulerContainerResourcesApi.Resources { return c.Resources } -func (c *Container) GetSecurity() *schedulerContainerResourcesApi.Security { +func (c *Container) GetSecurity() *schedulerContainerResourcesApiv1alpha1.Security { if c == nil || c.Security == nil { return nil } @@ -204,7 +204,7 @@ func (c *Container) GetSecurity() *schedulerContainerResourcesApi.Security { return c.Security } -func (c *Container) GetEnvironments() *schedulerContainerResourcesApi.Environments { +func (c *Container) GetEnvironments() *schedulerContainerResourcesApiv1alpha1.Environments { if c == nil || c.Environments == nil { return nil } @@ -212,7 +212,7 @@ func (c *Container) GetEnvironments() *schedulerContainerResourcesApi.Environmen return c.Environments } -func (c *Container) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMounts { +func (c *Container) GetVolumeMounts() *schedulerContainerResourcesApiv1alpha1.VolumeMounts { if c == nil || c.VolumeMounts == nil { return nil } @@ -220,7 +220,7 @@ func (c *Container) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMoun return c.VolumeMounts } -func (c *Container) GetProbes() *schedulerContainerResourcesApi.Probes { +func (c *Container) GetProbes() *schedulerContainerResourcesApiv1alpha1.Probes { if c == nil || c.Probes == nil { return nil } @@ -228,7 +228,7 @@ func (c *Container) GetProbes() *schedulerContainerResourcesApi.Probes { return c.Probes } -func (c *Container) GetNetworking() *schedulerContainerResourcesApi.Networking { +func (c *Container) GetNetworking() *schedulerContainerResourcesApiv1alpha1.Networking { if c == nil || c.Networking == nil { return nil } @@ -236,7 +236,7 @@ func (c *Container) GetNetworking() *schedulerContainerResourcesApi.Networking { return c.Networking } -func (c *Container) GetLifecycle() *schedulerContainerResourcesApi.Lifecycle { +func (c *Container) GetLifecycle() *schedulerContainerResourcesApiv1alpha1.Lifecycle { if c == nil || c.Lifecycle == nil { return nil } diff --git a/pkg/apis/scheduler/v1alpha1/container/definition_container_test.go b/pkg/apis/scheduler/v1alpha1/container/definition_container_test.go index 4af163118..e081a6b24 100644 --- a/pkg/apis/scheduler/v1alpha1/container/definition_container_test.go +++ b/pkg/apis/scheduler/v1alpha1/container/definition_container_test.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/yaml" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -110,15 +110,15 @@ func Test_Container(t *testing.T) { }) t.Run("With fields", func(t *testing.T) { applyContainer(t, &core.PodTemplateSpec{}, &core.Container{}, &Container{ - Core: &schedulerContainerResourcesApi.Core{ + Core: &schedulerContainerResourcesApiv1alpha1.Core{ Args: []string{"A"}, }, - Security: &schedulerContainerResourcesApi.Security{ + Security: &schedulerContainerResourcesApiv1alpha1.Security{ SecurityContext: &core.SecurityContext{ RunAsUser: util.NewType[int64](50), }, }, - Environments: &schedulerContainerResourcesApi.Environments{ + Environments: &schedulerContainerResourcesApiv1alpha1.Environments{ Env: []core.EnvVar{ { Name: "key1", @@ -126,17 +126,17 @@ func Test_Container(t *testing.T) { }, }, }, - Image: &schedulerContainerResourcesApi.Image{ + Image: &schedulerContainerResourcesApiv1alpha1.Image{ Image: util.NewType("test"), }, - Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &schedulerContainerResourcesApiv1alpha1.Resources{ Resources: &core.ResourceRequirements{ Limits: map[core.ResourceName]resource.Quantity{ core.ResourceCPU: resource.MustParse("1"), }, }, }, - VolumeMounts: &schedulerContainerResourcesApi.VolumeMounts{ + VolumeMounts: &schedulerContainerResourcesApiv1alpha1.VolumeMounts{ VolumeMounts: []core.VolumeMount{ { Name: "TEST", @@ -144,7 +144,7 @@ func Test_Container(t *testing.T) { }, }, }, - Probes: &schedulerContainerResourcesApi.Probes{ + Probes: &schedulerContainerResourcesApiv1alpha1.Probes{ LivenessProbe: &core.Probe{ InitialDelaySeconds: 1, }, @@ -155,7 +155,7 @@ func Test_Container(t *testing.T) { InitialDelaySeconds: 3, }, }, - Lifecycle: &schedulerContainerResourcesApi.Lifecycle{ + Lifecycle: &schedulerContainerResourcesApiv1alpha1.Lifecycle{ Lifecycle: &core.Lifecycle{ PostStart: &core.LifecycleHandler{ HTTPGet: &core.HTTPGetAction{ @@ -169,7 +169,7 @@ func Test_Container(t *testing.T) { }, }, }, - Networking: &schedulerContainerResourcesApi.Networking{ + Networking: &schedulerContainerResourcesApiv1alpha1.Networking{ Ports: []core.ContainerPort{ { Name: "TEST", diff --git a/pkg/apis/scheduler/v1alpha1/container/definition_containers_test.go b/pkg/apis/scheduler/v1alpha1/container/definition_containers_test.go index 2d5047412..5aba4dec7 100644 --- a/pkg/apis/scheduler/v1alpha1/container/definition_containers_test.go +++ b/pkg/apis/scheduler/v1alpha1/container/definition_containers_test.go @@ -28,7 +28,7 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/yaml" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -90,10 +90,10 @@ func Test_Containers(t *testing.T) { t.Run("Add container", func(t *testing.T) { applyContainers(t, &core.PodTemplateSpec{}, Containers{ "test": { - Image: &schedulerContainerResourcesApi.Image{ + Image: &schedulerContainerResourcesApiv1alpha1.Image{ Image: util.NewType("test"), }, - Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &schedulerContainerResourcesApiv1alpha1.Resources{ Resources: &core.ResourceRequirements{ Limits: map[core.ResourceName]resource.Quantity{ core.ResourceCPU: resource.MustParse("1"), @@ -122,10 +122,10 @@ func Test_Containers(t *testing.T) { }, }, Containers{ "test": { - Image: &schedulerContainerResourcesApi.Image{ + Image: &schedulerContainerResourcesApiv1alpha1.Image{ Image: util.NewType("test"), }, - Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &schedulerContainerResourcesApiv1alpha1.Resources{ Resources: &core.ResourceRequirements{ Limits: map[core.ResourceName]resource.Quantity{ core.ResourceCPU: resource.MustParse("1"), diff --git a/pkg/apis/scheduler/v1alpha1/container/generic.go b/pkg/apis/scheduler/v1alpha1/container/generic.go index b8e3047a8..a692007cf 100644 --- a/pkg/apis/scheduler/v1alpha1/container/generic.go +++ b/pkg/apis/scheduler/v1alpha1/container/generic.go @@ -23,7 +23,7 @@ package container import ( core "k8s.io/api/core/v1" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" ) @@ -32,10 +32,10 @@ var _ interfaces.Pod[Generic] = &Generic{} type Generic struct { // Environments keeps the environment variables for Container - *schedulerContainerResourcesApi.Environments `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.Environments `json:",inline"` // VolumeMounts define volume mounts assigned to the Container - *schedulerContainerResourcesApi.VolumeMounts `json:",inline"` + *schedulerContainerResourcesApiv1alpha1.VolumeMounts `json:",inline"` } func (g *Generic) Apply(template *core.PodTemplateSpec) error { @@ -55,7 +55,7 @@ func (g *Generic) Apply(template *core.PodTemplateSpec) error { return nil } -func (g *Generic) GetEnvironments() *schedulerContainerResourcesApi.Environments { +func (g *Generic) GetEnvironments() *schedulerContainerResourcesApiv1alpha1.Environments { if g == nil || g.Environments == nil { return nil } @@ -63,7 +63,7 @@ func (g *Generic) GetEnvironments() *schedulerContainerResourcesApi.Environments return g.Environments } -func (g *Generic) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMounts { +func (g *Generic) GetVolumeMounts() *schedulerContainerResourcesApiv1alpha1.VolumeMounts { if g == nil || g.VolumeMounts == nil { return nil } diff --git a/pkg/apis/scheduler/v1alpha1/container/generic_test.go b/pkg/apis/scheduler/v1alpha1/container/generic_test.go index af0476f3f..fe2f461ad 100644 --- a/pkg/apis/scheduler/v1alpha1/container/generic_test.go +++ b/pkg/apis/scheduler/v1alpha1/container/generic_test.go @@ -27,7 +27,7 @@ import ( core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/yaml" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" ) func applyGeneric(t *testing.T, template *core.PodTemplateSpec, ns ...*Generic) func(in func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic)) { @@ -93,7 +93,7 @@ func Test_Generic(t *testing.T) { }, }, }, &Generic{ - Environments: &schedulerContainerResourcesApi.Environments{ + Environments: &schedulerContainerResourcesApiv1alpha1.Environments{ Env: []core.EnvVar{ { Name: "key1", @@ -101,7 +101,7 @@ func Test_Generic(t *testing.T) { }, }, }, - VolumeMounts: &schedulerContainerResourcesApi.VolumeMounts{ + VolumeMounts: &schedulerContainerResourcesApiv1alpha1.VolumeMounts{ VolumeMounts: []core.VolumeMount{ { Name: "TEST", diff --git a/pkg/apis/scheduler/v1alpha1/pod/definition.go b/pkg/apis/scheduler/v1alpha1/pod/definition.go index 9648d2cfb..b3ee29ccf 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/definition.go +++ b/pkg/apis/scheduler/v1alpha1/pod/definition.go @@ -24,7 +24,7 @@ import ( core "k8s.io/api/core/v1" "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/interfaces" - schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources" + schedulerPodResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" ) @@ -32,25 +32,25 @@ var _ interfaces.Pod[Pod] = &Pod{} type Pod struct { // Metadata keeps the metadata settings for Pod - *schedulerPodResourcesApi.Metadata `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Metadata `json:",inline"` // Image keeps the image information - *schedulerPodResourcesApi.Image `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Image `json:",inline"` // Scheduling keeps the scheduling information - *schedulerPodResourcesApi.Scheduling `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Scheduling `json:",inline"` // Namespace keeps the Container layer Kernel namespace configuration - *schedulerPodResourcesApi.Namespace `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Namespace `json:",inline"` // Security keeps the security settings for Pod - *schedulerPodResourcesApi.Security `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Security `json:",inline"` // Volumes keeps the volumes settings for Pod - *schedulerPodResourcesApi.Volumes `json:",inline"` + *schedulerPodResourcesApiv1alpha1.Volumes `json:",inline"` // ServiceAccount keeps the service account settings for Pod - *schedulerPodResourcesApi.ServiceAccount `json:",inline"` + *schedulerPodResourcesApiv1alpha1.ServiceAccount `json:",inline"` } func (a *Pod) With(other *Pod) *Pod { @@ -93,7 +93,7 @@ func (a *Pod) Apply(template *core.PodTemplateSpec) error { ) } -func (a *Pod) GetSecurity() *schedulerPodResourcesApi.Security { +func (a *Pod) GetSecurity() *schedulerPodResourcesApiv1alpha1.Security { if a == nil { return nil } @@ -101,7 +101,7 @@ func (a *Pod) GetSecurity() *schedulerPodResourcesApi.Security { return a.Security } -func (a *Pod) GetImage() *schedulerPodResourcesApi.Image { +func (a *Pod) GetImage() *schedulerPodResourcesApiv1alpha1.Image { if a == nil { return nil } @@ -109,7 +109,7 @@ func (a *Pod) GetImage() *schedulerPodResourcesApi.Image { return a.Image } -func (a *Pod) GetScheduling() *schedulerPodResourcesApi.Scheduling { +func (a *Pod) GetScheduling() *schedulerPodResourcesApiv1alpha1.Scheduling { if a == nil { return nil } @@ -117,7 +117,7 @@ func (a *Pod) GetScheduling() *schedulerPodResourcesApi.Scheduling { return a.Scheduling } -func (a *Pod) GetContainerNamespace() *schedulerPodResourcesApi.Namespace { +func (a *Pod) GetContainerNamespace() *schedulerPodResourcesApiv1alpha1.Namespace { if a == nil { return nil } @@ -125,7 +125,7 @@ func (a *Pod) GetContainerNamespace() *schedulerPodResourcesApi.Namespace { return a.Namespace } -func (a *Pod) GetVolumes() *schedulerPodResourcesApi.Volumes { +func (a *Pod) GetVolumes() *schedulerPodResourcesApiv1alpha1.Volumes { if a == nil { return nil } @@ -133,7 +133,7 @@ func (a *Pod) GetVolumes() *schedulerPodResourcesApi.Volumes { return a.Volumes } -func (a *Pod) GetServiceAccount() *schedulerPodResourcesApi.ServiceAccount { +func (a *Pod) GetServiceAccount() *schedulerPodResourcesApiv1alpha1.ServiceAccount { if a == nil { return nil } @@ -141,7 +141,7 @@ func (a *Pod) GetServiceAccount() *schedulerPodResourcesApi.ServiceAccount { return a.ServiceAccount } -func (a *Pod) GetMetadata() *schedulerPodResourcesApi.Metadata { +func (a *Pod) GetMetadata() *schedulerPodResourcesApiv1alpha1.Metadata { if a == nil { return nil } diff --git a/pkg/apis/scheduler/v1alpha1/pod/definition_test.go b/pkg/apis/scheduler/v1alpha1/pod/definition_test.go index b9a40c5c7..59cbee925 100644 --- a/pkg/apis/scheduler/v1alpha1/pod/definition_test.go +++ b/pkg/apis/scheduler/v1alpha1/pod/definition_test.go @@ -27,7 +27,7 @@ import ( core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/yaml" - schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources" + schedulerPodResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources" "github.com/arangodb/kube-arangodb/pkg/util" ) @@ -90,19 +90,19 @@ func Test_Pod(t *testing.T) { }) t.Run("Add scheduling", func(t *testing.T) { applyPod(t, &core.PodTemplateSpec{}, &Pod{ - Security: &schedulerPodResourcesApi.Security{ + Security: &schedulerPodResourcesApiv1alpha1.Security{ PodSecurityContext: &core.PodSecurityContext{ RunAsGroup: util.NewType[int64](50), }, }, }, &Pod{ - Scheduling: &schedulerPodResourcesApi.Scheduling{ + Scheduling: &schedulerPodResourcesApiv1alpha1.Scheduling{ NodeSelector: map[string]string{ "A": "B", }, }, }, &Pod{ - Scheduling: &schedulerPodResourcesApi.Scheduling{ + Scheduling: &schedulerPodResourcesApiv1alpha1.Scheduling{ NodeSelector: map[string]string{ "A1": "B1", }, diff --git a/pkg/apis/scheduler/v1alpha1/profile_container_template.go b/pkg/apis/scheduler/v1alpha1/profile_container_template.go index 18a8a60ec..cd766aab5 100644 --- a/pkg/apis/scheduler/v1alpha1/profile_container_template.go +++ b/pkg/apis/scheduler/v1alpha1/profile_container_template.go @@ -23,14 +23,14 @@ package v1alpha1 import ( core "k8s.io/api/core/v1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" ) type ProfileContainerTemplate struct { - Containers schedulerContainerApi.Containers `json:"containers,omitempty"` + Containers schedulerContainerApiv1alpha1.Containers `json:"containers,omitempty"` - All *schedulerContainerApi.Generic `json:"all,omitempty"` + All *schedulerContainerApiv1alpha1.Generic `json:"all,omitempty"` } func (p *ProfileContainerTemplate) ApplyContainers(template *core.PodTemplateSpec) error { diff --git a/pkg/apis/scheduler/v1alpha1/profile_template.go b/pkg/apis/scheduler/v1alpha1/profile_template.go index d24b1420a..c6b2e25e2 100644 --- a/pkg/apis/scheduler/v1alpha1/profile_template.go +++ b/pkg/apis/scheduler/v1alpha1/profile_template.go @@ -21,7 +21,7 @@ package v1alpha1 import ( - schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod" + schedulerPodApiv1alpha1 "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" ) @@ -29,12 +29,12 @@ import ( type ProfileTemplate struct { Priority *int `json:"priority,omitempty"` - Pod *schedulerPodApi.Pod `json:"pod,omitempty"` + Pod *schedulerPodApiv1alpha1.Pod `json:"pod,omitempty"` Container *ProfileContainerTemplate `json:"container,omitempty"` } -func (p *ProfileTemplate) GetPod() *schedulerPodApi.Pod { +func (p *ProfileTemplate) GetPod() *schedulerPodApiv1alpha1.Pod { if p == nil || p.Pod == nil { return nil } diff --git a/pkg/apis/scheduler/v1alpha1/profiles/environments.container.kubernetes.go b/pkg/apis/scheduler/v1alpha1/profiles/environments.container.kubernetes.go index b48be4da0..adcfaa201 100644 --- a/pkg/apis/scheduler/v1alpha1/profiles/environments.container.kubernetes.go +++ b/pkg/apis/scheduler/v1alpha1/profiles/environments.container.kubernetes.go @@ -23,19 +23,19 @@ package profiles import ( core "k8s.io/api/core/v1" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" ) -func ContainerKubernetesEnvironments() *schedulerApi.ProfileTemplate { +func ContainerKubernetesEnvironments() *schedulerApiv1alpha1.ProfileTemplate { return containerKubernetesEnvironments.DeepCopy() } -var containerKubernetesEnvironments = schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - All: &schedulerContainerApi.Generic{ - Environments: &schedulerContainerResourcesApi.Environments{ +var containerKubernetesEnvironments = schedulerApiv1alpha1.ProfileTemplate{ + Container: &schedulerApiv1alpha1.ProfileContainerTemplate{ + All: &schedulerContainerApiv1alpha1.Generic{ + Environments: &schedulerContainerResourcesApiv1alpha1.Environments{ Env: []core.EnvVar{ { Name: "KUBE_NAMESPACE", diff --git a/pkg/apis/scheduler/v1alpha1/profiles/environments.container.resources.go b/pkg/apis/scheduler/v1alpha1/profiles/environments.container.resources.go index cc7d1cfb7..794eeb00d 100644 --- a/pkg/apis/scheduler/v1alpha1/profiles/environments.container.resources.go +++ b/pkg/apis/scheduler/v1alpha1/profiles/environments.container.resources.go @@ -24,9 +24,9 @@ import ( core "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerContainerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" + schedulerContainerResourcesApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" ) var ( @@ -34,14 +34,14 @@ var ( divisor1Mi = resource.MustParse("1Mi") ) -func ContainerResourceEnvironments() *schedulerApi.ProfileTemplate { +func ContainerResourceEnvironments() *schedulerApiv1alpha1.ProfileTemplate { return containerResourceEnvironments.DeepCopy() } -var containerResourceEnvironments = schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - All: &schedulerContainerApi.Generic{ - Environments: &schedulerContainerResourcesApi.Environments{ +var containerResourceEnvironments = schedulerApiv1alpha1.ProfileTemplate{ + Container: &schedulerApiv1alpha1.ProfileContainerTemplate{ + All: &schedulerContainerApiv1alpha1.Generic{ + Environments: &schedulerContainerResourcesApiv1alpha1.Environments{ Env: []core.EnvVar{ { Name: "CONTAINER_CPU_REQUESTS", diff --git a/pkg/apis/scheduler/v1beta1/container/definition.go b/pkg/apis/scheduler/v1beta1/container/definition.go new file mode 100644 index 000000000..0ac44c28d --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/definition.go @@ -0,0 +1,289 @@ +// +// 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 container + +import ( + core "k8s.io/api/core/v1" + + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/interfaces" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +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 + } + + for k, v := range c { + if id := kresources.GetContainerIDByName(template.Spec.Containers, k); id >= 0 { + if err := v.Apply(template, &template.Spec.Containers[id]); err != nil { + return err + } + } else { + id = len(template.Spec.Containers) + + template.Spec.Containers = append(template.Spec.Containers, core.Container{ + Name: k, + }) + + if err := v.Apply(template, &template.Spec.Containers[id]); err != nil { + return err + } + } + } + + return nil +} + +func (c Containers) With(other Containers) Containers { + if len(c) == 0 && len(other) == 0 { + return nil + } + + if len(c) == 0 { + return other.DeepCopy() + } + + if len(other) == 0 { + return c.DeepCopy() + } + + ret := Containers{} + + for k, v := range c { + if v1, ok := other[k]; !ok { + ret[k] = v + } else { + ret[k] = util.TypeOrDefault(v.With(&v1)) + } + } + + for k, v := range other { + if _, ok := c[k]; !ok { + ret[k] = v + } + } + + return ret +} + +func (c Containers) Validate() error { + for name, container := range c { + if err := container.Validate(); err != nil { + return errors.Wrapf(err, "Container %s failed", name) + } + } + + return nil +} + +var _ interfaces.Container[Container] = &Container{} + +type Container struct { + // Core keeps the core settings for Container + *schedulerContainerResourcesApi.Core `json:",inline"` + + // Security keeps the security settings for Container + *schedulerContainerResourcesApi.Security `json:",inline"` + + // Environments keeps the environment variables for Container + *schedulerContainerResourcesApi.Environments `json:",inline"` + + // Image define default image used for the Container + *schedulerContainerResourcesApi.Image `json:",inline"` + + // Resources define resources assigned to the Container + *schedulerContainerResourcesApi.Resources `json:",inline"` + + // VolumeMounts define volume mounts assigned to the Container + *schedulerContainerResourcesApi.VolumeMounts `json:",inline"` + + // Probes define probes assigned to the Container + *schedulerContainerResourcesApi.Probes `json:",inline"` + + // Networking define networking assigned to the Container + *schedulerContainerResourcesApi.Networking `json:",inline"` + + // Lifecycle define lifecycle assigned to the Container + *schedulerContainerResourcesApi.Lifecycle `json:",inline"` +} + +func (c *Container) Apply(template *core.PodTemplateSpec, container *core.Container) error { + if c == nil { + return nil + } + + return shared.WithErrors( + c.Core.Apply(template, container), + c.Security.Apply(template, container), + c.Environments.Apply(template, container), + c.Image.Apply(template, container), + c.Resources.Apply(template, container), + c.VolumeMounts.Apply(template, container), + c.Probes.Apply(template, container), + c.Networking.Apply(template, container), + c.Lifecycle.Apply(template, container), + ) +} + +func (c *Container) GetCore() *schedulerContainerResourcesApi.Core { + if c == nil || c.Core == nil { + return nil + } + + return c.Core +} + +func (c *Container) GetImage() *schedulerContainerResourcesApi.Image { + if c == nil || c.Image == nil { + return nil + } + + return c.Image +} + +func (c *Container) GetResources() *schedulerContainerResourcesApi.Resources { + if c == nil || c.Resources == nil { + return nil + } + + return c.Resources +} + +func (c *Container) GetSecurity() *schedulerContainerResourcesApi.Security { + if c == nil || c.Security == nil { + return nil + } + + return c.Security +} + +func (c *Container) GetEnvironments() *schedulerContainerResourcesApi.Environments { + if c == nil || c.Environments == nil { + return nil + } + + return c.Environments +} + +func (c *Container) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMounts { + if c == nil || c.VolumeMounts == nil { + return nil + } + + return c.VolumeMounts +} + +func (c *Container) GetProbes() *schedulerContainerResourcesApi.Probes { + if c == nil || c.Probes == nil { + return nil + } + + return c.Probes +} + +func (c *Container) GetNetworking() *schedulerContainerResourcesApi.Networking { + if c == nil || c.Networking == nil { + return nil + } + + return c.Networking +} + +func (c *Container) GetLifecycle() *schedulerContainerResourcesApi.Lifecycle { + if c == nil || c.Lifecycle == nil { + return nil + } + + return c.Lifecycle +} + +func (c *Container) With(other *Container) *Container { + if c == nil && other == nil { + return nil + } + + if c == nil { + return other.DeepCopy() + } + + if other == nil { + return c.DeepCopy() + } + + return &Container{ + Core: c.Core.With(other.Core), + Security: c.Security.With(other.Security), + Environments: c.Environments.With(other.Environments), + Image: c.Image.With(other.Image), + Resources: c.Resources.With(other.Resources), + VolumeMounts: c.VolumeMounts.With(other.VolumeMounts), + Lifecycle: c.Lifecycle.With(other.Lifecycle), + Networking: c.Networking.With(other.Networking), + Probes: c.Probes.With(other.Probes), + } +} + +func (c *Container) Validate() error { + if c == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("core", c.Core.Validate()), + shared.PrefixResourceErrors("containerSecurity", c.Security.Validate()), + shared.PrefixResourceErrors("containerEnvironments", c.Environments.Validate()), + shared.PrefixResourceErrors("containerResources", c.Image.Validate()), + shared.PrefixResourceErrors("containerImage", c.Resources.Validate()), + shared.PrefixResourceErrors("volumeMounts", c.VolumeMounts.Validate()), + shared.PrefixResourceErrors("lifecycle", c.Lifecycle.Validate()), + shared.PrefixResourceErrors("networking", c.Networking.Validate()), + shared.PrefixResourceErrors("probes", c.Probes.Validate()), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/container/definition_container_test.go b/pkg/apis/scheduler/v1beta1/container/definition_container_test.go new file mode 100644 index 000000000..64f0cb351 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/definition_container_test.go @@ -0,0 +1,371 @@ +// +// 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 container + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/yaml" + + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func applyContainer(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Container) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container)) { + var i *Container + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container)) { + t.Run("Validate", func(t *testing.T) { + if i != nil { + in(t, template, container, i) + } else { + in(t, template, container, &Container{}) + } + }) + } +} + +func applyContainerYAML(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...string) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container)) { + elements := make([]*Container, len(ns)) + + for id := range ns { + var p Container + require.NoError(t, yaml.Unmarshal([]byte(ns[id]), &p)) + elements[id] = p.DeepCopy() + } + + return applyContainer(t, template, container, elements...) +} + +func Test_Container(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyContainer(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) { + require.Nil(t, spec.Resources) + require.Nil(t, spec.Image) + require.Nil(t, spec.Security) + require.Nil(t, spec.Environments) + require.Nil(t, spec.VolumeMounts) + require.Nil(t, spec.Core) + + require.Len(t, container.Env, 0) + }) + }) + t.Run("Empty template", func(t *testing.T) { + applyContainer(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) { + require.Nil(t, spec.Resources) + require.Nil(t, spec.Image) + require.Nil(t, spec.Security) + require.Nil(t, spec.Environments) + require.Nil(t, spec.VolumeMounts) + require.Nil(t, spec.Core) + + require.Len(t, container.Env, 0) + }) + }) + t.Run("With fields", func(t *testing.T) { + applyContainer(t, &core.PodTemplateSpec{}, &core.Container{}, &Container{ + Core: &schedulerContainerResourcesApi.Core{ + Args: []string{"A"}, + }, + Security: &schedulerContainerResourcesApi.Security{ + SecurityContext: &core.SecurityContext{ + RunAsUser: util.NewType[int64](50), + }, + }, + Environments: &schedulerContainerResourcesApi.Environments{ + Env: []core.EnvVar{ + { + Name: "key1", + Value: "value1", + }, + }, + }, + Image: &schedulerContainerResourcesApi.Image{ + Image: util.NewType("test"), + }, + Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &core.ResourceRequirements{ + Limits: map[core.ResourceName]resource.Quantity{ + core.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + VolumeMounts: &schedulerContainerResourcesApi.VolumeMounts{ + VolumeMounts: []core.VolumeMount{ + { + Name: "TEST", + MountPath: "/data", + }, + }, + }, + Probes: &schedulerContainerResourcesApi.Probes{ + LivenessProbe: &core.Probe{ + InitialDelaySeconds: 1, + }, + ReadinessProbe: &core.Probe{ + InitialDelaySeconds: 2, + }, + StartupProbe: &core.Probe{ + InitialDelaySeconds: 3, + }, + }, + Lifecycle: &schedulerContainerResourcesApi.Lifecycle{ + Lifecycle: &core.Lifecycle{ + PostStart: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "test1", + }, + }, + PreStop: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "test2", + }, + }, + }, + }, + Networking: &schedulerContainerResourcesApi.Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST", + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) { + // Spec + require.NotNil(t, spec.Core) + require.NotNil(t, spec.Core.Args) + require.Contains(t, spec.Core.Args, "A") + require.Empty(t, spec.Core.Command) + require.Empty(t, spec.Core.WorkingDir) + + require.NotNil(t, spec.Resources) + require.NotNil(t, spec.Resources.Resources) + require.Contains(t, spec.Resources.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), spec.Resources.Resources.Limits[core.ResourceCPU]) + + require.NotNil(t, spec.Image) + require.NotNil(t, spec.Image.Image) + require.EqualValues(t, "test", *spec.Image.Image) + + require.NotNil(t, spec.Security) + require.NotNil(t, spec.Security.SecurityContext) + require.NotNil(t, spec.Security.SecurityContext.RunAsUser) + require.EqualValues(t, 50, *spec.Security.SecurityContext.RunAsUser) + + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value1", spec.Environments.Env[0].Value) + + require.NotNil(t, spec.VolumeMounts) + require.Len(t, spec.VolumeMounts.VolumeMounts, 1) + require.EqualValues(t, "TEST", spec.VolumeMounts.VolumeMounts[0].Name) + + require.NotNil(t, spec.Probes) + require.NotNil(t, spec.Probes.LivenessProbe) + require.EqualValues(t, 1, spec.Probes.LivenessProbe.InitialDelaySeconds) + require.NotNil(t, spec.Probes.ReadinessProbe) + require.EqualValues(t, 2, spec.Probes.ReadinessProbe.InitialDelaySeconds) + require.NotNil(t, spec.Probes.StartupProbe) + require.EqualValues(t, 3, spec.Probes.StartupProbe.InitialDelaySeconds) + + require.NotNil(t, spec.Lifecycle) + require.NotNil(t, spec.Lifecycle.Lifecycle) + require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart) + require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart.HTTPGet) + require.EqualValues(t, "test1", spec.Lifecycle.Lifecycle.PostStart.HTTPGet.Path) + require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop) + require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop.HTTPGet) + require.EqualValues(t, "test2", spec.Lifecycle.Lifecycle.PreStop.HTTPGet.Path) + + require.NotNil(t, spec.Networking) + require.Len(t, spec.Networking.Ports, 1) + require.EqualValues(t, "TEST", spec.Networking.Ports[0].Name) + }) + }) +} + +func Test_Container_YAML(t *testing.T) { + t.Run("With Override", func(t *testing.T) { + applyContainerYAML(t, &core.PodTemplateSpec{}, &core.Container{}, ` +--- +securityContext: + runAsUser: 50 + +args: +- A + +env: +- name: key1 + value: value1 + +image: test + +resources: + limits: + cpu: 1 + +volumeMounts: + - name: TEST + +livenessProbe: + initialDelaySeconds: 1 + +readinessProbe: + initialDelaySeconds: 2 + +startupProbe: + initialDelaySeconds: 3 + +lifecycle: + postStart: + httpGet: + path: test1 + preStop: + httpGet: + path: test2 + +ports: + - name: TEST +`, ` +--- + +securityContext: + runAsUser: 10 +`)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) { + // Spec + require.NotNil(t, spec.Core) + require.NotNil(t, spec.Core.Args) + require.Contains(t, spec.Core.Args, "A") + require.Empty(t, spec.Core.Command) + require.Empty(t, spec.Core.WorkingDir) + + require.NotNil(t, spec.Resources) + require.NotNil(t, spec.Resources.Resources) + require.Contains(t, spec.Resources.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), spec.Resources.Resources.Limits[core.ResourceCPU]) + + require.NotNil(t, spec.Image) + require.NotNil(t, spec.Image.Image) + require.EqualValues(t, "test", *spec.Image.Image) + + require.NotNil(t, spec.Security) + require.NotNil(t, spec.Security.SecurityContext) + require.NotNil(t, spec.Security.SecurityContext.RunAsUser) + require.EqualValues(t, 10, *spec.Security.SecurityContext.RunAsUser) + + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value1", spec.Environments.Env[0].Value) + + require.NotNil(t, spec.VolumeMounts) + require.Len(t, spec.VolumeMounts.VolumeMounts, 1) + require.EqualValues(t, "TEST", spec.VolumeMounts.VolumeMounts[0].Name) + + require.NotNil(t, spec.Probes) + require.NotNil(t, spec.Probes.LivenessProbe) + require.EqualValues(t, 1, spec.Probes.LivenessProbe.InitialDelaySeconds) + require.NotNil(t, spec.Probes.ReadinessProbe) + require.EqualValues(t, 2, spec.Probes.ReadinessProbe.InitialDelaySeconds) + require.NotNil(t, spec.Probes.StartupProbe) + require.EqualValues(t, 3, spec.Probes.StartupProbe.InitialDelaySeconds) + + require.NotNil(t, spec.Lifecycle) + require.NotNil(t, spec.Lifecycle.Lifecycle) + require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart) + require.NotNil(t, spec.Lifecycle.Lifecycle.PostStart.HTTPGet) + require.EqualValues(t, "test1", spec.Lifecycle.Lifecycle.PostStart.HTTPGet.Path) + require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop) + require.NotNil(t, spec.Lifecycle.Lifecycle.PreStop.HTTPGet) + require.EqualValues(t, "test2", spec.Lifecycle.Lifecycle.PreStop.HTTPGet.Path) + + require.NotNil(t, spec.Networking) + require.Len(t, spec.Networking.Ports, 1) + require.EqualValues(t, "TEST", spec.Networking.Ports[0].Name) + }) + }) + t.Run("With fields", func(t *testing.T) { + applyContainerYAML(t, &core.PodTemplateSpec{}, &core.Container{}, ` +--- +securityContext: + runAsUser: 50 + +env: +- name: key1 + value: value1 + +image: test + +resources: + limits: + cpu: 1 +`)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container, spec *Container) { + // Spec + require.NotNil(t, spec.Resources) + require.NotNil(t, spec.Resources.Resources) + require.Contains(t, spec.Resources.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), spec.Resources.Resources.Limits[core.ResourceCPU]) + + require.NotNil(t, spec.Image) + require.NotNil(t, spec.Image.Image) + require.EqualValues(t, "test", *spec.Image.Image) + + require.NotNil(t, spec.Security) + require.NotNil(t, spec.Security.SecurityContext) + require.NotNil(t, spec.Security.SecurityContext.RunAsUser) + require.EqualValues(t, 50, *spec.Security.SecurityContext.RunAsUser) + + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value1", spec.Environments.Env[0].Value) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/definition_containers_test.go b/pkg/apis/scheduler/v1beta1/container/definition_containers_test.go new file mode 100644 index 000000000..583e24b66 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/definition_containers_test.go @@ -0,0 +1,205 @@ +// +// 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 container + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/util/yaml" + + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func applyContainers(t *testing.T, template *core.PodTemplateSpec, ns ...Containers) func(in func(t *testing.T, pod *core.PodTemplateSpec, spec Containers)) { + var i Containers + + 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, pod *core.PodTemplateSpec, spec Containers)) { + t.Run("Validate", func(t *testing.T) { + if i != nil { + in(t, template, i) + } else { + in(t, template, Containers{}) + } + }) + } +} + +func applyContainersYAML(t *testing.T, template *core.PodTemplateSpec, ns ...string) func(in func(t *testing.T, pod *core.PodTemplateSpec, spec Containers)) { + elements := make([]Containers, len(ns)) + + for id := range ns { + var p Containers + require.NoError(t, yaml.Unmarshal([]byte(ns[id]), &p)) + elements[id] = p.DeepCopy() + } + + return applyContainers(t, template, elements...) +} + +func Test_Containers(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyContainers(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 0) + require.Len(t, pod.Spec.Containers, 0) + }) + }) + t.Run("Empty template", func(t *testing.T) { + applyContainers(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 0) + require.Len(t, pod.Spec.Containers, 0) + }) + }) + t.Run("Add container", func(t *testing.T) { + applyContainers(t, &core.PodTemplateSpec{}, Containers{ + "test": { + Image: &schedulerContainerResourcesApi.Image{ + Image: util.NewType("test"), + }, + Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &core.ResourceRequirements{ + Limits: map[core.ResourceName]resource.Quantity{ + core.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 1) + require.Len(t, pod.Spec.Containers, 1) + require.EqualValues(t, "test", pod.Spec.Containers[0].Name) + require.EqualValues(t, "test", pod.Spec.Containers[0].Image) + require.Len(t, pod.Spec.Containers[0].Resources.Limits, 1) + require.Contains(t, pod.Spec.Containers[0].Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), pod.Spec.Containers[0].Resources.Limits[core.ResourceCPU]) + }) + }) + t.Run("Append container", func(t *testing.T) { + applyContainers(t, &core.PodTemplateSpec{ + Spec: core.PodSpec{ + Containers: []core.Container{ + { + Name: "example", + }, + }, + }, + }, Containers{ + "test": { + Image: &schedulerContainerResourcesApi.Image{ + Image: util.NewType("test"), + }, + Resources: &schedulerContainerResourcesApi.Resources{ + Resources: &core.ResourceRequirements{ + Limits: map[core.ResourceName]resource.Quantity{ + core.ResourceCPU: resource.MustParse("1"), + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 1) + require.Len(t, pod.Spec.Containers, 2) + require.EqualValues(t, "test", pod.Spec.Containers[1].Name) + require.EqualValues(t, "test", pod.Spec.Containers[1].Image) + require.Len(t, pod.Spec.Containers[1].Resources.Limits, 1) + require.Contains(t, pod.Spec.Containers[1].Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), pod.Spec.Containers[1].Resources.Limits[core.ResourceCPU]) + }) + }) +} + +func Test_Containers_YAML(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyContainersYAML(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 0) + require.Len(t, pod.Spec.Containers, 0) + }) + }) + t.Run("Empty template", func(t *testing.T) { + applyContainersYAML(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 0) + require.Len(t, pod.Spec.Containers, 0) + }) + }) + t.Run("Add container", func(t *testing.T) { + applyContainersYAML(t, &core.PodTemplateSpec{}, ` +--- +test: + image: test + resources: + limits: + cpu: 1 +`)(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 1) + require.Len(t, pod.Spec.Containers, 1) + require.EqualValues(t, "test", pod.Spec.Containers[0].Name) + require.EqualValues(t, "test", pod.Spec.Containers[0].Image) + require.Len(t, pod.Spec.Containers[0].Resources.Limits, 1) + require.Contains(t, pod.Spec.Containers[0].Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), pod.Spec.Containers[0].Resources.Limits[core.ResourceCPU]) + }) + }) + t.Run("Append container", func(t *testing.T) { + applyContainersYAML(t, &core.PodTemplateSpec{ + Spec: core.PodSpec{ + Containers: []core.Container{ + { + Name: "example", + }, + }, + }, + }, ` +--- +test: + image: test + resources: + limits: + cpu: 1 +`)(func(t *testing.T, pod *core.PodTemplateSpec, spec Containers) { + require.Len(t, spec, 1) + require.Len(t, pod.Spec.Containers, 2) + require.EqualValues(t, "test", pod.Spec.Containers[1].Name) + require.EqualValues(t, "test", pod.Spec.Containers[1].Image) + require.Len(t, pod.Spec.Containers[1].Resources.Limits, 1) + require.Contains(t, pod.Spec.Containers[1].Resources.Limits, core.ResourceCPU) + require.EqualValues(t, resource.MustParse("1"), pod.Spec.Containers[1].Resources.Limits[core.ResourceCPU]) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/doc.go b/pkg/apis/scheduler/v1beta1/container/doc.go new file mode 100644 index 000000000..ee9cc4b65 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=scheduler.arangodb.com +package container diff --git a/pkg/apis/scheduler/v1beta1/container/generic.go b/pkg/apis/scheduler/v1beta1/container/generic.go new file mode 100644 index 000000000..611ab116f --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/generic.go @@ -0,0 +1,102 @@ +// +// 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 container + +import ( + core "k8s.io/api/core/v1" + + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/interfaces" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +var _ interfaces.Pod[Generic] = &Generic{} + +type Generic struct { + // Environments keeps the environment variables for Container + *schedulerContainerResourcesApi.Environments `json:",inline"` + + // VolumeMounts define volume mounts assigned to the Container + *schedulerContainerResourcesApi.VolumeMounts `json:",inline"` +} + +func (g *Generic) Apply(template *core.PodTemplateSpec) error { + if g == nil { + return nil + } + + for id := range template.Spec.Containers { + if err := shared.WithErrors( + g.Environments.Apply(template, &template.Spec.Containers[id]), + g.VolumeMounts.Apply(template, &template.Spec.Containers[id]), + ); err != nil { + return err + } + } + + return nil +} + +func (g *Generic) GetEnvironments() *schedulerContainerResourcesApi.Environments { + if g == nil || g.Environments == nil { + return nil + } + + return g.Environments +} + +func (g *Generic) GetVolumeMounts() *schedulerContainerResourcesApi.VolumeMounts { + if g == nil || g.VolumeMounts == nil { + return nil + } + + return g.VolumeMounts +} + +func (g *Generic) With(other *Generic) *Generic { + if g == nil && other == nil { + return nil + } + + if g == nil { + return other.DeepCopy() + } + + if other == nil { + return g.DeepCopy() + } + + return &Generic{ + Environments: g.Environments.With(other.Environments), + VolumeMounts: g.VolumeMounts.With(other.VolumeMounts), + } +} + +func (g *Generic) Validate() error { + if g == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("containerEnvironments", g.Environments.Validate()), + shared.PrefixResourceErrors("volumeMounts", g.VolumeMounts.Validate()), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/container/generic_test.go b/pkg/apis/scheduler/v1beta1/container/generic_test.go new file mode 100644 index 000000000..59908cd0b --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/generic_test.go @@ -0,0 +1,190 @@ +// +// 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 container + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/yaml" + + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" +) + +func applyGeneric(t *testing.T, template *core.PodTemplateSpec, ns ...*Generic) func(in func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic)) { + var i *Generic + + 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, pod *core.PodTemplateSpec, spec *Generic)) { + t.Run("Validate", func(t *testing.T) { + if i != nil { + in(t, template, i) + } else { + in(t, template, &Generic{}) + } + }) + } +} + +func applyGenericYAML(t *testing.T, template *core.PodTemplateSpec, ns ...string) func(in func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic)) { + elements := make([]*Generic, len(ns)) + + for id := range ns { + var p Generic + require.NoError(t, yaml.Unmarshal([]byte(ns[id]), &p)) + elements[id] = p.DeepCopy() + } + + return applyGeneric(t, template, elements...) +} + +func Test_Generic(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyGeneric(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic) { + require.Nil(t, spec.Environments) + require.Nil(t, spec.VolumeMounts) + }) + }) + t.Run("Empty template", func(t *testing.T) { + applyGeneric(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic) { + require.Nil(t, spec.Environments) + require.Nil(t, spec.VolumeMounts) + }) + }) + t.Run("With fields", func(t *testing.T) { + applyGeneric(t, &core.PodTemplateSpec{ + Spec: core.PodSpec{ + Containers: []core.Container{ + {}, + }, + }, + }, &Generic{ + Environments: &schedulerContainerResourcesApi.Environments{ + Env: []core.EnvVar{ + { + Name: "key1", + Value: "value1", + }, + }, + }, + VolumeMounts: &schedulerContainerResourcesApi.VolumeMounts{ + VolumeMounts: []core.VolumeMount{ + { + Name: "TEST", + MountPath: "/data", + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic) { + require.NotNil(t, spec.VolumeMounts) + require.Len(t, spec.VolumeMounts.VolumeMounts, 1) + require.EqualValues(t, "TEST", spec.VolumeMounts.VolumeMounts[0].Name) + + // Spec + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value1", spec.Environments.Env[0].Value) + + // Check + require.Len(t, pod.Spec.Containers, 1) + require.Len(t, pod.Spec.Containers[0].Env, 1) + require.EqualValues(t, "key1", pod.Spec.Containers[0].Env[0].Name) + require.EqualValues(t, "value1", pod.Spec.Containers[0].Env[0].Value) + }) + }) +} + +func Test_Generic_YAML(t *testing.T) { + t.Run("With Override", func(t *testing.T) { + applyGenericYAML(t, &core.PodTemplateSpec{ + Spec: core.PodSpec{ + Containers: []core.Container{ + {}, + }, + }, + }, ` +--- +env: +- name: key1 + value: value1 +`, ` +--- +env: +- name: key1 + value: value2 +`)(func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic) { + // Spec + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value2", spec.Environments.Env[0].Value) + + // Check + require.Len(t, pod.Spec.Containers, 1) + require.Len(t, pod.Spec.Containers[0].Env, 1) + require.EqualValues(t, "key1", pod.Spec.Containers[0].Env[0].Name) + require.EqualValues(t, "value2", pod.Spec.Containers[0].Env[0].Value) + }) + }) + t.Run("With fields", func(t *testing.T) { + applyGenericYAML(t, &core.PodTemplateSpec{ + Spec: core.PodSpec{ + Containers: []core.Container{ + {}, + }, + }, + }, ` +--- +env: +- name: key1 + value: value1 +`)(func(t *testing.T, pod *core.PodTemplateSpec, spec *Generic) { + // Spec + require.NotNil(t, spec.Environments) + require.Len(t, spec.Environments.Env, 1) + require.EqualValues(t, "key1", spec.Environments.Env[0].Name) + require.EqualValues(t, "value1", spec.Environments.Env[0].Value) + + // Check + require.Len(t, pod.Spec.Containers, 1) + require.Len(t, pod.Spec.Containers[0].Env, 1) + require.EqualValues(t, "key1", pod.Spec.Containers[0].Env[0].Name) + require.EqualValues(t, "value1", pod.Spec.Containers[0].Env[0].Value) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/core.go b/pkg/apis/scheduler/v1beta1/container/resources/core.go new file mode 100644 index 000000000..a36e72049 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/core.go @@ -0,0 +1,86 @@ +// +// 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/v1beta1/interfaces" +) + +var _ interfaces.Container[Core] = &Core{} + +type Core struct { + // Entrypoint array. Not executed within a shell. + // The container image's ENTRYPOINT is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // +doc/link: Kubernetes Docs|https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + Command []string `json:"command,omitempty"` + + // Arguments to the entrypoint. + // The container image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // +doc/link: Kubernetes Docs|https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + Args []string `json:"args,omitempty"` + + // Container's working directory. + // If not specified, the container runtime's default will be used, which + // might be configured in the container image. + WorkingDir string `json:"workingDir,omitempty"` +} + +func (c *Core) Apply(_ *core.PodTemplateSpec, container *core.Container) error { + if c == nil { + return nil + } + + d := c.DeepCopy() + + container.Args = d.Args + container.Command = d.Command + container.WorkingDir = d.WorkingDir + + return nil +} + +func (c *Core) With(other *Core) *Core { + if c == nil && other == nil { + return nil + } + + if other == nil { + return c.DeepCopy() + } + + return other.DeepCopy() +} + +func (c *Core) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/core_test.go b/pkg/apis/scheduler/v1beta1/container/resources/core_test.go new file mode 100644 index 000000000..f26fcd863 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/core_test.go @@ -0,0 +1,107 @@ +// +// 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" +) + +func applyCore(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Core) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Core + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Core(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyCore(t, nil, nil)(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Args, 0) + require.Len(t, container.Command, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyCore(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Args, 0) + require.Len(t, container.Command, 0) + }) + }) + t.Run("With One", func(t *testing.T) { + applyCore(t, &core.PodTemplateSpec{}, &core.Container{}, &Core{ + Command: []string{"A"}, + Args: []string{"B"}, + WorkingDir: "C", + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Args, 1) + require.Contains(t, container.Args, "B") + + require.Len(t, container.Command, 1) + require.Contains(t, container.Command, "A") + + require.EqualValues(t, "C", container.WorkingDir) + }) + }) + t.Run("With Override", func(t *testing.T) { + applyCore(t, &core.PodTemplateSpec{}, &core.Container{}, &Core{ + Command: []string{"B"}, + Args: []string{"A"}, + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Args, 1) + require.Contains(t, container.Args, "A") + + require.Len(t, container.Command, 1) + require.Contains(t, container.Command, "B") + + require.EqualValues(t, "", container.WorkingDir) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/doc.go b/pkg/apis/scheduler/v1beta1/container/resources/doc.go new file mode 100644 index 000000000..43be1f3fb --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=scheduler.arangodb.com +package resources diff --git a/pkg/apis/scheduler/v1beta1/container/resources/environments.go b/pkg/apis/scheduler/v1beta1/container/resources/environments.go new file mode 100644 index 000000000..34e60a820 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/environments.go @@ -0,0 +1,76 @@ +// +// 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/v1beta1/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[Environments] = &Environments{} + +type Environments struct { + // Env keeps the information about environment variables provided to the container + // +doc/type: core.EnvVar + // +doc/link: Kubernetes Docs|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envvar-v1-core + Env []core.EnvVar `json:"env,omitempty"` + + // EnvFrom keeps the information about environment variable sources provided to the container + // +doc/type: core.EnvFromSource + // +doc/link: Kubernetes Docs|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#envfromsource-v1-core + EnvFrom []core.EnvFromSource `json:"envFrom,omitempty"` +} + +func (e *Environments) Apply(_ *core.PodTemplateSpec, container *core.Container) error { + if e == nil { + return nil + } + + container.Env = kresources.MergeEnvs(container.Env, e.Env...) + container.EnvFrom = kresources.MergeEnvFrom(container.EnvFrom, e.EnvFrom...) + + return nil +} + +func (e *Environments) With(other *Environments) *Environments { + if e == nil && other == nil { + return nil + } + + if e == nil { + return other.DeepCopy() + } + + if other == nil { + return e.DeepCopy() + } + + return &Environments{ + Env: kresources.MergeEnvs(e.Env, other.Env...), + EnvFrom: kresources.MergeEnvFrom(e.EnvFrom, other.EnvFrom...), + } +} + +func (e *Environments) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/environments_test.go b/pkg/apis/scheduler/v1beta1/container/resources/environments_test.go new file mode 100644 index 000000000..c7416d408 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/environments_test.go @@ -0,0 +1,221 @@ +// +// 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" + "k8s.io/apimachinery/pkg/api/resource" +) + +func applyEnvironments(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Environments) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Environments + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Environments(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyEnvironments(t, nil, nil)(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Env, 0) + require.Len(t, container.EnvFrom, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyEnvironments(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Env, 0) + require.Len(t, container.EnvFrom, 0) + }) + }) + t.Run("With Env", func(t *testing.T) { + applyEnvironments(t, &core.PodTemplateSpec{}, &core.Container{}, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + Value: "value1", + }, + }, + EnvFrom: []core.EnvFromSource{ + { + Prefix: "DATA_", + SecretRef: &core.SecretEnvSource{ + LocalObjectReference: core.LocalObjectReference{ + Name: "secret1", + }, + }, + }, + }, + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Env, 1) + require.EqualValues(t, "var1", container.Env[0].Name) + require.EqualValues(t, "value1", container.Env[0].Value) + require.Nil(t, container.Env[0].ValueFrom) + + require.Len(t, container.EnvFrom, 1) + require.EqualValues(t, "DATA_", container.EnvFrom[0].Prefix) + require.NotNil(t, container.EnvFrom[0].SecretRef) + require.Nil(t, container.EnvFrom[0].SecretRef.Optional) + require.EqualValues(t, "secret1", container.EnvFrom[0].SecretRef.Name) + require.Nil(t, container.EnvFrom[0].ConfigMapRef) + }) + }) + t.Run("With Env Merge", func(t *testing.T) { + applyEnvironments(t, &core.PodTemplateSpec{}, &core.Container{}, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + Value: "value1", + }, + }, + EnvFrom: []core.EnvFromSource{ + { + Prefix: "DATA_", + SecretRef: &core.SecretEnvSource{ + LocalObjectReference: core.LocalObjectReference{ + Name: "secret1", + }, + }, + }, + }, + }, &Environments{ + Env: []core.EnvVar{ + { + Name: "var2", + Value: "value2", + }, + }, + EnvFrom: []core.EnvFromSource{ + { + Prefix: "DATA2_", + ConfigMapRef: &core.ConfigMapEnvSource{ + LocalObjectReference: core.LocalObjectReference{ + Name: "cm1", + }, + }, + }, + }, + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Env, 2) + require.EqualValues(t, "var1", container.Env[0].Name) + require.EqualValues(t, "value1", container.Env[0].Value) + require.Nil(t, container.Env[0].ValueFrom) + require.EqualValues(t, "var2", container.Env[1].Name) + require.EqualValues(t, "value2", container.Env[1].Value) + require.Nil(t, container.Env[1].ValueFrom) + + require.Len(t, container.EnvFrom, 2) + require.EqualValues(t, "DATA_", container.EnvFrom[0].Prefix) + require.NotNil(t, container.EnvFrom[0].SecretRef) + require.Nil(t, container.EnvFrom[0].SecretRef.Optional) + require.EqualValues(t, "secret1", container.EnvFrom[0].SecretRef.Name) + require.Nil(t, container.EnvFrom[0].ConfigMapRef) + + require.EqualValues(t, "DATA2_", container.EnvFrom[1].Prefix) + require.NotNil(t, container.EnvFrom[1].ConfigMapRef) + require.Nil(t, container.EnvFrom[1].ConfigMapRef.Optional) + require.EqualValues(t, "cm1", container.EnvFrom[1].ConfigMapRef.Name) + require.Nil(t, container.EnvFrom[1].SecretRef) + }) + }) + t.Run("With Env Replace", func(t *testing.T) { + applyEnvironments(t, &core.PodTemplateSpec{}, &core.Container{}, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + Value: "value1", + }, + }, + }, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + Value: "value2", + }, + }, + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.EnvFrom, 0) + require.Len(t, container.Env, 1) + require.EqualValues(t, "var1", container.Env[0].Name) + require.EqualValues(t, "value2", container.Env[0].Value) + require.Nil(t, container.Env[0].ValueFrom) + }) + }) + t.Run("With Env Replace Type", func(t *testing.T) { + applyEnvironments(t, &core.PodTemplateSpec{}, &core.Container{}, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + Value: "value1", + }, + }, + }, &Environments{ + Env: []core.EnvVar{ + { + Name: "var1", + ValueFrom: &core.EnvVarSource{ + ResourceFieldRef: &core.ResourceFieldSelector{ + ContainerName: "a", + Resource: "b", + Divisor: resource.Quantity{}, + }, + }, + }, + }, + })(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.EnvFrom, 0) + require.Len(t, container.Env, 1) + require.EqualValues(t, "var1", container.Env[0].Name) + require.Empty(t, container.Env[0].Value) + require.NotNil(t, container.Env[0].ValueFrom) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/image.go b/pkg/apis/scheduler/v1beta1/container/resources/image.go new file mode 100644 index 000000000..11e9d1e77 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/image.go @@ -0,0 +1,82 @@ +// +// 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/v1beta1/interfaces" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +var _ interfaces.Container[Image] = &Image{} + +type Image struct { + // Image define image details + Image *string `json:"image,omitempty"` + + // ImagePullPolicy define Image pull policy + // +doc/default: IfNotPresent + ImagePullPolicy *core.PullPolicy `json:"imagePullPolicy,omitempty"` +} + +func (i *Image) Apply(pod *core.PodTemplateSpec, container *core.Container) error { + if i == nil { + return nil + } + + container.Image = util.WithDefault(i.Image) + container.ImagePullPolicy = util.WithDefault(i.ImagePullPolicy) + + return nil +} + +func (i *Image) With(other *Image) *Image { + if i == nil && other == nil { + return nil + } + + if other == nil { + return i.DeepCopy() + } + + return other.DeepCopy() +} + +func (i *Image) GetImage() string { + if i == nil || i.Image == nil { + return "" + } + + return *i.Image +} + +func (i *Image) Validate() error { + if i == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("image", shared.ValidateRequired(i.Image, shared.ValidateImage)), + shared.PrefixResourceErrors("imagePullPolicy", shared.ValidateOptional(i.ImagePullPolicy, shared.ValidatePullPolicy)), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/image_test.go b/pkg/apis/scheduler/v1beta1/container/resources/image_test.go new file mode 100644 index 000000000..47082a9f0 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/image_test.go @@ -0,0 +1,109 @@ +// +// 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 applyImage(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Image) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Image + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Image(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyImage(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Empty(t, container.Image) + require.Empty(t, container.ImagePullPolicy) + require.Len(t, pod.Spec.ImagePullSecrets, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Empty(t, container.Image) + require.Empty(t, container.ImagePullPolicy) + require.Len(t, pod.Spec.ImagePullSecrets, 0) + }) + }) + t.Run("With Image", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &core.Container{}, &Image{ + Image: util.NewType("image"), + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.EqualValues(t, "image", container.Image) + require.Empty(t, container.ImagePullPolicy) + require.Len(t, pod.Spec.ImagePullSecrets, 0) + }) + }) + t.Run("With PS", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &core.Container{}, &Image{ + Image: util.NewType("image"), + ImagePullPolicy: util.NewType(core.PullAlways), + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.EqualValues(t, "image", container.Image) + require.EqualValues(t, core.PullAlways, container.ImagePullPolicy) + }) + }) + t.Run("With PS2", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &core.Container{}, &Image{ + Image: util.NewType("image"), + ImagePullPolicy: util.NewType(core.PullAlways), + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.EqualValues(t, "image", container.Image) + require.EqualValues(t, core.PullAlways, container.ImagePullPolicy) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go b/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go new file mode 100644 index 000000000..0c1e127d5 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/lifecycle.go @@ -0,0 +1,68 @@ +// +// 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/v1beta1/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[Lifecycle] = &Lifecycle{} + +type Lifecycle struct { + // Lifecycle keeps actions that the management system should take in response to container lifecycle events. + // +doc/type: core.Lifecycle + Lifecycle *core.Lifecycle `json:"lifecycle,omitempty"` +} + +func (n *Lifecycle) Apply(_ *core.PodTemplateSpec, template *core.Container) error { + if n == nil { + return nil + } + + template.Lifecycle = n.Lifecycle.DeepCopy() + + return nil +} + +func (n *Lifecycle) With(newResources *Lifecycle) *Lifecycle { + if n == nil && newResources == nil { + return nil + } + + if n == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return n.DeepCopy() + } + + return &Lifecycle{ + Lifecycle: kresources.MergeLifecycle(n.Lifecycle, newResources.Lifecycle), + } +} + +func (n *Lifecycle) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/lifecycle_test.go b/pkg/apis/scheduler/v1beta1/container/resources/lifecycle_test.go new file mode 100644 index 000000000..2d22563f8 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/lifecycle_test.go @@ -0,0 +1,181 @@ +// +// 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" +) + +func applyLifecycle(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Lifecycle) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Lifecycle + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Lifecycle(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyLifecycle(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.Lifecycle) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.Lifecycle) + }) + }) + t.Run("With lifecycles", func(t *testing.T) { + applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{}, &Lifecycle{ + Lifecycle: &core.Lifecycle{ + PostStart: &core.LifecycleHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + PreStop: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.Lifecycle) + + require.NotNil(t, container.Lifecycle.PostStart) + require.NotNil(t, container.Lifecycle.PostStart.Exec) + require.Nil(t, container.Lifecycle.PostStart.HTTPGet) + require.Len(t, container.Lifecycle.PostStart.Exec.Command, 1) + require.EqualValues(t, "test", container.Lifecycle.PostStart.Exec.Command[0]) + + require.NotNil(t, container.Lifecycle.PreStop) + require.Nil(t, container.Lifecycle.PreStop.Exec) + require.NotNil(t, container.Lifecycle.PreStop.HTTPGet) + require.EqualValues(t, "/test", container.Lifecycle.PreStop.HTTPGet.Path) + }) + }) + t.Run("With merge", func(t *testing.T) { + applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{}, + &Lifecycle{ + Lifecycle: &core.Lifecycle{ + PostStart: &core.LifecycleHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + }, + }, + &Lifecycle{ + Lifecycle: &core.Lifecycle{ + PreStop: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.Lifecycle) + + require.NotNil(t, container.Lifecycle.PostStart) + require.NotNil(t, container.Lifecycle.PostStart.Exec) + require.Nil(t, container.Lifecycle.PostStart.HTTPGet) + require.Len(t, container.Lifecycle.PostStart.Exec.Command, 1) + require.EqualValues(t, "test", container.Lifecycle.PostStart.Exec.Command[0]) + + require.NotNil(t, container.Lifecycle.PreStop) + require.Nil(t, container.Lifecycle.PreStop.Exec) + require.NotNil(t, container.Lifecycle.PreStop.HTTPGet) + require.EqualValues(t, "/test", container.Lifecycle.PreStop.HTTPGet.Path) + }) + }) + t.Run("With override", func(t *testing.T) { + applyLifecycle(t, &core.PodTemplateSpec{}, &core.Container{}, &Lifecycle{ + Lifecycle: &core.Lifecycle{ + PostStart: &core.LifecycleHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + PreStop: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + }, + }, &Lifecycle{ + Lifecycle: &core.Lifecycle{ + PostStart: &core.LifecycleHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + PreStop: &core.LifecycleHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.Lifecycle) + + require.NotNil(t, container.Lifecycle.PreStop) + require.NotNil(t, container.Lifecycle.PreStop.Exec) + require.Nil(t, container.Lifecycle.PreStop.HTTPGet) + require.Len(t, container.Lifecycle.PreStop.Exec.Command, 1) + require.EqualValues(t, "test", container.Lifecycle.PreStop.Exec.Command[0]) + + require.NotNil(t, container.Lifecycle.PostStart) + require.Nil(t, container.Lifecycle.PostStart.Exec) + require.NotNil(t, container.Lifecycle.PostStart.HTTPGet) + require.EqualValues(t, "/test", container.Lifecycle.PostStart.HTTPGet.Path) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/networking.go b/pkg/apis/scheduler/v1beta1/container/resources/networking.go new file mode 100644 index 000000000..3f1510d2f --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/networking.go @@ -0,0 +1,86 @@ +// +// 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/v1beta1/interfaces" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[Networking] = &Networking{} + +type Networking struct { + // Ports contains list of ports to expose from the container. Not specifying a port here + // DOES NOT prevent that port from being exposed. Any port which is + // listening on the default "0.0.0.0" address inside a container will be + // accessible from the network. + // +doc/type: []core.ContainerPort + Ports []core.ContainerPort `json:"ports,omitempty"` +} + +func (n *Networking) Apply(pod *core.PodTemplateSpec, template *core.Container) error { + if n == nil { + return nil + } + + for _, port := range n.Ports { + if port.Name == "" { + continue + } + + for _, container := range pod.Spec.Containers { + for _, existingPort := range container.Ports { + if port.Name == existingPort.Name { + return errors.Errorf("Port with name `%s` already exposed in container `%s`", port.Name, container.Name) + } + } + } + } + + obj := n.DeepCopy() + + template.Ports = obj.Ports + + return nil +} + +func (n *Networking) With(newResources *Networking) *Networking { + if n == nil && newResources == nil { + return nil + } + + if n == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return n.DeepCopy() + } + + return &Networking{Ports: kresources.MergeContainerPorts(n.Ports, newResources.Ports...)} +} + +func (n *Networking) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/networking_test.go b/pkg/apis/scheduler/v1beta1/container/resources/networking_test.go new file mode 100644 index 000000000..18bf3d8d8 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/networking_test.go @@ -0,0 +1,140 @@ +// +// 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" +) + +func applyNetworking(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Networking) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Networking + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Networking(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyNetworking(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Ports, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Ports, 0) + }) + }) + t.Run("With Port", func(t *testing.T) { + applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST", + ContainerPort: 1, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Ports, 1) + + require.EqualValues(t, "TEST", container.Ports[0].Name) + require.EqualValues(t, 1, container.Ports[0].ContainerPort) + }) + }) + t.Run("With Port Append", func(t *testing.T) { + applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST", + ContainerPort: 1, + }, + }, + }, &Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST2", + ContainerPort: 2, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Ports, 2) + + require.EqualValues(t, "TEST", container.Ports[0].Name) + require.EqualValues(t, 1, container.Ports[0].ContainerPort) + + require.EqualValues(t, "TEST2", container.Ports[1].Name) + require.EqualValues(t, 2, container.Ports[1].ContainerPort) + }) + }) + t.Run("With Port Update", func(t *testing.T) { + applyNetworking(t, &core.PodTemplateSpec{}, &core.Container{}, &Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST", + ContainerPort: 1, + HostIP: "IP", + }, + }, + }, &Networking{ + Ports: []core.ContainerPort{ + { + Name: "TEST", + ContainerPort: 2, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Ports, 1) + + require.EqualValues(t, "TEST", container.Ports[0].Name) + require.EqualValues(t, 2, container.Ports[0].ContainerPort) + require.EqualValues(t, "", container.Ports[0].HostIP) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/probes.go b/pkg/apis/scheduler/v1beta1/container/resources/probes.go new file mode 100644 index 000000000..7b3c6eb6a --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/probes.go @@ -0,0 +1,87 @@ +// +// 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/v1beta1/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[Probes] = &Probes{} + +type Probes struct { + // LivenessProbe keeps configuration of periodic probe of container liveness. + // Container will be restarted if the probe fails. + // +doc/type: core.Probe + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + LivenessProbe *core.Probe `json:"livenessProbe,omitempty"` + // ReadinessProbe keeps configuration of periodic probe of container service readiness. + // Container will be removed from service endpoints if the probe fails. + // +doc/type: core.Probe + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + ReadinessProbe *core.Probe `json:"readinessProbe,omitempty"` + // StartupProbe indicates that the Pod has successfully initialized. + // If specified, no other probes are executed until this completes successfully. + // If this probe fails, the Pod will be restarted, just as if the livenessProbe failed. + // This can be used to provide different probe parameters at the beginning of a Pod's lifecycle, + // when it might take a long time to load data or warm a cache, than during steady-state operation. + // +doc/type: core.Probe + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes + StartupProbe *core.Probe `json:"startupProbe,omitempty"` +} + +func (n *Probes) Apply(_ *core.PodTemplateSpec, template *core.Container) error { + if n == nil { + return nil + } + + template.LivenessProbe = n.LivenessProbe.DeepCopy() + template.StartupProbe = n.StartupProbe.DeepCopy() + template.ReadinessProbe = n.ReadinessProbe.DeepCopy() + + return nil +} + +func (n *Probes) With(newResources *Probes) *Probes { + if n == nil && newResources == nil { + return nil + } + + if n == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return n.DeepCopy() + } + + return &Probes{ + LivenessProbe: kresources.MergeProbes(n.LivenessProbe, newResources.LivenessProbe), + ReadinessProbe: kresources.MergeProbes(n.ReadinessProbe, newResources.ReadinessProbe), + StartupProbe: kresources.MergeProbes(n.StartupProbe, newResources.StartupProbe), + } +} + +func (n *Probes) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/probes_test.go b/pkg/apis/scheduler/v1beta1/container/resources/probes_test.go new file mode 100644 index 000000000..150af55bb --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/probes_test.go @@ -0,0 +1,271 @@ +// +// 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" +) + +func applyProbes(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Probes) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Probes + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Probes(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyProbes(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.ReadinessProbe) + require.Nil(t, container.LivenessProbe) + require.Nil(t, container.StartupProbe) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyProbes(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.ReadinessProbe) + require.Nil(t, container.LivenessProbe) + require.Nil(t, container.StartupProbe) + }) + }) + t.Run("With Probes", func(t *testing.T) { + applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{ + ReadinessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + InitialDelaySeconds: 10, + }, + LivenessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + InitialDelaySeconds: 15, + }, + StartupProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + GRPC: &core.GRPCAction{ + Port: 33, + }, + }, + InitialDelaySeconds: 20, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.ReadinessProbe) + require.EqualValues(t, 10, container.ReadinessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds) + require.Nil(t, container.ReadinessProbe.HTTPGet) + require.NotNil(t, container.ReadinessProbe.Exec) + require.Nil(t, container.ReadinessProbe.GRPC) + require.Len(t, container.ReadinessProbe.Exec.Command, 1) + require.EqualValues(t, "test", container.ReadinessProbe.Exec.Command[0]) + + require.NotNil(t, container.LivenessProbe) + require.EqualValues(t, 15, container.LivenessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds) + require.NotNil(t, container.LivenessProbe.HTTPGet) + require.Nil(t, container.LivenessProbe.Exec) + require.Nil(t, container.LivenessProbe.GRPC) + require.EqualValues(t, "/test", container.LivenessProbe.HTTPGet.Path) + + require.NotNil(t, container.StartupProbe) + require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.StartupProbe.TimeoutSeconds) + require.Nil(t, container.StartupProbe.HTTPGet) + require.Nil(t, container.StartupProbe.Exec) + require.NotNil(t, container.StartupProbe.GRPC) + require.EqualValues(t, 33, container.StartupProbe.GRPC.Port) + }) + }) + t.Run("With Time Updates", func(t *testing.T) { + applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{ + ReadinessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + InitialDelaySeconds: 10, + }, + LivenessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + InitialDelaySeconds: 15, + }, + StartupProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + GRPC: &core.GRPCAction{ + Port: 33, + }, + }, + InitialDelaySeconds: 20, + }, + }, &Probes{ + ReadinessProbe: &core.Probe{ + InitialDelaySeconds: 60, + }, + LivenessProbe: &core.Probe{ + InitialDelaySeconds: 61, + }, + StartupProbe: &core.Probe{ + TimeoutSeconds: 62, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.ReadinessProbe) + require.EqualValues(t, 60, container.ReadinessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds) + require.Nil(t, container.ReadinessProbe.HTTPGet) + require.NotNil(t, container.ReadinessProbe.Exec) + require.Nil(t, container.ReadinessProbe.GRPC) + require.Len(t, container.ReadinessProbe.Exec.Command, 1) + require.EqualValues(t, "test", container.ReadinessProbe.Exec.Command[0]) + + require.NotNil(t, container.LivenessProbe) + require.EqualValues(t, 61, container.LivenessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds) + require.NotNil(t, container.LivenessProbe.HTTPGet) + require.Nil(t, container.LivenessProbe.Exec) + require.Nil(t, container.LivenessProbe.GRPC) + require.EqualValues(t, "/test", container.LivenessProbe.HTTPGet.Path) + + require.NotNil(t, container.StartupProbe) + require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds) + require.EqualValues(t, 62, container.StartupProbe.TimeoutSeconds) + require.Nil(t, container.StartupProbe.HTTPGet) + require.Nil(t, container.StartupProbe.Exec) + require.NotNil(t, container.StartupProbe.GRPC) + require.EqualValues(t, 33, container.StartupProbe.GRPC.Port) + }) + }) + t.Run("With Exec Updates", func(t *testing.T) { + applyProbes(t, &core.PodTemplateSpec{}, &core.Container{}, &Probes{ + ReadinessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + InitialDelaySeconds: 10, + }, + LivenessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + InitialDelaySeconds: 15, + }, + StartupProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + GRPC: &core.GRPCAction{ + Port: 33, + }, + }, + InitialDelaySeconds: 20, + }, + }, &Probes{ + ReadinessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + GRPC: &core.GRPCAction{ + Port: 33, + }, + }, + }, + LivenessProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + Exec: &core.ExecAction{ + Command: []string{"test"}, + }, + }, + }, + StartupProbe: &core.Probe{ + ProbeHandler: core.ProbeHandler{ + HTTPGet: &core.HTTPGetAction{ + Path: "/test", + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.ReadinessProbe) + require.EqualValues(t, 10, container.ReadinessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.ReadinessProbe.TimeoutSeconds) + require.Nil(t, container.ReadinessProbe.HTTPGet) + require.Nil(t, container.ReadinessProbe.Exec) + require.NotNil(t, container.ReadinessProbe.GRPC) + require.EqualValues(t, 33, container.ReadinessProbe.GRPC.Port) + + require.NotNil(t, container.LivenessProbe) + require.EqualValues(t, 15, container.LivenessProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.LivenessProbe.TimeoutSeconds) + require.Nil(t, container.LivenessProbe.HTTPGet) + require.NotNil(t, container.LivenessProbe.Exec) + require.Nil(t, container.LivenessProbe.GRPC) + require.Len(t, container.LivenessProbe.Exec.Command, 1) + require.EqualValues(t, "test", container.LivenessProbe.Exec.Command[0]) + + require.NotNil(t, container.StartupProbe) + require.EqualValues(t, 20, container.StartupProbe.InitialDelaySeconds) + require.EqualValues(t, 0, container.StartupProbe.TimeoutSeconds) + require.NotNil(t, container.StartupProbe.HTTPGet) + require.Nil(t, container.StartupProbe.Exec) + require.Nil(t, container.StartupProbe.GRPC) + require.EqualValues(t, "/test", container.StartupProbe.HTTPGet.Path) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/resources.go b/pkg/apis/scheduler/v1beta1/container/resources/resources.go new file mode 100644 index 000000000..e6d45cff2 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/resources.go @@ -0,0 +1,83 @@ +// +// 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/v1beta1/interfaces" + "github.com/arangodb/kube-arangodb/pkg/util" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[Resources] = &Resources{} + +type Resources struct { + // Resources holds resource requests & limits for container + // +doc/type: core.ResourceRequirements + // +doc/link: Documentation of core.ResourceRequirements|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core + Resources *core.ResourceRequirements `json:"resources,omitempty"` +} + +func (r *Resources) Apply(_ *core.PodTemplateSpec, template *core.Container) error { + if r == nil { + return nil + } + + res := r.GetResources() + + template.Resources.Limits = kresources.UpscaleContainerResourceList(template.Resources.Limits, res.Limits) + template.Resources.Requests = kresources.UpscaleContainerResourceList(template.Resources.Requests, res.Requests) + + return nil +} + +func (r *Resources) With(newResources *Resources) *Resources { + if r == nil && newResources == nil { + return nil + } + + if r == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return r.DeepCopy() + } + + return &Resources{Resources: util.NewType(kresources.MergeContainerResource(r.GetResources(), newResources.GetResources()))} +} + +func (r *Resources) GetResources() core.ResourceRequirements { + if r == nil || r.Resources == nil { + return core.ResourceRequirements{} + } + + local := r.Resources.DeepCopy() + + local.Limits = kresources.UpscaleOptionalContainerResourceList(local.Limits, local.Requests) + + return *local +} + +func (r *Resources) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/resources_test.go b/pkg/apis/scheduler/v1beta1/container/resources/resources_test.go new file mode 100644 index 000000000..91941b66c --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/resources_test.go @@ -0,0 +1,210 @@ +// +// 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" + "k8s.io/apimachinery/pkg/api/resource" +) + +func applyResources(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Resources) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Resources + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Resources(t *testing.T) { + v1Mi := resource.MustParse("1Mi") + v8Mi := resource.MustParse("8Mi") + v0 := resource.MustParse("0") + + t.Run("With Nil", func(t *testing.T) { + applyResources(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Empty(t, container.Resources) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Empty(t, container.Resources) + }) + }) + t.Run("Add", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{}, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Resources.Limits, 1) + require.Contains(t, container.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Limits[core.ResourceCPU]) + + require.Len(t, container.Resources.Requests, 1) + require.Contains(t, container.Resources.Requests, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Requests[core.ResourceCPU]) + }) + }) + t.Run("Add New One", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{}, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + }, + }, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceMemory: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceMemory: v1Mi, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Resources.Limits, 2) + require.Contains(t, container.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Limits[core.ResourceCPU]) + require.Contains(t, container.Resources.Limits, core.ResourceMemory) + require.EqualValues(t, v1Mi, container.Resources.Limits[core.ResourceMemory]) + + require.Len(t, container.Resources.Requests, 2) + require.Contains(t, container.Resources.Requests, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Requests[core.ResourceCPU]) + require.Contains(t, container.Resources.Requests, core.ResourceMemory) + require.EqualValues(t, v1Mi, container.Resources.Requests[core.ResourceMemory]) + }) + }) + t.Run("Update", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{}, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + }, + }, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v8Mi, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Resources.Limits, 1) + require.Contains(t, container.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, v8Mi, container.Resources.Limits[core.ResourceCPU]) + + require.Len(t, container.Resources.Requests, 1) + require.Contains(t, container.Resources.Requests, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Requests[core.ResourceCPU]) + }) + }) + t.Run("Remove", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{}, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + }, + }, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v0, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Resources.Limits, 0) + + require.Len(t, container.Resources.Requests, 1) + require.Contains(t, container.Resources.Requests, core.ResourceCPU) + require.EqualValues(t, v1Mi, container.Resources.Requests[core.ResourceCPU]) + }) + }) + t.Run("Upscale", func(t *testing.T) { + applyResources(t, &core.PodTemplateSpec{}, &core.Container{}, &Resources{ + Resources: &core.ResourceRequirements{ + Limits: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + Requests: core.ResourceList{ + core.ResourceCPU: v1Mi, + }, + }, + }, &Resources{ + Resources: &core.ResourceRequirements{ + Requests: core.ResourceList{ + core.ResourceCPU: v8Mi, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.Resources.Limits, 1) + require.Contains(t, container.Resources.Limits, core.ResourceCPU) + require.EqualValues(t, v8Mi, container.Resources.Limits[core.ResourceCPU]) + + require.Len(t, container.Resources.Requests, 1) + require.Contains(t, container.Resources.Requests, core.ResourceCPU) + require.EqualValues(t, v8Mi, container.Resources.Requests[core.ResourceCPU]) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/security.go b/pkg/apis/scheduler/v1beta1/container/resources/security.go new file mode 100644 index 000000000..84a59e995 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/security.go @@ -0,0 +1,70 @@ +// +// 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/v1beta1/interfaces" +) + +var _ interfaces.Container[Security] = &Security{} + +type Security struct { + // SecurityContext holds container-level security attributes and common container settings. + // +doc/type: core.SecurityContext + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + SecurityContext *core.SecurityContext `json:"securityContext,omitempty"` +} + +func (s *Security) Apply(_ *core.PodTemplateSpec, template *core.Container) error { + if s == nil { + return nil + } + + template.SecurityContext = s.SecurityContext.DeepCopy() + + return nil +} + +func (s *Security) With(other *Security) *Security { + if s == nil && other == nil { + return nil + } + + if other == nil { + return s.DeepCopy() + } + + return other.DeepCopy() +} + +func (s *Security) GetSecurityContext() core.SecurityContext { + if s == nil { + return core.SecurityContext{} + } + + return *s.SecurityContext +} + +func (s *Security) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/security_test.go b/pkg/apis/scheduler/v1beta1/container/resources/security_test.go new file mode 100644 index 000000000..02dc8e154 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/security_test.go @@ -0,0 +1,96 @@ +// +// 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 applySecurity(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*Security) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *Security + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_Security(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applySecurity(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.SecurityContext) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applySecurity(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Nil(t, container.SecurityContext) + }) + }) + t.Run("Pick Always Latest Not Nil", func(t *testing.T) { + applySecurity(t, &core.PodTemplateSpec{}, &core.Container{}, &Security{ + SecurityContext: &core.SecurityContext{ + RunAsUser: util.NewType[int64](20), + RunAsGroup: util.NewType[int64](30), + }, + }, &Security{ + SecurityContext: &core.SecurityContext{ + RunAsGroup: util.NewType[int64](60), + }, + }, nil)(func(t *testing.T, _ *core.PodTemplateSpec, container *core.Container) { + require.NotNil(t, container.SecurityContext) + + require.Nil(t, container.SecurityContext.RunAsUser) + require.NotNil(t, container.SecurityContext.RunAsGroup) + require.EqualValues(t, 60, *container.SecurityContext.RunAsGroup) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go b/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go new file mode 100644 index 000000000..a99e0f598 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts.go @@ -0,0 +1,70 @@ +// +// 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/v1beta1/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Container[VolumeMounts] = &VolumeMounts{} + +type VolumeMounts struct { + // VolumeMounts keeps list of pod volumes to mount into the container's filesystem. + // +doc/type: []core.VolumeMount + VolumeMounts []core.VolumeMount `json:"volumeMounts,omitempty"` +} + +func (v *VolumeMounts) Apply(_ *core.PodTemplateSpec, container *core.Container) error { + if v == nil { + return nil + } + + obj := v.DeepCopy() + + container.VolumeMounts = kresources.MergeVolumeMounts(container.VolumeMounts, obj.VolumeMounts...) + + return nil +} + +func (v *VolumeMounts) With(other *VolumeMounts) *VolumeMounts { + if v == nil && other == nil { + return nil + } + + if v == nil { + return other.DeepCopy() + } + + if other == nil { + return v.DeepCopy() + } + + return &VolumeMounts{ + VolumeMounts: kresources.MergeVolumeMounts(v.VolumeMounts, other.VolumeMounts...), + } +} + +func (v *VolumeMounts) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts_test.go b/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts_test.go new file mode 100644 index 000000000..1de913554 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/volume_mounts_test.go @@ -0,0 +1,145 @@ +// +// 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" +) + +func applyVolumeMounts(t *testing.T, template *core.PodTemplateSpec, container *core.Container, ns ...*VolumeMounts) func(in func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container)) { + var i *VolumeMounts + + 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{} + } + + container = container.DeepCopy() + if container == nil { + container = &core.Container{} + } + + template.Spec.Containers = append(template.Spec.Containers, *container) + + container = &template.Spec.Containers[0] + + require.NoError(t, i.Apply(template, container)) + + return func(in func(t *testing.T, spec *core.PodTemplateSpec, container *core.Container)) { + t.Run("Validate", func(t *testing.T) { + in(t, template, container) + }) + } +} + +func Test_VolumeMounts(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyVolumeMounts(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.VolumeMounts, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{})(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.VolumeMounts, 0) + }) + }) + t.Run("Add mount", func(t *testing.T) { + applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{ + VolumeMounts: []core.VolumeMount{ + { + Name: "test", + ReadOnly: false, + MountPath: "/var/test", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.VolumeMounts, 1) + + require.EqualValues(t, "test", container.VolumeMounts[0].Name) + require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath) + require.False(t, container.VolumeMounts[0].ReadOnly) + }) + }) + t.Run("Append mount", func(t *testing.T) { + applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{ + VolumeMounts: []core.VolumeMount{ + { + Name: "test", + ReadOnly: false, + MountPath: "/var/test", + }, + { + Name: "test2", + ReadOnly: true, + MountPath: "/var/test2", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.VolumeMounts, 2) + + require.EqualValues(t, "test", container.VolumeMounts[0].Name) + require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath) + require.False(t, container.VolumeMounts[0].ReadOnly) + + require.EqualValues(t, "test2", container.VolumeMounts[1].Name) + require.EqualValues(t, "/var/test2", container.VolumeMounts[1].MountPath) + require.True(t, container.VolumeMounts[1].ReadOnly) + }) + }) + t.Run("Second mount", func(t *testing.T) { + applyVolumeMounts(t, &core.PodTemplateSpec{}, &core.Container{}, &VolumeMounts{ + VolumeMounts: []core.VolumeMount{ + { + Name: "test", + ReadOnly: false, + MountPath: "/var/test", + }, + { + Name: "test", + ReadOnly: true, + MountPath: "/var/test2", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, container *core.Container) { + require.Len(t, container.VolumeMounts, 2) + + require.EqualValues(t, "test", container.VolumeMounts[0].Name) + require.EqualValues(t, "/var/test", container.VolumeMounts[0].MountPath) + require.False(t, container.VolumeMounts[0].ReadOnly) + + require.EqualValues(t, "test", container.VolumeMounts[1].Name) + require.EqualValues(t, "/var/test2", container.VolumeMounts[1].MountPath) + require.True(t, container.VolumeMounts[1].ReadOnly) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/container/resources/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/container/resources/zz_generated.deepcopy.go new file mode 100644 index 000000000..1a201856b --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/resources/zz_generated.deepcopy.go @@ -0,0 +1,250 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package resources + +import ( + v1 "k8s.io/api/core/v1" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Core) DeepCopyInto(out *Core) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Core. +func (in *Core) DeepCopy() *Core { + if in == nil { + return nil + } + out := new(Core) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Environments) DeepCopyInto(out *Environments) { + *out = *in + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.EnvFrom != nil { + in, out := &in.EnvFrom, &out.EnvFrom + *out = make([]v1.EnvFromSource, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Environments. +func (in *Environments) DeepCopy() *Environments { + if in == nil { + return nil + } + out := new(Environments) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Image) DeepCopyInto(out *Image) { + *out = *in + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(string) + **out = **in + } + if in.ImagePullPolicy != nil { + in, out := &in.ImagePullPolicy, &out.ImagePullPolicy + *out = new(v1.PullPolicy) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image. +func (in *Image) DeepCopy() *Image { + if in == nil { + return nil + } + out := new(Image) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Lifecycle) DeepCopyInto(out *Lifecycle) { + *out = *in + if in.Lifecycle != nil { + in, out := &in.Lifecycle, &out.Lifecycle + *out = new(v1.Lifecycle) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Lifecycle. +func (in *Lifecycle) DeepCopy() *Lifecycle { + if in == nil { + return nil + } + out := new(Lifecycle) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Networking) DeepCopyInto(out *Networking) { + *out = *in + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = make([]v1.ContainerPort, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Networking. +func (in *Networking) DeepCopy() *Networking { + if in == nil { + return nil + } + out := new(Networking) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Probes) DeepCopyInto(out *Probes) { + *out = *in + if in.LivenessProbe != nil { + in, out := &in.LivenessProbe, &out.LivenessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.ReadinessProbe != nil { + in, out := &in.ReadinessProbe, &out.ReadinessProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + if in.StartupProbe != nil { + in, out := &in.StartupProbe, &out.StartupProbe + *out = new(v1.Probe) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Probes. +func (in *Probes) DeepCopy() *Probes { + if in == nil { + return nil + } + out := new(Probes) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resources) DeepCopyInto(out *Resources) { + *out = *in + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(v1.ResourceRequirements) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. +func (in *Resources) DeepCopy() *Resources { + if in == nil { + return nil + } + out := new(Resources) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Security) DeepCopyInto(out *Security) { + *out = *in + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(v1.SecurityContext) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Security. +func (in *Security) DeepCopy() *Security { + if in == nil { + return nil + } + out := new(Security) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VolumeMounts) DeepCopyInto(out *VolumeMounts) { + *out = *in + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]v1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VolumeMounts. +func (in *VolumeMounts) DeepCopy() *VolumeMounts { + if in == nil { + return nil + } + out := new(VolumeMounts) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/scheduler/v1beta1/container/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/container/zz_generated.deepcopy.go new file mode 100644 index 000000000..49e97e42a --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/container/zz_generated.deepcopy.go @@ -0,0 +1,139 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package container + +import ( + resources "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Container) DeepCopyInto(out *Container) { + *out = *in + if in.Core != nil { + in, out := &in.Core, &out.Core + *out = new(resources.Core) + (*in).DeepCopyInto(*out) + } + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(resources.Security) + (*in).DeepCopyInto(*out) + } + if in.Environments != nil { + in, out := &in.Environments, &out.Environments + *out = new(resources.Environments) + (*in).DeepCopyInto(*out) + } + if in.Image != nil { + in, out := &in.Image, &out.Image + *out = new(resources.Image) + (*in).DeepCopyInto(*out) + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(resources.Resources) + (*in).DeepCopyInto(*out) + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = new(resources.VolumeMounts) + (*in).DeepCopyInto(*out) + } + if in.Probes != nil { + in, out := &in.Probes, &out.Probes + *out = new(resources.Probes) + (*in).DeepCopyInto(*out) + } + if in.Networking != nil { + in, out := &in.Networking, &out.Networking + *out = new(resources.Networking) + (*in).DeepCopyInto(*out) + } + if in.Lifecycle != nil { + in, out := &in.Lifecycle, &out.Lifecycle + *out = new(resources.Lifecycle) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Container. +func (in *Container) DeepCopy() *Container { + if in == nil { + return nil + } + out := new(Container) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in Containers) DeepCopyInto(out *Containers) { + { + in := &in + *out = make(Containers, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Containers. +func (in Containers) DeepCopy() Containers { + if in == nil { + return nil + } + out := new(Containers) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Generic) DeepCopyInto(out *Generic) { + *out = *in + if in.Environments != nil { + in, out := &in.Environments, &out.Environments + *out = new(resources.Environments) + (*in).DeepCopyInto(*out) + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = new(resources.VolumeMounts) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Generic. +func (in *Generic) DeepCopy() *Generic { + if in == nil { + return nil + } + out := new(Generic) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/scheduler/v1beta1/doc.go b/pkg/apis/scheduler/v1beta1/doc.go new file mode 100644 index 000000000..f1b026431 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=scheduler.arangodb.com +package v1beta1 diff --git a/pkg/apis/scheduler/v1beta1/interfaces/interfaces.go b/pkg/apis/scheduler/v1beta1/interfaces/interfaces.go new file mode 100644 index 000000000..3d3e2004d --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/interfaces/interfaces.go @@ -0,0 +1,38 @@ +// +// 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 interfaces + +import core "k8s.io/api/core/v1" + +type Core[T any] interface { + With(T) T + Validate() error +} + +type Container[T any] interface { + Core[*T] + Apply(template *core.PodTemplateSpec, container *core.Container) error +} + +type Pod[T any] interface { + Core[*T] + Apply(template *core.PodTemplateSpec) error +} diff --git a/pkg/apis/scheduler/v1beta1/pod/definition.go b/pkg/apis/scheduler/v1beta1/pod/definition.go new file mode 100644 index 000000000..5c3ab9713 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/definition.go @@ -0,0 +1,165 @@ +// +// 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 pod + +import ( + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/interfaces" + schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod/resources" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +var _ interfaces.Pod[Pod] = &Pod{} + +type Pod struct { + // Metadata keeps the metadata settings for Pod + *schedulerPodResourcesApi.Metadata `json:",inline"` + + // Image keeps the image information + *schedulerPodResourcesApi.Image `json:",inline"` + + // Scheduling keeps the scheduling information + *schedulerPodResourcesApi.Scheduling `json:",inline"` + + // Namespace keeps the Container layer Kernel namespace configuration + *schedulerPodResourcesApi.Namespace `json:",inline"` + + // Security keeps the security settings for Pod + *schedulerPodResourcesApi.Security `json:",inline"` + + // 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 { + if a == nil && other == nil { + return nil + } + + if a == nil { + return other.DeepCopy() + } + + if other == nil { + return a.DeepCopy() + } + + return &Pod{ + Scheduling: a.Scheduling.With(other.Scheduling), + Image: a.Image.With(other.Image), + 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), + } +} + +func (a *Pod) Apply(template *core.PodTemplateSpec) error { + if a == nil { + return nil + } + + return shared.WithErrors( + a.Scheduling.Apply(template), + a.Image.Apply(template), + a.Namespace.Apply(template), + a.Security.Apply(template), + a.Volumes.Apply(template), + a.ServiceAccount.Apply(template), + a.Metadata.Apply(template), + ) +} + +func (a *Pod) GetSecurity() *schedulerPodResourcesApi.Security { + if a == nil { + return nil + } + + return a.Security +} + +func (a *Pod) GetImage() *schedulerPodResourcesApi.Image { + if a == nil { + return nil + } + + return a.Image +} + +func (a *Pod) GetScheduling() *schedulerPodResourcesApi.Scheduling { + if a == nil { + return nil + } + + return a.Scheduling +} + +func (a *Pod) GetContainerNamespace() *schedulerPodResourcesApi.Namespace { + if a == nil { + return nil + } + + return a.Namespace +} + +func (a *Pod) GetVolumes() *schedulerPodResourcesApi.Volumes { + if a == nil { + return nil + } + + 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 + } + return shared.WithErrors( + a.Scheduling.Validate(), + a.Image.Validate(), + a.Namespace.Validate(), + a.Security.Validate(), + a.Volumes.Validate(), + a.ServiceAccount.Validate(), + a.Metadata.Validate(), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/definition_test.go b/pkg/apis/scheduler/v1beta1/pod/definition_test.go new file mode 100644 index 000000000..3368289b4 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/definition_test.go @@ -0,0 +1,239 @@ +// +// 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 pod + +import ( + "testing" + + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/yaml" + + schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod/resources" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func applyPod(t *testing.T, template *core.PodTemplateSpec, ns ...*Pod) func(in func(t *testing.T, pod *core.PodTemplateSpec, podData *Pod)) { + var i *Pod + + 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, podData *Pod)) { + t.Run("Validate", func(t *testing.T) { + if i != nil { + in(t, template, i) + } else { + in(t, template, &Pod{}) + } + }) + } +} + +func applyPodYAML(t *testing.T, template *core.PodTemplateSpec, ns ...string) func(in func(t *testing.T, pod *core.PodTemplateSpec, podData *Pod)) { + elements := make([]*Pod, len(ns)) + + for id := range ns { + var p Pod + require.NoError(t, yaml.Unmarshal([]byte(ns[id]), &p)) + elements[id] = p.DeepCopy() + } + + return applyPod(t, template, elements...) +} + +func Test_Pod(t *testing.T) { + t.Run("Nil", func(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) { + applyPod(t, &core.PodTemplateSpec{}, &Pod{ + Security: &schedulerPodResourcesApi.Security{ + PodSecurityContext: &core.PodSecurityContext{ + RunAsGroup: util.NewType[int64](50), + }, + }, + }, &Pod{ + Scheduling: &schedulerPodResourcesApi.Scheduling{ + NodeSelector: map[string]string{ + "A": "B", + }, + }, + }, &Pod{ + Scheduling: &schedulerPodResourcesApi.Scheduling{ + NodeSelector: map[string]string{ + "A1": "B1", + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec, _ *Pod) { + require.NotNil(t, pod.Spec.SecurityContext) + require.NotNil(t, pod.Spec.SecurityContext.RunAsGroup) + require.EqualValues(t, 50, *pod.Spec.SecurityContext.RunAsGroup) + + require.NotNil(t, pod.Spec.NodeSelector) + require.Len(t, pod.Spec.NodeSelector, 2) + + require.Contains(t, pod.Spec.NodeSelector, "A") + require.Equal(t, "B", pod.Spec.NodeSelector["A"]) + + require.Contains(t, pod.Spec.NodeSelector, "A1") + require.Equal(t, "B1", pod.Spec.NodeSelector["A1"]) + }) + }) +} + +func Test_Pod_YAML(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyPodYAML(t, nil)(func(t *testing.T, _ *core.PodTemplateSpec, spec *Pod) { + 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) { + applyPodYAML(t, nil, ` +--- + +nodeSelector: + A: B +`)(func(t *testing.T, _ *core.PodTemplateSpec, spec *Pod) { + require.Nil(t, spec.Security) + require.NotNil(t, spec.Scheduling) + require.Len(t, spec.Scheduling.NodeSelector, 1) + require.Contains(t, spec.Scheduling.NodeSelector, "A") + require.Equal(t, "B", spec.Scheduling.NodeSelector["A"]) + require.Nil(t, spec.Namespace) + }) + }) + t.Run("Merge nodeSelector", func(t *testing.T) { + applyPodYAML(t, nil, ` +--- + +nodeSelector: + A: B +`, ` +--- + +nodeSelector: + C: D +`)(func(t *testing.T, _ *core.PodTemplateSpec, spec *Pod) { + require.Nil(t, spec.Security) + require.NotNil(t, spec.Scheduling) + require.Len(t, spec.Scheduling.NodeSelector, 2) + require.Contains(t, spec.Scheduling.NodeSelector, "A") + require.Equal(t, "B", spec.Scheduling.NodeSelector["A"]) + require.Contains(t, spec.Scheduling.NodeSelector, "C") + require.Equal(t, "D", spec.Scheduling.NodeSelector["C"]) + require.Nil(t, spec.Namespace) + }) + }) + t.Run("Add multiple values", func(t *testing.T) { + applyPodYAML(t, nil, ` +--- + +nodeSelector: + A: B +podSecurityContext: + runAsUser: 10 +hostPID: true +serviceAccountName: test +labels: + A: B +volumes: + - name: test + emptyDir: {} +`)(func(t *testing.T, pod *core.PodTemplateSpec, spec *Pod) { + // Spec + require.NotNil(t, spec.Security) + require.NotNil(t, spec.Security.PodSecurityContext) + require.NotNil(t, spec.Security.PodSecurityContext.RunAsUser) + require.EqualValues(t, 10, *spec.Security.PodSecurityContext.RunAsUser) + require.NotNil(t, spec.Scheduling) + require.Len(t, spec.Scheduling.NodeSelector, 1) + require.Contains(t, spec.Scheduling.NodeSelector, "A") + require.Equal(t, "B", spec.Scheduling.NodeSelector["A"]) + require.NotNil(t, spec.Namespace) + require.NotNil(t, spec.Namespace.HostPID) + require.True(t, *spec.Namespace.HostPID) + require.NotNil(t, spec.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) + require.NotNil(t, pod.Spec.SecurityContext.RunAsUser) + require.EqualValues(t, 10, *pod.Spec.SecurityContext.RunAsUser) + require.NotNil(t, pod.Spec.NodeSelector) + require.Len(t, pod.Spec.NodeSelector, 1) + require.Contains(t, pod.Spec.NodeSelector, "A") + require.Equal(t, "B", pod.Spec.NodeSelector["A"]) + require.Nil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.HostPID) + require.True(t, pod.Spec.HostPID) + 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/v1beta1/pod/doc.go b/pkg/apis/scheduler/v1beta1/pod/doc.go new file mode 100644 index 000000000..7978454ce --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=scheduler.arangodb.com +package pod diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/doc.go b/pkg/apis/scheduler/v1beta1/pod/resources/doc.go new file mode 100644 index 000000000..43be1f3fb --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/doc.go @@ -0,0 +1,23 @@ +// +// 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 +// + +// +k8s:deepcopy-gen=package +// +groupName=scheduler.arangodb.com +package resources diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/image.go b/pkg/apis/scheduler/v1beta1/pod/resources/image.go new file mode 100644 index 000000000..cbf17e01c --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/image.go @@ -0,0 +1,87 @@ +// +// 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/v1beta1/interfaces" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +type ImagePullSecrets []string + +var _ interfaces.Pod[Image] = &Image{} + +type Image struct { + // ImagePullSecrets define Secrets used to pull Image from registry + ImagePullSecrets ImagePullSecrets `json:"imagePullSecrets,omitempty"` +} + +func (i *Image) Apply(pod *core.PodTemplateSpec) error { + if i == nil { + return nil + } + + for _, secret := range i.ImagePullSecrets { + if hasImagePullSecret(pod.Spec.ImagePullSecrets, secret) { + continue + } + + pod.Spec.ImagePullSecrets = append(pod.Spec.ImagePullSecrets, core.LocalObjectReference{ + Name: secret, + }) + } + + return nil +} + +func (i *Image) With(other *Image) *Image { + if i == nil && other == nil { + return nil + } + + if other == nil { + return i.DeepCopy() + } + + return other.DeepCopy() +} + +func (i *Image) Validate() error { + if i == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("pullSecrets", shared.ValidateList(i.ImagePullSecrets, shared.ValidateResourceName)), + ) +} + +func hasImagePullSecret(secrets []core.LocalObjectReference, secret string) bool { + for _, sec := range secrets { + if sec.Name == secret { + return true + } + } + + return false +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/image_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/image_test.go new file mode 100644 index 000000000..0c44770b2 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/image_test.go @@ -0,0 +1,88 @@ +// +// 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" +) + +func applyImage(t *testing.T, template *core.PodTemplateSpec, ns ...*Image) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Image + + 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_Image(t *testing.T) { + t.Run("With Nil", func(t *testing.T) { + applyImage(t, nil, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.ImagePullSecrets, 0) + }) + }) + t.Run("With Empty", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.ImagePullSecrets, 0) + }) + }) + t.Run("With PS", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &Image{ + ImagePullSecrets: []string{ + "secret", + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.ImagePullSecrets, 1) + require.Equal(t, "secret", pod.Spec.ImagePullSecrets[0].Name) + }) + }) + t.Run("With PS2", func(t *testing.T) { + applyImage(t, &core.PodTemplateSpec{}, &Image{ + ImagePullSecrets: []string{ + "secret", + "secret", + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.ImagePullSecrets, 1) + require.Equal(t, "secret", pod.Spec.ImagePullSecrets[0].Name) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/metadata.go b/pkg/apis/scheduler/v1beta1/pod/resources/metadata.go new file mode 100644 index 000000000..674fb8278 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/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/v1beta1/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/v1beta1/pod/resources/metadata_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/metadata_test.go new file mode 100644 index 000000000..ad4558078 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/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/v1beta1/pod/resources/namespace.go b/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go new file mode 100644 index 000000000..fd038c988 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/namespace.go @@ -0,0 +1,123 @@ +// +// 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/v1beta1/interfaces" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +var _ interfaces.Pod[Namespace] = &Namespace{} + +type Namespace struct { + // HostNetwork requests Host network for this pod. Use the host's network namespace. + // If this option is set, the ports that will be used must be specified. + // +doc/default: false + HostNetwork *bool `json:"hostNetwork,omitempty" protobuf:"varint,11,opt,name=hostNetwork"` + // HostPID define to use the host's pid namespace. + // +doc/default: false + HostPID *bool `json:"hostPID,omitempty" protobuf:"varint,12,opt,name=hostPID"` + // HostIPC defines to use the host's ipc namespace. + // +doc/default: false + HostIPC *bool `json:"hostIPC,omitempty" protobuf:"varint,13,opt,name=hostIPC"` + // ShareProcessNamespace defines to share a single process namespace between all of the containers in a pod. + // When this is set containers will be able to view and signal processes from other containers + // in the same pod, and the first process in each container will not be assigned PID 1. + // HostPID and ShareProcessNamespace cannot both be set. + // +doc/default: false + ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty" protobuf:"varint,27,opt,name=shareProcessNamespace"` +} + +func (n *Namespace) Apply(template *core.PodTemplateSpec) error { + if n == nil { + return nil + } + + template.Spec.HostNetwork = util.WithDefault(n.HostNetwork) + template.Spec.HostPID = util.WithDefault(n.HostPID) + template.Spec.HostIPC = util.WithDefault(n.HostIPC) + if v := n.ShareProcessNamespace; v != nil { + template.Spec.ShareProcessNamespace = util.NewType(*v) + } else { + template.Spec.ShareProcessNamespace = nil + } + + return nil +} + +func (n *Namespace) GetHostNetwork() *bool { + if n == nil || n.HostNetwork == nil { + return nil + } + + return n.HostNetwork +} + +func (n *Namespace) GetHostPID() *bool { + if n == nil || n.HostPID == nil { + return nil + } + + return n.HostPID +} + +func (n *Namespace) GetHostIPC() *bool { + if n == nil || n.HostIPC == nil { + return nil + } + + return n.HostIPC +} + +func (n *Namespace) GetShareProcessNamespace() *bool { + if n == nil { + return nil + } + + return n.ShareProcessNamespace +} + +func (n *Namespace) With(other *Namespace) *Namespace { + if n == nil && other == nil { + return nil + } + + if n == nil { + return other.DeepCopy() + } + + if other == nil { + return n.DeepCopy() + } + + return &Namespace{ + HostNetwork: util.First(other.HostNetwork, n.HostNetwork), + HostPID: util.First(other.HostPID, n.HostPID), + HostIPC: util.First(other.HostIPC, n.HostIPC), + ShareProcessNamespace: util.First(other.ShareProcessNamespace, n.ShareProcessNamespace), + } +} + +func (n *Namespace) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/namespace_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/namespace_test.go new file mode 100644 index 000000000..9e00c2239 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/namespace_test.go @@ -0,0 +1,136 @@ +// +// 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/assert" + "github.com/stretchr/testify/require" + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func applyNamespace(t *testing.T, template *core.PodTemplateSpec, ns ...*Namespace) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Namespace + + 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_Namespace(t *testing.T) { + t.Run("Apply", func(t *testing.T) { + applyNamespace(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.False(t, pod.Spec.HostNetwork) + assert.False(t, pod.Spec.HostPID) + assert.False(t, pod.Spec.HostIPC) + assert.Nil(t, pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply nil", func(t *testing.T) { + applyNamespace(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.False(t, pod.Spec.HostNetwork) + assert.False(t, pod.Spec.HostPID) + assert.False(t, pod.Spec.HostIPC) + assert.Nil(t, pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply with nils", func(t *testing.T) { + applyNamespace(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.False(t, pod.Spec.HostNetwork) + assert.False(t, pod.Spec.HostPID) + assert.False(t, pod.Spec.HostIPC) + assert.Nil(t, pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply with template", func(t *testing.T) { + applyNamespace(t, nil, &Namespace{ + HostPID: util.NewType(true), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.False(t, pod.Spec.HostNetwork) + assert.True(t, pod.Spec.HostPID) + assert.False(t, pod.Spec.HostIPC) + assert.Nil(t, pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply with template overrides", func(t *testing.T) { + applyNamespace(t, nil, &Namespace{ + HostPID: util.NewType(true), + }, &Namespace{ + HostNetwork: util.NewType(true), + }, &Namespace{ + HostPID: util.NewType(false), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.True(t, pod.Spec.HostNetwork) + assert.False(t, pod.Spec.HostPID) + assert.False(t, pod.Spec.HostIPC) + assert.Nil(t, pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply with all", func(t *testing.T) { + applyNamespace(t, nil, &Namespace{ + HostNetwork: util.NewType(true), + HostPID: util.NewType(true), + HostIPC: util.NewType(true), + ShareProcessNamespace: util.NewType(true), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.True(t, pod.Spec.HostNetwork) + assert.True(t, pod.Spec.HostPID) + assert.True(t, pod.Spec.HostIPC) + assert.NotNil(t, pod.Spec.ShareProcessNamespace) + assert.True(t, *pod.Spec.ShareProcessNamespace) + }) + }) + t.Run("Apply false", func(t *testing.T) { + applyNamespace(t, nil, &Namespace{ + HostNetwork: util.NewType(true), + HostPID: util.NewType(true), + HostIPC: util.NewType(true), + ShareProcessNamespace: util.NewType(false), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + assert.True(t, pod.Spec.HostNetwork) + assert.True(t, pod.Spec.HostPID) + assert.True(t, pod.Spec.HostIPC) + assert.NotNil(t, pod.Spec.ShareProcessNamespace) + assert.False(t, *pod.Spec.ShareProcessNamespace) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go b/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go new file mode 100644 index 000000000..945044104 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/scheduling.go @@ -0,0 +1,166 @@ +// +// 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/v1beta1/interfaces" + "github.com/arangodb/kube-arangodb/pkg/util" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/tolerations" +) + +type Tolerations []core.Toleration + +var _ interfaces.Pod[Scheduling] = &Scheduling{} + +type Scheduling struct { + // NodeSelector is a selector that must be true for the workload to fit on a node. + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + NodeSelector map[string]string `json:"nodeSelector,omitempty"` + + // Affinity defines scheduling constraints for workload + // +doc/type: core.Affinity + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity + Affinity *core.Affinity `json:"affinity,omitempty"` + + // Tolerations defines tolerations + // +doc/type: []core.Toleration + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/ + Tolerations Tolerations `json:"tolerations,omitempty"` + + // SchedulerName specifies, the pod will be dispatched by specified scheduler. + // If not specified, the pod will be dispatched by default scheduler. + // +doc/default: "" + SchedulerName *string `json:"schedulerName,omitempty"` +} + +func (s *Scheduling) Apply(template *core.PodTemplateSpec) error { + if s == nil { + return nil + } + + if len(s.NodeSelector) == 0 { + template.Spec.NodeSelector = nil + } else { + template.Spec.NodeSelector = map[string]string{} + for k, v := range s.NodeSelector { + template.Spec.NodeSelector[k] = v + } + } + + if s.Affinity != nil { + if s.Affinity.NodeAffinity != nil || s.Affinity.PodAffinity != nil || s.Affinity.PodAntiAffinity != nil { + template.Spec.Affinity = s.Affinity.DeepCopy() + } + } + + template.Spec.Tolerations = tolerations.AddTolerationsIfNotFound(nil, s.Tolerations.DeepCopy()...) + + template.Spec.SchedulerName = util.WithDefault(s.SchedulerName) + + return nil +} + +func (s *Scheduling) GetNodeSelector() map[string]string { + if s != nil { + return s.NodeSelector + } + + return nil +} + +func (s *Scheduling) GetSchedulerName() string { + if s != nil && s.SchedulerName != nil { + return *s.SchedulerName + } + + return "" +} + +func (s *Scheduling) GetAffinity() *core.Affinity { + if s != nil { + return s.Affinity + } + + return nil +} + +func (s *Scheduling) GetTolerations() Tolerations { + if s != nil { + return s.Tolerations + } + + return nil +} + +func (s *Scheduling) With(other *Scheduling) *Scheduling { + if s == nil && other == nil { + return nil + } + + if other == nil { + return s.DeepCopy() + } + + if s == nil { + return other.DeepCopy() + } + + current := s.DeepCopy() + new := other.DeepCopy() + + // NodeSelector + if len(current.NodeSelector) == 0 { + current.NodeSelector = new.NodeSelector + } else if len(new.NodeSelector) > 0 { + for k, v := range new.NodeSelector { + current.NodeSelector[k] = v + } + } + + // SchedulerName + if new.SchedulerName != nil { + current.SchedulerName = new.SchedulerName + } + + // Tolerations + current.Tolerations = tolerations.AddTolerationsIfNotFound(new.Tolerations, other.Tolerations...) + + // Affinity + current.Affinity = kresources.Merge(current.Affinity, new.Affinity) + + // return + + if current.Affinity == nil && + current.SchedulerName == nil && + len(current.Tolerations) == 0 && + len(current.NodeSelector) == 0 { + return nil + } + + return current +} + +func (s *Scheduling) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/scheduling_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/scheduling_test.go new file mode 100644 index 000000000..f292a6d5d --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/scheduling_test.go @@ -0,0 +1,844 @@ +// +// 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 applyScheduling(t *testing.T, template *core.PodTemplateSpec, ns ...*Scheduling) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Scheduling + + 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_Scheduling_Affinity(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyScheduling(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Nil(t, pod.Spec.Affinity) + }) + }) + t.Run("Empty Template", func(t *testing.T) { + applyScheduling(t, &core.PodTemplateSpec{}, &Scheduling{ + Affinity: &core.Affinity{}, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Nil(t, pod.Spec.Affinity) + }) + }) + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{}, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Nil(t, pod.Spec.Affinity) + }) + }) + t.Run("PodAffinity", func(t *testing.T) { + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{}, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAffinity) + }) + }) + + t.Run("One", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAffinity) + + require.Len(t, pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + }) + }) + + t.Run("Merge - with Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + }, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{}, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAffinity) + + require.Len(t, pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + }) + }) + + t.Run("Merge", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + }, &Scheduling{ + Affinity: &core.Affinity{ + PodAffinity: &core.PodAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test2", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test2", + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAffinity) + + require.Len(t, pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 2) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + require.EqualValues(t, "test2", pod.Spec.Affinity.PodAffinity.RequiredDuringSchedulingIgnoredDuringExecution[1].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 2) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + require.EqualValues(t, "test2", pod.Spec.Affinity.PodAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].PodAffinityTerm.TopologyKey) + }) + }) + }) + + t.Run("PodAntiAffinity", func(t *testing.T) { + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{}, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAntiAffinity) + }) + }) + + t.Run("One", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAntiAffinity) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + }) + }) + + t.Run("Merge - with Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + }, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{}, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAntiAffinity) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 1) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + }) + }) + + t.Run("Merge", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test", + }, + }, + }, + }, + }, + }, &Scheduling{ + Affinity: &core.Affinity{ + PodAntiAffinity: &core.PodAntiAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: []core.PodAffinityTerm{ + { + TopologyKey: "test2", + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.WeightedPodAffinityTerm{ + { + PodAffinityTerm: core.PodAffinityTerm{ + TopologyKey: "test2", + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.PodAntiAffinity) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution, 2) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[0].TopologyKey) + require.EqualValues(t, "test2", pod.Spec.Affinity.PodAntiAffinity.RequiredDuringSchedulingIgnoredDuringExecution[1].TopologyKey) + + require.Len(t, pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 2) + + require.EqualValues(t, "test", pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].PodAffinityTerm.TopologyKey) + require.EqualValues(t, "test2", pod.Spec.Affinity.PodAntiAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].PodAffinityTerm.TopologyKey) + }) + }) + }) + + t.Run("NodeAffinity", func(t *testing.T) { + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + NodeAffinity: &core.NodeAffinity{}, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.NodeAffinity) + }) + }) + + t.Run("One", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + NodeAffinity: &core.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &core.NodeSelector{ + NodeSelectorTerms: []core.NodeSelectorTerm{ + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + }, + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + }, + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.PreferredSchedulingTerm{ + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + }, + }, + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.NodeAffinity) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 2) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchFields, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions[0].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchFields, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchExpressions, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchExpressions[0].Key) + + require.NotNil(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms, 2) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchFields, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchExpressions, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchExpressions[0].Key) + }) + }) + + t.Run("Merge", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Affinity: &core.Affinity{ + NodeAffinity: &core.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &core.NodeSelector{ + NodeSelectorTerms: []core.NodeSelectorTerm{ + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + }, + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + }, + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.PreferredSchedulingTerm{ + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term1", + }, + }, + }, + }, + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term2", + }, + }, + }, + }, + }, + }, + }, + }, &Scheduling{ + Affinity: &core.Affinity{ + NodeAffinity: &core.NodeAffinity{ + RequiredDuringSchedulingIgnoredDuringExecution: &core.NodeSelector{ + NodeSelectorTerms: []core.NodeSelectorTerm{ + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term3", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term3", + }, + }, + }, + { + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term4", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term4", + }, + }, + }, + }, + }, + PreferredDuringSchedulingIgnoredDuringExecution: []core.PreferredSchedulingTerm{ + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term3", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term3", + }, + }, + }, + }, + { + Preference: core.NodeSelectorTerm{ + MatchExpressions: []core.NodeSelectorRequirement{ + { + Key: "term4", + }, + }, + MatchFields: []core.NodeSelectorRequirement{ + { + Key: "term4", + }, + }, + }, + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.Affinity) + require.NotNil(t, pod.Spec.Affinity.NodeAffinity) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution, 4) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchFields, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions, 1) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[0].Preference.MatchExpressions[0].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchFields, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchFields[0].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchExpressions, 1) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.PreferredDuringSchedulingIgnoredDuringExecution[1].Preference.MatchExpressions[0].Key) + + require.NotNil(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms, 4) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields, 2) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields[0].Key) + require.EqualValues(t, "term3", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchFields[1].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions, 2) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[0].Key) + require.EqualValues(t, "term3", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[0].MatchExpressions[1].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchFields, 2) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchFields[0].Key) + require.EqualValues(t, "term4", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchFields[1].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchExpressions, 2) + require.EqualValues(t, "term1", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchExpressions[0].Key) + require.EqualValues(t, "term4", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[1].MatchExpressions[1].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchFields, 2) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchFields[0].Key) + require.EqualValues(t, "term3", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchFields[1].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchExpressions, 2) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchExpressions[0].Key) + require.EqualValues(t, "term3", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[2].MatchExpressions[1].Key) + + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchFields, 2) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchFields[0].Key) + require.EqualValues(t, "term4", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchFields[1].Key) + require.Len(t, pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchExpressions, 2) + require.EqualValues(t, "term2", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchExpressions[0].Key) + require.EqualValues(t, "term4", pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution.NodeSelectorTerms[3].MatchExpressions[1].Key) + }) + }) + }) +} + +func Test_Scheduling_Tolerations(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyScheduling(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 0) + }) + }) + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{}, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 0) + }) + }) + t.Run("Single", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 1) + + require.EqualValues(t, core.TolerationOpExists, pod.Spec.Tolerations[0].Operator) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Key) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Value) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Effect) + require.Nil(t, pod.Spec.Tolerations[0].TolerationSeconds) + }) + }) + t.Run("Single - With Grace", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + TolerationSeconds: util.NewType[int64](5), + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 1) + + require.EqualValues(t, core.TolerationOpExists, pod.Spec.Tolerations[0].Operator) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Key) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Value) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Effect) + require.NotNil(t, pod.Spec.Tolerations[0].TolerationSeconds) + require.EqualValues(t, 5, *pod.Spec.Tolerations[0].TolerationSeconds) + }) + }) + t.Run("One - merge within spec", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + }, + { + Operator: core.TolerationOpExists, + TolerationSeconds: util.NewType[int64](5), + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 1) + + require.EqualValues(t, core.TolerationOpExists, pod.Spec.Tolerations[0].Operator) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Key) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Value) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Effect) + require.NotNil(t, pod.Spec.Tolerations[0].TolerationSeconds) + require.EqualValues(t, 5, *pod.Spec.Tolerations[0].TolerationSeconds) + }) + }) + t.Run("Multi - Update", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + }, + }, + }, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + TolerationSeconds: util.NewType[int64](5), + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 1) + + require.EqualValues(t, core.TolerationOpExists, pod.Spec.Tolerations[0].Operator) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Key) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Value) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Effect) + require.NotNil(t, pod.Spec.Tolerations[0].TolerationSeconds) + require.EqualValues(t, 5, *pod.Spec.Tolerations[0].TolerationSeconds) + }) + }) + t.Run("Multi - Update", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + TolerationSeconds: util.NewType[int64](5), + }, + }, + }, &Scheduling{ + Tolerations: Tolerations{ + { + Operator: core.TolerationOpExists, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Tolerations, 1) + + require.EqualValues(t, core.TolerationOpExists, pod.Spec.Tolerations[0].Operator) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Key) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Value) + require.EqualValues(t, "", pod.Spec.Tolerations[0].Effect) + require.Nil(t, pod.Spec.Tolerations[0].TolerationSeconds) + }) + }) +} + +func Test_Scheduling_NodeSelector(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyScheduling(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.NodeSelector, 0) + }) + }) + t.Run("Empty", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + NodeSelector: map[string]string{}, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.NodeSelector, 0) + }) + }) + t.Run("Selector", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + NodeSelector: map[string]string{ + "1": "1", + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.NodeSelector, 1) + + require.Contains(t, pod.Spec.NodeSelector, "1") + require.EqualValues(t, pod.Spec.NodeSelector["1"], "1") + }) + }) + t.Run("Append", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + NodeSelector: map[string]string{ + "1": "1", + }, + }, &Scheduling{ + NodeSelector: map[string]string{ + "2": "1", + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.NodeSelector, 2) + + require.Contains(t, pod.Spec.NodeSelector, "1") + require.EqualValues(t, pod.Spec.NodeSelector["1"], "1") + + require.Contains(t, pod.Spec.NodeSelector, "2") + require.EqualValues(t, pod.Spec.NodeSelector["2"], "1") + }) + }) + t.Run("Override", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + NodeSelector: map[string]string{ + "1": "1", + }, + }, &Scheduling{ + NodeSelector: map[string]string{ + "2": "1", + "1": "2", + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.NodeSelector, 2) + + require.Contains(t, pod.Spec.NodeSelector, "1") + require.EqualValues(t, pod.Spec.NodeSelector["1"], "2") + + require.Contains(t, pod.Spec.NodeSelector, "2") + require.EqualValues(t, pod.Spec.NodeSelector["2"], "1") + }) + }) +} + +func Test_Scheduling_SchedulerName(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyScheduling(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "", pod.Spec.SchedulerName) + }) + }) + t.Run("With Scheduler", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + SchedulerName: util.NewType("example"), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "example", pod.Spec.SchedulerName) + }) + }) + t.Run("With override", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + SchedulerName: util.NewType("example"), + }, &Scheduling{ + SchedulerName: util.NewType("example2"), + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "example2", pod.Spec.SchedulerName) + }) + }) + t.Run("With skip", func(t *testing.T) { + applyScheduling(t, nil, &Scheduling{ + SchedulerName: util.NewType("example"), + }, &Scheduling{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.EqualValues(t, "example", pod.Spec.SchedulerName) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/security.go b/pkg/apis/scheduler/v1beta1/pod/resources/security.go new file mode 100644 index 000000000..e941bd16d --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/security.go @@ -0,0 +1,74 @@ +// +// 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/v1beta1/interfaces" +) + +var _ interfaces.Pod[Security] = &Security{} + +type Security struct { + // PodSecurityContext holds pod-level security attributes and common container settings. + // +doc/type: core.PodSecurityContext + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + PodSecurityContext *core.PodSecurityContext `json:"podSecurityContext,omitempty"` +} + +func (s *Security) Apply(template *core.PodTemplateSpec) error { + if s == nil { + return nil + } + + template.Spec.SecurityContext = s.PodSecurityContext.DeepCopy() + + return nil +} + +func (s *Security) GetSecurityContext() *core.PodSecurityContext { + if s == nil { + return nil + } + + return s.PodSecurityContext +} + +func (s *Security) With(newResources *Security) *Security { + if s == nil && newResources == nil { + return nil + } + + if s == nil { + return newResources.DeepCopy() + } + + if newResources == nil { + return s.DeepCopy() + } + + return newResources.DeepCopy() +} + +func (s *Security) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/security_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/security_test.go new file mode 100644 index 000000000..93d947779 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/security_test.go @@ -0,0 +1,87 @@ +// +// 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 applySecurity(t *testing.T, template *core.PodTemplateSpec, ns ...*Security) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Security + + 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_Security(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applySecurity(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Nil(t, pod.Spec.SecurityContext) + }) + }) + t.Run("Empty", func(t *testing.T) { + applySecurity(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Nil(t, pod.Spec.SecurityContext) + }) + }) + t.Run("Pick Always Latest Not Nil", func(t *testing.T) { + applySecurity(t, &core.PodTemplateSpec{}, &Security{ + PodSecurityContext: &core.PodSecurityContext{ + FSGroup: util.NewType[int64](50), + RunAsGroup: util.NewType[int64](128), + }, + }, &Security{ + PodSecurityContext: &core.PodSecurityContext{ + FSGroup: util.NewType[int64](60), + }, + }, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.NotNil(t, pod.Spec.SecurityContext) + + require.Nil(t, pod.Spec.SecurityContext.RunAsGroup) + require.NotNil(t, pod.Spec.SecurityContext.FSGroup) + require.EqualValues(t, 60, *pod.Spec.SecurityContext.FSGroup) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/service_account.go b/pkg/apis/scheduler/v1beta1/pod/resources/service_account.go new file mode 100644 index 000000000..f283f34c1 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/service_account.go @@ -0,0 +1,74 @@ +// +// 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/v1beta1/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 + if c.AutomountServiceAccountToken != nil { + 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/v1beta1/pod/resources/service_account_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/service_account_test.go new file mode 100644 index 000000000..6097c58d1 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/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/v1beta1/pod/resources/volumes.go b/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go new file mode 100644 index 000000000..7d91e7a2d --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/volumes.go @@ -0,0 +1,71 @@ +// +// 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/v1beta1/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +var _ interfaces.Pod[Volumes] = &Volumes{} + +type Volumes struct { + // Volumes keeps list of volumes that can be mounted by containers belonging to the pod. + // +doc/type: []core.Volume + // +doc/link: Kubernetes docs|https://kubernetes.io/docs/concepts/storage/volumes + Volumes []core.Volume `json:"volumes,omitempty"` +} + +func (v *Volumes) Apply(template *core.PodTemplateSpec) error { + if v == nil { + return nil + } + + obj := v.DeepCopy() + + template.Spec.Volumes = kresources.MergeVolumes(template.Spec.Volumes, obj.Volumes...) + + return nil +} + +func (v *Volumes) With(other *Volumes) *Volumes { + if v == nil && other == nil { + return nil + } + + if v == nil { + return other.DeepCopy() + } + + if other == nil { + return v.DeepCopy() + } + + return &Volumes{ + Volumes: kresources.MergeVolumes(v.Volumes, other.Volumes...), + } +} + +func (v *Volumes) Validate() error { + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/volumes_test.go b/pkg/apis/scheduler/v1beta1/pod/resources/volumes_test.go new file mode 100644 index 000000000..381affd40 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/volumes_test.go @@ -0,0 +1,149 @@ +// +// 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" +) + +func applyVolumes(t *testing.T, template *core.PodTemplateSpec, ns ...*Volumes) func(in func(t *testing.T, pod *core.PodTemplateSpec)) { + var i *Volumes + + 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_Volumes(t *testing.T) { + t.Run("Nil", func(t *testing.T) { + applyVolumes(t, nil)(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Volumes, 0) + }) + }) + t.Run("Empty", func(t *testing.T) { + applyVolumes(t, &core.PodTemplateSpec{})(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Volumes, 0) + }) + }) + t.Run("Add volume", func(t *testing.T) { + applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{ + Volumes: []core.Volume{ + { + Name: "test", + VolumeSource: core.VolumeSource{ + EmptyDir: &core.EmptyDirVolumeSource{}, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Volumes, 1) + + require.EqualValues(t, "test", pod.Spec.Volumes[0].Name) + require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir) + require.Nil(t, pod.Spec.Volumes[0].VolumeSource.Secret) + }) + }) + t.Run("Append volume", func(t *testing.T) { + applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{ + Volumes: []core.Volume{ + { + Name: "test", + VolumeSource: core.VolumeSource{ + EmptyDir: &core.EmptyDirVolumeSource{}, + }, + }, + }, + }, &Volumes{ + Volumes: []core.Volume{ + { + Name: "test2", + VolumeSource: core.VolumeSource{ + Secret: &core.SecretVolumeSource{ + SecretName: "test", + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Volumes, 2) + + require.EqualValues(t, "test", pod.Spec.Volumes[0].Name) + require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir) + require.Nil(t, pod.Spec.Volumes[0].VolumeSource.Secret) + + require.EqualValues(t, "test2", pod.Spec.Volumes[1].Name) + require.Nil(t, pod.Spec.Volumes[1].VolumeSource.EmptyDir) + require.NotNil(t, pod.Spec.Volumes[1].VolumeSource.Secret) + require.EqualValues(t, "test", pod.Spec.Volumes[1].VolumeSource.Secret.SecretName) + }) + }) + t.Run("Update volume", func(t *testing.T) { + applyVolumes(t, &core.PodTemplateSpec{}, &Volumes{ + Volumes: []core.Volume{ + { + Name: "test", + VolumeSource: core.VolumeSource{ + EmptyDir: &core.EmptyDirVolumeSource{}, + }, + }, + }, + }, &Volumes{ + Volumes: []core.Volume{ + { + Name: "test", + VolumeSource: core.VolumeSource{ + Secret: &core.SecretVolumeSource{ + SecretName: "test", + }, + }, + }, + }, + })(func(t *testing.T, pod *core.PodTemplateSpec) { + require.Len(t, pod.Spec.Volumes, 1) + + require.EqualValues(t, "test", pod.Spec.Volumes[0].Name) + require.Nil(t, pod.Spec.Volumes[0].VolumeSource.EmptyDir) + require.NotNil(t, pod.Spec.Volumes[0].VolumeSource.Secret) + require.EqualValues(t, "test", pod.Spec.Volumes[0].VolumeSource.Secret.SecretName) + }) + }) +} diff --git a/pkg/apis/scheduler/v1beta1/pod/resources/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/pod/resources/zz_generated.deepcopy.go new file mode 100644 index 000000000..b35c27c24 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/resources/zz_generated.deepcopy.go @@ -0,0 +1,272 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package resources + +import ( + 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 *Image) DeepCopyInto(out *Image) { + *out = *in + if in.ImagePullSecrets != nil { + in, out := &in.ImagePullSecrets, &out.ImagePullSecrets + *out = make(ImagePullSecrets, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image. +func (in *Image) DeepCopy() *Image { + if in == nil { + return nil + } + out := new(Image) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ImagePullSecrets) DeepCopyInto(out *ImagePullSecrets) { + { + in := &in + *out = make(ImagePullSecrets, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImagePullSecrets. +func (in ImagePullSecrets) DeepCopy() ImagePullSecrets { + if in == nil { + return nil + } + out := new(ImagePullSecrets) + in.DeepCopyInto(out) + return *out +} + +// 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 + if in.HostNetwork != nil { + in, out := &in.HostNetwork, &out.HostNetwork + *out = new(bool) + **out = **in + } + if in.HostPID != nil { + in, out := &in.HostPID, &out.HostPID + *out = new(bool) + **out = **in + } + if in.HostIPC != nil { + in, out := &in.HostIPC, &out.HostIPC + *out = new(bool) + **out = **in + } + if in.ShareProcessNamespace != nil { + in, out := &in.ShareProcessNamespace, &out.ShareProcessNamespace + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Namespace. +func (in *Namespace) DeepCopy() *Namespace { + if in == nil { + return nil + } + out := new(Namespace) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Scheduling) DeepCopyInto(out *Scheduling) { + *out = *in + if in.NodeSelector != nil { + in, out := &in.NodeSelector, &out.NodeSelector + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Affinity != nil { + in, out := &in.Affinity, &out.Affinity + *out = new(corev1.Affinity) + (*in).DeepCopyInto(*out) + } + if in.Tolerations != nil { + in, out := &in.Tolerations, &out.Tolerations + *out = make(Tolerations, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SchedulerName != nil { + in, out := &in.SchedulerName, &out.SchedulerName + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Scheduling. +func (in *Scheduling) DeepCopy() *Scheduling { + if in == nil { + return nil + } + out := new(Scheduling) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Security) DeepCopyInto(out *Security) { + *out = *in + if in.PodSecurityContext != nil { + in, out := &in.PodSecurityContext, &out.PodSecurityContext + *out = new(corev1.PodSecurityContext) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Security. +func (in *Security) DeepCopy() *Security { + if in == nil { + return nil + } + out := new(Security) + in.DeepCopyInto(out) + 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) { + { + in := &in + *out = make(Tolerations, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Tolerations. +func (in Tolerations) DeepCopy() Tolerations { + if in == nil { + return nil + } + out := new(Tolerations) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Volumes) DeepCopyInto(out *Volumes) { + *out = *in + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]corev1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Volumes. +func (in *Volumes) DeepCopy() *Volumes { + if in == nil { + return nil + } + out := new(Volumes) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/scheduler/v1beta1/pod/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/pod/zz_generated.deepcopy.go new file mode 100644 index 000000000..d6707e5e8 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/pod/zz_generated.deepcopy.go @@ -0,0 +1,81 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package pod + +import ( + resources "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod/resources" +) + +// 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.Image != nil { + in, out := &in.Image, &out.Image + *out = new(resources.Image) + (*in).DeepCopyInto(*out) + } + if in.Scheduling != nil { + in, out := &in.Scheduling, &out.Scheduling + *out = new(resources.Scheduling) + (*in).DeepCopyInto(*out) + } + if in.Namespace != nil { + in, out := &in.Namespace, &out.Namespace + *out = new(resources.Namespace) + (*in).DeepCopyInto(*out) + } + if in.Security != nil { + in, out := &in.Security, &out.Security + *out = new(resources.Security) + (*in).DeepCopyInto(*out) + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *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 +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Pod. +func (in *Pod) DeepCopy() *Pod { + if in == nil { + return nil + } + out := new(Pod) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/apis/scheduler/v1beta1/profile.go b/pkg/apis/scheduler/v1beta1/profile.go new file mode 100644 index 000000000..89888779c --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile.go @@ -0,0 +1,45 @@ +// +// 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 v1beta1 + +import meta "k8s.io/apimachinery/pkg/apis/meta/v1" + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoProfileList is a list of Arango Profile. +type ArangoProfileList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoProfile `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoProfile contains definition and status of the Arango Profile. +type ArangoProfile struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ProfileSpec `json:"spec"` + Status ProfileStatus `json:"status"` +} diff --git a/pkg/apis/scheduler/v1beta1/profile_container_template.go b/pkg/apis/scheduler/v1beta1/profile_container_template.go new file mode 100644 index 000000000..37634dad4 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_container_template.go @@ -0,0 +1,80 @@ +// +// 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 v1beta1 + +import ( + core "k8s.io/api/core/v1" + + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +type ProfileContainerTemplate struct { + Containers schedulerContainerApi.Containers `json:"containers,omitempty"` + + All *schedulerContainerApi.Generic `json:"all,omitempty"` +} + +func (p *ProfileContainerTemplate) ApplyContainers(template *core.PodTemplateSpec) error { + if p == nil { + return nil + } + + return p.Containers.Apply(template) +} + +func (p *ProfileContainerTemplate) ApplyGeneric(template *core.PodTemplateSpec) error { + if p == nil { + return nil + } + + return p.All.Apply(template) +} + +func (p *ProfileContainerTemplate) With(other *ProfileContainerTemplate) *ProfileContainerTemplate { + if p == nil && other == nil { + return nil + } + + if p == nil { + return other.DeepCopy() + } + + if other == nil { + return p.DeepCopy() + } + + return &ProfileContainerTemplate{ + Containers: p.Containers.With(other.Containers), + All: p.All.With(other.All), + } +} + +func (p *ProfileContainerTemplate) Validate() error { + if p == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("containers", p.Containers.Validate()), + shared.PrefixResourceErrors("all", p.All.Validate()), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/profile_selectors.go b/pkg/apis/scheduler/v1beta1/profile_selectors.go new file mode 100644 index 000000000..15f43e68e --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_selectors.go @@ -0,0 +1,49 @@ +// +// 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 v1beta1 + +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +type ProfileSelectors struct { + // Label keeps information about label selector + // +doc/type: meta.LabelSelector + Label *meta.LabelSelector `json:"label,omitempty"` +} + +func (p *ProfileSelectors) Validate() error { + if p == nil { + return nil + } + + return nil +} + +func (p *ProfileSelectors) Select(labels map[string]string) bool { + if p == nil || p.Label == nil { + return false + } + + return kresources.SelectLabels(p.Label, labels) +} diff --git a/pkg/apis/scheduler/v1beta1/profile_spec.go b/pkg/apis/scheduler/v1beta1/profile_spec.go new file mode 100644 index 000000000..e23242ca9 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_spec.go @@ -0,0 +1,44 @@ +// +// 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 v1beta1 + +import ( + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" +) + +type ProfileSpec struct { + // Selectors keeps information about ProfileSelectors + Selectors *ProfileSelectors `json:"selectors,omitempty"` + + // Template keeps the Profile Template + Template *ProfileTemplate `json:"template,omitempty"` +} + +func (p *ProfileSpec) Validate() error { + if p == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("selectors", p.Selectors.Validate()), + shared.PrefixResourceErrors("template", p.Template.Validate()), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/profile_status.go b/pkg/apis/scheduler/v1beta1/profile_status.go new file mode 100644 index 000000000..7652443ac --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_status.go @@ -0,0 +1,24 @@ +// +// 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 v1beta1 + +type ProfileStatus struct { +} diff --git a/pkg/apis/scheduler/v1beta1/profile_template.go b/pkg/apis/scheduler/v1beta1/profile_template.go new file mode 100644 index 000000000..176a13baa --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_template.go @@ -0,0 +1,90 @@ +// +// 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 v1beta1 + +import ( + schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +type ProfileTemplate struct { + Priority *int `json:"priority,omitempty"` + + Pod *schedulerPodApi.Pod `json:"pod,omitempty"` + + Container *ProfileContainerTemplate `json:"container,omitempty"` +} + +func (p *ProfileTemplate) GetPod() *schedulerPodApi.Pod { + if p == nil || p.Pod == nil { + return nil + } + + return p.Pod +} + +func (p *ProfileTemplate) GetContainer() *ProfileContainerTemplate { + if p == nil || p.Container == nil { + return nil + } + + return p.Container +} + +func (p *ProfileTemplate) GetPriority() int { + if p == nil || p.Priority == nil { + return 0 + } + + return *p.Priority +} + +func (p *ProfileTemplate) With(other *ProfileTemplate) *ProfileTemplate { + if p == nil && other == nil { + return nil + } + + if p == nil { + return other.DeepCopy() + } + + if other == nil { + return p.DeepCopy() + } + + return &ProfileTemplate{ + Priority: util.NewType(max(p.GetPriority(), other.GetPriority())), + Pod: p.Pod.With(other.Pod), + Container: p.Container.With(other.Container), + } +} + +func (p *ProfileTemplate) Validate() error { + if p == nil { + return nil + } + + return shared.WithErrors( + shared.PrefixResourceErrors("pod", p.Pod.Validate()), + shared.PrefixResourceErrors("container", p.Container.Validate()), + ) +} diff --git a/pkg/apis/scheduler/v1beta1/profile_templates.go b/pkg/apis/scheduler/v1beta1/profile_templates.go new file mode 100644 index 000000000..c083bc0d5 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profile_templates.go @@ -0,0 +1,74 @@ +// +// 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 v1beta1 + +import ( + "sort" + + core "k8s.io/api/core/v1" + + "github.com/arangodb/kube-arangodb/pkg/util/errors" +) + +type ProfileTemplates []*ProfileTemplate + +func (p ProfileTemplates) Sort() ProfileTemplates { + sort.Slice(p, func(i, j int) bool { + if a, b := p[i].GetPriority(), p[j].GetPriority(); a != b { + return a > b + } + + return false + }) + + return p +} + +func (p ProfileTemplates) Merge() *ProfileTemplate { + var z *ProfileTemplate + + for id := len(p) - 1; id >= 0; id-- { + z = z.With(p[id]) + } + + return z +} + +func (p ProfileTemplates) RenderOnTemplate(pod *core.PodTemplateSpec) error { + t := p.Merge() + + // Apply Pod Spec + if err := t.GetPod().Apply(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod") + } + + // Apply Generic Containers Spec + if err := t.GetContainer().ApplyGeneric(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod") + } + + // Apply Containers Spec + if err := t.GetContainer().ApplyContainers(pod); err != nil { + return errors.Wrapf(err, "Error while rendering Pod") + } + + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/profiles/environments.container.kubernetes.go b/pkg/apis/scheduler/v1beta1/profiles/environments.container.kubernetes.go new file mode 100644 index 000000000..cc046821b --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profiles/environments.container.kubernetes.go @@ -0,0 +1,76 @@ +// +// 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 profiles + +import ( + core "k8s.io/api/core/v1" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" +) + +func ContainerKubernetesEnvironments() *schedulerApi.ProfileTemplate { + return containerKubernetesEnvironments.DeepCopy() +} + +var containerKubernetesEnvironments = schedulerApi.ProfileTemplate{ + Container: &schedulerApi.ProfileContainerTemplate{ + All: &schedulerContainerApi.Generic{ + Environments: &schedulerContainerResourcesApi.Environments{ + Env: []core.EnvVar{ + { + Name: "KUBE_NAMESPACE", + ValueFrom: &core.EnvVarSource{ + FieldRef: &core.ObjectFieldSelector{ + FieldPath: "metadata.namespace", + }, + }, + }, + { + Name: "KUBE_NAME", + ValueFrom: &core.EnvVarSource{ + FieldRef: &core.ObjectFieldSelector{ + FieldPath: "metadata.name", + }, + }, + }, + { + Name: "KUBE_IP", + ValueFrom: &core.EnvVarSource{ + FieldRef: &core.ObjectFieldSelector{ + FieldPath: "status.podIP", + }, + }, + }, + { + Name: "KUBE_SERVICE_ACCOUNT", + ValueFrom: &core.EnvVarSource{ + FieldRef: &core.ObjectFieldSelector{ + FieldPath: "spec.serviceAccountName", + }, + }, + }, + }, + }, + }, + }, +} diff --git a/pkg/apis/scheduler/v1beta1/profiles/environments.container.resources.go b/pkg/apis/scheduler/v1beta1/profiles/environments.container.resources.go new file mode 100644 index 000000000..1c09cd0ae --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/profiles/environments.container.resources.go @@ -0,0 +1,86 @@ +// +// 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 profiles + +import ( + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" +) + +var ( + divisor1m = resource.MustParse("1m") + divisor1Mi = resource.MustParse("1Mi") +) + +func ContainerResourceEnvironments() *schedulerApi.ProfileTemplate { + return containerResourceEnvironments.DeepCopy() +} + +var containerResourceEnvironments = schedulerApi.ProfileTemplate{ + Container: &schedulerApi.ProfileContainerTemplate{ + All: &schedulerContainerApi.Generic{ + Environments: &schedulerContainerResourcesApi.Environments{ + Env: []core.EnvVar{ + { + Name: "CONTAINER_CPU_REQUESTS", + ValueFrom: &core.EnvVarSource{ + ResourceFieldRef: &core.ResourceFieldSelector{ + Resource: "requests.cpu", + Divisor: divisor1m, + }, + }, + }, + { + Name: "CONTAINER_MEMORY_REQUESTS", + ValueFrom: &core.EnvVarSource{ + ResourceFieldRef: &core.ResourceFieldSelector{ + Resource: "requests.memory", + Divisor: divisor1Mi, + }, + }, + }, + { + Name: "CONTAINER_CPU_LIMITS", + ValueFrom: &core.EnvVarSource{ + ResourceFieldRef: &core.ResourceFieldSelector{ + Resource: "limits.cpu", + Divisor: divisor1m, + }, + }, + }, + { + Name: "CONTAINER_MEMORY_LIMITS", + ValueFrom: &core.EnvVarSource{ + ResourceFieldRef: &core.ResourceFieldSelector{ + Resource: "limits.memory", + Divisor: divisor1Mi, + }, + }, + }, + }, + }, + }, + }, +} diff --git a/pkg/apis/scheduler/v1beta1/register.go b/pkg/apis/scheduler/v1beta1/register.go new file mode 100644 index 000000000..4a05cbf69 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/register.go @@ -0,0 +1,56 @@ +// +// 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 v1beta1 + +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) + +const ( + ArangoSchedulerVersion = "v1beta1" +) + +var ( + SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) + AddToScheme = SchemeBuilder.AddToScheme + + SchemeGroupVersion = schema.GroupVersion{Group: scheduler.ArangoSchedulerGroupName, + Version: ArangoSchedulerVersion} +) + +// Resource gets an ArangoCluster GroupResource for a specified resource +func Resource(resource string) schema.GroupResource { + return SchemeGroupVersion.WithResource(resource).GroupResource() +} + +// addKnownTypes adds the set of types defined in this package to the supplied scheme. +func addKnownTypes(s *runtime.Scheme) error { + s.AddKnownTypes(SchemeGroupVersion, + &ArangoProfile{}, + &ArangoProfileList{}, + ) + meta.AddToGroupVersion(s, SchemeGroupVersion) + return nil +} diff --git a/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go new file mode 100644 index 000000000..2c0006389 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go @@ -0,0 +1,242 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// +// 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 +// + +// Code generated by deepcopy-gen. DO NOT EDIT. + +package v1beta1 + +import ( + container "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + pod "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoProfile) DeepCopyInto(out *ArangoProfile) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + out.Status = in.Status + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoProfile. +func (in *ArangoProfile) DeepCopy() *ArangoProfile { + if in == nil { + return nil + } + out := new(ArangoProfile) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoProfile) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoProfileList) DeepCopyInto(out *ArangoProfileList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoProfile, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoProfileList. +func (in *ArangoProfileList) DeepCopy() *ArangoProfileList { + if in == nil { + return nil + } + out := new(ArangoProfileList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoProfileList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProfileContainerTemplate) DeepCopyInto(out *ProfileContainerTemplate) { + *out = *in + if in.Containers != nil { + in, out := &in.Containers, &out.Containers + *out = make(container.Containers, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.All != nil { + in, out := &in.All, &out.All + *out = new(container.Generic) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileContainerTemplate. +func (in *ProfileContainerTemplate) DeepCopy() *ProfileContainerTemplate { + if in == nil { + return nil + } + out := new(ProfileContainerTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProfileSelectors) DeepCopyInto(out *ProfileSelectors) { + *out = *in + if in.Label != nil { + in, out := &in.Label, &out.Label + *out = new(v1.LabelSelector) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileSelectors. +func (in *ProfileSelectors) DeepCopy() *ProfileSelectors { + if in == nil { + return nil + } + out := new(ProfileSelectors) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProfileSpec) DeepCopyInto(out *ProfileSpec) { + *out = *in + if in.Selectors != nil { + in, out := &in.Selectors, &out.Selectors + *out = new(ProfileSelectors) + (*in).DeepCopyInto(*out) + } + if in.Template != nil { + in, out := &in.Template, &out.Template + *out = new(ProfileTemplate) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileSpec. +func (in *ProfileSpec) DeepCopy() *ProfileSpec { + if in == nil { + return nil + } + out := new(ProfileSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProfileStatus) DeepCopyInto(out *ProfileStatus) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileStatus. +func (in *ProfileStatus) DeepCopy() *ProfileStatus { + if in == nil { + return nil + } + out := new(ProfileStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProfileTemplate) DeepCopyInto(out *ProfileTemplate) { + *out = *in + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(int) + **out = **in + } + if in.Pod != nil { + in, out := &in.Pod, &out.Pod + *out = new(pod.Pod) + (*in).DeepCopyInto(*out) + } + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(ProfileContainerTemplate) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileTemplate. +func (in *ProfileTemplate) DeepCopy() *ProfileTemplate { + if in == nil { + return nil + } + out := new(ProfileTemplate) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in ProfileTemplates) DeepCopyInto(out *ProfileTemplates) { + { + in := &in + *out = make(ProfileTemplates, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(ProfileTemplate) + (*in).DeepCopyInto(*out) + } + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProfileTemplates. +func (in ProfileTemplates) DeepCopy() ProfileTemplates { + if in == nil { + return nil + } + out := new(ProfileTemplates) + in.DeepCopyInto(out) + return *out +} diff --git a/pkg/crd/crds/ml-extension.schema.generated.yaml b/pkg/crd/crds/ml-extension.schema.generated.yaml index bddbf4f8c..f8a55b348 100644 --- a/pkg/crd/crds/ml-extension.schema.generated.yaml +++ b/pkg/crd/crds/ml-extension.schema.generated.yaml @@ -13023,3 +13023,12998 @@ v1alpha1: type: object type: object x-kubernetes-preserve-unknown-fields: true +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + deployment: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + gpu: + type: boolean + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + port: + format: int32 + type: integer + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + replicas: + format: int32 + type: integer + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + service: + properties: + type: + type: string + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tls: + properties: + altNames: + items: + type: string + type: array + enabled: + type: boolean + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + init: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + jobsTemplates: + properties: + featurization: + properties: + cpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + gpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + type: object + prediction: + properties: + cpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + gpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + type: object + training: + properties: + cpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + gpu: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + 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 + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + image: + type: string + imagePullPolicy: + type: string + imagePullSecrets: + items: + type: string + type: array + labels: + additionalProperties: + type: string + type: object + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + type: string + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + workingDir: + type: string + type: object + type: object + type: object + metadataService: + properties: + local: + properties: + arangoMLFeatureStore: + type: string + arangoPipeDatabase: + type: string + type: object + type: object + storage: + properties: + checksum: + description: UID keeps the information about object Checksum + type: string + name: + description: Name of the object + type: string + namespace: + description: Namespace of the object. Should default to the namespace of the parent object + type: string + uid: + description: UID keeps the information about object UID + type: string + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/pkg/crd/crds/ml-extension.yaml b/pkg/crd/crds/ml-extension.yaml index 776be6000..1ba50dd8c 100644 --- a/pkg/crd/crds/ml-extension.yaml +++ b/pkg/crd/crds/ml-extension.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/pkg/crd/crds/ml-storage.schema.generated.yaml b/pkg/crd/crds/ml-storage.schema.generated.yaml index ff9ae5fb0..9ac7a31e4 100644 --- a/pkg/crd/crds/ml-storage.schema.generated.yaml +++ b/pkg/crd/crds/ml-storage.schema.generated.yaml @@ -567,3 +567,549 @@ v1alpha1: type: object type: object x-kubernetes-preserve-unknown-fields: true +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + backend: + properties: + s3: + properties: + allowInsecure: + type: boolean + caSecret: + properties: + checksum: + description: UID keeps the information about object Checksum + type: string + name: + description: Name of the object + type: string + namespace: + description: Namespace of the object. Should default to the namespace of the parent object + type: string + uid: + description: UID keeps the information about object UID + type: string + type: object + credentialsSecret: + properties: + checksum: + description: UID keeps the information about object Checksum + type: string + name: + description: Name of the object + type: string + namespace: + description: Namespace of the object. Should default to the namespace of the parent object + type: string + uid: + description: UID keeps the information about object UID + type: string + type: object + endpoint: + type: string + region: + type: string + type: object + type: object + bucketName: + type: string + bucketPath: + type: string + mode: + properties: + sidecar: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + controllerListenPort: + format: int32 + type: integer + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + listenPort: + format: int32 + type: integer + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + workingDir: + type: string + type: object + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/pkg/crd/crds/ml-storage.yaml b/pkg/crd/crds/ml-storage.yaml index 77303d266..01b23a672 100644 --- a/pkg/crd/crds/ml-storage.yaml +++ b/pkg/crd/crds/ml-storage.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/pkg/crd/crds/scheduler-profile.schema.generated.yaml b/pkg/crd/crds/scheduler-profile.schema.generated.yaml index 6dda17df0..bfde5bec1 100644 --- a/pkg/crd/crds/scheduler-profile.schema.generated.yaml +++ b/pkg/crd/crds/scheduler-profile.schema.generated.yaml @@ -1749,3 +1749,1751 @@ v1alpha1: type: object type: object x-kubernetes-preserve-unknown-fields: true +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + selectors: + properties: + label: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + type: object + template: + properties: + container: + properties: + all: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + type: object + containers: + additionalProperties: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + type: object + type: object + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + lifecycle: + properties: + postStart: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + preStop: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + type: object + type: object + livenessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + ports: + items: + properties: + containerPort: + format: int32 + type: integer + hostIP: + type: string + hostPort: + format: int32 + type: integer + name: + type: string + protocol: + type: string + type: object + type: array + readinessProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resources: + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + startupProbe: + properties: + exec: + properties: + command: + items: + type: string + type: array + type: object + failureThreshold: + format: int32 + type: integer + grpc: + properties: + port: + format: int32 + type: integer + service: + type: string + type: object + httpGet: + properties: + host: + type: string + httpHeaders: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + path: + type: string + port: + format: int-or-string + type: string + scheme: + type: string + type: object + initialDelaySeconds: + format: int32 + type: integer + periodSeconds: + format: int32 + type: integer + successThreshold: + format: int32 + type: integer + tcpSocket: + properties: + host: + type: string + port: + format: int-or-string + type: string + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + workingDir: + type: string + type: object + type: object + type: object + pod: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + type: object + type: array + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + weight: + format: int32 + type: integer + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + matchLabelKeys: + items: + type: string + type: array + mismatchLabelKeys: + items: + type: string + type: array + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + type: object + type: array + type: object + type: object + annotations: + additionalProperties: + type: string + type: object + automountServiceAccountToken: + type: boolean + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + imagePullSecrets: + items: + type: string + type: array + 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: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + schedulerName: + type: string + serviceAccountName: + type: string + shareProcessNamespace: + type: boolean + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + type: string + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + creationTimestamp: + format: date-time + type: string + deletionGracePeriodSeconds: + format: int64 + type: integer + deletionTimestamp: + format: date-time + type: string + finalizers: + items: + type: string + type: array + generateName: + type: string + generation: + format: int64 + type: integer + labels: + additionalProperties: + type: string + type: object + managedFields: + items: + properties: + apiVersion: + type: string + fieldsType: + type: string + fieldsV1: + type: object + manager: + type: string + operation: + type: string + subresource: + type: string + time: + format: date-time + type: string + type: object + type: array + name: + type: string + namespace: + type: string + 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 + resourceVersion: + type: string + selfLink: + type: string + uid: + type: string + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + namespace: + type: string + type: object + resources: + properties: + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeAttributesClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + type: object + hostPath: + properties: + path: + type: string + type: + type: string + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + clusterTrustBundle: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + name: + type: string + optional: + type: boolean + path: + type: string + signerName: + type: string + type: object + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + type: string + resource: + type: string + type: object + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + type: object + type: object + type: array + type: object + priority: + format: int32 + type: integer + type: object + type: object + type: object + x-kubernetes-preserve-unknown-fields: true diff --git a/pkg/crd/crds/scheduler-profile.yaml b/pkg/crd/crds/scheduler-profile.yaml index 685448169..2be38f32a 100644 --- a/pkg/crd/crds/scheduler-profile.yaml +++ b/pkg/crd/crds/scheduler-profile.yaml @@ -12,6 +12,15 @@ spec: scope: Namespaced versions: - name: v1alpha1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: false + subresources: + status: {} + - name: v1beta1 schema: openAPIV3Schema: type: object diff --git a/pkg/debug_package/generators/kubernetes/arango_ml_batch_job.go b/pkg/debug_package/generators/kubernetes/arango_ml_batch_job.go index 4622d5f29..25752a478 100644 --- a/pkg/debug_package/generators/kubernetes/arango_ml_batch_job.go +++ b/pkg/debug_package/generators/kubernetes/arango_ml_batch_job.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-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. @@ -26,7 +26,7 @@ import ( "github.com/rs/zerolog" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" "github.com/arangodb/kube-arangodb/pkg/debug_package/cli" "github.com/arangodb/kube-arangodb/pkg/debug_package/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -52,7 +52,7 @@ func mlBatchJobs(logger zerolog.Logger, files chan<- shared.File, client kclient return nil } -func mlBatchJob(client kclient.Client, files chan<- shared.File, ext *mlApi.ArangoMLBatchJob) error { +func mlBatchJob(client kclient.Client, files chan<- shared.File, ext *mlApiv1alpha1.ArangoMLBatchJob) error { files <- shared.NewYAMLFile(fmt.Sprintf("kubernetes/arango/ml/batchjobs/%s.yaml", ext.GetName()), func() ([]interface{}, error) { return []interface{}{ext}, nil }) @@ -60,9 +60,9 @@ func mlBatchJob(client kclient.Client, files chan<- shared.File, ext *mlApi.Aran return nil } -func listMLBatchJobs(client kclient.Client) ([]*mlApi.ArangoMLBatchJob, error) { - return ListObjects[*mlApi.ArangoMLBatchJobList, *mlApi.ArangoMLBatchJob](context.Background(), client.Arango().MlV1alpha1().ArangoMLBatchJobs(cli.GetInput().Namespace), func(result *mlApi.ArangoMLBatchJobList) []*mlApi.ArangoMLBatchJob { - q := make([]*mlApi.ArangoMLBatchJob, len(result.Items)) +func listMLBatchJobs(client kclient.Client) ([]*mlApiv1alpha1.ArangoMLBatchJob, error) { + return ListObjects[*mlApiv1alpha1.ArangoMLBatchJobList, *mlApiv1alpha1.ArangoMLBatchJob](context.Background(), client.Arango().MlV1alpha1().ArangoMLBatchJobs(cli.GetInput().Namespace), func(result *mlApiv1alpha1.ArangoMLBatchJobList) []*mlApiv1alpha1.ArangoMLBatchJob { + q := make([]*mlApiv1alpha1.ArangoMLBatchJob, len(result.Items)) for id, e := range result.Items { q[id] = e.DeepCopy() diff --git a/pkg/debug_package/generators/kubernetes/arango_ml_cron_job.go b/pkg/debug_package/generators/kubernetes/arango_ml_cron_job.go index f49c81378..5051aa1e8 100644 --- a/pkg/debug_package/generators/kubernetes/arango_ml_cron_job.go +++ b/pkg/debug_package/generators/kubernetes/arango_ml_cron_job.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-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. @@ -26,7 +26,7 @@ import ( "github.com/rs/zerolog" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" "github.com/arangodb/kube-arangodb/pkg/debug_package/cli" "github.com/arangodb/kube-arangodb/pkg/debug_package/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -52,7 +52,7 @@ func mlCronJobs(logger zerolog.Logger, files chan<- shared.File, client kclient. return nil } -func mlCronJob(client kclient.Client, files chan<- shared.File, ext *mlApi.ArangoMLCronJob) error { +func mlCronJob(client kclient.Client, files chan<- shared.File, ext *mlApiv1alpha1.ArangoMLCronJob) error { files <- shared.NewYAMLFile(fmt.Sprintf("kubernetes/arango/ml/cronjobs/%s.yaml", ext.GetName()), func() ([]interface{}, error) { return []interface{}{ext}, nil }) @@ -60,9 +60,9 @@ func mlCronJob(client kclient.Client, files chan<- shared.File, ext *mlApi.Arang return nil } -func listMLCronJobs(client kclient.Client) ([]*mlApi.ArangoMLCronJob, error) { - return ListObjects[*mlApi.ArangoMLCronJobList, *mlApi.ArangoMLCronJob](context.Background(), client.Arango().MlV1alpha1().ArangoMLCronJobs(cli.GetInput().Namespace), func(result *mlApi.ArangoMLCronJobList) []*mlApi.ArangoMLCronJob { - q := make([]*mlApi.ArangoMLCronJob, len(result.Items)) +func listMLCronJobs(client kclient.Client) ([]*mlApiv1alpha1.ArangoMLCronJob, error) { + return ListObjects[*mlApiv1alpha1.ArangoMLCronJobList, *mlApiv1alpha1.ArangoMLCronJob](context.Background(), client.Arango().MlV1alpha1().ArangoMLCronJobs(cli.GetInput().Namespace), func(result *mlApiv1alpha1.ArangoMLCronJobList) []*mlApiv1alpha1.ArangoMLCronJob { + q := make([]*mlApiv1alpha1.ArangoMLCronJob, len(result.Items)) for id, e := range result.Items { q[id] = e.DeepCopy() diff --git a/pkg/debug_package/generators/kubernetes/arango_ml_extension.go b/pkg/debug_package/generators/kubernetes/arango_ml_extension.go index 2c894c344..6cb523c4c 100644 --- a/pkg/debug_package/generators/kubernetes/arango_ml_extension.go +++ b/pkg/debug_package/generators/kubernetes/arango_ml_extension.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-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. @@ -26,7 +26,7 @@ import ( "github.com/rs/zerolog" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" "github.com/arangodb/kube-arangodb/pkg/debug_package/cli" "github.com/arangodb/kube-arangodb/pkg/debug_package/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -61,7 +61,7 @@ func mlExtension(client kclient.Client, files chan<- shared.File, ext *mlApi.Ara } func listMLExtensions(client kclient.Client) ([]*mlApi.ArangoMLExtension, error) { - return ListObjects[*mlApi.ArangoMLExtensionList, *mlApi.ArangoMLExtension](context.Background(), client.Arango().MlV1alpha1().ArangoMLExtensions(cli.GetInput().Namespace), func(result *mlApi.ArangoMLExtensionList) []*mlApi.ArangoMLExtension { + return ListObjects[*mlApi.ArangoMLExtensionList, *mlApi.ArangoMLExtension](context.Background(), client.Arango().MlV1beta1().ArangoMLExtensions(cli.GetInput().Namespace), func(result *mlApi.ArangoMLExtensionList) []*mlApi.ArangoMLExtension { q := make([]*mlApi.ArangoMLExtension, len(result.Items)) for id, e := range result.Items { diff --git a/pkg/debug_package/generators/kubernetes/arango_ml_storage.go b/pkg/debug_package/generators/kubernetes/arango_ml_storage.go index d68d8c04a..5a7c0f6d2 100644 --- a/pkg/debug_package/generators/kubernetes/arango_ml_storage.go +++ b/pkg/debug_package/generators/kubernetes/arango_ml_storage.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-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. @@ -26,7 +26,7 @@ import ( "github.com/rs/zerolog" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" "github.com/arangodb/kube-arangodb/pkg/debug_package/cli" "github.com/arangodb/kube-arangodb/pkg/debug_package/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -61,7 +61,7 @@ func mlStorage(client kclient.Client, files chan<- shared.File, ext *mlApi.Arang } func listMLStorages(client kclient.Client) ([]*mlApi.ArangoMLStorage, error) { - return ListObjects[*mlApi.ArangoMLStorageList, *mlApi.ArangoMLStorage](context.Background(), client.Arango().MlV1alpha1().ArangoMLStorages(cli.GetInput().Namespace), func(result *mlApi.ArangoMLStorageList) []*mlApi.ArangoMLStorage { + return ListObjects[*mlApi.ArangoMLStorageList, *mlApi.ArangoMLStorage](context.Background(), client.Arango().MlV1beta1().ArangoMLStorages(cli.GetInput().Namespace), func(result *mlApi.ArangoMLStorageList) []*mlApi.ArangoMLStorage { q := make([]*mlApi.ArangoMLStorage, len(result.Items)) for id, e := range result.Items { diff --git a/pkg/debug_package/generators/kubernetes/arango_scheduler_profile.go b/pkg/debug_package/generators/kubernetes/arango_scheduler_profile.go index 49b0f07bc..9c3c25cb1 100644 --- a/pkg/debug_package/generators/kubernetes/arango_scheduler_profile.go +++ b/pkg/debug_package/generators/kubernetes/arango_scheduler_profile.go @@ -26,7 +26,7 @@ import ( "github.com/rs/zerolog" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" "github.com/arangodb/kube-arangodb/pkg/debug_package/cli" "github.com/arangodb/kube-arangodb/pkg/debug_package/shared" "github.com/arangodb/kube-arangodb/pkg/util/errors" @@ -61,7 +61,7 @@ func schedulerProfile(client kclient.Client, files chan<- shared.File, ext *sche } func listSchedulerProfiles(client kclient.Client) ([]*schedulerApi.ArangoProfile, error) { - return ListObjects[*schedulerApi.ArangoProfileList, *schedulerApi.ArangoProfile](context.Background(), client.Arango().SchedulerV1alpha1().ArangoProfiles(cli.GetInput().Namespace), func(result *schedulerApi.ArangoProfileList) []*schedulerApi.ArangoProfile { + return ListObjects[*schedulerApi.ArangoProfileList, *schedulerApi.ArangoProfile](context.Background(), client.Arango().SchedulerV1beta1().ArangoProfiles(cli.GetInput().Namespace), func(result *schedulerApi.ArangoProfileList) []*schedulerApi.ArangoProfile { q := make([]*schedulerApi.ArangoProfile, len(result.Items)) for id, e := range result.Items { diff --git a/pkg/generated/clientset/versioned/clientset.go b/pkg/generated/clientset/versioned/clientset.go index 9757effe5..84b582636 100644 --- a/pkg/generated/clientset/versioned/clientset.go +++ b/pkg/generated/clientset/versioned/clientset.go @@ -31,9 +31,11 @@ import ( databasev1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/deployment/v1" databasev2alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/deployment/v2alpha1" mlv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1alpha1" + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1beta1" replicationv1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v1" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v2alpha1" schedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1alpha1" + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1beta1" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/storage/v1alpha" discovery "k8s.io/client-go/discovery" rest "k8s.io/client-go/rest" @@ -47,9 +49,11 @@ type Interface interface { DatabaseV1() databasev1.DatabaseV1Interface DatabaseV2alpha1() databasev2alpha1.DatabaseV2alpha1Interface MlV1alpha1() mlv1alpha1.MlV1alpha1Interface + MlV1beta1() mlv1beta1.MlV1beta1Interface ReplicationV1() replicationv1.ReplicationV1Interface ReplicationV2alpha1() replicationv2alpha1.ReplicationV2alpha1Interface SchedulerV1alpha1() schedulerv1alpha1.SchedulerV1alpha1Interface + SchedulerV1beta1() schedulerv1beta1.SchedulerV1beta1Interface StorageV1alpha() storagev1alpha.StorageV1alphaInterface } @@ -61,9 +65,11 @@ type Clientset struct { databaseV1 *databasev1.DatabaseV1Client databaseV2alpha1 *databasev2alpha1.DatabaseV2alpha1Client mlV1alpha1 *mlv1alpha1.MlV1alpha1Client + mlV1beta1 *mlv1beta1.MlV1beta1Client replicationV1 *replicationv1.ReplicationV1Client replicationV2alpha1 *replicationv2alpha1.ReplicationV2alpha1Client schedulerV1alpha1 *schedulerv1alpha1.SchedulerV1alpha1Client + schedulerV1beta1 *schedulerv1beta1.SchedulerV1beta1Client storageV1alpha *storagev1alpha.StorageV1alphaClient } @@ -92,6 +98,11 @@ func (c *Clientset) MlV1alpha1() mlv1alpha1.MlV1alpha1Interface { return c.mlV1alpha1 } +// MlV1beta1 retrieves the MlV1beta1Client +func (c *Clientset) MlV1beta1() mlv1beta1.MlV1beta1Interface { + return c.mlV1beta1 +} + // ReplicationV1 retrieves the ReplicationV1Client func (c *Clientset) ReplicationV1() replicationv1.ReplicationV1Interface { return c.replicationV1 @@ -107,6 +118,11 @@ func (c *Clientset) SchedulerV1alpha1() schedulerv1alpha1.SchedulerV1alpha1Inter return c.schedulerV1alpha1 } +// SchedulerV1beta1 retrieves the SchedulerV1beta1Client +func (c *Clientset) SchedulerV1beta1() schedulerv1beta1.SchedulerV1beta1Interface { + return c.schedulerV1beta1 +} + // StorageV1alpha retrieves the StorageV1alphaClient func (c *Clientset) StorageV1alpha() storagev1alpha.StorageV1alphaInterface { return c.storageV1alpha @@ -176,6 +192,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.mlV1beta1, err = mlv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.replicationV1, err = replicationv1.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -188,6 +208,10 @@ func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, if err != nil { return nil, err } + cs.schedulerV1beta1, err = schedulerv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) + if err != nil { + return nil, err + } cs.storageV1alpha, err = storagev1alpha.NewForConfigAndClient(&configShallowCopy, httpClient) if err != nil { return nil, err @@ -218,9 +242,11 @@ func New(c rest.Interface) *Clientset { cs.databaseV1 = databasev1.New(c) cs.databaseV2alpha1 = databasev2alpha1.New(c) cs.mlV1alpha1 = mlv1alpha1.New(c) + cs.mlV1beta1 = mlv1beta1.New(c) cs.replicationV1 = replicationv1.New(c) cs.replicationV2alpha1 = replicationv2alpha1.New(c) cs.schedulerV1alpha1 = schedulerv1alpha1.New(c) + cs.schedulerV1beta1 = schedulerv1beta1.New(c) cs.storageV1alpha = storagev1alpha.New(c) cs.DiscoveryClient = discovery.NewDiscoveryClient(c) diff --git a/pkg/generated/clientset/versioned/fake/clientset_generated.go b/pkg/generated/clientset/versioned/fake/clientset_generated.go index bbdc529b9..1ad16d4fa 100644 --- a/pkg/generated/clientset/versioned/fake/clientset_generated.go +++ b/pkg/generated/clientset/versioned/fake/clientset_generated.go @@ -34,12 +34,16 @@ import ( fakedatabasev2alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/deployment/v2alpha1/fake" mlv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1alpha1" fakemlv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1alpha1/fake" + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1beta1" + fakemlv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake" replicationv1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v1" fakereplicationv1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v1/fake" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v2alpha1" fakereplicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/replication/v2alpha1/fake" schedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1alpha1" fakeschedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1alpha1/fake" + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1beta1" + fakeschedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/storage/v1alpha" fakestoragev1alpha "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/storage/v1alpha/fake" "k8s.io/apimachinery/pkg/runtime" @@ -124,6 +128,11 @@ func (c *Clientset) MlV1alpha1() mlv1alpha1.MlV1alpha1Interface { return &fakemlv1alpha1.FakeMlV1alpha1{Fake: &c.Fake} } +// MlV1beta1 retrieves the MlV1beta1Client +func (c *Clientset) MlV1beta1() mlv1beta1.MlV1beta1Interface { + return &fakemlv1beta1.FakeMlV1beta1{Fake: &c.Fake} +} + // ReplicationV1 retrieves the ReplicationV1Client func (c *Clientset) ReplicationV1() replicationv1.ReplicationV1Interface { return &fakereplicationv1.FakeReplicationV1{Fake: &c.Fake} @@ -139,6 +148,11 @@ func (c *Clientset) SchedulerV1alpha1() schedulerv1alpha1.SchedulerV1alpha1Inter return &fakeschedulerv1alpha1.FakeSchedulerV1alpha1{Fake: &c.Fake} } +// SchedulerV1beta1 retrieves the SchedulerV1beta1Client +func (c *Clientset) SchedulerV1beta1() schedulerv1beta1.SchedulerV1beta1Interface { + return &fakeschedulerv1beta1.FakeSchedulerV1beta1{Fake: &c.Fake} +} + // StorageV1alpha retrieves the StorageV1alphaClient func (c *Clientset) StorageV1alpha() storagev1alpha.StorageV1alphaInterface { return &fakestoragev1alpha.FakeStorageV1alpha{Fake: &c.Fake} diff --git a/pkg/generated/clientset/versioned/fake/register.go b/pkg/generated/clientset/versioned/fake/register.go index c8385285f..a95fee35e 100644 --- a/pkg/generated/clientset/versioned/fake/register.go +++ b/pkg/generated/clientset/versioned/fake/register.go @@ -28,9 +28,11 @@ import ( databasev1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" databasev2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v2alpha1" mlv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" replicationv1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v2alpha1" schedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -48,9 +50,11 @@ var localSchemeBuilder = runtime.SchemeBuilder{ databasev1.AddToScheme, databasev2alpha1.AddToScheme, mlv1alpha1.AddToScheme, + mlv1beta1.AddToScheme, replicationv1.AddToScheme, replicationv2alpha1.AddToScheme, schedulerv1alpha1.AddToScheme, + schedulerv1beta1.AddToScheme, storagev1alpha.AddToScheme, } diff --git a/pkg/generated/clientset/versioned/scheme/register.go b/pkg/generated/clientset/versioned/scheme/register.go index ddd5006c1..0f069075e 100644 --- a/pkg/generated/clientset/versioned/scheme/register.go +++ b/pkg/generated/clientset/versioned/scheme/register.go @@ -28,9 +28,11 @@ import ( databasev1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" databasev2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v2alpha1" mlv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" replicationv1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v2alpha1" schedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" @@ -48,9 +50,11 @@ var localSchemeBuilder = runtime.SchemeBuilder{ databasev1.AddToScheme, databasev2alpha1.AddToScheme, mlv1alpha1.AddToScheme, + mlv1beta1.AddToScheme, replicationv1.AddToScheme, replicationv2alpha1.AddToScheme, schedulerv1alpha1.AddToScheme, + schedulerv1beta1.AddToScheme, storagev1alpha.AddToScheme, } diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlextension.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlextension.go new file mode 100644 index 000000000..2c38e940e --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlextension.go @@ -0,0 +1,199 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + scheme "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ArangoMLExtensionsGetter has a method to return a ArangoMLExtensionInterface. +// A group's client should implement this interface. +type ArangoMLExtensionsGetter interface { + ArangoMLExtensions(namespace string) ArangoMLExtensionInterface +} + +// ArangoMLExtensionInterface has methods to work with ArangoMLExtension resources. +type ArangoMLExtensionInterface interface { + Create(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.CreateOptions) (*v1beta1.ArangoMLExtension, error) + Update(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (*v1beta1.ArangoMLExtension, error) + UpdateStatus(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (*v1beta1.ArangoMLExtension, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.ArangoMLExtension, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoMLExtensionList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLExtension, err error) + ArangoMLExtensionExpansion +} + +// arangoMLExtensions implements ArangoMLExtensionInterface +type arangoMLExtensions struct { + client rest.Interface + ns string +} + +// newArangoMLExtensions returns a ArangoMLExtensions +func newArangoMLExtensions(c *MlV1beta1Client, namespace string) *arangoMLExtensions { + return &arangoMLExtensions{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoMLExtension, and returns the corresponding arangoMLExtension object, and an error if there is any. +func (c *arangoMLExtensions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoMLExtension, err error) { + result = &v1beta1.ArangoMLExtension{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangomlextensions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoMLExtensions that match those selectors. +func (c *arangoMLExtensions) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoMLExtensionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoMLExtensionList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangomlextensions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoMLExtensions. +func (c *arangoMLExtensions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("arangomlextensions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoMLExtension and creates it. Returns the server's representation of the arangoMLExtension, and an error, if there is any. +func (c *arangoMLExtensions) Create(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.CreateOptions) (result *v1beta1.ArangoMLExtension, err error) { + result = &v1beta1.ArangoMLExtension{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangomlextensions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLExtension). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoMLExtension and updates it. Returns the server's representation of the arangoMLExtension, and an error, if there is any. +func (c *arangoMLExtensions) Update(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (result *v1beta1.ArangoMLExtension, err error) { + result = &v1beta1.ArangoMLExtension{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangomlextensions"). + Name(arangoMLExtension.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLExtension). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *arangoMLExtensions) UpdateStatus(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (result *v1beta1.ArangoMLExtension, err error) { + result = &v1beta1.ArangoMLExtension{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangomlextensions"). + Name(arangoMLExtension.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLExtension). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoMLExtension and deletes it. Returns an error if one occurs. +func (c *arangoMLExtensions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangomlextensions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoMLExtensions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("arangomlextensions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoMLExtension. +func (c *arangoMLExtensions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLExtension, err error) { + result = &v1beta1.ArangoMLExtension{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangomlextensions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlstorage.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlstorage.go new file mode 100644 index 000000000..f8c4f4d86 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/arangomlstorage.go @@ -0,0 +1,199 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + scheme "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ArangoMLStoragesGetter has a method to return a ArangoMLStorageInterface. +// A group's client should implement this interface. +type ArangoMLStoragesGetter interface { + ArangoMLStorages(namespace string) ArangoMLStorageInterface +} + +// ArangoMLStorageInterface has methods to work with ArangoMLStorage resources. +type ArangoMLStorageInterface interface { + Create(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.CreateOptions) (*v1beta1.ArangoMLStorage, error) + Update(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (*v1beta1.ArangoMLStorage, error) + UpdateStatus(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (*v1beta1.ArangoMLStorage, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.ArangoMLStorage, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoMLStorageList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLStorage, err error) + ArangoMLStorageExpansion +} + +// arangoMLStorages implements ArangoMLStorageInterface +type arangoMLStorages struct { + client rest.Interface + ns string +} + +// newArangoMLStorages returns a ArangoMLStorages +func newArangoMLStorages(c *MlV1beta1Client, namespace string) *arangoMLStorages { + return &arangoMLStorages{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoMLStorage, and returns the corresponding arangoMLStorage object, and an error if there is any. +func (c *arangoMLStorages) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoMLStorage, err error) { + result = &v1beta1.ArangoMLStorage{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangomlstorages"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoMLStorages that match those selectors. +func (c *arangoMLStorages) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoMLStorageList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoMLStorageList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangomlstorages"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoMLStorages. +func (c *arangoMLStorages) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("arangomlstorages"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoMLStorage and creates it. Returns the server's representation of the arangoMLStorage, and an error, if there is any. +func (c *arangoMLStorages) Create(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.CreateOptions) (result *v1beta1.ArangoMLStorage, err error) { + result = &v1beta1.ArangoMLStorage{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangomlstorages"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLStorage). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoMLStorage and updates it. Returns the server's representation of the arangoMLStorage, and an error, if there is any. +func (c *arangoMLStorages) Update(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (result *v1beta1.ArangoMLStorage, err error) { + result = &v1beta1.ArangoMLStorage{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangomlstorages"). + Name(arangoMLStorage.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLStorage). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *arangoMLStorages) UpdateStatus(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (result *v1beta1.ArangoMLStorage, err error) { + result = &v1beta1.ArangoMLStorage{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangomlstorages"). + Name(arangoMLStorage.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoMLStorage). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoMLStorage and deletes it. Returns an error if one occurs. +func (c *arangoMLStorages) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangomlstorages"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoMLStorages) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("arangomlstorages"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoMLStorage. +func (c *arangoMLStorages) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLStorage, err error) { + result = &v1beta1.ArangoMLStorage{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangomlstorages"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/doc.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/doc.go new file mode 100644 index 000000000..f22204098 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/doc.go @@ -0,0 +1,24 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/doc.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/doc.go new file mode 100644 index 000000000..cc487d814 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/doc.go @@ -0,0 +1,24 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlextension.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlextension.go new file mode 100644 index 000000000..1282d7b8d --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlextension.go @@ -0,0 +1,145 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeArangoMLExtensions implements ArangoMLExtensionInterface +type FakeArangoMLExtensions struct { + Fake *FakeMlV1beta1 + ns string +} + +var arangomlextensionsResource = v1beta1.SchemeGroupVersion.WithResource("arangomlextensions") + +var arangomlextensionsKind = v1beta1.SchemeGroupVersion.WithKind("ArangoMLExtension") + +// Get takes name of the arangoMLExtension, and returns the corresponding arangoMLExtension object, and an error if there is any. +func (c *FakeArangoMLExtensions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoMLExtension, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangomlextensionsResource, c.ns, name), &v1beta1.ArangoMLExtension{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLExtension), err +} + +// List takes label and field selectors, and returns the list of ArangoMLExtensions that match those selectors. +func (c *FakeArangoMLExtensions) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoMLExtensionList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangomlextensionsResource, arangomlextensionsKind, c.ns, opts), &v1beta1.ArangoMLExtensionList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoMLExtensionList{ListMeta: obj.(*v1beta1.ArangoMLExtensionList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoMLExtensionList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested arangoMLExtensions. +func (c *FakeArangoMLExtensions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangomlextensionsResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoMLExtension and creates it. Returns the server's representation of the arangoMLExtension, and an error, if there is any. +func (c *FakeArangoMLExtensions) Create(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.CreateOptions) (result *v1beta1.ArangoMLExtension, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangomlextensionsResource, c.ns, arangoMLExtension), &v1beta1.ArangoMLExtension{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLExtension), err +} + +// Update takes the representation of a arangoMLExtension and updates it. Returns the server's representation of the arangoMLExtension, and an error, if there is any. +func (c *FakeArangoMLExtensions) Update(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (result *v1beta1.ArangoMLExtension, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangomlextensionsResource, c.ns, arangoMLExtension), &v1beta1.ArangoMLExtension{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLExtension), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeArangoMLExtensions) UpdateStatus(ctx context.Context, arangoMLExtension *v1beta1.ArangoMLExtension, opts v1.UpdateOptions) (*v1beta1.ArangoMLExtension, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangomlextensionsResource, "status", c.ns, arangoMLExtension), &v1beta1.ArangoMLExtension{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLExtension), err +} + +// Delete takes name of the arangoMLExtension and deletes it. Returns an error if one occurs. +func (c *FakeArangoMLExtensions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangomlextensionsResource, c.ns, name, opts), &v1beta1.ArangoMLExtension{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoMLExtensions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangomlextensionsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoMLExtensionList{}) + return err +} + +// Patch applies the patch and returns the patched arangoMLExtension. +func (c *FakeArangoMLExtensions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLExtension, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangomlextensionsResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoMLExtension{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLExtension), err +} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlstorage.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlstorage.go new file mode 100644 index 000000000..d824684f0 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_arangomlstorage.go @@ -0,0 +1,145 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeArangoMLStorages implements ArangoMLStorageInterface +type FakeArangoMLStorages struct { + Fake *FakeMlV1beta1 + ns string +} + +var arangomlstoragesResource = v1beta1.SchemeGroupVersion.WithResource("arangomlstorages") + +var arangomlstoragesKind = v1beta1.SchemeGroupVersion.WithKind("ArangoMLStorage") + +// Get takes name of the arangoMLStorage, and returns the corresponding arangoMLStorage object, and an error if there is any. +func (c *FakeArangoMLStorages) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoMLStorage, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangomlstoragesResource, c.ns, name), &v1beta1.ArangoMLStorage{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLStorage), err +} + +// List takes label and field selectors, and returns the list of ArangoMLStorages that match those selectors. +func (c *FakeArangoMLStorages) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoMLStorageList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangomlstoragesResource, arangomlstoragesKind, c.ns, opts), &v1beta1.ArangoMLStorageList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoMLStorageList{ListMeta: obj.(*v1beta1.ArangoMLStorageList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoMLStorageList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested arangoMLStorages. +func (c *FakeArangoMLStorages) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangomlstoragesResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoMLStorage and creates it. Returns the server's representation of the arangoMLStorage, and an error, if there is any. +func (c *FakeArangoMLStorages) Create(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.CreateOptions) (result *v1beta1.ArangoMLStorage, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangomlstoragesResource, c.ns, arangoMLStorage), &v1beta1.ArangoMLStorage{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLStorage), err +} + +// Update takes the representation of a arangoMLStorage and updates it. Returns the server's representation of the arangoMLStorage, and an error, if there is any. +func (c *FakeArangoMLStorages) Update(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (result *v1beta1.ArangoMLStorage, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangomlstoragesResource, c.ns, arangoMLStorage), &v1beta1.ArangoMLStorage{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLStorage), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeArangoMLStorages) UpdateStatus(ctx context.Context, arangoMLStorage *v1beta1.ArangoMLStorage, opts v1.UpdateOptions) (*v1beta1.ArangoMLStorage, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangomlstoragesResource, "status", c.ns, arangoMLStorage), &v1beta1.ArangoMLStorage{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLStorage), err +} + +// Delete takes name of the arangoMLStorage and deletes it. Returns an error if one occurs. +func (c *FakeArangoMLStorages) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangomlstoragesResource, c.ns, name, opts), &v1beta1.ArangoMLStorage{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoMLStorages) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangomlstoragesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoMLStorageList{}) + return err +} + +// Patch applies the patch and returns the patched arangoMLStorage. +func (c *FakeArangoMLStorages) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoMLStorage, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangomlstoragesResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoMLStorage{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoMLStorage), err +} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_ml_client.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_ml_client.go new file mode 100644 index 000000000..52542249f --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/fake/fake_ml_client.go @@ -0,0 +1,48 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/ml/v1beta1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeMlV1beta1 struct { + *testing.Fake +} + +func (c *FakeMlV1beta1) ArangoMLExtensions(namespace string) v1beta1.ArangoMLExtensionInterface { + return &FakeArangoMLExtensions{c, namespace} +} + +func (c *FakeMlV1beta1) ArangoMLStorages(namespace string) v1beta1.ArangoMLStorageInterface { + return &FakeArangoMLStorages{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeMlV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/generated_expansion.go new file mode 100644 index 000000000..0d2d90361 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/generated_expansion.go @@ -0,0 +1,27 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type ArangoMLExtensionExpansion interface{} + +type ArangoMLStorageExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/ml/v1beta1/ml_client.go b/pkg/generated/clientset/versioned/typed/ml/v1beta1/ml_client.go new file mode 100644 index 000000000..3d16cf2cd --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/ml/v1beta1/ml_client.go @@ -0,0 +1,116 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "net/http" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type MlV1beta1Interface interface { + RESTClient() rest.Interface + ArangoMLExtensionsGetter + ArangoMLStoragesGetter +} + +// MlV1beta1Client is used to interact with features provided by the ml.arangodb.com group. +type MlV1beta1Client struct { + restClient rest.Interface +} + +func (c *MlV1beta1Client) ArangoMLExtensions(namespace string) ArangoMLExtensionInterface { + return newArangoMLExtensions(c, namespace) +} + +func (c *MlV1beta1Client) ArangoMLStorages(namespace string) ArangoMLStorageInterface { + return newArangoMLStorages(c, namespace) +} + +// NewForConfig creates a new MlV1beta1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*MlV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new MlV1beta1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*MlV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &MlV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new MlV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *MlV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new MlV1beta1Client for the given RESTClient. +func New(c rest.Interface) *MlV1beta1Client { + return &MlV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *MlV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoprofile.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoprofile.go new file mode 100644 index 000000000..37b9c7ab5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoprofile.go @@ -0,0 +1,199 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + scheme "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// ArangoProfilesGetter has a method to return a ArangoProfileInterface. +// A group's client should implement this interface. +type ArangoProfilesGetter interface { + ArangoProfiles(namespace string) ArangoProfileInterface +} + +// ArangoProfileInterface has methods to work with ArangoProfile resources. +type ArangoProfileInterface interface { + Create(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.CreateOptions) (*v1beta1.ArangoProfile, error) + Update(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (*v1beta1.ArangoProfile, error) + UpdateStatus(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (*v1beta1.ArangoProfile, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.ArangoProfile, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoProfileList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoProfile, err error) + ArangoProfileExpansion +} + +// arangoProfiles implements ArangoProfileInterface +type arangoProfiles struct { + client rest.Interface + ns string +} + +// newArangoProfiles returns a ArangoProfiles +func newArangoProfiles(c *SchedulerV1beta1Client, namespace string) *arangoProfiles { + return &arangoProfiles{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoProfile, and returns the corresponding arangoProfile object, and an error if there is any. +func (c *arangoProfiles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoProfile, err error) { + result = &v1beta1.ArangoProfile{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoprofiles"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoProfiles that match those selectors. +func (c *arangoProfiles) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoProfileList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoProfileList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoProfiles. +func (c *arangoProfiles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("arangoprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoProfile and creates it. Returns the server's representation of the arangoProfile, and an error, if there is any. +func (c *arangoProfiles) Create(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.CreateOptions) (result *v1beta1.ArangoProfile, err error) { + result = &v1beta1.ArangoProfile{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangoprofiles"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoProfile). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoProfile and updates it. Returns the server's representation of the arangoProfile, and an error, if there is any. +func (c *arangoProfiles) Update(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (result *v1beta1.ArangoProfile, err error) { + result = &v1beta1.ArangoProfile{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoprofiles"). + Name(arangoProfile.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoProfile). + Do(ctx). + Into(result) + return +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *arangoProfiles) UpdateStatus(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (result *v1beta1.ArangoProfile, err error) { + result = &v1beta1.ArangoProfile{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoprofiles"). + Name(arangoProfile.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoProfile). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoProfile and deletes it. Returns an error if one occurs. +func (c *arangoProfiles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoprofiles"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoProfiles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoprofiles"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoProfile. +func (c *arangoProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoProfile, err error) { + result = &v1beta1.ArangoProfile{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangoprofiles"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/doc.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/doc.go new file mode 100644 index 000000000..f22204098 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/doc.go @@ -0,0 +1,24 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +// This package has the automatically generated typed clients. +package v1beta1 diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/doc.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/doc.go new file mode 100644 index 000000000..cc487d814 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/doc.go @@ -0,0 +1,24 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +// Package fake has the automatically generated clients. +package fake diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoprofile.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoprofile.go new file mode 100644 index 000000000..b7ae44fa5 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoprofile.go @@ -0,0 +1,145 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeArangoProfiles implements ArangoProfileInterface +type FakeArangoProfiles struct { + Fake *FakeSchedulerV1beta1 + ns string +} + +var arangoprofilesResource = v1beta1.SchemeGroupVersion.WithResource("arangoprofiles") + +var arangoprofilesKind = v1beta1.SchemeGroupVersion.WithKind("ArangoProfile") + +// Get takes name of the arangoProfile, and returns the corresponding arangoProfile object, and an error if there is any. +func (c *FakeArangoProfiles) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangoprofilesResource, c.ns, name), &v1beta1.ArangoProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoProfile), err +} + +// List takes label and field selectors, and returns the list of ArangoProfiles that match those selectors. +func (c *FakeArangoProfiles) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoProfileList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangoprofilesResource, arangoprofilesKind, c.ns, opts), &v1beta1.ArangoProfileList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoProfileList{ListMeta: obj.(*v1beta1.ArangoProfileList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoProfileList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested arangoProfiles. +func (c *FakeArangoProfiles) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangoprofilesResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoProfile and creates it. Returns the server's representation of the arangoProfile, and an error, if there is any. +func (c *FakeArangoProfiles) Create(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.CreateOptions) (result *v1beta1.ArangoProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangoprofilesResource, c.ns, arangoProfile), &v1beta1.ArangoProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoProfile), err +} + +// Update takes the representation of a arangoProfile and updates it. Returns the server's representation of the arangoProfile, and an error, if there is any. +func (c *FakeArangoProfiles) Update(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (result *v1beta1.ArangoProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangoprofilesResource, c.ns, arangoProfile), &v1beta1.ArangoProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoProfile), err +} + +// UpdateStatus was generated because the type contains a Status member. +// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). +func (c *FakeArangoProfiles) UpdateStatus(ctx context.Context, arangoProfile *v1beta1.ArangoProfile, opts v1.UpdateOptions) (*v1beta1.ArangoProfile, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangoprofilesResource, "status", c.ns, arangoProfile), &v1beta1.ArangoProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoProfile), err +} + +// Delete takes name of the arangoProfile and deletes it. Returns an error if one occurs. +func (c *FakeArangoProfiles) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangoprofilesResource, c.ns, name, opts), &v1beta1.ArangoProfile{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoProfiles) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangoprofilesResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoProfileList{}) + return err +} + +// Patch applies the patch and returns the patched arangoProfile. +func (c *FakeArangoProfiles) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoProfile, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangoprofilesResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoProfile{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoProfile), err +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_scheduler_client.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_scheduler_client.go new file mode 100644 index 000000000..b00b03e6b --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_scheduler_client.go @@ -0,0 +1,44 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/typed/scheduler/v1beta1" + rest "k8s.io/client-go/rest" + testing "k8s.io/client-go/testing" +) + +type FakeSchedulerV1beta1 struct { + *testing.Fake +} + +func (c *FakeSchedulerV1beta1) ArangoProfiles(namespace string) v1beta1.ArangoProfileInterface { + return &FakeArangoProfiles{c, namespace} +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *FakeSchedulerV1beta1) RESTClient() rest.Interface { + var ret *rest.RESTClient + return ret +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go new file mode 100644 index 000000000..5d703a84e --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go @@ -0,0 +1,25 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +type ArangoProfileExpansion interface{} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go new file mode 100644 index 000000000..c2d911e0b --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go @@ -0,0 +1,111 @@ +// +// 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 +// + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "net/http" + + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/scheme" + rest "k8s.io/client-go/rest" +) + +type SchedulerV1beta1Interface interface { + RESTClient() rest.Interface + ArangoProfilesGetter +} + +// SchedulerV1beta1Client is used to interact with features provided by the scheduler.arangodb.com group. +type SchedulerV1beta1Client struct { + restClient rest.Interface +} + +func (c *SchedulerV1beta1Client) ArangoProfiles(namespace string) ArangoProfileInterface { + return newArangoProfiles(c, namespace) +} + +// NewForConfig creates a new SchedulerV1beta1Client for the given config. +// NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), +// where httpClient was generated with rest.HTTPClientFor(c). +func NewForConfig(c *rest.Config) (*SchedulerV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + httpClient, err := rest.HTTPClientFor(&config) + if err != nil { + return nil, err + } + return NewForConfigAndClient(&config, httpClient) +} + +// NewForConfigAndClient creates a new SchedulerV1beta1Client for the given config and http client. +// Note the http client provided takes precedence over the configured transport values. +func NewForConfigAndClient(c *rest.Config, h *http.Client) (*SchedulerV1beta1Client, error) { + config := *c + if err := setConfigDefaults(&config); err != nil { + return nil, err + } + client, err := rest.RESTClientForConfigAndClient(&config, h) + if err != nil { + return nil, err + } + return &SchedulerV1beta1Client{client}, nil +} + +// NewForConfigOrDie creates a new SchedulerV1beta1Client for the given config and +// panics if there is an error in the config. +func NewForConfigOrDie(c *rest.Config) *SchedulerV1beta1Client { + client, err := NewForConfig(c) + if err != nil { + panic(err) + } + return client +} + +// New creates a new SchedulerV1beta1Client for the given RESTClient. +func New(c rest.Interface) *SchedulerV1beta1Client { + return &SchedulerV1beta1Client{c} +} + +func setConfigDefaults(config *rest.Config) error { + gv := v1beta1.SchemeGroupVersion + config.GroupVersion = &gv + config.APIPath = "/apis" + config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() + + if config.UserAgent == "" { + config.UserAgent = rest.DefaultKubernetesUserAgent() + } + + return nil +} + +// RESTClient returns a RESTClient that is used to communicate +// with API server by this client implementation. +func (c *SchedulerV1beta1Client) RESTClient() rest.Interface { + if c == nil { + return nil + } + return c.restClient +} diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index d9a68a773..59c6826ac 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -30,9 +30,11 @@ import ( deploymentv1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" v2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v2alpha1" v1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" replicationv1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1" replicationv2alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/replication/v2alpha1" schedulerv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" v1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" schema "k8s.io/apimachinery/pkg/runtime/schema" cache "k8s.io/client-go/tools/cache" @@ -104,6 +106,12 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case v1alpha1.SchemeGroupVersion.WithResource("arangomlstorages"): return &genericInformer{resource: resource.GroupResource(), informer: f.Ml().V1alpha1().ArangoMLStorages().Informer()}, nil + // Group=ml.arangodb.com, Version=v1beta1 + case v1beta1.SchemeGroupVersion.WithResource("arangomlextensions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Ml().V1beta1().ArangoMLExtensions().Informer()}, nil + case v1beta1.SchemeGroupVersion.WithResource("arangomlstorages"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Ml().V1beta1().ArangoMLStorages().Informer()}, nil + // Group=replication.database.arangodb.com, Version=v1 case replicationv1.SchemeGroupVersion.WithResource("arangodeploymentreplications"): return &genericInformer{resource: resource.GroupResource(), informer: f.Replication().V1().ArangoDeploymentReplications().Informer()}, nil @@ -116,6 +124,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource case schedulerv1alpha1.SchemeGroupVersion.WithResource("arangoprofiles"): return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1alpha1().ArangoProfiles().Informer()}, nil + // Group=scheduler.arangodb.com, Version=v1beta1 + case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoprofiles"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoProfiles().Informer()}, nil + // Group=storage.arangodb.com, Version=v1alpha case v1alpha.SchemeGroupVersion.WithResource("arangolocalstorages"): return &genericInformer{resource: resource.GroupResource(), informer: f.Storage().V1alpha().ArangoLocalStorages().Informer()}, nil diff --git a/pkg/generated/informers/externalversions/ml/interface.go b/pkg/generated/informers/externalversions/ml/interface.go index 6bf76c576..3d20a3e01 100644 --- a/pkg/generated/informers/externalversions/ml/interface.go +++ b/pkg/generated/informers/externalversions/ml/interface.go @@ -25,12 +25,15 @@ package ml import ( internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" v1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/ml/v1alpha1" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/ml/v1beta1" ) // Interface provides access to each of this group's versions. type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface } type group struct { @@ -48,3 +51,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/generated/informers/externalversions/ml/v1beta1/arangomlextension.go b/pkg/generated/informers/externalversions/ml/v1beta1/arangomlextension.go new file mode 100644 index 000000000..845de2eba --- /dev/null +++ b/pkg/generated/informers/externalversions/ml/v1beta1/arangomlextension.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 +// + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + versioned "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/listers/ml/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ArangoMLExtensionInformer provides access to a shared informer and lister for +// ArangoMLExtensions. +type ArangoMLExtensionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoMLExtensionLister +} + +type arangoMLExtensionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoMLExtensionInformer constructs a new informer for ArangoMLExtension type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewArangoMLExtensionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoMLExtensionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoMLExtensionInformer constructs a new informer for ArangoMLExtension type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredArangoMLExtensionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MlV1beta1().ArangoMLExtensions(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MlV1beta1().ArangoMLExtensions(namespace).Watch(context.TODO(), options) + }, + }, + &mlv1beta1.ArangoMLExtension{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoMLExtensionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoMLExtensionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoMLExtensionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&mlv1beta1.ArangoMLExtension{}, f.defaultInformer) +} + +func (f *arangoMLExtensionInformer) Lister() v1beta1.ArangoMLExtensionLister { + return v1beta1.NewArangoMLExtensionLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/ml/v1beta1/arangomlstorage.go b/pkg/generated/informers/externalversions/ml/v1beta1/arangomlstorage.go new file mode 100644 index 000000000..ab518348a --- /dev/null +++ b/pkg/generated/informers/externalversions/ml/v1beta1/arangomlstorage.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 +// + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + mlv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + versioned "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/listers/ml/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ArangoMLStorageInformer provides access to a shared informer and lister for +// ArangoMLStorages. +type ArangoMLStorageInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoMLStorageLister +} + +type arangoMLStorageInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoMLStorageInformer constructs a new informer for ArangoMLStorage type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewArangoMLStorageInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoMLStorageInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoMLStorageInformer constructs a new informer for ArangoMLStorage type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredArangoMLStorageInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MlV1beta1().ArangoMLStorages(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.MlV1beta1().ArangoMLStorages(namespace).Watch(context.TODO(), options) + }, + }, + &mlv1beta1.ArangoMLStorage{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoMLStorageInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoMLStorageInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoMLStorageInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&mlv1beta1.ArangoMLStorage{}, f.defaultInformer) +} + +func (f *arangoMLStorageInformer) Lister() v1beta1.ArangoMLStorageLister { + return v1beta1.NewArangoMLStorageLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/ml/v1beta1/interface.go b/pkg/generated/informers/externalversions/ml/v1beta1/interface.go new file mode 100644 index 000000000..fa7d3fe91 --- /dev/null +++ b/pkg/generated/informers/externalversions/ml/v1beta1/interface.go @@ -0,0 +1,56 @@ +// +// 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 +// + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ArangoMLExtensions returns a ArangoMLExtensionInformer. + ArangoMLExtensions() ArangoMLExtensionInformer + // ArangoMLStorages returns a ArangoMLStorageInformer. + ArangoMLStorages() ArangoMLStorageInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ArangoMLExtensions returns a ArangoMLExtensionInformer. +func (v *version) ArangoMLExtensions() ArangoMLExtensionInformer { + return &arangoMLExtensionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ArangoMLStorages returns a ArangoMLStorageInformer. +func (v *version) ArangoMLStorages() ArangoMLStorageInformer { + return &arangoMLStorageInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/informers/externalversions/scheduler/interface.go b/pkg/generated/informers/externalversions/scheduler/interface.go index bb28e6d0b..7d276ad87 100644 --- a/pkg/generated/informers/externalversions/scheduler/interface.go +++ b/pkg/generated/informers/externalversions/scheduler/interface.go @@ -25,12 +25,15 @@ package scheduler import ( internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" v1alpha1 "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/scheduler/v1alpha1" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/scheduler/v1beta1" ) // Interface provides access to each of this group's versions. type Interface interface { // V1alpha1 provides access to shared informers for resources in V1alpha1. V1alpha1() v1alpha1.Interface + // V1beta1 provides access to shared informers for resources in V1beta1. + V1beta1() v1beta1.Interface } type group struct { @@ -48,3 +51,8 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (g *group) V1alpha1() v1alpha1.Interface { return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions) } + +// V1beta1 returns a new v1beta1.Interface. +func (g *group) V1beta1() v1beta1.Interface { + return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoprofile.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoprofile.go new file mode 100644 index 000000000..b201f39ac --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoprofile.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 +// + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + schedulerv1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + versioned "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" + v1beta1 "github.com/arangodb/kube-arangodb/pkg/generated/listers/scheduler/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// ArangoProfileInformer provides access to a shared informer and lister for +// ArangoProfiles. +type ArangoProfileInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoProfileLister +} + +type arangoProfileInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoProfileInformer constructs a new informer for ArangoProfile type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewArangoProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoProfileInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoProfileInformer constructs a new informer for ArangoProfile type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredArangoProfileInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoProfiles(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoProfiles(namespace).Watch(context.TODO(), options) + }, + }, + &schedulerv1beta1.ArangoProfile{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoProfileInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoProfileInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoProfileInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulerv1beta1.ArangoProfile{}, f.defaultInformer) +} + +func (f *arangoProfileInformer) Lister() v1beta1.ArangoProfileLister { + return v1beta1.NewArangoProfileLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go new file mode 100644 index 000000000..1f5e0f743 --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go @@ -0,0 +1,49 @@ +// +// 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 +// + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + internalinterfaces "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions/internalinterfaces" +) + +// Interface provides access to all the informers in this group version. +type Interface interface { + // ArangoProfiles returns a ArangoProfileInformer. + ArangoProfiles() ArangoProfileInformer +} + +type version struct { + factory internalinterfaces.SharedInformerFactory + namespace string + tweakListOptions internalinterfaces.TweakListOptionsFunc +} + +// New returns a new Interface. +func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { + return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} +} + +// ArangoProfiles returns a ArangoProfileInformer. +func (v *version) ArangoProfiles() ArangoProfileInformer { + return &arangoProfileInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/listers/ml/v1beta1/arangomlextension.go b/pkg/generated/listers/ml/v1beta1/arangomlextension.go new file mode 100644 index 000000000..67a7fc3e9 --- /dev/null +++ b/pkg/generated/listers/ml/v1beta1/arangomlextension.go @@ -0,0 +1,103 @@ +// +// 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 +// + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ArangoMLExtensionLister helps list ArangoMLExtensions. +// All objects returned here must be treated as read-only. +type ArangoMLExtensionLister interface { + // List lists all ArangoMLExtensions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoMLExtension, err error) + // ArangoMLExtensions returns an object that can list and get ArangoMLExtensions. + ArangoMLExtensions(namespace string) ArangoMLExtensionNamespaceLister + ArangoMLExtensionListerExpansion +} + +// arangoMLExtensionLister implements the ArangoMLExtensionLister interface. +type arangoMLExtensionLister struct { + indexer cache.Indexer +} + +// NewArangoMLExtensionLister returns a new ArangoMLExtensionLister. +func NewArangoMLExtensionLister(indexer cache.Indexer) ArangoMLExtensionLister { + return &arangoMLExtensionLister{indexer: indexer} +} + +// List lists all ArangoMLExtensions in the indexer. +func (s *arangoMLExtensionLister) List(selector labels.Selector) (ret []*v1beta1.ArangoMLExtension, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoMLExtension)) + }) + return ret, err +} + +// ArangoMLExtensions returns an object that can list and get ArangoMLExtensions. +func (s *arangoMLExtensionLister) ArangoMLExtensions(namespace string) ArangoMLExtensionNamespaceLister { + return arangoMLExtensionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoMLExtensionNamespaceLister helps list and get ArangoMLExtensions. +// All objects returned here must be treated as read-only. +type ArangoMLExtensionNamespaceLister interface { + // List lists all ArangoMLExtensions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoMLExtension, err error) + // Get retrieves the ArangoMLExtension from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoMLExtension, error) + ArangoMLExtensionNamespaceListerExpansion +} + +// arangoMLExtensionNamespaceLister implements the ArangoMLExtensionNamespaceLister +// interface. +type arangoMLExtensionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoMLExtensions in the indexer for a given namespace. +func (s arangoMLExtensionNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoMLExtension, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoMLExtension)) + }) + return ret, err +} + +// Get retrieves the ArangoMLExtension from the indexer for a given namespace and name. +func (s arangoMLExtensionNamespaceLister) Get(name string) (*v1beta1.ArangoMLExtension, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangomlextension"), name) + } + return obj.(*v1beta1.ArangoMLExtension), nil +} diff --git a/pkg/generated/listers/ml/v1beta1/arangomlstorage.go b/pkg/generated/listers/ml/v1beta1/arangomlstorage.go new file mode 100644 index 000000000..802fa10c8 --- /dev/null +++ b/pkg/generated/listers/ml/v1beta1/arangomlstorage.go @@ -0,0 +1,103 @@ +// +// 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 +// + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ArangoMLStorageLister helps list ArangoMLStorages. +// All objects returned here must be treated as read-only. +type ArangoMLStorageLister interface { + // List lists all ArangoMLStorages in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoMLStorage, err error) + // ArangoMLStorages returns an object that can list and get ArangoMLStorages. + ArangoMLStorages(namespace string) ArangoMLStorageNamespaceLister + ArangoMLStorageListerExpansion +} + +// arangoMLStorageLister implements the ArangoMLStorageLister interface. +type arangoMLStorageLister struct { + indexer cache.Indexer +} + +// NewArangoMLStorageLister returns a new ArangoMLStorageLister. +func NewArangoMLStorageLister(indexer cache.Indexer) ArangoMLStorageLister { + return &arangoMLStorageLister{indexer: indexer} +} + +// List lists all ArangoMLStorages in the indexer. +func (s *arangoMLStorageLister) List(selector labels.Selector) (ret []*v1beta1.ArangoMLStorage, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoMLStorage)) + }) + return ret, err +} + +// ArangoMLStorages returns an object that can list and get ArangoMLStorages. +func (s *arangoMLStorageLister) ArangoMLStorages(namespace string) ArangoMLStorageNamespaceLister { + return arangoMLStorageNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoMLStorageNamespaceLister helps list and get ArangoMLStorages. +// All objects returned here must be treated as read-only. +type ArangoMLStorageNamespaceLister interface { + // List lists all ArangoMLStorages in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoMLStorage, err error) + // Get retrieves the ArangoMLStorage from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoMLStorage, error) + ArangoMLStorageNamespaceListerExpansion +} + +// arangoMLStorageNamespaceLister implements the ArangoMLStorageNamespaceLister +// interface. +type arangoMLStorageNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoMLStorages in the indexer for a given namespace. +func (s arangoMLStorageNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoMLStorage, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoMLStorage)) + }) + return ret, err +} + +// Get retrieves the ArangoMLStorage from the indexer for a given namespace and name. +func (s arangoMLStorageNamespaceLister) Get(name string) (*v1beta1.ArangoMLStorage, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangomlstorage"), name) + } + return obj.(*v1beta1.ArangoMLStorage), nil +} diff --git a/pkg/generated/listers/ml/v1beta1/expansion_generated.go b/pkg/generated/listers/ml/v1beta1/expansion_generated.go new file mode 100644 index 000000000..38a07d562 --- /dev/null +++ b/pkg/generated/listers/ml/v1beta1/expansion_generated.go @@ -0,0 +1,39 @@ +// +// 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 +// + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// ArangoMLExtensionListerExpansion allows custom methods to be added to +// ArangoMLExtensionLister. +type ArangoMLExtensionListerExpansion interface{} + +// ArangoMLExtensionNamespaceListerExpansion allows custom methods to be added to +// ArangoMLExtensionNamespaceLister. +type ArangoMLExtensionNamespaceListerExpansion interface{} + +// ArangoMLStorageListerExpansion allows custom methods to be added to +// ArangoMLStorageLister. +type ArangoMLStorageListerExpansion interface{} + +// ArangoMLStorageNamespaceListerExpansion allows custom methods to be added to +// ArangoMLStorageNamespaceLister. +type ArangoMLStorageNamespaceListerExpansion interface{} diff --git a/pkg/generated/listers/scheduler/v1beta1/arangoprofile.go b/pkg/generated/listers/scheduler/v1beta1/arangoprofile.go new file mode 100644 index 000000000..f53124f3e --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/arangoprofile.go @@ -0,0 +1,103 @@ +// +// 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 +// + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// ArangoProfileLister helps list ArangoProfiles. +// All objects returned here must be treated as read-only. +type ArangoProfileLister interface { + // List lists all ArangoProfiles in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoProfile, err error) + // ArangoProfiles returns an object that can list and get ArangoProfiles. + ArangoProfiles(namespace string) ArangoProfileNamespaceLister + ArangoProfileListerExpansion +} + +// arangoProfileLister implements the ArangoProfileLister interface. +type arangoProfileLister struct { + indexer cache.Indexer +} + +// NewArangoProfileLister returns a new ArangoProfileLister. +func NewArangoProfileLister(indexer cache.Indexer) ArangoProfileLister { + return &arangoProfileLister{indexer: indexer} +} + +// List lists all ArangoProfiles in the indexer. +func (s *arangoProfileLister) List(selector labels.Selector) (ret []*v1beta1.ArangoProfile, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoProfile)) + }) + return ret, err +} + +// ArangoProfiles returns an object that can list and get ArangoProfiles. +func (s *arangoProfileLister) ArangoProfiles(namespace string) ArangoProfileNamespaceLister { + return arangoProfileNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoProfileNamespaceLister helps list and get ArangoProfiles. +// All objects returned here must be treated as read-only. +type ArangoProfileNamespaceLister interface { + // List lists all ArangoProfiles in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoProfile, err error) + // Get retrieves the ArangoProfile from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoProfile, error) + ArangoProfileNamespaceListerExpansion +} + +// arangoProfileNamespaceLister implements the ArangoProfileNamespaceLister +// interface. +type arangoProfileNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoProfiles in the indexer for a given namespace. +func (s arangoProfileNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoProfile, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoProfile)) + }) + return ret, err +} + +// Get retrieves the ArangoProfile from the indexer for a given namespace and name. +func (s arangoProfileNamespaceLister) Get(name string) (*v1beta1.ArangoProfile, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangoprofile"), name) + } + return obj.(*v1beta1.ArangoProfile), nil +} diff --git a/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go b/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go new file mode 100644 index 000000000..accfa66ce --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go @@ -0,0 +1,31 @@ +// +// 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 +// + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +// ArangoProfileListerExpansion allows custom methods to be added to +// ArangoProfileLister. +type ArangoProfileListerExpansion interface{} + +// ArangoProfileNamespaceListerExpansion allows custom methods to be added to +// ArangoProfileNamespaceLister. +type ArangoProfileNamespaceListerExpansion interface{} diff --git a/pkg/operatorV2/update_wraps.go b/pkg/operatorV2/update_wraps.go index c7a4ed0f4..a7bc813a8 100644 --- a/pkg/operatorV2/update_wraps.go +++ b/pkg/operatorV2/update_wraps.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2023-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. @@ -26,7 +26,8 @@ import ( meta "k8s.io/apimachinery/pkg/apis/meta/v1" backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" ) func WithArangoBackupUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[backupApi.ArangoBackupStatus, *backupApi.ArangoBackup], obj *backupApi.ArangoBackup, status backupApi.ArangoBackupStatus, opts meta.UpdateOptions) (*backupApi.ArangoBackup, error) { @@ -37,12 +38,12 @@ func WithArangoExtensionUpdateStatusInterfaceRetry(ctx context.Context, client U return WithUpdateStatusInterfaceRetry[mlApi.ArangoMLExtensionStatus, *mlApi.ArangoMLExtension](ctx, client, obj, status, opts) } -func WithArangoCronJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApi.ArangoMLCronJobStatus, *mlApi.ArangoMLCronJob], obj *mlApi.ArangoMLCronJob, status mlApi.ArangoMLCronJobStatus, opts meta.UpdateOptions) (*mlApi.ArangoMLCronJob, error) { - return WithUpdateStatusInterfaceRetry[mlApi.ArangoMLCronJobStatus, *mlApi.ArangoMLCronJob](ctx, client, obj, status, opts) +func WithArangoCronJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApiv1alpha1.ArangoMLCronJobStatus, *mlApiv1alpha1.ArangoMLCronJob], obj *mlApiv1alpha1.ArangoMLCronJob, status mlApiv1alpha1.ArangoMLCronJobStatus, opts meta.UpdateOptions) (*mlApiv1alpha1.ArangoMLCronJob, error) { + return WithUpdateStatusInterfaceRetry[mlApiv1alpha1.ArangoMLCronJobStatus, *mlApiv1alpha1.ArangoMLCronJob](ctx, client, obj, status, opts) } -func WithArangoBatchJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApi.ArangoMLBatchJobStatus, *mlApi.ArangoMLBatchJob], obj *mlApi.ArangoMLBatchJob, status mlApi.ArangoMLBatchJobStatus, opts meta.UpdateOptions) (*mlApi.ArangoMLBatchJob, error) { - return WithUpdateStatusInterfaceRetry[mlApi.ArangoMLBatchJobStatus, *mlApi.ArangoMLBatchJob](ctx, client, obj, status, opts) +func WithArangoBatchJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApiv1alpha1.ArangoMLBatchJobStatus, *mlApiv1alpha1.ArangoMLBatchJob], obj *mlApiv1alpha1.ArangoMLBatchJob, status mlApiv1alpha1.ArangoMLBatchJobStatus, opts meta.UpdateOptions) (*mlApiv1alpha1.ArangoMLBatchJob, error) { + return WithUpdateStatusInterfaceRetry[mlApiv1alpha1.ArangoMLBatchJobStatus, *mlApiv1alpha1.ArangoMLBatchJob](ctx, client, obj, status, opts) } func WithArangoStorageUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApi.ArangoMLStorageStatus, *mlApi.ArangoMLStorage], obj *mlApi.ArangoMLStorage, status mlApi.ArangoMLStorageStatus, opts meta.UpdateOptions) (*mlApi.ArangoMLStorage, error) { diff --git a/pkg/scheduler/input.go b/pkg/scheduler/input.go index 6a31349a2..000bfa985 100644 --- a/pkg/scheduler/input.go +++ b/pkg/scheduler/input.go @@ -26,11 +26,11 @@ import ( core "k8s.io/api/core/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" - schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod" - schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/pod/resources" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" + schedulerPodApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod" + schedulerPodResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/pod/resources" "github.com/arangodb/kube-arangodb/pkg/util" ) diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go index 0affbb801..53e77d076 100644 --- a/pkg/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -26,7 +26,7 @@ import ( core "k8s.io/api/core/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" "github.com/arangodb/kube-arangodb/pkg/debug_package/generators/kubernetes" "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/kclient" @@ -53,7 +53,7 @@ func (s scheduler) Render(ctx context.Context, in *pbSchedulerV1.Spec, templates return nil, nil, errors.Errorf("Unable to parse nil Spec") } - profileMap, err := kubernetes.MapObjects[*schedulerApi.ArangoProfileList, *schedulerApi.ArangoProfile](ctx, s.client.Arango().SchedulerV1alpha1().ArangoProfiles(s.namespace), func(result *schedulerApi.ArangoProfileList) []*schedulerApi.ArangoProfile { + profileMap, err := kubernetes.MapObjects[*schedulerApi.ArangoProfileList, *schedulerApi.ArangoProfile](ctx, s.client.Arango().SchedulerV1beta1().ArangoProfiles(s.namespace), func(result *schedulerApi.ArangoProfileList) []*schedulerApi.ArangoProfile { q := make([]*schedulerApi.ArangoProfile, len(result.Items)) for id, e := range result.Items { diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 149382eb4..c70e16bb9 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -31,9 +31,9 @@ import ( "sigs.k8s.io/yaml" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/kclient" "github.com/arangodb/kube-arangodb/pkg/util/tests" diff --git a/pkg/util/k8sutil/images.go b/pkg/util/k8sutil/images.go index 9bbd881bc..9f9a3dc3f 100644 --- a/pkg/util/k8sutil/images.go +++ b/pkg/util/k8sutil/images.go @@ -25,7 +25,7 @@ import ( core "k8s.io/api/core/v1" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" "github.com/arangodb/kube-arangodb/pkg/util/errors" kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" ) diff --git a/pkg/util/k8sutil/pods.go b/pkg/util/k8sutil/pods.go index 1b39a40e4..b2215843a 100644 --- a/pkg/util/k8sutil/pods.go +++ b/pkg/util/k8sutil/pods.go @@ -35,8 +35,8 @@ import ( "k8s.io/apimachinery/pkg/util/json" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container" - schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1/container/resources" + schedulerContainerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container" + schedulerContainerResourcesApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1/container/resources" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/deployment/patch" diff --git a/pkg/util/tests/kubernetes.go b/pkg/util/tests/kubernetes.go index 31a052a41..e9a6a89dd 100644 --- a/pkg/util/tests/kubernetes.go +++ b/pkg/util/tests/kubernetes.go @@ -40,9 +40,11 @@ import ( "github.com/arangodb/kube-arangodb/pkg/apis/deployment" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" "github.com/arangodb/kube-arangodb/pkg/apis/ml" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" @@ -164,14 +166,38 @@ func CreateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe require.NotNil(t, v) vl := *v - _, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + _, err := arango.MlV1beta1().ArangoMLExtensions(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) case **mlApi.ArangoMLStorage: require.NotNil(t, v) + vl := *v + _, err := arango.MlV1beta1().ArangoMLStorages(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLExtension: + require.NotNil(t, v) + + vl := *v + _, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLStorage: + require.NotNil(t, v) + vl := *v _, err := arango.MlV1alpha1().ArangoMLStorages(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLBatchJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.MlV1alpha1().ArangoMLBatchJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLCronJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.MlV1alpha1().ArangoMLCronJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) case **rbac.ClusterRole: require.NotNil(t, v) @@ -196,23 +222,17 @@ func CreateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := k8s.RbacV1().RoleBindings(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) - case **mlApi.ArangoMLBatchJob: + case **schedulerApiv1alpha1.ArangoProfile: require.NotNil(t, v) vl := *v - _, err := arango.MlV1alpha1().ArangoMLBatchJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) - require.NoError(t, err) - case **mlApi.ArangoMLCronJob: - require.NotNil(t, v) - - vl := *v - _, err := arango.MlV1alpha1().ArangoMLCronJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + _, err := arango.SchedulerV1alpha1().ArangoProfiles(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) case **schedulerApi.ArangoProfile: require.NotNil(t, v) vl := *v - _, err := arango.SchedulerV1alpha1().ArangoProfiles(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + _, err := arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) default: require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String())) @@ -294,21 +314,33 @@ func UpdateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe require.NotNil(t, v) vl := *v - _, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + _, err := arango.MlV1beta1().ArangoMLExtensions(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) case **mlApi.ArangoMLStorage: require.NotNil(t, v) + vl := *v + _, err := arango.MlV1beta1().ArangoMLStorages(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLExtension: + require.NotNil(t, v) + + vl := *v + _, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) + case **mlApiv1alpha1.ArangoMLStorage: + require.NotNil(t, v) + vl := *v _, err := arango.MlV1alpha1().ArangoMLStorages(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) - case **mlApi.ArangoMLBatchJob: + case **mlApiv1alpha1.ArangoMLBatchJob: require.NotNil(t, v) vl := *v _, err := arango.MlV1alpha1().ArangoMLBatchJobs(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) - case **mlApi.ArangoMLCronJob: + case **mlApiv1alpha1.ArangoMLCronJob: require.NotNil(t, v) vl := *v @@ -338,12 +370,18 @@ func UpdateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := k8s.RbacV1().RoleBindings(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) - case **schedulerApi.ArangoProfile: + case **schedulerApiv1alpha1.ArangoProfile: require.NotNil(t, v) vl := *v _, err := arango.SchedulerV1alpha1().ArangoProfiles(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) + case **schedulerApi.ArangoProfile: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) default: require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String())) } @@ -411,18 +449,28 @@ func DeleteObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe require.NotNil(t, v) vl := *v - require.NoError(t, arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + require.NoError(t, arango.MlV1beta1().ArangoMLExtensions(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) case **mlApi.ArangoMLStorage: require.NotNil(t, v) + vl := *v + require.NoError(t, arango.MlV1beta1().ArangoMLStorages(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **mlApiv1alpha1.ArangoMLExtension: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **mlApiv1alpha1.ArangoMLStorage: + require.NotNil(t, v) + vl := *v require.NoError(t, arango.MlV1alpha1().ArangoMLStorages(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) - case **mlApi.ArangoMLBatchJob: + case **mlApiv1alpha1.ArangoMLBatchJob: require.NotNil(t, v) vl := *v require.NoError(t, arango.MlV1alpha1().ArangoMLBatchJobs(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) - case **mlApi.ArangoMLCronJob: + case **mlApiv1alpha1.ArangoMLCronJob: require.NotNil(t, v) vl := *v @@ -447,11 +495,16 @@ func DeleteObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v require.NoError(t, k8s.RbacV1().RoleBindings(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) - case **schedulerApi.ArangoProfile: + case **schedulerApiv1alpha1.ArangoProfile: require.NotNil(t, v) vl := *v require.NoError(t, arango.SchedulerV1alpha1().ArangoProfiles(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **schedulerApi.ArangoProfile: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) default: require.Fail(t, fmt.Sprintf("Unable to delete object: %s", reflect.TypeOf(v).String())) } @@ -619,7 +672,7 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS vl := *v - vn, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) + vn, err := arango.MlV1beta1().ArangoMLExtensions(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { *v = nil @@ -634,6 +687,36 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS vl := *v + vn, err := arango.MlV1beta1().ArangoMLStorages(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + *v = nil + } else { + require.NoError(t, err) + } + } else { + *v = vn + } + case **mlApiv1alpha1.ArangoMLExtension: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.MlV1alpha1().ArangoMLExtensions(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + *v = nil + } else { + require.NoError(t, err) + } + } else { + *v = vn + } + case **mlApiv1alpha1.ArangoMLStorage: + require.NotNil(t, v) + + vl := *v + vn, err := arango.MlV1alpha1().ArangoMLStorages(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) if err != nil { if kerrors.IsNotFound(err) { @@ -644,7 +727,7 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } - case **mlApi.ArangoMLBatchJob: + case **mlApiv1alpha1.ArangoMLBatchJob: require.NotNil(t, v) vl := *v @@ -659,7 +742,7 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } - case **mlApi.ArangoMLCronJob: + case **mlApiv1alpha1.ArangoMLCronJob: require.NotNil(t, v) vl := *v @@ -734,7 +817,7 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } - case **schedulerApi.ArangoProfile: + case **schedulerApiv1alpha1.ArangoProfile: require.NotNil(t, v) vl := *v @@ -749,6 +832,21 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } + case **schedulerApi.ArangoProfile: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + *v = nil + } else { + require.NoError(t, err) + } + } else { + *v = vn + } default: require.Fail(t, fmt.Sprintf("Unable to get object: %s", reflect.TypeOf(v).String())) } @@ -841,6 +939,38 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) { ml.ArangoMLStorageResourcePlural, object.GetNamespace(), object.GetName())) + case *mlApiv1alpha1.ArangoMLExtension: + v.Kind = ml.ArangoMLExtensionResourceKind + v.APIVersion = mlApiv1alpha1.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + mlApiv1alpha1.SchemeGroupVersion.String(), + ml.ArangoMLExtensionResourcePlural, + object.GetNamespace(), + object.GetName())) + case *mlApiv1alpha1.ArangoMLStorage: + v.Kind = ml.ArangoMLStorageResourceKind + v.APIVersion = mlApiv1alpha1.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + mlApiv1alpha1.SchemeGroupVersion.String(), + ml.ArangoMLStorageResourcePlural, + object.GetNamespace(), + object.GetName())) + case *mlApiv1alpha1.ArangoMLBatchJob: + v.Kind = ml.ArangoMLBatchJobResourceKind + v.APIVersion = mlApiv1alpha1.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + mlApiv1alpha1.SchemeGroupVersion.String(), + ml.ArangoMLBatchJobResourcePlural, + object.GetNamespace(), + object.GetName())) + case *mlApiv1alpha1.ArangoMLCronJob: + v.Kind = ml.ArangoMLCronJobResourceKind + v.APIVersion = mlApiv1alpha1.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + mlApiv1alpha1.SchemeGroupVersion.String(), + ml.ArangoMLCronJobResourcePlural, + object.GetNamespace(), + object.GetName())) case *rbac.ClusterRole: v.Kind = "ClusterRole" v.APIVersion = "rbac.authorization.k8s.io/v1" @@ -865,20 +995,12 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) { v.SetSelfLink(fmt.Sprintf("/api/rbac.authorization.k8s.io/v1/rolebingings/%s/%s", object.GetNamespace(), object.GetName())) - case *mlApi.ArangoMLBatchJob: - v.Kind = ml.ArangoMLBatchJobResourceKind - v.APIVersion = mlApi.SchemeGroupVersion.String() - v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", - mlApi.SchemeGroupVersion.String(), - ml.ArangoMLBatchJobResourcePlural, - object.GetNamespace(), - object.GetName())) - case *mlApi.ArangoMLCronJob: - v.Kind = ml.ArangoMLCronJobResourceKind - v.APIVersion = mlApi.SchemeGroupVersion.String() + case *schedulerApiv1alpha1.ArangoProfile: + v.Kind = scheduler.ArangoProfileResourceKind + v.APIVersion = schedulerApiv1alpha1.SchemeGroupVersion.String() v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", - mlApi.SchemeGroupVersion.String(), - ml.ArangoMLCronJobResourcePlural, + schedulerApiv1alpha1.SchemeGroupVersion.String(), + scheduler.ArangoProfileResourcePlural, object.GetNamespace(), object.GetName())) case *schedulerApi.ArangoProfile: @@ -988,6 +1110,22 @@ func NewItem(t *testing.T, o operation.Operation, object meta.Object) operation. item.Group = ml.ArangoMLGroupName item.Version = mlApi.ArangoMLVersion item.Kind = ml.ArangoMLStorageResourceKind + case *mlApiv1alpha1.ArangoMLExtension: + item.Group = ml.ArangoMLGroupName + item.Version = mlApiv1alpha1.ArangoMLVersion + item.Kind = ml.ArangoMLExtensionResourceKind + case *mlApiv1alpha1.ArangoMLStorage: + item.Group = ml.ArangoMLGroupName + item.Version = mlApiv1alpha1.ArangoMLVersion + item.Kind = ml.ArangoMLStorageResourceKind + case *mlApiv1alpha1.ArangoMLBatchJob: + item.Group = ml.ArangoMLGroupName + item.Version = mlApiv1alpha1.ArangoMLVersion + item.Kind = ml.ArangoMLBatchJobResourceKind + case *mlApiv1alpha1.ArangoMLCronJob: + item.Group = ml.ArangoMLGroupName + item.Version = mlApiv1alpha1.ArangoMLVersion + item.Kind = ml.ArangoMLCronJobResourceKind case *rbac.ClusterRole: item.Group = "rbac.authorization.k8s.io" item.Version = "v1" @@ -1004,14 +1142,6 @@ func NewItem(t *testing.T, o operation.Operation, object meta.Object) operation. item.Group = "rbac.authorization.k8s.io" item.Version = "v1" item.Kind = "RoleBinding" - case *mlApi.ArangoMLBatchJob: - item.Group = ml.ArangoMLGroupName - item.Version = mlApi.ArangoMLVersion - item.Kind = ml.ArangoMLBatchJobResourceKind - case *mlApi.ArangoMLCronJob: - item.Group = ml.ArangoMLGroupName - item.Version = mlApi.ArangoMLVersion - item.Kind = ml.ArangoMLCronJobResourceKind case *schedulerApi.ArangoProfile: item.Group = scheduler.ArangoSchedulerGroupName item.Version = schedulerApi.ArangoSchedulerVersion diff --git a/pkg/util/tests/kubernetes_test.go b/pkg/util/tests/kubernetes_test.go index f5c466d4f..84477e301 100644 --- a/pkg/util/tests/kubernetes_test.go +++ b/pkg/util/tests/kubernetes_test.go @@ -33,8 +33,9 @@ import ( backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" - mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" - schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" + mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1" + mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" "github.com/arangodb/kube-arangodb/pkg/util/kclient" ) @@ -79,5 +80,9 @@ func Test_NewMetaObject(t *testing.T) { NewMetaObjectRun[*backupApi.ArangoBackup](t) NewMetaObjectRun[*mlApi.ArangoMLExtension](t) NewMetaObjectRun[*mlApi.ArangoMLStorage](t) + NewMetaObjectRun[*mlApiv1alpha1.ArangoMLExtension](t) + NewMetaObjectRun[*mlApiv1alpha1.ArangoMLStorage](t) + NewMetaObjectRun[*mlApiv1alpha1.ArangoMLBatchJob](t) + NewMetaObjectRun[*mlApiv1alpha1.ArangoMLCronJob](t) NewMetaObjectRun[*schedulerApi.ArangoProfile](t) }