From 459462b0dcd02886e78fd63749aba1f2bb1d4cad Mon Sep 17 00:00:00 2001 From: Adam Janikowski <12255597+ajanikow@users.noreply.github.com> Date: Thu, 26 Sep 2024 17:20:57 +0200 Subject: [PATCH] [Feature] Scheduler Types (#1730) --- CHANGELOG.md | 1 + Makefile | 2 +- README.md | 2 +- .../crds/scheduler-batchjob.yaml | 22 + .../crds/scheduler-cronjob.yaml | 22 + .../crds/scheduler-deployment.yaml | 22 + .../crds/scheduler-pod.yaml | 22 + .../templates/crd/cluster-role.yaml | 4 + .../templates/scheduler-operator/role.yaml | 31 + .../crds/scheduler-batchjob.yaml | 22 + .../crds/scheduler-cronjob.yaml | 22 + .../crds/scheduler-deployment.yaml | 22 + .../crds/scheduler-pod.yaml | 22 + .../templates/crd/cluster-role.yaml | 4 + .../templates/scheduler-operator/role.yaml | 31 + .../crds/scheduler-batchjob.yaml | 22 + .../crds/scheduler-cronjob.yaml | 22 + .../crds/scheduler-deployment.yaml | 22 + .../crds/scheduler-pod.yaml | 22 + .../templates/crd/cluster-role.yaml | 4 + .../templates/scheduler-operator/role.yaml | 31 + .../crds/scheduler-batchjob.yaml | 22 + .../kube-arangodb/crds/scheduler-cronjob.yaml | 22 + .../crds/scheduler-deployment.yaml | 22 + chart/kube-arangodb/crds/scheduler-pod.yaml | 22 + .../templates/crd/cluster-role.yaml | 4 + .../templates/scheduler-operator/role.yaml | 31 + docs/cli/arangodb_operator.md | 2 +- integrations/scheduler/v1/batch_job.go | 177 + integrations/scheduler/v1/batch_job_test.go | 15 +- integrations/scheduler/v1/cron_job.go | 249 ++ integrations/scheduler/v1/cron_job_test.go | 19 +- .../scheduler/v1/definition/batchjob.pb.go | 99 +- .../scheduler/v1/definition/batchjob.proto | 9 +- .../scheduler/v1/definition/common.pb.go | 262 +- .../scheduler/v1/definition/common.proto | 21 +- .../scheduler/v1/definition/cronjob.pb.go | 156 +- .../scheduler/v1/definition/cronjob.proto | 15 +- .../scheduler/v1/definition/definition.pb.go | 1163 +++++-- .../scheduler/v1/definition/definition.proto | 102 +- .../v1/definition/definition_grpc.pb.go | 190 + .../scheduler/v1/definition/deployment.pb.go | 388 +++ .../scheduler/v1/definition/deployment.proto | 66 + integrations/scheduler/v1/deployment.go | 210 ++ integrations/scheduler/v1/deployment_test.go | 199 ++ integrations/scheduler/v1/helpers.go | 43 + integrations/scheduler/v1/implementation.go | 467 +-- internal/cr_validation_test.go | 36 + pkg/apis/scheduler/definitions.go | 16 + pkg/apis/scheduler/v1beta1/profile.go | 18 +- .../scheduler/v1beta1/profile_templates.go | 8 +- pkg/apis/scheduler/v1beta1/register.go | 8 + pkg/apis/scheduler/v1beta1/types.go | 31 + pkg/apis/scheduler/v1beta1/types_batchjob.go | 83 + pkg/apis/scheduler/v1beta1/types_cronjob.go | 83 + .../scheduler/v1beta1/types_deployment.go | 83 + pkg/apis/scheduler/v1beta1/types_pod.go | 83 + .../v1beta1/zz_generated.deepcopy.go | 435 ++- pkg/crd/crds/crds.go | 4 + pkg/crd/crds/crds_test.go | 8 + pkg/crd/crds/scheduler-batchjob.go | 51 + .../scheduler-batchjob.schema.generated.yaml | 2985 ++++++++++++++++ pkg/crd/crds/scheduler-batchjob.yaml | 22 + pkg/crd/crds/scheduler-cronjob.go | 51 + .../scheduler-cronjob.schema.generated.yaml | 3084 +++++++++++++++++ pkg/crd/crds/scheduler-cronjob.yaml | 22 + pkg/crd/crds/scheduler-deployment.go | 51 + ...scheduler-deployment.schema.generated.yaml | 2953 ++++++++++++++++ pkg/crd/crds/scheduler-deployment.yaml | 22 + pkg/crd/crds/scheduler-pod.go | 51 + .../crds/scheduler-pod.schema.generated.yaml | 2823 +++++++++++++++ pkg/crd/crds/scheduler-pod.yaml | 22 + pkg/crd/scheduling.go | 58 + .../generators/kubernetes/lister.go | 75 +- pkg/deployment/images.go | 12 +- pkg/deployment/resources/arango_profiles.go | 174 +- .../v1beta1/arangoschedulerbatchjob.go | 199 ++ .../v1beta1/arangoschedulercronjob.go | 199 ++ .../v1beta1/arangoschedulerdeployment.go | 199 ++ .../scheduler/v1beta1/arangoschedulerpod.go | 199 ++ .../fake/fake_arangoschedulerbatchjob.go | 145 + .../fake/fake_arangoschedulercronjob.go | 145 + .../fake/fake_arangoschedulerdeployment.go | 145 + .../v1beta1/fake/fake_arangoschedulerpod.go | 145 + .../v1beta1/fake/fake_scheduler_client.go | 16 + .../scheduler/v1beta1/generated_expansion.go | 8 + .../scheduler/v1beta1/scheduler_client.go | 20 + .../informers/externalversions/generic.go | 8 + .../v1beta1/arangoschedulerbatchjob.go | 94 + .../v1beta1/arangoschedulercronjob.go | 94 + .../v1beta1/arangoschedulerdeployment.go | 94 + .../scheduler/v1beta1/arangoschedulerpod.go | 94 + .../scheduler/v1beta1/interface.go | 28 + .../v1beta1/arangoschedulerbatchjob.go | 103 + .../v1beta1/arangoschedulercronjob.go | 103 + .../v1beta1/arangoschedulerdeployment.go | 103 + .../scheduler/v1beta1/arangoschedulerpod.go | 103 + .../scheduler/v1beta1/expansion_generated.go | 32 + pkg/handlers/generic/parent/parent.go | 114 + pkg/handlers/scheduler/batchjob/handler.go | 228 ++ .../scheduler/batchjob/handler_manage_test.go | 230 ++ .../scheduler/batchjob/handler_test.go | 59 + pkg/handlers/scheduler/batchjob/local.go | 48 + pkg/handlers/scheduler/batchjob/register.go | 80 + pkg/handlers/scheduler/batchjob/suite_test.go | 61 + pkg/handlers/scheduler/cronjob/handler.go | 228 ++ .../scheduler/cronjob/handler_manage_test.go | 231 ++ .../scheduler/cronjob/handler_test.go | 59 + pkg/handlers/scheduler/cronjob/local.go | 48 + pkg/handlers/scheduler/cronjob/register.go | 80 + pkg/handlers/scheduler/cronjob/suite_test.go | 61 + pkg/handlers/scheduler/deployment/handler.go | 229 ++ .../deployment/handler_manage_test.go | 227 ++ .../scheduler/deployment/handler_test.go | 59 + pkg/handlers/scheduler/deployment/local.go | 48 + pkg/handlers/scheduler/deployment/register.go | 80 + .../scheduler/deployment/suite_test.go | 61 + pkg/handlers/scheduler/pod/handler.go | 224 ++ .../scheduler/pod/handler_manage_test.go | 227 ++ pkg/handlers/scheduler/pod/handler_test.go | 59 + pkg/handlers/scheduler/pod/local.go | 48 + pkg/handlers/scheduler/pod/register.go | 80 + pkg/handlers/scheduler/pod/suite_test.go | 61 + pkg/handlers/scheduler/profile/handler.go | 2 +- pkg/handlers/scheduler/profile/local.go | 10 + pkg/integrations/sidecar/integration.go | 2 + pkg/operator/operator.go | 48 +- pkg/operatorV2/operation/item.go | 12 + pkg/operatorV2/update.go | 8 +- pkg/operatorV2/update_wraps.go | 18 +- pkg/scheduler/input.go | 57 +- pkg/scheduler/profiles.go | 106 + pkg/scheduler/scheduler.go | 136 - pkg/scheduler/scheduler_test.go | 344 -- .../constants/profiles.go} | 16 +- pkg/util/k8sutil/gvk.go | 55 + pkg/util/k8sutil/inspector/generic/mod.go | 10 +- pkg/util/k8sutil/list.go | 14 +- pkg/util/k8sutil/patcher/metadata.go | 54 + pkg/util/list.go | 26 +- pkg/util/tests/ap.go | 47 + pkg/util/tests/kubernetes.go | 244 +- pkg/util/tests/kubernetes_test.go | 6 + 143 files changed, 22644 insertions(+), 1478 deletions(-) create mode 100644 chart/kube-arangodb-arm64/crds/scheduler-batchjob.yaml create mode 100644 chart/kube-arangodb-arm64/crds/scheduler-cronjob.yaml create mode 100644 chart/kube-arangodb-arm64/crds/scheduler-deployment.yaml create mode 100644 chart/kube-arangodb-arm64/crds/scheduler-pod.yaml create mode 100644 chart/kube-arangodb-enterprise-arm64/crds/scheduler-batchjob.yaml create mode 100644 chart/kube-arangodb-enterprise-arm64/crds/scheduler-cronjob.yaml create mode 100644 chart/kube-arangodb-enterprise-arm64/crds/scheduler-deployment.yaml create mode 100644 chart/kube-arangodb-enterprise-arm64/crds/scheduler-pod.yaml create mode 100644 chart/kube-arangodb-enterprise/crds/scheduler-batchjob.yaml create mode 100644 chart/kube-arangodb-enterprise/crds/scheduler-cronjob.yaml create mode 100644 chart/kube-arangodb-enterprise/crds/scheduler-deployment.yaml create mode 100644 chart/kube-arangodb-enterprise/crds/scheduler-pod.yaml create mode 100644 chart/kube-arangodb/crds/scheduler-batchjob.yaml create mode 100644 chart/kube-arangodb/crds/scheduler-cronjob.yaml create mode 100644 chart/kube-arangodb/crds/scheduler-deployment.yaml create mode 100644 chart/kube-arangodb/crds/scheduler-pod.yaml create mode 100644 integrations/scheduler/v1/batch_job.go create mode 100644 integrations/scheduler/v1/cron_job.go create mode 100644 integrations/scheduler/v1/definition/deployment.pb.go create mode 100644 integrations/scheduler/v1/definition/deployment.proto create mode 100644 integrations/scheduler/v1/deployment.go create mode 100644 integrations/scheduler/v1/deployment_test.go create mode 100644 integrations/scheduler/v1/helpers.go create mode 100644 pkg/apis/scheduler/v1beta1/types.go create mode 100644 pkg/apis/scheduler/v1beta1/types_batchjob.go create mode 100644 pkg/apis/scheduler/v1beta1/types_cronjob.go create mode 100644 pkg/apis/scheduler/v1beta1/types_deployment.go create mode 100644 pkg/apis/scheduler/v1beta1/types_pod.go create mode 100644 pkg/crd/crds/scheduler-batchjob.go create mode 100644 pkg/crd/crds/scheduler-batchjob.schema.generated.yaml create mode 100644 pkg/crd/crds/scheduler-batchjob.yaml create mode 100644 pkg/crd/crds/scheduler-cronjob.go create mode 100644 pkg/crd/crds/scheduler-cronjob.schema.generated.yaml create mode 100644 pkg/crd/crds/scheduler-cronjob.yaml create mode 100644 pkg/crd/crds/scheduler-deployment.go create mode 100644 pkg/crd/crds/scheduler-deployment.schema.generated.yaml create mode 100644 pkg/crd/crds/scheduler-deployment.yaml create mode 100644 pkg/crd/crds/scheduler-pod.go create mode 100644 pkg/crd/crds/scheduler-pod.schema.generated.yaml create mode 100644 pkg/crd/crds/scheduler-pod.yaml create mode 100644 pkg/crd/scheduling.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerbatchjob.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulercronjob.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerdeployment.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerpod.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerbatchjob.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulercronjob.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerdeployment.go create mode 100644 pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerpod.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerbatchjob.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulercronjob.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerdeployment.go create mode 100644 pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerpod.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/arangoschedulerbatchjob.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/arangoschedulercronjob.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/arangoschedulerdeployment.go create mode 100644 pkg/generated/listers/scheduler/v1beta1/arangoschedulerpod.go create mode 100644 pkg/handlers/generic/parent/parent.go create mode 100644 pkg/handlers/scheduler/batchjob/handler.go create mode 100644 pkg/handlers/scheduler/batchjob/handler_manage_test.go create mode 100644 pkg/handlers/scheduler/batchjob/handler_test.go create mode 100644 pkg/handlers/scheduler/batchjob/local.go create mode 100644 pkg/handlers/scheduler/batchjob/register.go create mode 100644 pkg/handlers/scheduler/batchjob/suite_test.go create mode 100644 pkg/handlers/scheduler/cronjob/handler.go create mode 100644 pkg/handlers/scheduler/cronjob/handler_manage_test.go create mode 100644 pkg/handlers/scheduler/cronjob/handler_test.go create mode 100644 pkg/handlers/scheduler/cronjob/local.go create mode 100644 pkg/handlers/scheduler/cronjob/register.go create mode 100644 pkg/handlers/scheduler/cronjob/suite_test.go create mode 100644 pkg/handlers/scheduler/deployment/handler.go create mode 100644 pkg/handlers/scheduler/deployment/handler_manage_test.go create mode 100644 pkg/handlers/scheduler/deployment/handler_test.go create mode 100644 pkg/handlers/scheduler/deployment/local.go create mode 100644 pkg/handlers/scheduler/deployment/register.go create mode 100644 pkg/handlers/scheduler/deployment/suite_test.go create mode 100644 pkg/handlers/scheduler/pod/handler.go create mode 100644 pkg/handlers/scheduler/pod/handler_manage_test.go create mode 100644 pkg/handlers/scheduler/pod/handler_test.go create mode 100644 pkg/handlers/scheduler/pod/local.go create mode 100644 pkg/handlers/scheduler/pod/register.go create mode 100644 pkg/handlers/scheduler/pod/suite_test.go create mode 100644 pkg/scheduler/profiles.go delete mode 100644 pkg/scheduler/scheduler.go delete mode 100644 pkg/scheduler/scheduler_test.go rename pkg/{crd/arangoprofile.go => util/constants/profiles.go} (69%) create mode 100644 pkg/util/k8sutil/gvk.go create mode 100644 pkg/util/k8sutil/patcher/metadata.go create mode 100644 pkg/util/tests/ap.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 8afd9abe6..4b451c1ec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - (Feature) (Networking) Endpoints Destination - (Improvement) Improve Metrics Handling - (Feature) (Scheduler) Create Integration Profile +- (Feature) (Scheduler) Additional types ## [1.2.42](https://github.com/arangodb/kube-arangodb/tree/1.2.42) (2024-07-23) - (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries diff --git a/Makefile b/Makefile index c59780eb2..7c176d50e 100644 --- a/Makefile +++ b/Makefile @@ -911,7 +911,7 @@ CRDS:=apps-job \ database-clustersynchronization database-deployment database-member database-task \ replication-deploymentreplication \ ml-storage ml-extension ml-job-batch ml-job-cron \ - scheduler-profile \ + scheduler-profile scheduler-pod scheduler-deployment scheduler-batchjob scheduler-cronjob \ analytics-graphanalyticsengine \ networking-route diff --git a/README.md b/README.md index f6b852ac8..5643abcbd 100644 --- a/README.md +++ b/README.md @@ -182,7 +182,7 @@ Flags: --kubernetes.max-batch-size int Size of batch during objects read (default 256) --kubernetes.qps float32 Number of queries per second for k8s API (default 15) --log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty") - --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, http, inspector, integration-config-v1, integration-envoy-auth-v3, integrations, k8s-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, scheduler-profile-operator, server, server-authentication (default [info]) + --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, http, inspector, integration-config-v1, integration-envoy-auth-v3, integrations, k8s-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication (default [info]) --log.sampling If true, operator will try to minimize duplication of logging events (default true) --memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing --metrics.excluded-prefixes stringArray List of the excluded metrics prefixes diff --git a/chart/kube-arangodb-arm64/crds/scheduler-batchjob.yaml b/chart/kube-arangodb-arm64/crds/scheduler-batchjob.yaml new file mode 100644 index 000000000..e20a31952 --- /dev/null +++ b/chart/kube-arangodb-arm64/crds/scheduler-batchjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerbatchjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerBatchJob + listKind: ArangoSchedulerBatchJobList + plural: arangoschedulerbatchjobs + singular: arangoschedulerbatchjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-arm64/crds/scheduler-cronjob.yaml b/chart/kube-arangodb-arm64/crds/scheduler-cronjob.yaml new file mode 100644 index 000000000..7c6b02d9b --- /dev/null +++ b/chart/kube-arangodb-arm64/crds/scheduler-cronjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulercronjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerCronJob + listKind: ArangoSchedulerCronJobList + plural: arangoschedulercronjobs + singular: arangoschedulercronjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-arm64/crds/scheduler-deployment.yaml b/chart/kube-arangodb-arm64/crds/scheduler-deployment.yaml new file mode 100644 index 000000000..0178e1c89 --- /dev/null +++ b/chart/kube-arangodb-arm64/crds/scheduler-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerdeployments.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerDeployment + listKind: ArangoSchedulerDeploymentList + plural: arangoschedulerdeployments + singular: arangoschedulerdeployment + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-arm64/crds/scheduler-pod.yaml b/chart/kube-arangodb-arm64/crds/scheduler-pod.yaml new file mode 100644 index 000000000..97ab5f973 --- /dev/null +++ b/chart/kube-arangodb-arm64/crds/scheduler-pod.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerpods.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerPod + listKind: ArangoSchedulerPodList + plural: arangoschedulerpods + singular: arangoschedulerpod + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-arm64/templates/crd/cluster-role.yaml b/chart/kube-arangodb-arm64/templates/crd/cluster-role.yaml index 93ee7ad4d..17936fa1b 100644 --- a/chart/kube-arangodb-arm64/templates/crd/cluster-role.yaml +++ b/chart/kube-arangodb-arm64/templates/crd/cluster-role.yaml @@ -68,6 +68,10 @@ rules: verbs: ["get", "list", "watch", "update", "delete"] resourceNames: - "arangoprofiles.scheduler.arangodb.com" + - "arangoschedulerpods.scheduler.arangodb.com" + - "arangoschedulerdeploymets.scheduler.arangodb.com" + - "arangoschedulerbatchjobs.scheduler.arangodb.com" + - "arangoschedulercronjobs.scheduler.arangodb.com" {{- end }} {{- end }} diff --git a/chart/kube-arangodb-arm64/templates/scheduler-operator/role.yaml b/chart/kube-arangodb-arm64/templates/scheduler-operator/role.yaml index 46a3d92f0..f254c77c6 100644 --- a/chart/kube-arangodb-arm64/templates/scheduler-operator/role.yaml +++ b/chart/kube-arangodb-arm64/templates/scheduler-operator/role.yaml @@ -18,6 +18,37 @@ rules: resources: - "arangoprofiles" - "arangoprofiles/status" + - "arangoschedulerpods" + - "arangoschedulerpods/status" + - "arangoschedulerdeployments" + - "arangoschedulerdeployments/status" + - "arangoschedulerbatchjobs" + - "arangoschedulerbatchjobs/status" + - "arangoschedulercronjobs" + - "arangoschedulercronjobs/status" + verbs: + - "*" + - apiGroups: + - "" + resources: + - "pods" + - "pods/status" + verbs: + - "*" + - apiGroups: + - "apps" + resources: + - "deployments" + - "deployments/status" + verbs: + - "*" + - apiGroups: + - "batch" + resources: + - "jobs" + - "jobs/status" + - "cronjobs" + - "cronjobs/status" verbs: - "*" - apiGroups: diff --git a/chart/kube-arangodb-enterprise-arm64/crds/scheduler-batchjob.yaml b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-batchjob.yaml new file mode 100644 index 000000000..e20a31952 --- /dev/null +++ b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-batchjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerbatchjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerBatchJob + listKind: ArangoSchedulerBatchJobList + plural: arangoschedulerbatchjobs + singular: arangoschedulerbatchjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise-arm64/crds/scheduler-cronjob.yaml b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-cronjob.yaml new file mode 100644 index 000000000..7c6b02d9b --- /dev/null +++ b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-cronjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulercronjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerCronJob + listKind: ArangoSchedulerCronJobList + plural: arangoschedulercronjobs + singular: arangoschedulercronjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise-arm64/crds/scheduler-deployment.yaml b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-deployment.yaml new file mode 100644 index 000000000..0178e1c89 --- /dev/null +++ b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerdeployments.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerDeployment + listKind: ArangoSchedulerDeploymentList + plural: arangoschedulerdeployments + singular: arangoschedulerdeployment + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise-arm64/crds/scheduler-pod.yaml b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-pod.yaml new file mode 100644 index 000000000..97ab5f973 --- /dev/null +++ b/chart/kube-arangodb-enterprise-arm64/crds/scheduler-pod.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerpods.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerPod + listKind: ArangoSchedulerPodList + plural: arangoschedulerpods + singular: arangoschedulerpod + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise-arm64/templates/crd/cluster-role.yaml b/chart/kube-arangodb-enterprise-arm64/templates/crd/cluster-role.yaml index 93ee7ad4d..17936fa1b 100644 --- a/chart/kube-arangodb-enterprise-arm64/templates/crd/cluster-role.yaml +++ b/chart/kube-arangodb-enterprise-arm64/templates/crd/cluster-role.yaml @@ -68,6 +68,10 @@ rules: verbs: ["get", "list", "watch", "update", "delete"] resourceNames: - "arangoprofiles.scheduler.arangodb.com" + - "arangoschedulerpods.scheduler.arangodb.com" + - "arangoschedulerdeploymets.scheduler.arangodb.com" + - "arangoschedulerbatchjobs.scheduler.arangodb.com" + - "arangoschedulercronjobs.scheduler.arangodb.com" {{- end }} {{- end }} diff --git a/chart/kube-arangodb-enterprise-arm64/templates/scheduler-operator/role.yaml b/chart/kube-arangodb-enterprise-arm64/templates/scheduler-operator/role.yaml index 46a3d92f0..f254c77c6 100644 --- a/chart/kube-arangodb-enterprise-arm64/templates/scheduler-operator/role.yaml +++ b/chart/kube-arangodb-enterprise-arm64/templates/scheduler-operator/role.yaml @@ -18,6 +18,37 @@ rules: resources: - "arangoprofiles" - "arangoprofiles/status" + - "arangoschedulerpods" + - "arangoschedulerpods/status" + - "arangoschedulerdeployments" + - "arangoschedulerdeployments/status" + - "arangoschedulerbatchjobs" + - "arangoschedulerbatchjobs/status" + - "arangoschedulercronjobs" + - "arangoschedulercronjobs/status" + verbs: + - "*" + - apiGroups: + - "" + resources: + - "pods" + - "pods/status" + verbs: + - "*" + - apiGroups: + - "apps" + resources: + - "deployments" + - "deployments/status" + verbs: + - "*" + - apiGroups: + - "batch" + resources: + - "jobs" + - "jobs/status" + - "cronjobs" + - "cronjobs/status" verbs: - "*" - apiGroups: diff --git a/chart/kube-arangodb-enterprise/crds/scheduler-batchjob.yaml b/chart/kube-arangodb-enterprise/crds/scheduler-batchjob.yaml new file mode 100644 index 000000000..e20a31952 --- /dev/null +++ b/chart/kube-arangodb-enterprise/crds/scheduler-batchjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerbatchjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerBatchJob + listKind: ArangoSchedulerBatchJobList + plural: arangoschedulerbatchjobs + singular: arangoschedulerbatchjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise/crds/scheduler-cronjob.yaml b/chart/kube-arangodb-enterprise/crds/scheduler-cronjob.yaml new file mode 100644 index 000000000..7c6b02d9b --- /dev/null +++ b/chart/kube-arangodb-enterprise/crds/scheduler-cronjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulercronjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerCronJob + listKind: ArangoSchedulerCronJobList + plural: arangoschedulercronjobs + singular: arangoschedulercronjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise/crds/scheduler-deployment.yaml b/chart/kube-arangodb-enterprise/crds/scheduler-deployment.yaml new file mode 100644 index 000000000..0178e1c89 --- /dev/null +++ b/chart/kube-arangodb-enterprise/crds/scheduler-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerdeployments.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerDeployment + listKind: ArangoSchedulerDeploymentList + plural: arangoschedulerdeployments + singular: arangoschedulerdeployment + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise/crds/scheduler-pod.yaml b/chart/kube-arangodb-enterprise/crds/scheduler-pod.yaml new file mode 100644 index 000000000..97ab5f973 --- /dev/null +++ b/chart/kube-arangodb-enterprise/crds/scheduler-pod.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerpods.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerPod + listKind: ArangoSchedulerPodList + plural: arangoschedulerpods + singular: arangoschedulerpod + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb-enterprise/templates/crd/cluster-role.yaml b/chart/kube-arangodb-enterprise/templates/crd/cluster-role.yaml index 93ee7ad4d..17936fa1b 100644 --- a/chart/kube-arangodb-enterprise/templates/crd/cluster-role.yaml +++ b/chart/kube-arangodb-enterprise/templates/crd/cluster-role.yaml @@ -68,6 +68,10 @@ rules: verbs: ["get", "list", "watch", "update", "delete"] resourceNames: - "arangoprofiles.scheduler.arangodb.com" + - "arangoschedulerpods.scheduler.arangodb.com" + - "arangoschedulerdeploymets.scheduler.arangodb.com" + - "arangoschedulerbatchjobs.scheduler.arangodb.com" + - "arangoschedulercronjobs.scheduler.arangodb.com" {{- end }} {{- end }} diff --git a/chart/kube-arangodb-enterprise/templates/scheduler-operator/role.yaml b/chart/kube-arangodb-enterprise/templates/scheduler-operator/role.yaml index 46a3d92f0..f254c77c6 100644 --- a/chart/kube-arangodb-enterprise/templates/scheduler-operator/role.yaml +++ b/chart/kube-arangodb-enterprise/templates/scheduler-operator/role.yaml @@ -18,6 +18,37 @@ rules: resources: - "arangoprofiles" - "arangoprofiles/status" + - "arangoschedulerpods" + - "arangoschedulerpods/status" + - "arangoschedulerdeployments" + - "arangoschedulerdeployments/status" + - "arangoschedulerbatchjobs" + - "arangoschedulerbatchjobs/status" + - "arangoschedulercronjobs" + - "arangoschedulercronjobs/status" + verbs: + - "*" + - apiGroups: + - "" + resources: + - "pods" + - "pods/status" + verbs: + - "*" + - apiGroups: + - "apps" + resources: + - "deployments" + - "deployments/status" + verbs: + - "*" + - apiGroups: + - "batch" + resources: + - "jobs" + - "jobs/status" + - "cronjobs" + - "cronjobs/status" verbs: - "*" - apiGroups: diff --git a/chart/kube-arangodb/crds/scheduler-batchjob.yaml b/chart/kube-arangodb/crds/scheduler-batchjob.yaml new file mode 100644 index 000000000..e20a31952 --- /dev/null +++ b/chart/kube-arangodb/crds/scheduler-batchjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerbatchjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerBatchJob + listKind: ArangoSchedulerBatchJobList + plural: arangoschedulerbatchjobs + singular: arangoschedulerbatchjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb/crds/scheduler-cronjob.yaml b/chart/kube-arangodb/crds/scheduler-cronjob.yaml new file mode 100644 index 000000000..7c6b02d9b --- /dev/null +++ b/chart/kube-arangodb/crds/scheduler-cronjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulercronjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerCronJob + listKind: ArangoSchedulerCronJobList + plural: arangoschedulercronjobs + singular: arangoschedulercronjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb/crds/scheduler-deployment.yaml b/chart/kube-arangodb/crds/scheduler-deployment.yaml new file mode 100644 index 000000000..0178e1c89 --- /dev/null +++ b/chart/kube-arangodb/crds/scheduler-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerdeployments.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerDeployment + listKind: ArangoSchedulerDeploymentList + plural: arangoschedulerdeployments + singular: arangoschedulerdeployment + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb/crds/scheduler-pod.yaml b/chart/kube-arangodb/crds/scheduler-pod.yaml new file mode 100644 index 000000000..97ab5f973 --- /dev/null +++ b/chart/kube-arangodb/crds/scheduler-pod.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerpods.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerPod + listKind: ArangoSchedulerPodList + plural: arangoschedulerpods + singular: arangoschedulerpod + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/chart/kube-arangodb/templates/crd/cluster-role.yaml b/chart/kube-arangodb/templates/crd/cluster-role.yaml index 93ee7ad4d..17936fa1b 100644 --- a/chart/kube-arangodb/templates/crd/cluster-role.yaml +++ b/chart/kube-arangodb/templates/crd/cluster-role.yaml @@ -68,6 +68,10 @@ rules: verbs: ["get", "list", "watch", "update", "delete"] resourceNames: - "arangoprofiles.scheduler.arangodb.com" + - "arangoschedulerpods.scheduler.arangodb.com" + - "arangoschedulerdeploymets.scheduler.arangodb.com" + - "arangoschedulerbatchjobs.scheduler.arangodb.com" + - "arangoschedulercronjobs.scheduler.arangodb.com" {{- end }} {{- end }} diff --git a/chart/kube-arangodb/templates/scheduler-operator/role.yaml b/chart/kube-arangodb/templates/scheduler-operator/role.yaml index 46a3d92f0..f254c77c6 100644 --- a/chart/kube-arangodb/templates/scheduler-operator/role.yaml +++ b/chart/kube-arangodb/templates/scheduler-operator/role.yaml @@ -18,6 +18,37 @@ rules: resources: - "arangoprofiles" - "arangoprofiles/status" + - "arangoschedulerpods" + - "arangoschedulerpods/status" + - "arangoschedulerdeployments" + - "arangoschedulerdeployments/status" + - "arangoschedulerbatchjobs" + - "arangoschedulerbatchjobs/status" + - "arangoschedulercronjobs" + - "arangoschedulercronjobs/status" + verbs: + - "*" + - apiGroups: + - "" + resources: + - "pods" + - "pods/status" + verbs: + - "*" + - apiGroups: + - "apps" + resources: + - "deployments" + - "deployments/status" + verbs: + - "*" + - apiGroups: + - "batch" + resources: + - "jobs" + - "jobs/status" + - "cronjobs" + - "cronjobs/status" verbs: - "*" - apiGroups: diff --git a/docs/cli/arangodb_operator.md b/docs/cli/arangodb_operator.md index 0caa979b0..390ac513b 100644 --- a/docs/cli/arangodb_operator.md +++ b/docs/cli/arangodb_operator.md @@ -80,7 +80,7 @@ Flags: --kubernetes.max-batch-size int Size of batch during objects read (default 256) --kubernetes.qps float32 Number of queries per second for k8s API (default 15) --log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty") - --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, http, inspector, integration-config-v1, integration-envoy-auth-v3, integrations, k8s-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, scheduler-profile-operator, server, server-authentication (default [info]) + --log.level stringArray Set log levels in format or =. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, generic-parent-operator, http, inspector, integration-config-v1, integration-envoy-auth-v3, integrations, k8s-client, kubernetes-informer, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, scheduler-batchjob-operator, scheduler-cronjob-operator, scheduler-deployment-operator, scheduler-pod-operator, scheduler-profile-operator, server, server-authentication (default [info]) --log.sampling If true, operator will try to minimize duplication of logging events (default true) --memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing --metrics.excluded-prefixes stringArray List of the excluded metrics prefixes diff --git a/integrations/scheduler/v1/batch_job.go b/integrations/scheduler/v1/batch_job.go new file mode 100644 index 000000000..c2316ea0e --- /dev/null +++ b/integrations/scheduler/v1/batch_job.go @@ -0,0 +1,177 @@ +// +// 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 v1 + +import ( + "context" + + 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/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/debug_package/generators/kubernetes" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" +) + +func (i *implementation) CreateBatchJob(ctx context.Context, request *pbSchedulerV1.CreateBatchJobRequest) (*pbSchedulerV1.CreateBatchJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + template := scheduler.SpecAsTemplate(request.GetSpec()) + + var spec schedulerApi.ArangoSchedulerBatchJob + + spec.Namespace = i.cfg.Namespace + + if meta := request.GetSpec().GetMetadata(); meta != nil { + if util.TypeOrDefault(meta.GenerateName, false) { + spec.GenerateName = meta.Name + } else { + spec.Name = meta.Name + } + } + + spec.Spec.Template = *template + + if batchJob := request.GetBatchJob(); batchJob != nil { + if v := batchJob.Completions; v != nil { + spec.Spec.Completions = v + } + + if v := batchJob.Parallelism; v != nil { + spec.Spec.Parallelism = v + } + + if v := batchJob.BackoffLimit; v != nil { + spec.Spec.BackoffLimit = v + } + } + + if batchJobSpec := request.GetSpec(); batchJobSpec != nil { + if base := batchJobSpec.Base; base != nil { + spec.Labels = base.Labels + } + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerBatchJobs(i.cfg.Namespace).Create(ctx, &spec, meta.CreateOptions{}) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.CreateBatchJobResponse{ + Name: job.Name, + }, nil +} + +func (i *implementation) GetBatchJob(ctx context.Context, request *pbSchedulerV1.GetBatchJobRequest) (*pbSchedulerV1.GetBatchJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerBatchJobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.GetBatchJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.GetBatchJobResponse{ + Exists: true, + + BatchJob: &pbSchedulerV1.BatchJob{ + Metadata: ExtractStatusMetadata(job.Status.ArangoSchedulerStatusMetadata), + Spec: &pbSchedulerV1.BatchJobSpec{ + Parallelism: job.Spec.Parallelism, + Completions: job.Spec.Completions, + BackoffLimit: job.Spec.BackoffLimit, + }, + Status: &pbSchedulerV1.BatchJobStatus{ + Active: job.Status.Active, + Succeeded: job.Status.Succeeded, + Failed: job.Status.Failed, + }, + }, + }, nil +} + +func (i *implementation) DeleteBatchJob(ctx context.Context, request *pbSchedulerV1.DeleteBatchJobRequest) (*pbSchedulerV1.DeleteBatchJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + var d meta.DeleteOptions + + if v := request.DeleteChildPods; v != nil { + if *v { + d.PropagationPolicy = util.NewType(meta.DeletePropagationBackground) + } else { + d.PropagationPolicy = util.NewType(meta.DeletePropagationOrphan) + } + } + + err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerBatchJobs(i.cfg.Namespace).Delete(ctx, request.GetName(), d) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.DeleteBatchJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.DeleteBatchJobResponse{Exists: true}, nil +} + +func (i *implementation) ListBatchJob(ctx context.Context, request *pbSchedulerV1.ListBatchJobRequest) (*pbSchedulerV1.ListBatchJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + objects, err := kubernetes.ListObjects[*schedulerApi.ArangoSchedulerBatchJobList, *schedulerApi.ArangoSchedulerBatchJob](ctx, i.client.Arango().SchedulerV1beta1().ArangoSchedulerBatchJobs(i.cfg.Namespace), func(result *schedulerApi.ArangoSchedulerBatchJobList) []*schedulerApi.ArangoSchedulerBatchJob { + r := make([]*schedulerApi.ArangoSchedulerBatchJob, len(result.Items)) + + for id := range result.Items { + r[id] = result.Items[id].DeepCopy() + } + + return r + }) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.ListBatchJobResponse{ + BatchJobs: util.FormatList(objects, func(in *schedulerApi.ArangoSchedulerBatchJob) string { + return in.GetName() + }), + }, nil +} diff --git a/integrations/scheduler/v1/batch_job_test.go b/integrations/scheduler/v1/batch_job_test.go index 368bee751..b7dedb741 100644 --- a/integrations/scheduler/v1/batch_job_test.go +++ b/integrations/scheduler/v1/batch_job_test.go @@ -25,7 +25,6 @@ import ( "testing" "github.com/stretchr/testify/require" - batch "k8s.io/api/batch/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" @@ -42,7 +41,7 @@ func Test_BatchJob(t *testing.T) { client := kclient.NewFakeClientBuilder().Add( tests.NewMetaObject(t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{} - }), + }, tests.MarkArangoProfileAsReady), tests.NewMetaObject(t, tests.FakeNamespace, "test-select-all", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{ Selectors: &schedulerApi.ProfileSelectors{ @@ -50,7 +49,7 @@ func Test_BatchJob(t *testing.T) { }, Template: &schedulerApi.ProfileTemplate{}, } - }), + }, tests.MarkArangoProfileAsReady), tests.NewMetaObject(t, tests.FakeNamespace, "test-select-specific", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{ Selectors: &schedulerApi.ProfileSelectors{ @@ -62,7 +61,7 @@ func Test_BatchJob(t *testing.T) { }, Template: &schedulerApi.ProfileTemplate{}, } - }), + }, tests.MarkArangoProfileAsReady), ).Client() scheduler := Client(t, ctx, client, func(c Configuration) Configuration { @@ -93,7 +92,7 @@ func Test_BatchJob(t *testing.T) { Metadata: &pbSchedulerV1.Metadata{ Name: "test", }, - Job: &pbSchedulerV1.JobBase{ + Base: &pbSchedulerV1.ObjectBase{ Labels: nil, Profiles: []string{ "test", @@ -117,10 +116,6 @@ func Test_BatchJob(t *testing.T) { require.NoError(t, err) require.EqualValues(t, "test", resp.GetName()) - require.Len(t, resp.Profiles, 2) - require.Contains(t, resp.Profiles, "test") - require.Contains(t, resp.Profiles, "test-select-all") - require.NotContains(t, resp.Profiles, "test-select-specific") }) t.Run("Ensure job exist - get", func(t *testing.T) { @@ -151,7 +146,7 @@ func Test_BatchJob(t *testing.T) { }) t.Run("Ensure job details - update", func(t *testing.T) { - job := tests.NewMetaObject[*batch.Job](t, tests.FakeNamespace, "test") + job := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test") tests.RefreshObjectsC(t, client, &job) diff --git a/integrations/scheduler/v1/cron_job.go b/integrations/scheduler/v1/cron_job.go new file mode 100644 index 000000000..892d91d75 --- /dev/null +++ b/integrations/scheduler/v1/cron_job.go @@ -0,0 +1,249 @@ +// +// 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 v1 + +import ( + "context" + + core "k8s.io/api/core/v1" + 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/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/debug_package/generators/kubernetes" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" +) + +func (i *implementation) CreateCronJob(ctx context.Context, request *pbSchedulerV1.CreateCronJobRequest) (*pbSchedulerV1.CreateCronJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + template := scheduler.SpecAsTemplate(request.GetSpec()) + + var spec schedulerApi.ArangoSchedulerCronJob + + spec.Namespace = i.cfg.Namespace + + if meta := request.GetSpec().GetMetadata(); meta != nil { + if util.TypeOrDefault(meta.GenerateName, false) { + spec.GenerateName = meta.Name + } else { + spec.Name = meta.Name + } + } + + spec.Spec.JobTemplate.Spec.Template = *template + + if cronJob := request.GetCronJob(); cronJob != nil { + spec.Spec.Schedule = cronJob.Schedule + + if batchJob := cronJob.GetJob(); batchJob != nil { + if v := batchJob.Completions; v != nil { + spec.Spec.JobTemplate.Spec.Completions = v + } + + if v := batchJob.Parallelism; v != nil { + spec.Spec.JobTemplate.Spec.Parallelism = v + } + + if v := batchJob.BackoffLimit; v != nil { + spec.Spec.JobTemplate.Spec.BackoffLimit = v + } + } + } + + if batchJobSpec := request.GetSpec(); batchJobSpec != nil { + if base := batchJobSpec.Base; base != nil { + spec.Labels = base.Labels + spec.Spec.JobTemplate.Labels = base.Labels + } + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace).Create(ctx, &spec, meta.CreateOptions{}) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.CreateCronJobResponse{ + Name: job.Name, + }, nil +} + +func (i *implementation) GetCronJob(ctx context.Context, request *pbSchedulerV1.GetCronJobRequest) (*pbSchedulerV1.GetCronJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.GetCronJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.GetCronJobResponse{ + Exists: true, + + CronJob: &pbSchedulerV1.CronJob{ + Metadata: ExtractStatusMetadata(job.Status.ArangoSchedulerStatusMetadata), + Spec: &pbSchedulerV1.CronJobSpec{ + Schedule: job.Spec.Schedule, + + Job: &pbSchedulerV1.BatchJobSpec{ + Parallelism: job.Spec.JobTemplate.Spec.Parallelism, + Completions: job.Spec.JobTemplate.Spec.Completions, + BackoffLimit: job.Spec.JobTemplate.Spec.BackoffLimit, + }, + }, + Status: &pbSchedulerV1.CronJobStatus{ + BatchJobs: util.FormatList(job.Status.Active, func(in core.ObjectReference) string { + return in.Name + }), + }, + }, + }, nil +} + +func (i *implementation) UpdateCronJob(ctx context.Context, request *pbSchedulerV1.UpdateCronJobRequest) (*pbSchedulerV1.UpdateCronJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.UpdateCronJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + if cronJob := request.GetSpec(); cronJob != nil { + job.Spec.Schedule = cronJob.Schedule + + if batchJob := cronJob.GetJob(); batchJob != nil { + if v := batchJob.Completions; v != nil { + job.Spec.JobTemplate.Spec.Completions = v + } + + if v := batchJob.Parallelism; v != nil { + job.Spec.JobTemplate.Spec.Parallelism = v + } + + if v := batchJob.BackoffLimit; v != nil { + job.Spec.JobTemplate.Spec.BackoffLimit = v + } + } + } + + job, err = i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace).Update(ctx, job, meta.UpdateOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.UpdateCronJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.UpdateCronJobResponse{ + Exists: true, + + CronJob: &pbSchedulerV1.CronJob{ + Spec: &pbSchedulerV1.CronJobSpec{ + Schedule: job.Spec.Schedule, + + Job: &pbSchedulerV1.BatchJobSpec{ + Parallelism: job.Spec.JobTemplate.Spec.Parallelism, + Completions: job.Spec.JobTemplate.Spec.Completions, + BackoffLimit: job.Spec.JobTemplate.Spec.BackoffLimit, + }, + }, + }, + }, nil +} + +func (i *implementation) ListCronJob(ctx context.Context, request *pbSchedulerV1.ListCronJobRequest) (*pbSchedulerV1.ListCronJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + objects, err := kubernetes.ListObjects[*schedulerApi.ArangoSchedulerCronJobList, *schedulerApi.ArangoSchedulerCronJob](ctx, i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace), func(result *schedulerApi.ArangoSchedulerCronJobList) []*schedulerApi.ArangoSchedulerCronJob { + r := make([]*schedulerApi.ArangoSchedulerCronJob, len(result.Items)) + + for id := range result.Items { + r[id] = result.Items[id].DeepCopy() + } + + return r + }) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.ListCronJobResponse{ + CronJobs: util.FormatList(objects, func(in *schedulerApi.ArangoSchedulerCronJob) string { + return in.GetName() + }), + }, nil +} + +func (i *implementation) DeleteCronJob(ctx context.Context, request *pbSchedulerV1.DeleteCronJobRequest) (*pbSchedulerV1.DeleteCronJobResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + var d meta.DeleteOptions + + if v := request.DeleteChildPods; v != nil { + if *v { + d.PropagationPolicy = util.NewType(meta.DeletePropagationBackground) + } else { + d.PropagationPolicy = util.NewType(meta.DeletePropagationOrphan) + } + } + + err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(i.cfg.Namespace).Delete(ctx, request.GetName(), d) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.DeleteCronJobResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.DeleteCronJobResponse{Exists: true}, nil +} diff --git a/integrations/scheduler/v1/cron_job_test.go b/integrations/scheduler/v1/cron_job_test.go index ecddcdac2..3ae9441f1 100644 --- a/integrations/scheduler/v1/cron_job_test.go +++ b/integrations/scheduler/v1/cron_job_test.go @@ -25,7 +25,6 @@ import ( "testing" "github.com/stretchr/testify/require" - batch "k8s.io/api/batch/v1" core "k8s.io/api/core/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,7 +42,7 @@ func Test_CronJob(t *testing.T) { client := kclient.NewFakeClientBuilder().Add( tests.NewMetaObject(t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{} - }), + }, tests.MarkArangoProfileAsReady), tests.NewMetaObject(t, tests.FakeNamespace, "test-select-all", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{ Selectors: &schedulerApi.ProfileSelectors{ @@ -51,7 +50,7 @@ func Test_CronJob(t *testing.T) { }, Template: &schedulerApi.ProfileTemplate{}, } - }), + }, tests.MarkArangoProfileAsReady), tests.NewMetaObject(t, tests.FakeNamespace, "test-select-specific", func(t *testing.T, obj *schedulerApi.ArangoProfile) { obj.Spec = schedulerApi.ProfileSpec{ Selectors: &schedulerApi.ProfileSelectors{ @@ -63,7 +62,7 @@ func Test_CronJob(t *testing.T) { }, Template: &schedulerApi.ProfileTemplate{}, } - }), + }, tests.MarkArangoProfileAsReady), ).Client() scheduler := Client(t, ctx, client, func(c Configuration) Configuration { @@ -94,7 +93,7 @@ func Test_CronJob(t *testing.T) { Metadata: &pbSchedulerV1.Metadata{ Name: "test", }, - Job: &pbSchedulerV1.JobBase{ + Base: &pbSchedulerV1.ObjectBase{ Labels: nil, Profiles: []string{ "test", @@ -123,10 +122,6 @@ func Test_CronJob(t *testing.T) { require.NoError(t, err) require.EqualValues(t, "test", resp.GetName()) - require.Len(t, resp.Profiles, 2) - require.Contains(t, resp.Profiles, "test") - require.Contains(t, resp.Profiles, "test-select-all") - require.NotContains(t, resp.Profiles, "test-select-specific") }) t.Run("Ensure job exist - get", func(t *testing.T) { @@ -153,11 +148,11 @@ func Test_CronJob(t *testing.T) { require.NoError(t, err) require.True(t, resp.GetExists()) - require.Len(t, resp.GetBatchJobs(), 0) + require.Len(t, resp.GetCronJob().GetStatus().GetBatchJobs(), 0) }) t.Run("Ensure job details - update", func(t *testing.T) { - job := tests.NewMetaObject[*batch.CronJob](t, tests.FakeNamespace, "test") + job := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test") tests.RefreshObjectsC(t, client, &job) @@ -177,7 +172,7 @@ func Test_CronJob(t *testing.T) { require.NoError(t, err) require.True(t, resp.GetExists()) - require.Len(t, resp.GetBatchJobs(), 1) + require.Len(t, resp.GetCronJob().GetStatus().GetBatchJobs(), 1) }) t.Run("Update Job - Pre", func(t *testing.T) { diff --git a/integrations/scheduler/v1/definition/batchjob.pb.go b/integrations/scheduler/v1/definition/batchjob.pb.go index fc6bbb589..dbc1e3c4b 100644 --- a/integrations/scheduler/v1/definition/batchjob.pb.go +++ b/integrations/scheduler/v1/definition/batchjob.pb.go @@ -46,10 +46,12 @@ type BatchJob struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // defines object status metadate + Metadata *StatusMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` // Keeps BatchJob settings - Spec *BatchJobSpec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Spec *BatchJobSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` // Keeps current BatchJob Status - Status *BatchJobStatus `protobuf:"bytes,2,opt,name=status,proto3,oneof" json:"status,omitempty"` + Status *BatchJobStatus `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"` } func (x *BatchJob) Reset() { @@ -84,6 +86,13 @@ func (*BatchJob) Descriptor() ([]byte, []int) { return file_integrations_scheduler_v1_definition_batchjob_proto_rawDescGZIP(), []int{0} } +func (x *BatchJob) GetMetadata() *StatusMetadata { + if x != nil { + return x.Metadata + } + return nil +} + func (x *BatchJob) GetSpec() *BatchJobSpec { if x != nil { return x.Spec @@ -239,37 +248,44 @@ var file_integrations_scheduler_v1_definition_batchjob_proto_rawDesc = []byte{ 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x22, 0x7a, 0x0a, 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x2b, 0x0a, 0x04, - 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, - 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x36, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, - 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xb8, 0x01, 0x0a, - 0x0c, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, - 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x05, 0x48, 0x00, 0x52, 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, - 0x6d, 0x88, 0x01, 0x01, 0x12, 0x25, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x62, - 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x05, 0x48, 0x02, 0x52, 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4c, 0x69, 0x6d, - 0x69, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, - 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, - 0x66, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x22, 0x5e, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x76, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x12, - 0x16, 0x0a, 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, - 0x06, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, - 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, - 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, - 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x1a, 0x31, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x22, 0xb1, 0x01, 0x0a, 0x08, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, + 0x12, 0x35, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, + 0x73, 0x70, 0x65, 0x63, 0x12, 0x36, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, + 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x0c, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x25, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x61, + 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, + 0x0b, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, 0x88, 0x01, 0x01, 0x12, + 0x25, 0x0a, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x05, 0x48, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x88, 0x01, 0x01, 0x12, 0x28, 0x0a, 0x0d, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, + 0x66, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x48, 0x02, 0x52, + 0x0c, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x88, 0x01, 0x01, + 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x69, 0x73, 0x6d, + 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x62, 0x61, 0x63, 0x6b, 0x6f, 0x66, 0x66, 0x5f, 0x6c, 0x69, 0x6d, + 0x69, 0x74, 0x22, 0x5e, 0x0a, 0x0e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x12, 0x1c, 0x0a, 0x09, + 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x61, + 0x69, 0x6c, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x66, 0x61, 0x69, 0x6c, + 0x65, 0x64, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, + 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, + 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -289,15 +305,17 @@ var file_integrations_scheduler_v1_definition_batchjob_proto_goTypes = []interfa (*BatchJob)(nil), // 0: scheduler.BatchJob (*BatchJobSpec)(nil), // 1: scheduler.BatchJobSpec (*BatchJobStatus)(nil), // 2: scheduler.BatchJobStatus + (*StatusMetadata)(nil), // 3: scheduler.StatusMetadata } var file_integrations_scheduler_v1_definition_batchjob_proto_depIdxs = []int32{ - 1, // 0: scheduler.BatchJob.spec:type_name -> scheduler.BatchJobSpec - 2, // 1: scheduler.BatchJob.status:type_name -> scheduler.BatchJobStatus - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 3, // 0: scheduler.BatchJob.metadata:type_name -> scheduler.StatusMetadata + 1, // 1: scheduler.BatchJob.spec:type_name -> scheduler.BatchJobSpec + 2, // 2: scheduler.BatchJob.status:type_name -> scheduler.BatchJobStatus + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_integrations_scheduler_v1_definition_batchjob_proto_init() } @@ -305,6 +323,7 @@ func file_integrations_scheduler_v1_definition_batchjob_proto_init() { if File_integrations_scheduler_v1_definition_batchjob_proto != nil { return } + file_integrations_scheduler_v1_definition_common_proto_init() if !protoimpl.UnsafeEnabled { file_integrations_scheduler_v1_definition_batchjob_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BatchJob); i { diff --git a/integrations/scheduler/v1/definition/batchjob.proto b/integrations/scheduler/v1/definition/batchjob.proto index 51492a6cc..309a8f2fd 100644 --- a/integrations/scheduler/v1/definition/batchjob.proto +++ b/integrations/scheduler/v1/definition/batchjob.proto @@ -22,15 +22,20 @@ syntax = "proto3"; package scheduler; +import "integrations/scheduler/v1/definition/common.proto"; + option go_package = "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition"; // Keeps information about Kubernetes Batch/V1 Job message BatchJob { + // defines object status metadate + StatusMetadata metadata = 1; + // Keeps BatchJob settings - BatchJobSpec spec = 1; + BatchJobSpec spec = 2; // Keeps current BatchJob Status - optional BatchJobStatus status = 2; + optional BatchJobStatus status = 3; } // Information about BatchJob run settings, like completions and parallelism diff --git a/integrations/scheduler/v1/definition/common.pb.go b/integrations/scheduler/v1/definition/common.pb.go index 6a2ed6844..e07fa1901 100644 --- a/integrations/scheduler/v1/definition/common.pb.go +++ b/integrations/scheduler/v1/definition/common.pb.go @@ -40,8 +40,8 @@ const ( _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) ) -// Common base of the Jobs -type JobBase struct { +// Common base of the objects +type ObjectBase struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields @@ -52,8 +52,8 @@ type JobBase struct { Profiles []string `protobuf:"bytes,2,rep,name=profiles,proto3" json:"profiles,omitempty"` } -func (x *JobBase) Reset() { - *x = JobBase{} +func (x *ObjectBase) Reset() { + *x = ObjectBase{} if protoimpl.UnsafeEnabled { mi := &file_integrations_scheduler_v1_definition_common_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -61,13 +61,13 @@ func (x *JobBase) Reset() { } } -func (x *JobBase) String() string { +func (x *ObjectBase) String() string { return protoimpl.X.MessageStringOf(x) } -func (*JobBase) ProtoMessage() {} +func (*ObjectBase) ProtoMessage() {} -func (x *JobBase) ProtoReflect() protoreflect.Message { +func (x *ObjectBase) ProtoReflect() protoreflect.Message { mi := &file_integrations_scheduler_v1_definition_common_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -79,19 +79,19 @@ func (x *JobBase) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use JobBase.ProtoReflect.Descriptor instead. -func (*JobBase) Descriptor() ([]byte, []int) { +// Deprecated: Use ObjectBase.ProtoReflect.Descriptor instead. +func (*ObjectBase) Descriptor() ([]byte, []int) { return file_integrations_scheduler_v1_definition_common_proto_rawDescGZIP(), []int{0} } -func (x *JobBase) GetLabels() map[string]string { +func (x *ObjectBase) GetLabels() map[string]string { if x != nil { return x.Labels } return nil } -func (x *JobBase) GetProfiles() []string { +func (x *ObjectBase) GetProfiles() []string { if x != nil { return x.Profiles } @@ -232,7 +232,7 @@ type Spec struct { // Keeps requested Metadata Metadata *Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` // Keeps requested Job base - Job *JobBase `protobuf:"bytes,2,opt,name=job,proto3" json:"job,omitempty"` + Base *ObjectBase `protobuf:"bytes,2,opt,name=base,proto3" json:"base,omitempty"` // Keeps map of the containers Containers map[string]*ContainerBase `protobuf:"bytes,3,rep,name=containers,proto3" json:"containers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } @@ -276,9 +276,9 @@ func (x *Spec) GetMetadata() *Metadata { return nil } -func (x *Spec) GetJob() *JobBase { +func (x *Spec) GetBase() *ObjectBase { if x != nil { - return x.Job + return x.Base } return nil } @@ -290,65 +290,151 @@ func (x *Spec) GetContainers() map[string]*ContainerBase { return nil } +// Defines status of the scheduled object +type StatusMetadata struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Defines if upstream object has been created + Created bool `protobuf:"varint,1,opt,name=created,proto3" json:"created,omitempty"` + // Defines checksum + Checksum *string `protobuf:"bytes,2,opt,name=checksum,proto3,oneof" json:"checksum,omitempty"` + // Defines uid + Uid *string `protobuf:"bytes,3,opt,name=uid,proto3,oneof" json:"uid,omitempty"` + // Defiles list of applied profiles + Profiles []string `protobuf:"bytes,4,rep,name=profiles,proto3" json:"profiles,omitempty"` +} + +func (x *StatusMetadata) Reset() { + *x = StatusMetadata{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_common_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StatusMetadata) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StatusMetadata) ProtoMessage() {} + +func (x *StatusMetadata) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_common_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StatusMetadata.ProtoReflect.Descriptor instead. +func (*StatusMetadata) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_common_proto_rawDescGZIP(), []int{4} +} + +func (x *StatusMetadata) GetCreated() bool { + if x != nil { + return x.Created + } + return false +} + +func (x *StatusMetadata) GetChecksum() string { + if x != nil && x.Checksum != nil { + return *x.Checksum + } + return "" +} + +func (x *StatusMetadata) GetUid() string { + if x != nil && x.Uid != nil { + return *x.Uid + } + return "" +} + +func (x *StatusMetadata) GetProfiles() []string { + if x != nil { + return x.Profiles + } + return nil +} + var File_integrations_scheduler_v1_definition_common_proto protoreflect.FileDescriptor var file_integrations_scheduler_v1_definition_common_proto_rawDesc = []byte{ 0x0a, 0x31, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x22, 0x98, - 0x01, 0x0a, 0x07, 0x4a, 0x6f, 0x62, 0x42, 0x61, 0x73, 0x65, 0x12, 0x36, 0x0a, 0x06, 0x6c, 0x61, - 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x62, 0x42, 0x61, 0x73, 0x65, 0x2e, 0x4c, - 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, - 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, - 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x1a, 0x39, - 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x5a, 0x0a, 0x08, 0x4d, 0x65, 0x74, - 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x0d, 0x67, 0x65, 0x6e, - 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, - 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xfa, 0x01, 0x0a, 0x0d, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x88, - 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, - 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, - 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x2e, - 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, - 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, - 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, - 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, - 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x04, 0x53, 0x70, 0x65, 0x63, 0x12, 0x2f, 0x0a, 0x08, 0x6d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x24, 0x0a, 0x03, - 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4a, 0x6f, 0x62, 0x42, 0x61, 0x73, 0x65, 0x52, 0x03, 0x6a, - 0x6f, 0x62, 0x12, 0x3f, 0x0a, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, - 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x72, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x65, 0x72, 0x73, 0x1a, 0x57, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x61, 0x73, - 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x48, 0x5a, 0x46, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, - 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, - 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, - 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, - 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x22, 0x9e, + 0x01, 0x0a, 0x0a, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x42, 0x61, 0x73, 0x65, 0x12, 0x39, 0x0a, + 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x21, 0x2e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, + 0x42, 0x61, 0x73, 0x65, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, + 0x69, 0x6c, 0x65, 0x73, 0x1a, 0x39, 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x5a, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x28, 0x0a, 0x0d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0c, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, + 0x74, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x42, 0x10, 0x0a, 0x0e, 0x5f, 0x67, 0x65, + 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0xfa, 0x01, 0x0a, 0x0d, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x12, 0x19, 0x0a, + 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, + 0x69, 0x6d, 0x61, 0x67, 0x65, 0x88, 0x01, 0x01, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x73, 0x12, 0x67, 0x0a, 0x15, + 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x76, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, + 0x72, 0x42, 0x61, 0x73, 0x65, 0x2e, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, + 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, + 0x14, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, + 0x61, 0x62, 0x6c, 0x65, 0x73, 0x1a, 0x47, 0x0a, 0x19, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x56, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x08, + 0x0a, 0x06, 0x5f, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0xfc, 0x01, 0x0a, 0x04, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x2f, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x29, 0x0a, 0x04, 0x62, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x15, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4f, 0x62, 0x6a, + 0x65, 0x63, 0x74, 0x42, 0x61, 0x73, 0x65, 0x52, 0x04, 0x62, 0x61, 0x73, 0x65, 0x12, 0x3f, 0x0a, + 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x70, + 0x65, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x0a, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x1a, 0x57, + 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x61, 0x73, 0x65, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x93, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x64, 0x12, 0x1f, 0x0a, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, 0x75, 0x6d, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x08, 0x63, 0x68, 0x65, 0x63, 0x6b, 0x73, + 0x75, 0x6d, 0x88, 0x01, 0x01, 0x12, 0x15, 0x0a, 0x03, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x01, 0x52, 0x03, 0x75, 0x69, 0x64, 0x88, 0x01, 0x01, 0x12, 0x1a, 0x0a, 0x08, + 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, + 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x68, 0x65, + 0x63, 0x6b, 0x73, 0x75, 0x6d, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x75, 0x69, 0x64, 0x42, 0x48, 0x5a, + 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, + 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, + 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -363,22 +449,23 @@ func file_integrations_scheduler_v1_definition_common_proto_rawDescGZIP() []byte return file_integrations_scheduler_v1_definition_common_proto_rawDescData } -var file_integrations_scheduler_v1_definition_common_proto_msgTypes = make([]protoimpl.MessageInfo, 7) +var file_integrations_scheduler_v1_definition_common_proto_msgTypes = make([]protoimpl.MessageInfo, 8) var file_integrations_scheduler_v1_definition_common_proto_goTypes = []interface{}{ - (*JobBase)(nil), // 0: scheduler.JobBase - (*Metadata)(nil), // 1: scheduler.Metadata - (*ContainerBase)(nil), // 2: scheduler.ContainerBase - (*Spec)(nil), // 3: scheduler.Spec - nil, // 4: scheduler.JobBase.LabelsEntry - nil, // 5: scheduler.ContainerBase.EnvironmentVariablesEntry - nil, // 6: scheduler.Spec.ContainersEntry + (*ObjectBase)(nil), // 0: scheduler.ObjectBase + (*Metadata)(nil), // 1: scheduler.Metadata + (*ContainerBase)(nil), // 2: scheduler.ContainerBase + (*Spec)(nil), // 3: scheduler.Spec + (*StatusMetadata)(nil), // 4: scheduler.StatusMetadata + nil, // 5: scheduler.ObjectBase.LabelsEntry + nil, // 6: scheduler.ContainerBase.EnvironmentVariablesEntry + nil, // 7: scheduler.Spec.ContainersEntry } var file_integrations_scheduler_v1_definition_common_proto_depIdxs = []int32{ - 4, // 0: scheduler.JobBase.labels:type_name -> scheduler.JobBase.LabelsEntry - 5, // 1: scheduler.ContainerBase.environment_variables:type_name -> scheduler.ContainerBase.EnvironmentVariablesEntry + 5, // 0: scheduler.ObjectBase.labels:type_name -> scheduler.ObjectBase.LabelsEntry + 6, // 1: scheduler.ContainerBase.environment_variables:type_name -> scheduler.ContainerBase.EnvironmentVariablesEntry 1, // 2: scheduler.Spec.metadata:type_name -> scheduler.Metadata - 0, // 3: scheduler.Spec.job:type_name -> scheduler.JobBase - 6, // 4: scheduler.Spec.containers:type_name -> scheduler.Spec.ContainersEntry + 0, // 3: scheduler.Spec.base:type_name -> scheduler.ObjectBase + 7, // 4: scheduler.Spec.containers:type_name -> scheduler.Spec.ContainersEntry 2, // 5: scheduler.Spec.ContainersEntry.value:type_name -> scheduler.ContainerBase 6, // [6:6] is the sub-list for method output_type 6, // [6:6] is the sub-list for method input_type @@ -394,7 +481,7 @@ func file_integrations_scheduler_v1_definition_common_proto_init() { } if !protoimpl.UnsafeEnabled { file_integrations_scheduler_v1_definition_common_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*JobBase); i { + switch v := v.(*ObjectBase); i { case 0: return &v.state case 1: @@ -441,16 +528,29 @@ func file_integrations_scheduler_v1_definition_common_proto_init() { return nil } } + file_integrations_scheduler_v1_definition_common_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StatusMetadata); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_integrations_scheduler_v1_definition_common_proto_msgTypes[1].OneofWrappers = []interface{}{} file_integrations_scheduler_v1_definition_common_proto_msgTypes[2].OneofWrappers = []interface{}{} + file_integrations_scheduler_v1_definition_common_proto_msgTypes[4].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_integrations_scheduler_v1_definition_common_proto_rawDesc, NumEnums: 0, - NumMessages: 7, + NumMessages: 8, NumExtensions: 0, NumServices: 0, }, diff --git a/integrations/scheduler/v1/definition/common.proto b/integrations/scheduler/v1/definition/common.proto index ab83b0bbb..525a0a3a2 100644 --- a/integrations/scheduler/v1/definition/common.proto +++ b/integrations/scheduler/v1/definition/common.proto @@ -24,8 +24,8 @@ package scheduler; option go_package = "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition"; -// Common base of the Jobs -message JobBase { +// Common base of the objects +message ObjectBase { // Map of the Labels assigned to the job. Used for Profile selection map labels = 1; @@ -60,8 +60,23 @@ message Spec { Metadata metadata = 1; // Keeps requested Job base - JobBase job = 2; + ObjectBase base = 2; // Keeps map of the containers map containers = 3; } + +// Defines status of the scheduled object +message StatusMetadata { + // Defines if upstream object has been created + bool created = 1; + + // Defines checksum + optional string checksum =2; + + // Defines uid + optional string uid =3; + + // Defiles list of applied profiles + repeated string profiles = 4; +} \ No newline at end of file diff --git a/integrations/scheduler/v1/definition/cronjob.pb.go b/integrations/scheduler/v1/definition/cronjob.pb.go index 6b32da840..fdf642257 100644 --- a/integrations/scheduler/v1/definition/cronjob.pb.go +++ b/integrations/scheduler/v1/definition/cronjob.pb.go @@ -46,8 +46,12 @@ type CronJob struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // defines object status metadate + Metadata *StatusMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` // Keeps the CronJob Settings - Spec *CronJobSpec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + Spec *CronJobSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` + // Keeps the CronJob Status + Status *CronJobStatus `protobuf:"bytes,3,opt,name=status,proto3" json:"status,omitempty"` } func (x *CronJob) Reset() { @@ -82,6 +86,13 @@ func (*CronJob) Descriptor() ([]byte, []int) { return file_integrations_scheduler_v1_definition_cronjob_proto_rawDescGZIP(), []int{0} } +func (x *CronJob) GetMetadata() *StatusMetadata { + if x != nil { + return x.Metadata + } + return nil +} + func (x *CronJob) GetSpec() *CronJobSpec { if x != nil { return x.Spec @@ -89,6 +100,13 @@ func (x *CronJob) GetSpec() *CronJobSpec { return nil } +func (x *CronJob) GetStatus() *CronJobStatus { + if x != nil { + return x.Status + } + return nil +} + // Information about CronJob run settings type CronJobSpec struct { state protoimpl.MessageState @@ -147,6 +165,55 @@ func (x *CronJobSpec) GetJob() *BatchJobSpec { return nil } +// Information about CronJob Status +type CronJobStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Keeps list of created BatchJobs + BatchJobs []string `protobuf:"bytes,1,rep,name=batch_jobs,json=batchJobs,proto3" json:"batch_jobs,omitempty"` +} + +func (x *CronJobStatus) Reset() { + *x = CronJobStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CronJobStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CronJobStatus) ProtoMessage() {} + +func (x *CronJobStatus) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CronJobStatus.ProtoReflect.Descriptor instead. +func (*CronJobStatus) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_cronjob_proto_rawDescGZIP(), []int{2} +} + +func (x *CronJobStatus) GetBatchJobs() []string { + if x != nil { + return x.BatchJobs + } + return nil +} + var File_integrations_scheduler_v1_definition_cronjob_proto protoreflect.FileDescriptor var file_integrations_scheduler_v1_definition_cronjob_proto_rawDesc = []byte{ @@ -154,24 +221,36 @@ var file_integrations_scheduler_v1_definition_cronjob_proto_rawDesc = []byte{ 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x72, 0x6f, 0x6e, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x1a, - 0x33, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, + 0x31, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x6a, 0x6f, 0x62, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x35, 0x0a, 0x07, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, - 0x2a, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, - 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x54, 0x0a, 0x0b, 0x43, - 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x6a, 0x6f, - 0x62, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, - 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, - 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x1a, 0x33, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x6a, 0x6f, + 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9e, 0x01, 0x0a, 0x07, 0x43, 0x72, 0x6f, 0x6e, + 0x4a, 0x6f, 0x62, 0x12, 0x35, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x30, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0x54, 0x0a, 0x0b, 0x43, 0x72, 0x6f, 0x6e, + 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x12, 0x29, 0x0a, 0x03, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x03, 0x6a, 0x6f, 0x62, 0x22, 0x2e, + 0x0a, 0x0d, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x42, 0x48, + 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, + 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, + 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -186,20 +265,24 @@ func file_integrations_scheduler_v1_definition_cronjob_proto_rawDescGZIP() []byt return file_integrations_scheduler_v1_definition_cronjob_proto_rawDescData } -var file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_integrations_scheduler_v1_definition_cronjob_proto_goTypes = []interface{}{ - (*CronJob)(nil), // 0: scheduler.CronJob - (*CronJobSpec)(nil), // 1: scheduler.CronJobSpec - (*BatchJobSpec)(nil), // 2: scheduler.BatchJobSpec + (*CronJob)(nil), // 0: scheduler.CronJob + (*CronJobSpec)(nil), // 1: scheduler.CronJobSpec + (*CronJobStatus)(nil), // 2: scheduler.CronJobStatus + (*StatusMetadata)(nil), // 3: scheduler.StatusMetadata + (*BatchJobSpec)(nil), // 4: scheduler.BatchJobSpec } var file_integrations_scheduler_v1_definition_cronjob_proto_depIdxs = []int32{ - 1, // 0: scheduler.CronJob.spec:type_name -> scheduler.CronJobSpec - 2, // 1: scheduler.CronJobSpec.job:type_name -> scheduler.BatchJobSpec - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 3, // 0: scheduler.CronJob.metadata:type_name -> scheduler.StatusMetadata + 1, // 1: scheduler.CronJob.spec:type_name -> scheduler.CronJobSpec + 2, // 2: scheduler.CronJob.status:type_name -> scheduler.CronJobStatus + 4, // 3: scheduler.CronJobSpec.job:type_name -> scheduler.BatchJobSpec + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_integrations_scheduler_v1_definition_cronjob_proto_init() } @@ -207,6 +290,7 @@ func file_integrations_scheduler_v1_definition_cronjob_proto_init() { if File_integrations_scheduler_v1_definition_cronjob_proto != nil { return } + file_integrations_scheduler_v1_definition_common_proto_init() file_integrations_scheduler_v1_definition_batchjob_proto_init() if !protoimpl.UnsafeEnabled { file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { @@ -233,6 +317,18 @@ func file_integrations_scheduler_v1_definition_cronjob_proto_init() { return nil } } + file_integrations_scheduler_v1_definition_cronjob_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CronJobStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -240,7 +336,7 @@ func file_integrations_scheduler_v1_definition_cronjob_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_integrations_scheduler_v1_definition_cronjob_proto_rawDesc, NumEnums: 0, - NumMessages: 2, + NumMessages: 3, NumExtensions: 0, NumServices: 0, }, diff --git a/integrations/scheduler/v1/definition/cronjob.proto b/integrations/scheduler/v1/definition/cronjob.proto index b0f37eadc..57fcf3430 100644 --- a/integrations/scheduler/v1/definition/cronjob.proto +++ b/integrations/scheduler/v1/definition/cronjob.proto @@ -22,14 +22,21 @@ syntax = "proto3"; package scheduler; +import "integrations/scheduler/v1/definition/common.proto"; import "integrations/scheduler/v1/definition/batchjob.proto"; option go_package = "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition"; // Keeps information about Kubernetes Batch/V1 CronJob message CronJob { + // defines object status metadate + StatusMetadata metadata = 1; + // Keeps the CronJob Settings - CronJobSpec spec = 1; + CronJobSpec spec = 2; + + // Keeps the CronJob Status + CronJobStatus status = 3; } // Information about CronJob run settings @@ -40,3 +47,9 @@ message CronJobSpec { // Keeps BatchJob settings BatchJobSpec job = 2; } + +// Information about CronJob Status +message CronJobStatus { + // Keeps list of created BatchJobs + repeated string batch_jobs = 1; +} diff --git a/integrations/scheduler/v1/definition/definition.pb.go b/integrations/scheduler/v1/definition/definition.pb.go index a86fab87a..854cb44e4 100644 --- a/integrations/scheduler/v1/definition/definition.pb.go +++ b/integrations/scheduler/v1/definition/definition.pb.go @@ -106,8 +106,6 @@ type CreateBatchJobResponse struct { // Name of the scheduled job Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // List of the assigned profiles - Profiles []string `protobuf:"bytes,2,rep,name=profiles,proto3" json:"profiles,omitempty"` } func (x *CreateBatchJobResponse) Reset() { @@ -149,13 +147,6 @@ func (x *CreateBatchJobResponse) GetName() string { return "" } -func (x *CreateBatchJobResponse) GetProfiles() []string { - if x != nil { - return x.Profiles - } - return nil -} - // Get Request type GetBatchJobRequest struct { state protoimpl.MessageState @@ -524,8 +515,6 @@ type CreateCronJobResponse struct { // Name of the scheduled job Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // List of the assigned profiles - Profiles []string `protobuf:"bytes,2,rep,name=profiles,proto3" json:"profiles,omitempty"` } func (x *CreateCronJobResponse) Reset() { @@ -567,13 +556,6 @@ func (x *CreateCronJobResponse) GetName() string { return "" } -func (x *CreateCronJobResponse) GetProfiles() []string { - if x != nil { - return x.Profiles - } - return nil -} - // Get Request type GetCronJobRequest struct { state protoimpl.MessageState @@ -633,8 +615,6 @@ type GetCronJobResponse struct { Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // CronJob run settings and current status CronJob *CronJob `protobuf:"bytes,2,opt,name=cron_job,json=cronJob,proto3,oneof" json:"cron_job,omitempty"` - // Keeps list of created BatchJobs - BatchJobs []string `protobuf:"bytes,3,rep,name=batch_jobs,json=batchJobs,proto3" json:"batch_jobs,omitempty"` } func (x *GetCronJobResponse) Reset() { @@ -683,13 +663,6 @@ func (x *GetCronJobResponse) GetCronJob() *CronJob { return nil } -func (x *GetCronJobResponse) GetBatchJobs() []string { - if x != nil { - return x.BatchJobs - } - return nil -} - // Update Request type UpdateCronJobRequest struct { state protoimpl.MessageState @@ -1001,6 +974,531 @@ func (x *DeleteCronJobResponse) GetExists() bool { return false } +// Create Request +type CreateDeploymentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Spec of the Schedule request + Spec *Spec `protobuf:"bytes,1,opt,name=spec,proto3" json:"spec,omitempty"` + // Deployment run settings + Deployment *DeploymentSpec `protobuf:"bytes,2,opt,name=deployment,proto3" json:"deployment,omitempty"` +} + +func (x *CreateDeploymentRequest) Reset() { + *x = CreateDeploymentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDeploymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDeploymentRequest) ProtoMessage() {} + +func (x *CreateDeploymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDeploymentRequest.ProtoReflect.Descriptor instead. +func (*CreateDeploymentRequest) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{18} +} + +func (x *CreateDeploymentRequest) GetSpec() *Spec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *CreateDeploymentRequest) GetDeployment() *DeploymentSpec { + if x != nil { + return x.Deployment + } + return nil +} + +// Create Response +type CreateDeploymentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the scheduled deployment + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *CreateDeploymentResponse) Reset() { + *x = CreateDeploymentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CreateDeploymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CreateDeploymentResponse) ProtoMessage() {} + +func (x *CreateDeploymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CreateDeploymentResponse.ProtoReflect.Descriptor instead. +func (*CreateDeploymentResponse) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{19} +} + +func (x *CreateDeploymentResponse) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// Get Request +type GetDeploymentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the scheduled deployment + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` +} + +func (x *GetDeploymentRequest) Reset() { + *x = GetDeploymentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeploymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeploymentRequest) ProtoMessage() {} + +func (x *GetDeploymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeploymentRequest.ProtoReflect.Descriptor instead. +func (*GetDeploymentRequest) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{20} +} + +func (x *GetDeploymentRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +// Get Response +type GetDeploymentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Defines if deployment was found + Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` + // Deployment run settings and current status + Deployment *Deployment `protobuf:"bytes,2,opt,name=deployment,proto3,oneof" json:"deployment,omitempty"` +} + +func (x *GetDeploymentResponse) Reset() { + *x = GetDeploymentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *GetDeploymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*GetDeploymentResponse) ProtoMessage() {} + +func (x *GetDeploymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use GetDeploymentResponse.ProtoReflect.Descriptor instead. +func (*GetDeploymentResponse) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{21} +} + +func (x *GetDeploymentResponse) GetExists() bool { + if x != nil { + return x.Exists + } + return false +} + +func (x *GetDeploymentResponse) GetDeployment() *Deployment { + if x != nil { + return x.Deployment + } + return nil +} + +// Update Request +type UpdateDeploymentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the scheduled deployment + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Deployment spec to be updated + Spec *DeploymentSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` +} + +func (x *UpdateDeploymentRequest) Reset() { + *x = UpdateDeploymentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeploymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeploymentRequest) ProtoMessage() {} + +func (x *UpdateDeploymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeploymentRequest.ProtoReflect.Descriptor instead. +func (*UpdateDeploymentRequest) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{22} +} + +func (x *UpdateDeploymentRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *UpdateDeploymentRequest) GetSpec() *DeploymentSpec { + if x != nil { + return x.Spec + } + return nil +} + +// Update Response +type UpdateDeploymentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Defines if deployment was found + Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` + // Deployment run settings and current status + Deployment *Deployment `protobuf:"bytes,2,opt,name=deployment,proto3,oneof" json:"deployment,omitempty"` +} + +func (x *UpdateDeploymentResponse) Reset() { + *x = UpdateDeploymentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UpdateDeploymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UpdateDeploymentResponse) ProtoMessage() {} + +func (x *UpdateDeploymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UpdateDeploymentResponse.ProtoReflect.Descriptor instead. +func (*UpdateDeploymentResponse) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{23} +} + +func (x *UpdateDeploymentResponse) GetExists() bool { + if x != nil { + return x.Exists + } + return false +} + +func (x *UpdateDeploymentResponse) GetDeployment() *Deployment { + if x != nil { + return x.Deployment + } + return nil +} + +// List Request +type ListDeploymentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ListDeploymentRequest) Reset() { + *x = ListDeploymentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDeploymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDeploymentRequest) ProtoMessage() {} + +func (x *ListDeploymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDeploymentRequest.ProtoReflect.Descriptor instead. +func (*ListDeploymentRequest) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{24} +} + +// List Response +type ListDeploymentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // List of the Deployments + Deployments []string `protobuf:"bytes,1,rep,name=deployments,proto3" json:"deployments,omitempty"` +} + +func (x *ListDeploymentResponse) Reset() { + *x = ListDeploymentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ListDeploymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListDeploymentResponse) ProtoMessage() {} + +func (x *ListDeploymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListDeploymentResponse.ProtoReflect.Descriptor instead. +func (*ListDeploymentResponse) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{25} +} + +func (x *ListDeploymentResponse) GetDeployments() []string { + if x != nil { + return x.Deployments + } + return nil +} + +// Delete Request +type DeleteDeploymentRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Name of the scheduled deployment + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Defines if all child containers/pods should be removed together with deployment + DeleteChildPods *bool `protobuf:"varint,2,opt,name=delete_child_pods,json=deleteChildPods,proto3,oneof" json:"delete_child_pods,omitempty"` +} + +func (x *DeleteDeploymentRequest) Reset() { + *x = DeleteDeploymentRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDeploymentRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDeploymentRequest) ProtoMessage() {} + +func (x *DeleteDeploymentRequest) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDeploymentRequest.ProtoReflect.Descriptor instead. +func (*DeleteDeploymentRequest) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{26} +} + +func (x *DeleteDeploymentRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DeleteDeploymentRequest) GetDeleteChildPods() bool { + if x != nil && x.DeleteChildPods != nil { + return *x.DeleteChildPods + } + return false +} + +// Delete Response +type DeleteDeploymentResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Defines if deployment was found + Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` +} + +func (x *DeleteDeploymentResponse) Reset() { + *x = DeleteDeploymentResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeleteDeploymentResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeleteDeploymentResponse) ProtoMessage() {} + +func (x *DeleteDeploymentResponse) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_definition_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeleteDeploymentResponse.ProtoReflect.Descriptor instead. +func (*DeleteDeploymentResponse) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP(), []int{27} +} + +func (x *DeleteDeploymentResponse) GetExists() bool { + if x != nil { + return x.Exists + } + return false +} + var File_integrations_scheduler_v1_definition_definition_proto protoreflect.FileDescriptor var file_integrations_scheduler_v1_definition_definition_proto_rawDesc = []byte{ @@ -1017,148 +1515,226 @@ var file_integrations_scheduler_v1_definition_definition_proto_rawDesc = []byte{ 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x32, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x2f, 0x63, 0x72, 0x6f, 0x6e, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x72, - 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, - 0x72, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x34, 0x0a, 0x09, - 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x17, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, - 0x6f, 0x62, 0x22, 0x48, 0x0a, 0x16, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x2f, 0x63, 0x72, 0x6f, 0x6e, 0x6a, 0x6f, 0x62, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x35, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, + 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x72, 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, + 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x12, 0x34, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, + 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x22, 0x2c, 0x0a, 0x16, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x28, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x72, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x12, 0x35, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x48, 0x00, 0x52, 0x08, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x4a, 0x6f, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, 0x5f, 0x62, 0x61, 0x74, 0x63, + 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x35, 0x0a, 0x14, + 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, + 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, + 0x6f, 0x62, 0x73, 0x22, 0x72, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x28, 0x0a, 0x12, - 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x72, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, - 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x35, 0x0a, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, - 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, - 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x48, 0x00, 0x52, - 0x08, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0c, 0x0a, 0x0a, - 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x22, 0x15, 0x0a, 0x13, 0x4c, 0x69, - 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x22, 0x35, 0x0a, 0x14, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, - 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x62, - 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x73, 0x22, 0x72, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, - 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x50, - 0x6f, 0x64, 0x73, 0x88, 0x01, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, - 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x30, 0x0a, 0x16, - 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x6e, - 0x0a, 0x14, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x2e, 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x08, 0x63, - 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, - 0x62, 0x53, 0x70, 0x65, 0x63, 0x52, 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x22, 0x47, - 0x0a, 0x15, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x70, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x70, - 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x73, 0x22, 0x27, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x72, - 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, - 0x22, 0x8c, 0x01, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, - 0x32, 0x0a, 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, - 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, - 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6a, 0x6f, 0x62, - 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, - 0x62, 0x73, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x22, - 0x56, 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x73, - 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, - 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x70, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x63, 0x72, 0x6f, 0x6e, - 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x63, 0x68, - 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x48, 0x00, - 0x52, 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, - 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, - 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, - 0x32, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, - 0x6f, 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x4a, - 0x6f, 0x62, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, + 0x12, 0x2f, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0f, 0x64, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x50, 0x6f, 0x64, 0x73, 0x88, 0x01, + 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, + 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x30, 0x0a, 0x16, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x6e, 0x0a, 0x14, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x31, 0x0a, 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, + 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x22, 0x2b, 0x0a, 0x15, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x27, 0x0a, 0x11, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, - 0x2f, 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, - 0x70, 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, - 0x6c, 0x65, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x50, 0x6f, 0x64, 0x73, 0x88, 0x01, 0x01, - 0x42, 0x14, 0x0a, 0x12, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, - 0x64, 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x2f, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, + 0x6d, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x32, 0x0a, + 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x12, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, + 0x4a, 0x6f, 0x62, 0x48, 0x00, 0x52, 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x88, 0x01, + 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x22, 0x56, + 0x0a, 0x14, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2a, 0x0a, 0x04, 0x73, 0x70, + 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, + 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x70, 0x0a, 0x15, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, - 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x32, 0x81, 0x06, 0x0a, 0x0b, 0x53, 0x63, 0x68, 0x65, - 0x64, 0x75, 0x6c, 0x65, 0x72, 0x56, 0x31, 0x12, 0x57, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x5f, + 0x6a, 0x6f, 0x62, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x48, 0x00, 0x52, + 0x07, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x88, 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, + 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, 0x62, 0x22, 0x14, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, + 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x32, + 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x72, 0x6f, 0x6e, 0x5f, 0x6a, 0x6f, + 0x62, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x63, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, + 0x62, 0x73, 0x22, 0x71, 0x0a, 0x14, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, + 0x0a, 0x11, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x70, + 0x6f, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x6c, + 0x65, 0x74, 0x65, 0x43, 0x68, 0x69, 0x6c, 0x64, 0x50, 0x6f, 0x64, 0x73, 0x88, 0x01, 0x01, 0x42, + 0x14, 0x0a, 0x12, 0x5f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, + 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x22, 0x2f, 0x0a, 0x15, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, + 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, + 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x22, 0x79, 0x0a, 0x17, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x23, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x0f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x53, 0x70, 0x65, 0x63, + 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x39, 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x70, 0x65, 0x63, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x22, 0x2e, 0x0a, 0x18, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x22, 0x2a, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x7a, 0x0a, + 0x15, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x3a, + 0x0a, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x64, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x5c, 0x0a, 0x17, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x22, 0x7d, 0x0a, 0x18, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x12, 0x3a, 0x0a, 0x0a, 0x64, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x0a, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f, 0x64, 0x65, 0x70, 0x6c, + 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x17, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, + 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, + 0x3a, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, + 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x74, 0x0a, 0x17, 0x44, + 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2f, 0x0a, 0x11, 0x64, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x64, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x00, 0x52, 0x0f, 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, + 0x68, 0x69, 0x6c, 0x64, 0x50, 0x6f, 0x64, 0x73, 0x88, 0x01, 0x01, 0x42, 0x14, 0x0a, 0x12, 0x5f, + 0x64, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x5f, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x5f, 0x70, 0x6f, 0x64, + 0x73, 0x22, 0x32, 0x0a, 0x18, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, + 0x78, 0x69, 0x73, 0x74, 0x73, 0x32, 0xcd, 0x09, 0x0a, 0x0b, 0x53, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x56, 0x31, 0x12, 0x57, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, + 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, + 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x4e, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, - 0x1d, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x51, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, - 0x12, 0x1e, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, - 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, - 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, + 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x2e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x51, + 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x12, 0x1e, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, + 0x00, 0x12, 0x57, 0x0a, 0x0e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x4a, 0x6f, 0x62, 0x12, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4a, - 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1f, 0x2e, - 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, - 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, - 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, - 0x12, 0x1c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, - 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1f, 0x2e, 0x73, 0x63, + 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x72, + 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, + 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x4b, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1c, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, - 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, - 0x54, 0x0a, 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, - 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, - 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x70, - 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, - 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, - 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, - 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, - 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, - 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, - 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, - 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x48, 0x5a, 0x46, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, - 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, - 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, - 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x72, 0x6f, 0x6e, + 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, + 0x0d, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1f, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x4e, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, + 0x6f, 0x62, 0x12, 0x1d, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, + 0x69, 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x1e, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, + 0x6e, 0x4a, 0x6f, 0x62, 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x72, 0x6f, 0x6e, 0x4a, 0x6f, 0x62, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x2e, + 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x72, + 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x54, 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x44, + 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, + 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, + 0x6e, 0x74, 0x12, 0x22, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, + 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x57, 0x0a, + 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x20, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x21, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5d, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x22, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x70, + 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, + 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, + 0x63, 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, + 0x65, 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, + 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, + 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1173,64 +1749,91 @@ func file_integrations_scheduler_v1_definition_definition_proto_rawDescGZIP() [] return file_integrations_scheduler_v1_definition_definition_proto_rawDescData } -var file_integrations_scheduler_v1_definition_definition_proto_msgTypes = make([]protoimpl.MessageInfo, 18) +var file_integrations_scheduler_v1_definition_definition_proto_msgTypes = make([]protoimpl.MessageInfo, 28) var file_integrations_scheduler_v1_definition_definition_proto_goTypes = []interface{}{ - (*CreateBatchJobRequest)(nil), // 0: scheduler.CreateBatchJobRequest - (*CreateBatchJobResponse)(nil), // 1: scheduler.CreateBatchJobResponse - (*GetBatchJobRequest)(nil), // 2: scheduler.GetBatchJobRequest - (*GetBatchJobResponse)(nil), // 3: scheduler.GetBatchJobResponse - (*ListBatchJobRequest)(nil), // 4: scheduler.ListBatchJobRequest - (*ListBatchJobResponse)(nil), // 5: scheduler.ListBatchJobResponse - (*DeleteBatchJobRequest)(nil), // 6: scheduler.DeleteBatchJobRequest - (*DeleteBatchJobResponse)(nil), // 7: scheduler.DeleteBatchJobResponse - (*CreateCronJobRequest)(nil), // 8: scheduler.CreateCronJobRequest - (*CreateCronJobResponse)(nil), // 9: scheduler.CreateCronJobResponse - (*GetCronJobRequest)(nil), // 10: scheduler.GetCronJobRequest - (*GetCronJobResponse)(nil), // 11: scheduler.GetCronJobResponse - (*UpdateCronJobRequest)(nil), // 12: scheduler.UpdateCronJobRequest - (*UpdateCronJobResponse)(nil), // 13: scheduler.UpdateCronJobResponse - (*ListCronJobRequest)(nil), // 14: scheduler.ListCronJobRequest - (*ListCronJobResponse)(nil), // 15: scheduler.ListCronJobResponse - (*DeleteCronJobRequest)(nil), // 16: scheduler.DeleteCronJobRequest - (*DeleteCronJobResponse)(nil), // 17: scheduler.DeleteCronJobResponse - (*Spec)(nil), // 18: scheduler.Spec - (*BatchJobSpec)(nil), // 19: scheduler.BatchJobSpec - (*BatchJob)(nil), // 20: scheduler.BatchJob - (*CronJobSpec)(nil), // 21: scheduler.CronJobSpec - (*CronJob)(nil), // 22: scheduler.CronJob + (*CreateBatchJobRequest)(nil), // 0: scheduler.CreateBatchJobRequest + (*CreateBatchJobResponse)(nil), // 1: scheduler.CreateBatchJobResponse + (*GetBatchJobRequest)(nil), // 2: scheduler.GetBatchJobRequest + (*GetBatchJobResponse)(nil), // 3: scheduler.GetBatchJobResponse + (*ListBatchJobRequest)(nil), // 4: scheduler.ListBatchJobRequest + (*ListBatchJobResponse)(nil), // 5: scheduler.ListBatchJobResponse + (*DeleteBatchJobRequest)(nil), // 6: scheduler.DeleteBatchJobRequest + (*DeleteBatchJobResponse)(nil), // 7: scheduler.DeleteBatchJobResponse + (*CreateCronJobRequest)(nil), // 8: scheduler.CreateCronJobRequest + (*CreateCronJobResponse)(nil), // 9: scheduler.CreateCronJobResponse + (*GetCronJobRequest)(nil), // 10: scheduler.GetCronJobRequest + (*GetCronJobResponse)(nil), // 11: scheduler.GetCronJobResponse + (*UpdateCronJobRequest)(nil), // 12: scheduler.UpdateCronJobRequest + (*UpdateCronJobResponse)(nil), // 13: scheduler.UpdateCronJobResponse + (*ListCronJobRequest)(nil), // 14: scheduler.ListCronJobRequest + (*ListCronJobResponse)(nil), // 15: scheduler.ListCronJobResponse + (*DeleteCronJobRequest)(nil), // 16: scheduler.DeleteCronJobRequest + (*DeleteCronJobResponse)(nil), // 17: scheduler.DeleteCronJobResponse + (*CreateDeploymentRequest)(nil), // 18: scheduler.CreateDeploymentRequest + (*CreateDeploymentResponse)(nil), // 19: scheduler.CreateDeploymentResponse + (*GetDeploymentRequest)(nil), // 20: scheduler.GetDeploymentRequest + (*GetDeploymentResponse)(nil), // 21: scheduler.GetDeploymentResponse + (*UpdateDeploymentRequest)(nil), // 22: scheduler.UpdateDeploymentRequest + (*UpdateDeploymentResponse)(nil), // 23: scheduler.UpdateDeploymentResponse + (*ListDeploymentRequest)(nil), // 24: scheduler.ListDeploymentRequest + (*ListDeploymentResponse)(nil), // 25: scheduler.ListDeploymentResponse + (*DeleteDeploymentRequest)(nil), // 26: scheduler.DeleteDeploymentRequest + (*DeleteDeploymentResponse)(nil), // 27: scheduler.DeleteDeploymentResponse + (*Spec)(nil), // 28: scheduler.Spec + (*BatchJobSpec)(nil), // 29: scheduler.BatchJobSpec + (*BatchJob)(nil), // 30: scheduler.BatchJob + (*CronJobSpec)(nil), // 31: scheduler.CronJobSpec + (*CronJob)(nil), // 32: scheduler.CronJob + (*DeploymentSpec)(nil), // 33: scheduler.DeploymentSpec + (*Deployment)(nil), // 34: scheduler.Deployment } var file_integrations_scheduler_v1_definition_definition_proto_depIdxs = []int32{ - 18, // 0: scheduler.CreateBatchJobRequest.spec:type_name -> scheduler.Spec - 19, // 1: scheduler.CreateBatchJobRequest.batch_job:type_name -> scheduler.BatchJobSpec - 20, // 2: scheduler.GetBatchJobResponse.batch_job:type_name -> scheduler.BatchJob - 18, // 3: scheduler.CreateCronJobRequest.spec:type_name -> scheduler.Spec - 21, // 4: scheduler.CreateCronJobRequest.cron_job:type_name -> scheduler.CronJobSpec - 22, // 5: scheduler.GetCronJobResponse.cron_job:type_name -> scheduler.CronJob - 21, // 6: scheduler.UpdateCronJobRequest.spec:type_name -> scheduler.CronJobSpec - 22, // 7: scheduler.UpdateCronJobResponse.cron_job:type_name -> scheduler.CronJob - 0, // 8: scheduler.SchedulerV1.CreateBatchJob:input_type -> scheduler.CreateBatchJobRequest - 2, // 9: scheduler.SchedulerV1.GetBatchJob:input_type -> scheduler.GetBatchJobRequest - 4, // 10: scheduler.SchedulerV1.ListBatchJob:input_type -> scheduler.ListBatchJobRequest - 6, // 11: scheduler.SchedulerV1.DeleteBatchJob:input_type -> scheduler.DeleteBatchJobRequest - 8, // 12: scheduler.SchedulerV1.CreateCronJob:input_type -> scheduler.CreateCronJobRequest - 10, // 13: scheduler.SchedulerV1.GetCronJob:input_type -> scheduler.GetCronJobRequest - 12, // 14: scheduler.SchedulerV1.UpdateCronJob:input_type -> scheduler.UpdateCronJobRequest - 14, // 15: scheduler.SchedulerV1.ListCronJob:input_type -> scheduler.ListCronJobRequest - 16, // 16: scheduler.SchedulerV1.DeleteCronJob:input_type -> scheduler.DeleteCronJobRequest - 1, // 17: scheduler.SchedulerV1.CreateBatchJob:output_type -> scheduler.CreateBatchJobResponse - 3, // 18: scheduler.SchedulerV1.GetBatchJob:output_type -> scheduler.GetBatchJobResponse - 5, // 19: scheduler.SchedulerV1.ListBatchJob:output_type -> scheduler.ListBatchJobResponse - 7, // 20: scheduler.SchedulerV1.DeleteBatchJob:output_type -> scheduler.DeleteBatchJobResponse - 9, // 21: scheduler.SchedulerV1.CreateCronJob:output_type -> scheduler.CreateCronJobResponse - 11, // 22: scheduler.SchedulerV1.GetCronJob:output_type -> scheduler.GetCronJobResponse - 13, // 23: scheduler.SchedulerV1.UpdateCronJob:output_type -> scheduler.UpdateCronJobResponse - 15, // 24: scheduler.SchedulerV1.ListCronJob:output_type -> scheduler.ListCronJobResponse - 17, // 25: scheduler.SchedulerV1.DeleteCronJob:output_type -> scheduler.DeleteCronJobResponse - 17, // [17:26] is the sub-list for method output_type - 8, // [8:17] is the sub-list for method input_type - 8, // [8:8] is the sub-list for extension type_name - 8, // [8:8] is the sub-list for extension extendee - 0, // [0:8] is the sub-list for field type_name + 28, // 0: scheduler.CreateBatchJobRequest.spec:type_name -> scheduler.Spec + 29, // 1: scheduler.CreateBatchJobRequest.batch_job:type_name -> scheduler.BatchJobSpec + 30, // 2: scheduler.GetBatchJobResponse.batch_job:type_name -> scheduler.BatchJob + 28, // 3: scheduler.CreateCronJobRequest.spec:type_name -> scheduler.Spec + 31, // 4: scheduler.CreateCronJobRequest.cron_job:type_name -> scheduler.CronJobSpec + 32, // 5: scheduler.GetCronJobResponse.cron_job:type_name -> scheduler.CronJob + 31, // 6: scheduler.UpdateCronJobRequest.spec:type_name -> scheduler.CronJobSpec + 32, // 7: scheduler.UpdateCronJobResponse.cron_job:type_name -> scheduler.CronJob + 28, // 8: scheduler.CreateDeploymentRequest.spec:type_name -> scheduler.Spec + 33, // 9: scheduler.CreateDeploymentRequest.deployment:type_name -> scheduler.DeploymentSpec + 34, // 10: scheduler.GetDeploymentResponse.deployment:type_name -> scheduler.Deployment + 33, // 11: scheduler.UpdateDeploymentRequest.spec:type_name -> scheduler.DeploymentSpec + 34, // 12: scheduler.UpdateDeploymentResponse.deployment:type_name -> scheduler.Deployment + 0, // 13: scheduler.SchedulerV1.CreateBatchJob:input_type -> scheduler.CreateBatchJobRequest + 2, // 14: scheduler.SchedulerV1.GetBatchJob:input_type -> scheduler.GetBatchJobRequest + 4, // 15: scheduler.SchedulerV1.ListBatchJob:input_type -> scheduler.ListBatchJobRequest + 6, // 16: scheduler.SchedulerV1.DeleteBatchJob:input_type -> scheduler.DeleteBatchJobRequest + 8, // 17: scheduler.SchedulerV1.CreateCronJob:input_type -> scheduler.CreateCronJobRequest + 10, // 18: scheduler.SchedulerV1.GetCronJob:input_type -> scheduler.GetCronJobRequest + 12, // 19: scheduler.SchedulerV1.UpdateCronJob:input_type -> scheduler.UpdateCronJobRequest + 14, // 20: scheduler.SchedulerV1.ListCronJob:input_type -> scheduler.ListCronJobRequest + 16, // 21: scheduler.SchedulerV1.DeleteCronJob:input_type -> scheduler.DeleteCronJobRequest + 18, // 22: scheduler.SchedulerV1.CreateDeployment:input_type -> scheduler.CreateDeploymentRequest + 20, // 23: scheduler.SchedulerV1.GetDeployment:input_type -> scheduler.GetDeploymentRequest + 22, // 24: scheduler.SchedulerV1.UpdateDeployment:input_type -> scheduler.UpdateDeploymentRequest + 24, // 25: scheduler.SchedulerV1.ListDeployment:input_type -> scheduler.ListDeploymentRequest + 26, // 26: scheduler.SchedulerV1.DeleteDeployment:input_type -> scheduler.DeleteDeploymentRequest + 1, // 27: scheduler.SchedulerV1.CreateBatchJob:output_type -> scheduler.CreateBatchJobResponse + 3, // 28: scheduler.SchedulerV1.GetBatchJob:output_type -> scheduler.GetBatchJobResponse + 5, // 29: scheduler.SchedulerV1.ListBatchJob:output_type -> scheduler.ListBatchJobResponse + 7, // 30: scheduler.SchedulerV1.DeleteBatchJob:output_type -> scheduler.DeleteBatchJobResponse + 9, // 31: scheduler.SchedulerV1.CreateCronJob:output_type -> scheduler.CreateCronJobResponse + 11, // 32: scheduler.SchedulerV1.GetCronJob:output_type -> scheduler.GetCronJobResponse + 13, // 33: scheduler.SchedulerV1.UpdateCronJob:output_type -> scheduler.UpdateCronJobResponse + 15, // 34: scheduler.SchedulerV1.ListCronJob:output_type -> scheduler.ListCronJobResponse + 17, // 35: scheduler.SchedulerV1.DeleteCronJob:output_type -> scheduler.DeleteCronJobResponse + 19, // 36: scheduler.SchedulerV1.CreateDeployment:output_type -> scheduler.CreateDeploymentResponse + 21, // 37: scheduler.SchedulerV1.GetDeployment:output_type -> scheduler.GetDeploymentResponse + 23, // 38: scheduler.SchedulerV1.UpdateDeployment:output_type -> scheduler.UpdateDeploymentResponse + 25, // 39: scheduler.SchedulerV1.ListDeployment:output_type -> scheduler.ListDeploymentResponse + 27, // 40: scheduler.SchedulerV1.DeleteDeployment:output_type -> scheduler.DeleteDeploymentResponse + 27, // [27:41] is the sub-list for method output_type + 13, // [13:27] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_integrations_scheduler_v1_definition_definition_proto_init() } @@ -1241,6 +1844,7 @@ func file_integrations_scheduler_v1_definition_definition_proto_init() { file_integrations_scheduler_v1_definition_batchjob_proto_init() file_integrations_scheduler_v1_definition_common_proto_init() file_integrations_scheduler_v1_definition_cronjob_proto_init() + file_integrations_scheduler_v1_definition_deployment_proto_init() if !protoimpl.UnsafeEnabled { file_integrations_scheduler_v1_definition_definition_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*CreateBatchJobRequest); i { @@ -1458,19 +2062,142 @@ func file_integrations_scheduler_v1_definition_definition_proto_init() { return nil } } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDeploymentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*CreateDeploymentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeploymentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*GetDeploymentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeploymentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UpdateDeploymentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDeploymentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ListDeploymentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDeploymentRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeleteDeploymentResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_integrations_scheduler_v1_definition_definition_proto_msgTypes[3].OneofWrappers = []interface{}{} file_integrations_scheduler_v1_definition_definition_proto_msgTypes[6].OneofWrappers = []interface{}{} file_integrations_scheduler_v1_definition_definition_proto_msgTypes[11].OneofWrappers = []interface{}{} file_integrations_scheduler_v1_definition_definition_proto_msgTypes[13].OneofWrappers = []interface{}{} file_integrations_scheduler_v1_definition_definition_proto_msgTypes[16].OneofWrappers = []interface{}{} + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[21].OneofWrappers = []interface{}{} + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[23].OneofWrappers = []interface{}{} + file_integrations_scheduler_v1_definition_definition_proto_msgTypes[26].OneofWrappers = []interface{}{} type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_integrations_scheduler_v1_definition_definition_proto_rawDesc, NumEnums: 0, - NumMessages: 18, + NumMessages: 28, NumExtensions: 0, NumServices: 1, }, diff --git a/integrations/scheduler/v1/definition/definition.proto b/integrations/scheduler/v1/definition/definition.proto index 71d8aec9b..bffc6fe75 100644 --- a/integrations/scheduler/v1/definition/definition.proto +++ b/integrations/scheduler/v1/definition/definition.proto @@ -25,6 +25,7 @@ package scheduler; import "integrations/scheduler/v1/definition/batchjob.proto"; import "integrations/scheduler/v1/definition/common.proto"; import "integrations/scheduler/v1/definition/cronjob.proto"; +import "integrations/scheduler/v1/definition/deployment.proto"; option go_package = "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition"; @@ -60,6 +61,23 @@ service SchedulerV1 { // Deletes CronJob. If job does not exists, Exists flag is set to false rpc DeleteCronJob(DeleteCronJobRequest) returns (DeleteCronJobResponse) {}; + + // Deployment + + // Creates Deployment from specification + rpc CreateDeployment(CreateDeploymentRequest) returns (CreateDeploymentResponse) {}; + + // Returns Deployment. If job does not exists, Exists flag is set to false + rpc GetDeployment(GetDeploymentRequest) returns (GetDeploymentResponse) {}; + + // Updates Deployment from specification + rpc UpdateDeployment(UpdateDeploymentRequest) returns (UpdateDeploymentResponse) {}; + + // Returns list of the Deployments + rpc ListDeployment(ListDeploymentRequest) returns (ListDeploymentResponse) {}; + + // Deletes Deployment. If job does not exists, Exists flag is set to false + rpc DeleteDeployment(DeleteDeploymentRequest) returns (DeleteDeploymentResponse) {}; } // BatchJob @@ -77,9 +95,6 @@ message CreateBatchJobRequest { message CreateBatchJobResponse { // Name of the scheduled job string name = 1; - - // List of the assigned profiles - repeated string profiles = 2; } // Get Request @@ -138,9 +153,6 @@ message CreateCronJobRequest { message CreateCronJobResponse { // Name of the scheduled job string name = 1; - - // List of the assigned profiles - repeated string profiles = 2; } // Get Request @@ -156,9 +168,6 @@ message GetCronJobResponse { // CronJob run settings and current status optional CronJob cron_job = 2; - - // Keeps list of created BatchJobs - repeated string batch_jobs = 3; } // Update Request @@ -202,4 +211,79 @@ message DeleteCronJobRequest { message DeleteCronJobResponse { // Defines if job was found bool exists = 1; +} + +// Deployment + +// Create Request +message CreateDeploymentRequest { + // Spec of the Schedule request + Spec spec = 1; + + // Deployment run settings + DeploymentSpec deployment = 2; +} + +// Create Response +message CreateDeploymentResponse { + // Name of the scheduled deployment + string name = 1; +} + +// Get Request +message GetDeploymentRequest { + // Name of the scheduled deployment + string name = 1; +} + +// Get Response +message GetDeploymentResponse { + // Defines if deployment was found + bool exists = 1; + + // Deployment run settings and current status + optional Deployment deployment = 2; +} + +// Update Request +message UpdateDeploymentRequest { + // Name of the scheduled deployment + string name = 1; + + // Deployment spec to be updated + DeploymentSpec spec = 2; +} + +// Update Response +message UpdateDeploymentResponse { + // Defines if deployment was found + bool exists = 1; + + // Deployment run settings and current status + optional Deployment deployment = 2; +} + +// List Request +message ListDeploymentRequest { +} + +// List Response +message ListDeploymentResponse { + // List of the Deployments + repeated string deployments = 1; +} + +// Delete Request +message DeleteDeploymentRequest { + // Name of the scheduled deployment + string name = 1; + + // Defines if all child containers/pods should be removed together with deployment + optional bool delete_child_pods = 2; +} + +// Delete Response +message DeleteDeploymentResponse { + // Defines if deployment was found + bool exists = 1; } \ No newline at end of file diff --git a/integrations/scheduler/v1/definition/definition_grpc.pb.go b/integrations/scheduler/v1/definition/definition_grpc.pb.go index 5d86fd505..528c0c308 100644 --- a/integrations/scheduler/v1/definition/definition_grpc.pb.go +++ b/integrations/scheduler/v1/definition/definition_grpc.pb.go @@ -40,6 +40,16 @@ type SchedulerV1Client interface { ListCronJob(ctx context.Context, in *ListCronJobRequest, opts ...grpc.CallOption) (*ListCronJobResponse, error) // Deletes CronJob. If job does not exists, Exists flag is set to false DeleteCronJob(ctx context.Context, in *DeleteCronJobRequest, opts ...grpc.CallOption) (*DeleteCronJobResponse, error) + // Creates Deployment from specification + CreateDeployment(ctx context.Context, in *CreateDeploymentRequest, opts ...grpc.CallOption) (*CreateDeploymentResponse, error) + // Returns Deployment. If job does not exists, Exists flag is set to false + GetDeployment(ctx context.Context, in *GetDeploymentRequest, opts ...grpc.CallOption) (*GetDeploymentResponse, error) + // Updates Deployment from specification + UpdateDeployment(ctx context.Context, in *UpdateDeploymentRequest, opts ...grpc.CallOption) (*UpdateDeploymentResponse, error) + // Returns list of the Deployments + ListDeployment(ctx context.Context, in *ListDeploymentRequest, opts ...grpc.CallOption) (*ListDeploymentResponse, error) + // Deletes Deployment. If job does not exists, Exists flag is set to false + DeleteDeployment(ctx context.Context, in *DeleteDeploymentRequest, opts ...grpc.CallOption) (*DeleteDeploymentResponse, error) } type schedulerV1Client struct { @@ -131,6 +141,51 @@ func (c *schedulerV1Client) DeleteCronJob(ctx context.Context, in *DeleteCronJob return out, nil } +func (c *schedulerV1Client) CreateDeployment(ctx context.Context, in *CreateDeploymentRequest, opts ...grpc.CallOption) (*CreateDeploymentResponse, error) { + out := new(CreateDeploymentResponse) + err := c.cc.Invoke(ctx, "/scheduler.SchedulerV1/CreateDeployment", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *schedulerV1Client) GetDeployment(ctx context.Context, in *GetDeploymentRequest, opts ...grpc.CallOption) (*GetDeploymentResponse, error) { + out := new(GetDeploymentResponse) + err := c.cc.Invoke(ctx, "/scheduler.SchedulerV1/GetDeployment", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *schedulerV1Client) UpdateDeployment(ctx context.Context, in *UpdateDeploymentRequest, opts ...grpc.CallOption) (*UpdateDeploymentResponse, error) { + out := new(UpdateDeploymentResponse) + err := c.cc.Invoke(ctx, "/scheduler.SchedulerV1/UpdateDeployment", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *schedulerV1Client) ListDeployment(ctx context.Context, in *ListDeploymentRequest, opts ...grpc.CallOption) (*ListDeploymentResponse, error) { + out := new(ListDeploymentResponse) + err := c.cc.Invoke(ctx, "/scheduler.SchedulerV1/ListDeployment", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *schedulerV1Client) DeleteDeployment(ctx context.Context, in *DeleteDeploymentRequest, opts ...grpc.CallOption) (*DeleteDeploymentResponse, error) { + out := new(DeleteDeploymentResponse) + err := c.cc.Invoke(ctx, "/scheduler.SchedulerV1/DeleteDeployment", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // SchedulerV1Server is the server API for SchedulerV1 service. // All implementations must embed UnimplementedSchedulerV1Server // for forward compatibility @@ -153,6 +208,16 @@ type SchedulerV1Server interface { ListCronJob(context.Context, *ListCronJobRequest) (*ListCronJobResponse, error) // Deletes CronJob. If job does not exists, Exists flag is set to false DeleteCronJob(context.Context, *DeleteCronJobRequest) (*DeleteCronJobResponse, error) + // Creates Deployment from specification + CreateDeployment(context.Context, *CreateDeploymentRequest) (*CreateDeploymentResponse, error) + // Returns Deployment. If job does not exists, Exists flag is set to false + GetDeployment(context.Context, *GetDeploymentRequest) (*GetDeploymentResponse, error) + // Updates Deployment from specification + UpdateDeployment(context.Context, *UpdateDeploymentRequest) (*UpdateDeploymentResponse, error) + // Returns list of the Deployments + ListDeployment(context.Context, *ListDeploymentRequest) (*ListDeploymentResponse, error) + // Deletes Deployment. If job does not exists, Exists flag is set to false + DeleteDeployment(context.Context, *DeleteDeploymentRequest) (*DeleteDeploymentResponse, error) mustEmbedUnimplementedSchedulerV1Server() } @@ -187,6 +252,21 @@ func (UnimplementedSchedulerV1Server) ListCronJob(context.Context, *ListCronJobR func (UnimplementedSchedulerV1Server) DeleteCronJob(context.Context, *DeleteCronJobRequest) (*DeleteCronJobResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method DeleteCronJob not implemented") } +func (UnimplementedSchedulerV1Server) CreateDeployment(context.Context, *CreateDeploymentRequest) (*CreateDeploymentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method CreateDeployment not implemented") +} +func (UnimplementedSchedulerV1Server) GetDeployment(context.Context, *GetDeploymentRequest) (*GetDeploymentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method GetDeployment not implemented") +} +func (UnimplementedSchedulerV1Server) UpdateDeployment(context.Context, *UpdateDeploymentRequest) (*UpdateDeploymentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method UpdateDeployment not implemented") +} +func (UnimplementedSchedulerV1Server) ListDeployment(context.Context, *ListDeploymentRequest) (*ListDeploymentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListDeployment not implemented") +} +func (UnimplementedSchedulerV1Server) DeleteDeployment(context.Context, *DeleteDeploymentRequest) (*DeleteDeploymentResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method DeleteDeployment not implemented") +} func (UnimplementedSchedulerV1Server) mustEmbedUnimplementedSchedulerV1Server() {} // UnsafeSchedulerV1Server may be embedded to opt out of forward compatibility for this service. @@ -362,6 +442,96 @@ func _SchedulerV1_DeleteCronJob_Handler(srv interface{}, ctx context.Context, de return interceptor(ctx, in, info, handler) } +func _SchedulerV1_CreateDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(CreateDeploymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SchedulerV1Server).CreateDeployment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/scheduler.SchedulerV1/CreateDeployment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SchedulerV1Server).CreateDeployment(ctx, req.(*CreateDeploymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SchedulerV1_GetDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(GetDeploymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SchedulerV1Server).GetDeployment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/scheduler.SchedulerV1/GetDeployment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SchedulerV1Server).GetDeployment(ctx, req.(*GetDeploymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SchedulerV1_UpdateDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(UpdateDeploymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SchedulerV1Server).UpdateDeployment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/scheduler.SchedulerV1/UpdateDeployment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SchedulerV1Server).UpdateDeployment(ctx, req.(*UpdateDeploymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SchedulerV1_ListDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListDeploymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SchedulerV1Server).ListDeployment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/scheduler.SchedulerV1/ListDeployment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SchedulerV1Server).ListDeployment(ctx, req.(*ListDeploymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _SchedulerV1_DeleteDeployment_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteDeploymentRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SchedulerV1Server).DeleteDeployment(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/scheduler.SchedulerV1/DeleteDeployment", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SchedulerV1Server).DeleteDeployment(ctx, req.(*DeleteDeploymentRequest)) + } + return interceptor(ctx, in, info, handler) +} + // SchedulerV1_ServiceDesc is the grpc.ServiceDesc for SchedulerV1 service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -405,6 +575,26 @@ var SchedulerV1_ServiceDesc = grpc.ServiceDesc{ MethodName: "DeleteCronJob", Handler: _SchedulerV1_DeleteCronJob_Handler, }, + { + MethodName: "CreateDeployment", + Handler: _SchedulerV1_CreateDeployment_Handler, + }, + { + MethodName: "GetDeployment", + Handler: _SchedulerV1_GetDeployment_Handler, + }, + { + MethodName: "UpdateDeployment", + Handler: _SchedulerV1_UpdateDeployment_Handler, + }, + { + MethodName: "ListDeployment", + Handler: _SchedulerV1_ListDeployment_Handler, + }, + { + MethodName: "DeleteDeployment", + Handler: _SchedulerV1_DeleteDeployment_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "integrations/scheduler/v1/definition/definition.proto", diff --git a/integrations/scheduler/v1/definition/deployment.pb.go b/integrations/scheduler/v1/definition/deployment.pb.go new file mode 100644 index 000000000..1016d0d50 --- /dev/null +++ b/integrations/scheduler/v1/definition/deployment.pb.go @@ -0,0 +1,388 @@ +// +// 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 protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.26.0 +// protoc v3.21.1 +// source: integrations/scheduler/v1/definition/deployment.proto + +package definition + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// Keeps information about Kubernetes Batch/V1 Job +type Deployment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // defines object status metadate + Metadata *StatusMetadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"` + // Keeps Deployment settings + Spec *DeploymentSpec `protobuf:"bytes,2,opt,name=spec,proto3" json:"spec,omitempty"` + // Keeps current Deployment Status + Status *DeploymentStatus `protobuf:"bytes,3,opt,name=status,proto3,oneof" json:"status,omitempty"` +} + +func (x *Deployment) Reset() { + *x = Deployment{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Deployment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Deployment) ProtoMessage() {} + +func (x *Deployment) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Deployment.ProtoReflect.Descriptor instead. +func (*Deployment) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_deployment_proto_rawDescGZIP(), []int{0} +} + +func (x *Deployment) GetMetadata() *StatusMetadata { + if x != nil { + return x.Metadata + } + return nil +} + +func (x *Deployment) GetSpec() *DeploymentSpec { + if x != nil { + return x.Spec + } + return nil +} + +func (x *Deployment) GetStatus() *DeploymentStatus { + if x != nil { + return x.Status + } + return nil +} + +// Information about Deployment run settings +type DeploymentSpec struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Number of Pods which are started within a deployment. Defaults to 1 + Replicas *int32 `protobuf:"varint,1,opt,name=replicas,proto3,oneof" json:"replicas,omitempty"` +} + +func (x *DeploymentSpec) Reset() { + *x = DeploymentSpec{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeploymentSpec) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeploymentSpec) ProtoMessage() {} + +func (x *DeploymentSpec) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeploymentSpec.ProtoReflect.Descriptor instead. +func (*DeploymentSpec) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_deployment_proto_rawDescGZIP(), []int{1} +} + +func (x *DeploymentSpec) GetReplicas() int32 { + if x != nil && x.Replicas != nil { + return *x.Replicas + } + return 0 +} + +// Information about Deployment Status +type DeploymentStatus struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + Replicas int32 `protobuf:"varint,1,opt,name=replicas,proto3" json:"replicas,omitempty"` + // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + UpdatedReplicas int32 `protobuf:"varint,2,opt,name=updated_replicas,json=updatedReplicas,proto3" json:"updated_replicas,omitempty"` + // readyReplicas is the number of pods targeted by this Deployment with a Ready Condition. + ReadyReplicas int32 `protobuf:"varint,3,opt,name=ready_replicas,json=readyReplicas,proto3" json:"ready_replicas,omitempty"` + // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + AvailableReplicas int32 `protobuf:"varint,4,opt,name=available_replicas,json=availableReplicas,proto3" json:"available_replicas,omitempty"` + // Total number of unavailable pods targeted by this deployment. This is the total number of + // pods that are still required for the deployment to have 100% available capacity. They may + // either be pods that are running but not yet available or pods that still have not been created. + UnavailableReplicas int32 `protobuf:"varint,5,opt,name=unavailable_replicas,json=unavailableReplicas,proto3" json:"unavailable_replicas,omitempty"` +} + +func (x *DeploymentStatus) Reset() { + *x = DeploymentStatus{} + if protoimpl.UnsafeEnabled { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DeploymentStatus) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DeploymentStatus) ProtoMessage() {} + +func (x *DeploymentStatus) ProtoReflect() protoreflect.Message { + mi := &file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DeploymentStatus.ProtoReflect.Descriptor instead. +func (*DeploymentStatus) Descriptor() ([]byte, []int) { + return file_integrations_scheduler_v1_definition_deployment_proto_rawDescGZIP(), []int{2} +} + +func (x *DeploymentStatus) GetReplicas() int32 { + if x != nil { + return x.Replicas + } + return 0 +} + +func (x *DeploymentStatus) GetUpdatedReplicas() int32 { + if x != nil { + return x.UpdatedReplicas + } + return 0 +} + +func (x *DeploymentStatus) GetReadyReplicas() int32 { + if x != nil { + return x.ReadyReplicas + } + return 0 +} + +func (x *DeploymentStatus) GetAvailableReplicas() int32 { + if x != nil { + return x.AvailableReplicas + } + return 0 +} + +func (x *DeploymentStatus) GetUnavailableReplicas() int32 { + if x != nil { + return x.UnavailableReplicas + } + return 0 +} + +var File_integrations_scheduler_v1_definition_deployment_proto protoreflect.FileDescriptor + +var file_integrations_scheduler_v1_definition_deployment_proto_rawDesc = []byte{ + 0x0a, 0x35, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, + 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, + 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x09, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x1a, 0x31, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, + 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xb7, 0x01, 0x0a, 0x0a, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x35, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, + 0x65, 0x72, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2d, 0x0a, 0x04, 0x73, + 0x70, 0x65, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x63, 0x68, 0x65, + 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, + 0x53, 0x70, 0x65, 0x63, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x38, 0x0a, 0x06, 0x73, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x73, 0x63, 0x68, + 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, + 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x48, 0x00, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, + 0x73, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, + 0x3e, 0x0a, 0x0e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x70, 0x65, + 0x63, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x05, 0x48, 0x00, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x88, + 0x01, 0x01, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x22, + 0xe2, 0x01, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, + 0x12, 0x29, 0x0a, 0x10, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x75, 0x70, 0x64, 0x61, + 0x74, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x05, 0x52, 0x0d, 0x72, 0x65, 0x61, 0x64, 0x79, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x73, 0x12, 0x2d, 0x0a, 0x12, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x11, + 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, + 0x73, 0x12, 0x31, 0x0a, 0x14, 0x75, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x13, 0x75, 0x6e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, + 0x69, 0x63, 0x61, 0x73, 0x42, 0x48, 0x5a, 0x46, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x6b, 0x75, 0x62, 0x65, + 0x2d, 0x61, 0x72, 0x61, 0x6e, 0x67, 0x6f, 0x64, 0x62, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x73, 0x63, 0x68, 0x65, 0x64, 0x75, 0x6c, 0x65, 0x72, + 0x2f, 0x76, 0x31, 0x2f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_integrations_scheduler_v1_definition_deployment_proto_rawDescOnce sync.Once + file_integrations_scheduler_v1_definition_deployment_proto_rawDescData = file_integrations_scheduler_v1_definition_deployment_proto_rawDesc +) + +func file_integrations_scheduler_v1_definition_deployment_proto_rawDescGZIP() []byte { + file_integrations_scheduler_v1_definition_deployment_proto_rawDescOnce.Do(func() { + file_integrations_scheduler_v1_definition_deployment_proto_rawDescData = protoimpl.X.CompressGZIP(file_integrations_scheduler_v1_definition_deployment_proto_rawDescData) + }) + return file_integrations_scheduler_v1_definition_deployment_proto_rawDescData +} + +var file_integrations_scheduler_v1_definition_deployment_proto_msgTypes = make([]protoimpl.MessageInfo, 3) +var file_integrations_scheduler_v1_definition_deployment_proto_goTypes = []interface{}{ + (*Deployment)(nil), // 0: scheduler.Deployment + (*DeploymentSpec)(nil), // 1: scheduler.DeploymentSpec + (*DeploymentStatus)(nil), // 2: scheduler.DeploymentStatus + (*StatusMetadata)(nil), // 3: scheduler.StatusMetadata +} +var file_integrations_scheduler_v1_definition_deployment_proto_depIdxs = []int32{ + 3, // 0: scheduler.Deployment.metadata:type_name -> scheduler.StatusMetadata + 1, // 1: scheduler.Deployment.spec:type_name -> scheduler.DeploymentSpec + 2, // 2: scheduler.Deployment.status:type_name -> scheduler.DeploymentStatus + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_integrations_scheduler_v1_definition_deployment_proto_init() } +func file_integrations_scheduler_v1_definition_deployment_proto_init() { + if File_integrations_scheduler_v1_definition_deployment_proto != nil { + return + } + file_integrations_scheduler_v1_definition_common_proto_init() + if !protoimpl.UnsafeEnabled { + file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Deployment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeploymentSpec); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DeploymentStatus); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[0].OneofWrappers = []interface{}{} + file_integrations_scheduler_v1_definition_deployment_proto_msgTypes[1].OneofWrappers = []interface{}{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_integrations_scheduler_v1_definition_deployment_proto_rawDesc, + NumEnums: 0, + NumMessages: 3, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_integrations_scheduler_v1_definition_deployment_proto_goTypes, + DependencyIndexes: file_integrations_scheduler_v1_definition_deployment_proto_depIdxs, + MessageInfos: file_integrations_scheduler_v1_definition_deployment_proto_msgTypes, + }.Build() + File_integrations_scheduler_v1_definition_deployment_proto = out.File + file_integrations_scheduler_v1_definition_deployment_proto_rawDesc = nil + file_integrations_scheduler_v1_definition_deployment_proto_goTypes = nil + file_integrations_scheduler_v1_definition_deployment_proto_depIdxs = nil +} diff --git a/integrations/scheduler/v1/definition/deployment.proto b/integrations/scheduler/v1/definition/deployment.proto new file mode 100644 index 000000000..60b798ea7 --- /dev/null +++ b/integrations/scheduler/v1/definition/deployment.proto @@ -0,0 +1,66 @@ +// +// 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 +// + +syntax = "proto3"; + +package scheduler; + +import "integrations/scheduler/v1/definition/common.proto"; + +option go_package = "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition"; + +// Keeps information about Kubernetes Batch/V1 Job +message Deployment { + // defines object status metadate + StatusMetadata metadata = 1; + + // Keeps Deployment settings + DeploymentSpec spec = 2; + + // Keeps current Deployment Status + optional DeploymentStatus status = 3; +} + +// Information about Deployment run settings +message DeploymentSpec { + // Number of Pods which are started within a deployment. Defaults to 1 + optional int32 replicas = 1; +} + +// Information about Deployment Status +message DeploymentStatus { + + // Total number of non-terminated pods targeted by this deployment (their labels match the selector). + int32 replicas=1; + + // Total number of non-terminated pods targeted by this deployment that have the desired template spec. + int32 updated_replicas = 2; + + // readyReplicas is the number of pods targeted by this Deployment with a Ready Condition. + int32 ready_replicas = 3; + + // Total number of available pods (ready for at least minReadySeconds) targeted by this deployment. + int32 available_replicas = 4; + + // Total number of unavailable pods targeted by this deployment. This is the total number of + // pods that are still required for the deployment to have 100% available capacity. They may + // either be pods that are running but not yet available or pods that still have not been created. + int32 unavailable_replicas = 5; +} diff --git a/integrations/scheduler/v1/deployment.go b/integrations/scheduler/v1/deployment.go new file mode 100644 index 000000000..f342c44c8 --- /dev/null +++ b/integrations/scheduler/v1/deployment.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 v1 + +import ( + "context" + + 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/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/debug_package/generators/kubernetes" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" +) + +func (i *implementation) CreateDeployment(ctx context.Context, request *pbSchedulerV1.CreateDeploymentRequest) (*pbSchedulerV1.CreateDeploymentResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + template := scheduler.SpecAsTemplate(request.GetSpec()) + + var spec schedulerApi.ArangoSchedulerDeployment + + spec.Namespace = i.cfg.Namespace + + if meta := request.GetSpec().GetMetadata(); meta != nil { + if util.TypeOrDefault(meta.GenerateName, false) { + spec.GenerateName = meta.Name + } else { + spec.Name = meta.Name + } + } + + spec.Spec.Template = *template + + if deployment := request.GetDeployment(); deployment != nil { + spec.Spec.Replicas = deployment.Replicas + } + + if jobSpec := request.GetSpec(); jobSpec != nil { + if base := jobSpec.Base; base != nil { + spec.Labels = base.Labels + spec.Spec.Template.Labels = base.Labels + } + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace).Create(ctx, &spec, meta.CreateOptions{}) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.CreateDeploymentResponse{ + Name: job.Name, + }, nil +} + +func (i *implementation) GetDeployment(ctx context.Context, request *pbSchedulerV1.GetDeploymentRequest) (*pbSchedulerV1.GetDeploymentResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + deployment, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.GetDeploymentResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.GetDeploymentResponse{ + Exists: true, + + Deployment: &pbSchedulerV1.Deployment{ + Metadata: ExtractStatusMetadata(deployment.Status.ArangoSchedulerStatusMetadata), + Spec: &pbSchedulerV1.DeploymentSpec{ + Replicas: deployment.Spec.Replicas, + }, + Status: &pbSchedulerV1.DeploymentStatus{ + Replicas: deployment.Status.DeploymentStatus.Replicas, + UpdatedReplicas: deployment.Status.DeploymentStatus.UpdatedReplicas, + ReadyReplicas: deployment.Status.DeploymentStatus.ReadyReplicas, + AvailableReplicas: deployment.Status.DeploymentStatus.AvailableReplicas, + UnavailableReplicas: deployment.Status.DeploymentStatus.UnavailableReplicas, + }, + }, + }, nil +} + +func (i *implementation) UpdateDeployment(ctx context.Context, request *pbSchedulerV1.UpdateDeploymentRequest) (*pbSchedulerV1.UpdateDeploymentResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + job, err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.UpdateDeploymentResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + if deployment := request.GetSpec(); deployment != nil { + job.Spec.Replicas = deployment.Replicas + } + + job, err = i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace).Update(ctx, job, meta.UpdateOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.UpdateDeploymentResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.UpdateDeploymentResponse{ + Exists: true, + + Deployment: &pbSchedulerV1.Deployment{ + Spec: &pbSchedulerV1.DeploymentSpec{ + Replicas: job.Spec.Replicas, + }, + }, + }, nil +} + +func (i *implementation) ListDeployment(ctx context.Context, request *pbSchedulerV1.ListDeploymentRequest) (*pbSchedulerV1.ListDeploymentResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + objects, err := kubernetes.ListObjects[*schedulerApi.ArangoSchedulerDeploymentList, *schedulerApi.ArangoSchedulerDeployment](ctx, i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace), func(result *schedulerApi.ArangoSchedulerDeploymentList) []*schedulerApi.ArangoSchedulerDeployment { + r := make([]*schedulerApi.ArangoSchedulerDeployment, len(result.Items)) + + for id := range result.Items { + r[id] = result.Items[id].DeepCopy() + } + + return r + }) + + if err != nil { + return nil, err + } + + return &pbSchedulerV1.ListDeploymentResponse{ + Deployments: util.FormatList(objects, func(in *schedulerApi.ArangoSchedulerDeployment) string { + return in.GetName() + }), + }, nil +} + +func (i *implementation) DeleteDeployment(ctx context.Context, request *pbSchedulerV1.DeleteDeploymentRequest) (*pbSchedulerV1.DeleteDeploymentResponse, error) { + if request == nil { + return nil, errors.Errorf("Request is nil") + } + + var d meta.DeleteOptions + + if v := request.DeleteChildPods; v != nil { + if *v { + d.PropagationPolicy = util.NewType(meta.DeletePropagationBackground) + } else { + d.PropagationPolicy = util.NewType(meta.DeletePropagationOrphan) + } + } + + err := i.client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(i.cfg.Namespace).Delete(ctx, request.GetName(), d) + if err != nil { + if kerrors.IsNotFound(err) { + return &pbSchedulerV1.DeleteDeploymentResponse{ + Exists: false, + }, nil + } + + return nil, err + } + + return &pbSchedulerV1.DeleteDeploymentResponse{Exists: true}, nil +} diff --git a/integrations/scheduler/v1/deployment_test.go b/integrations/scheduler/v1/deployment_test.go new file mode 100644 index 000000000..2c675a39d --- /dev/null +++ b/integrations/scheduler/v1/deployment_test.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 +// + +package v1 + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + 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/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/kclient" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_Deployment(t *testing.T) { + ctx, c := context.WithCancel(context.Background()) + defer c() + + client := kclient.NewFakeClientBuilder().Add( + tests.NewMetaObject(t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { + obj.Spec = schedulerApi.ProfileSpec{} + }, tests.MarkArangoProfileAsReady), + tests.NewMetaObject(t, tests.FakeNamespace, "test-select-all", func(t *testing.T, obj *schedulerApi.ArangoProfile) { + obj.Spec = schedulerApi.ProfileSpec{ + Selectors: &schedulerApi.ProfileSelectors{ + Label: &meta.LabelSelector{}, + }, + Template: &schedulerApi.ProfileTemplate{}, + } + }, tests.MarkArangoProfileAsReady), + tests.NewMetaObject(t, tests.FakeNamespace, "test-select-specific", func(t *testing.T, obj *schedulerApi.ArangoProfile) { + obj.Spec = schedulerApi.ProfileSpec{ + Selectors: &schedulerApi.ProfileSelectors{ + Label: &meta.LabelSelector{ + MatchLabels: map[string]string{ + "A": "B", + }, + }, + }, + Template: &schedulerApi.ProfileTemplate{}, + } + }, tests.MarkArangoProfileAsReady), + ).Client() + + scheduler := Client(t, ctx, client, func(c Configuration) Configuration { + c.Namespace = tests.FakeNamespace + c.VerifyAccess = false + return c + }) + + t.Run("Ensure job does not exist - get", func(t *testing.T) { + resp, err := scheduler.GetDeployment(context.Background(), &pbSchedulerV1.GetDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + + require.False(t, resp.GetExists()) + }) + + t.Run("Ensure job does not exist - list", func(t *testing.T) { + resp, err := scheduler.ListDeployment(context.Background(), &pbSchedulerV1.ListDeploymentRequest{}) + require.NoError(t, err) + + require.Len(t, resp.GetDeployments(), 0) + }) + + t.Run("Schedule Job", func(t *testing.T) { + resp, err := scheduler.CreateDeployment(context.Background(), &pbSchedulerV1.CreateDeploymentRequest{ + Spec: &pbSchedulerV1.Spec{ + Metadata: &pbSchedulerV1.Metadata{ + Name: "test", + }, + Base: &pbSchedulerV1.ObjectBase{ + Labels: nil, + Profiles: []string{ + "test", + }, + }, + Containers: map[string]*pbSchedulerV1.ContainerBase{ + "example": { + Image: util.NewType("ubuntu:20.04"), + Args: []string{ + "/bin/bash", + "-c", + "true", + }, + }, + }, + }, + Deployment: &pbSchedulerV1.DeploymentSpec{ + Replicas: util.NewType[int32](5), + }, + }) + require.NoError(t, err) + + require.EqualValues(t, "test", resp.GetName()) + }) + + t.Run("Ensure job exist - get", func(t *testing.T) { + resp, err := scheduler.GetDeployment(context.Background(), &pbSchedulerV1.GetDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + + require.True(t, resp.GetExists()) + }) + + t.Run("Ensure job exist - list", func(t *testing.T) { + resp, err := scheduler.ListDeployment(context.Background(), &pbSchedulerV1.ListDeploymentRequest{}) + require.NoError(t, err) + + require.Len(t, resp.GetDeployments(), 1) + require.Contains(t, resp.GetDeployments(), "test") + }) + + t.Run("Ensure job details - pre", func(t *testing.T) { + resp, err := scheduler.GetDeployment(context.Background(), &pbSchedulerV1.GetDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + + require.True(t, resp.GetExists()) + require.EqualValues(t, 0, resp.GetDeployment().GetStatus().GetReplicas()) + }) + + t.Run("Ensure job details - update", func(t *testing.T) { + job := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test") + + tests.RefreshObjectsC(t, client, &job) + + job.Status.Replicas = 1 + + tests.UpdateObjectsC(t, client, &job) + }) + + t.Run("Ensure job details - post", func(t *testing.T) { + resp, err := scheduler.GetDeployment(context.Background(), &pbSchedulerV1.GetDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + + require.True(t, resp.GetExists()) + require.EqualValues(t, 1, resp.GetDeployment().GetStatus().GetReplicas()) + }) + + t.Run("Delete Job", func(t *testing.T) { + resp, err := scheduler.DeleteDeployment(context.Background(), &pbSchedulerV1.DeleteDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + require.True(t, resp.GetExists()) + }) + + t.Run("Re-Delete Job", func(t *testing.T) { + resp, err := scheduler.DeleteDeployment(context.Background(), &pbSchedulerV1.DeleteDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + require.False(t, resp.GetExists()) + }) + + t.Run("Ensure job does not exist after deletion - get", func(t *testing.T) { + resp, err := scheduler.GetDeployment(context.Background(), &pbSchedulerV1.GetDeploymentRequest{ + Name: "test", + }) + require.NoError(t, err) + + require.False(t, resp.GetExists()) + }) + + t.Run("Ensure job does not exist after deletion - list", func(t *testing.T) { + resp, err := scheduler.ListDeployment(context.Background(), &pbSchedulerV1.ListDeploymentRequest{}) + require.NoError(t, err) + + require.Len(t, resp.GetDeployments(), 0) + }) +} diff --git a/integrations/scheduler/v1/helpers.go b/integrations/scheduler/v1/helpers.go new file mode 100644 index 000000000..0cb628333 --- /dev/null +++ b/integrations/scheduler/v1/helpers.go @@ -0,0 +1,43 @@ +// +// 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 v1 + +import ( + pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + "github.com/arangodb/kube-arangodb/pkg/util" +) + +func ExtractStatusMetadata(mt schedulerApi.ArangoSchedulerStatusMetadata) *pbSchedulerV1.StatusMetadata { + var r pbSchedulerV1.StatusMetadata + + r.Profiles = mt.Profiles + + if obj := mt.Object; obj == nil { + r.Created = false + } else { + r.Created = true + r.Checksum = util.NewType(obj.GetChecksum()) + r.Uid = util.NewType(obj.GetChecksum()) + } + + return &r +} diff --git a/integrations/scheduler/v1/implementation.go b/integrations/scheduler/v1/implementation.go index 0eec1473e..50eb509f6 100644 --- a/integrations/scheduler/v1/implementation.go +++ b/integrations/scheduler/v1/implementation.go @@ -24,16 +24,9 @@ import ( "context" "google.golang.org/grpc" - batch "k8s.io/api/batch/v1" - core "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - "github.com/arangodb/kube-arangodb/pkg/debug_package/generators/kubernetes" - "github.com/arangodb/kube-arangodb/pkg/scheduler" - "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/errors" - "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" "github.com/arangodb/kube-arangodb/pkg/util/kclient" "github.com/arangodb/kube-arangodb/pkg/util/svc" @@ -52,58 +45,114 @@ func newInternal(ctx context.Context, client kclient.Client, cfg Configuration) if err := kresources.VerifyAll(ctx, client.Kubernetes(), kresources.AccessRequest{ Verb: "create", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "jobs", + Resource: "arangoschedulerbatchjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "list", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "jobs", + Resource: "arangoschedulerbatchjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "delete", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "jobs", + Resource: "arangoschedulerbatchjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "get", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "jobs", + Resource: "arangoschedulerbatchjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "create", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "cronjobs", + Resource: "arangoschedulercronjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "list", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "cronjobs", + Resource: "arangoschedulercronjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "delete", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "cronjobs", + Resource: "arangoschedulercronjobs", Namespace: cfg.Namespace, }, kresources.AccessRequest{ Verb: "get", - Group: "batch", + Group: "scheduler.arangodb.com", Version: "v1", - Resource: "cronjobs", + Resource: "arangoschedulercronjobs", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "create", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerpods", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "list", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerpods", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "delete", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerpods", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "get", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerpods", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "create", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerdeployments", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "list", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerdeployments", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "delete", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerdeployments", + Namespace: cfg.Namespace, + }, + kresources.AccessRequest{ + Verb: "get", + Group: "scheduler.arangodb.com", + Version: "v1", + Resource: "arangoschedulerdeployments", Namespace: cfg.Namespace, }, ); err != nil { @@ -112,17 +161,15 @@ func newInternal(ctx context.Context, client kclient.Client, cfg Configuration) } return &implementation{ - cfg: cfg, - client: client, - scheduler: scheduler.NewScheduler(client, cfg.Namespace), + cfg: cfg, + client: client, }, nil } type implementation struct { cfg Configuration - client kclient.Client - scheduler scheduler.Scheduler + client kclient.Client pbSchedulerV1.UnimplementedSchedulerV1Server } @@ -138,367 +185,3 @@ func (i *implementation) Register(registrar *grpc.Server) { func (i *implementation) Health() svc.HealthState { return svc.Healthy } - -func (i *implementation) CreateBatchJob(ctx context.Context, request *pbSchedulerV1.CreateBatchJobRequest) (*pbSchedulerV1.CreateBatchJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - rendered, profiles, err := i.scheduler.Render(ctx, request.GetSpec()) - if err != nil { - return nil, err - } - - rendered.Spec.RestartPolicy = core.RestartPolicyNever - - var spec batch.Job - - spec.Namespace = i.cfg.Namespace - - if meta := request.GetSpec().GetMetadata(); meta != nil { - if util.TypeOrDefault(meta.GenerateName, false) { - spec.GenerateName = meta.Name - } else { - spec.Name = meta.Name - } - } - - spec.Spec.Template = *rendered - - if batchJob := request.GetBatchJob(); batchJob != nil { - if v := batchJob.Completions; v != nil { - spec.Spec.Completions = v - } - - if v := batchJob.Parallelism; v != nil { - spec.Spec.Parallelism = v - } - - if v := batchJob.BackoffLimit; v != nil { - spec.Spec.BackoffLimit = v - } - } - - if batchJobSpec := request.GetSpec(); batchJobSpec != nil { - if job := batchJobSpec.Job; job != nil { - spec.Labels = job.Labels - } - } - - job, err := i.client.Kubernetes().BatchV1().Jobs(i.cfg.Namespace).Create(ctx, &spec, meta.CreateOptions{}) - - if err != nil { - return nil, err - } - - return &pbSchedulerV1.CreateBatchJobResponse{ - Name: job.Name, - Profiles: profiles, - }, nil -} - -func (i *implementation) GetBatchJob(ctx context.Context, request *pbSchedulerV1.GetBatchJobRequest) (*pbSchedulerV1.GetBatchJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - job, err := i.client.Kubernetes().BatchV1().Jobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.GetBatchJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - return &pbSchedulerV1.GetBatchJobResponse{ - Exists: true, - - BatchJob: &pbSchedulerV1.BatchJob{ - Spec: &pbSchedulerV1.BatchJobSpec{ - Parallelism: job.Spec.Parallelism, - Completions: job.Spec.Completions, - BackoffLimit: job.Spec.BackoffLimit, - }, - Status: &pbSchedulerV1.BatchJobStatus{ - Active: job.Status.Active, - Succeeded: job.Status.Succeeded, - Failed: job.Status.Failed, - }, - }, - }, nil -} - -func (i *implementation) DeleteBatchJob(ctx context.Context, request *pbSchedulerV1.DeleteBatchJobRequest) (*pbSchedulerV1.DeleteBatchJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - var d meta.DeleteOptions - - if v := request.DeleteChildPods; v != nil { - if *v { - d.PropagationPolicy = util.NewType(meta.DeletePropagationBackground) - } else { - d.PropagationPolicy = util.NewType(meta.DeletePropagationOrphan) - } - } - - err := i.client.Kubernetes().BatchV1().Jobs(i.cfg.Namespace).Delete(ctx, request.GetName(), d) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.DeleteBatchJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - return &pbSchedulerV1.DeleteBatchJobResponse{Exists: true}, nil -} - -func (i *implementation) ListBatchJob(ctx context.Context, request *pbSchedulerV1.ListBatchJobRequest) (*pbSchedulerV1.ListBatchJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - objects, err := kubernetes.ListObjects[*batch.JobList, *batch.Job](ctx, i.client.Kubernetes().BatchV1().Jobs(i.cfg.Namespace), func(result *batch.JobList) []*batch.Job { - r := make([]*batch.Job, len(result.Items)) - - for id := range result.Items { - r[id] = result.Items[id].DeepCopy() - } - - return r - }) - - if err != nil { - return nil, err - } - - return &pbSchedulerV1.ListBatchJobResponse{ - BatchJobs: kubernetes.Extract(objects, func(in *batch.Job) string { - return in.GetName() - }), - }, nil -} - -func (i *implementation) CreateCronJob(ctx context.Context, request *pbSchedulerV1.CreateCronJobRequest) (*pbSchedulerV1.CreateCronJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - rendered, profiles, err := i.scheduler.Render(ctx, request.GetSpec()) - if err != nil { - return nil, err - } - - rendered.Spec.RestartPolicy = core.RestartPolicyNever - - var spec batch.CronJob - - spec.Namespace = i.cfg.Namespace - - if meta := request.GetSpec().GetMetadata(); meta != nil { - if util.TypeOrDefault(meta.GenerateName, false) { - spec.GenerateName = meta.Name - } else { - spec.Name = meta.Name - } - } - - spec.Spec.JobTemplate.Spec.Template = *rendered - - if cronJob := request.GetCronJob(); cronJob != nil { - spec.Spec.Schedule = cronJob.Schedule - - if batchJob := cronJob.GetJob(); batchJob != nil { - if v := batchJob.Completions; v != nil { - spec.Spec.JobTemplate.Spec.Completions = v - } - - if v := batchJob.Parallelism; v != nil { - spec.Spec.JobTemplate.Spec.Parallelism = v - } - - if v := batchJob.BackoffLimit; v != nil { - spec.Spec.JobTemplate.Spec.BackoffLimit = v - } - } - } - - if batchJobSpec := request.GetSpec(); batchJobSpec != nil { - if job := batchJobSpec.Job; job != nil { - spec.Labels = job.Labels - spec.Spec.JobTemplate.Labels = job.Labels - } - } - - job, err := i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace).Create(ctx, &spec, meta.CreateOptions{}) - - if err != nil { - return nil, err - } - - return &pbSchedulerV1.CreateCronJobResponse{ - Name: job.Name, - Profiles: profiles, - }, nil -} - -func (i *implementation) GetCronJob(ctx context.Context, request *pbSchedulerV1.GetCronJobRequest) (*pbSchedulerV1.GetCronJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - job, err := i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.GetCronJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - return &pbSchedulerV1.GetCronJobResponse{ - Exists: true, - - CronJob: &pbSchedulerV1.CronJob{ - Spec: &pbSchedulerV1.CronJobSpec{ - Schedule: job.Spec.Schedule, - - Job: &pbSchedulerV1.BatchJobSpec{ - Parallelism: job.Spec.JobTemplate.Spec.Parallelism, - Completions: job.Spec.JobTemplate.Spec.Completions, - BackoffLimit: job.Spec.JobTemplate.Spec.BackoffLimit, - }, - }, - }, - - BatchJobs: kubernetes.Extract(job.Status.Active, func(in core.ObjectReference) string { - return in.Name - }), - }, nil -} - -func (i *implementation) UpdateCronJob(ctx context.Context, request *pbSchedulerV1.UpdateCronJobRequest) (*pbSchedulerV1.UpdateCronJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - job, err := i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace).Get(ctx, request.GetName(), meta.GetOptions{}) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.UpdateCronJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - if cronJob := request.GetSpec(); cronJob != nil { - job.Spec.Schedule = cronJob.Schedule - - if batchJob := cronJob.GetJob(); batchJob != nil { - if v := batchJob.Completions; v != nil { - job.Spec.JobTemplate.Spec.Completions = v - } - - if v := batchJob.Parallelism; v != nil { - job.Spec.JobTemplate.Spec.Parallelism = v - } - - if v := batchJob.BackoffLimit; v != nil { - job.Spec.JobTemplate.Spec.BackoffLimit = v - } - } - } - - job, err = i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace).Update(ctx, job, meta.UpdateOptions{}) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.UpdateCronJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - return &pbSchedulerV1.UpdateCronJobResponse{ - Exists: true, - - CronJob: &pbSchedulerV1.CronJob{ - Spec: &pbSchedulerV1.CronJobSpec{ - Schedule: job.Spec.Schedule, - - Job: &pbSchedulerV1.BatchJobSpec{ - Parallelism: job.Spec.JobTemplate.Spec.Parallelism, - Completions: job.Spec.JobTemplate.Spec.Completions, - BackoffLimit: job.Spec.JobTemplate.Spec.BackoffLimit, - }, - }, - }, - }, nil -} - -func (i *implementation) ListCronJob(ctx context.Context, request *pbSchedulerV1.ListCronJobRequest) (*pbSchedulerV1.ListCronJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - objects, err := kubernetes.ListObjects[*batch.CronJobList, *batch.CronJob](ctx, i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace), func(result *batch.CronJobList) []*batch.CronJob { - r := make([]*batch.CronJob, len(result.Items)) - - for id := range result.Items { - r[id] = result.Items[id].DeepCopy() - } - - return r - }) - - if err != nil { - return nil, err - } - - return &pbSchedulerV1.ListCronJobResponse{ - CronJobs: kubernetes.Extract(objects, func(in *batch.CronJob) string { - return in.GetName() - }), - }, nil -} - -func (i *implementation) DeleteCronJob(ctx context.Context, request *pbSchedulerV1.DeleteCronJobRequest) (*pbSchedulerV1.DeleteCronJobResponse, error) { - if request == nil { - return nil, errors.Errorf("Request is nil") - } - - var d meta.DeleteOptions - - if v := request.DeleteChildPods; v != nil { - if *v { - d.PropagationPolicy = util.NewType(meta.DeletePropagationBackground) - } else { - d.PropagationPolicy = util.NewType(meta.DeletePropagationOrphan) - } - } - - err := i.client.Kubernetes().BatchV1().CronJobs(i.cfg.Namespace).Delete(ctx, request.GetName(), d) - if err != nil { - if kerrors.IsNotFound(err) { - return &pbSchedulerV1.DeleteCronJobResponse{ - Exists: false, - }, nil - } - - return nil, err - } - - return &pbSchedulerV1.DeleteCronJobResponse{Exists: true}, nil -} diff --git a/internal/cr_validation_test.go b/internal/cr_validation_test.go index b5d8dc04c..c376d4c4d 100644 --- a/internal/cr_validation_test.go +++ b/internal/cr_validation_test.go @@ -229,6 +229,42 @@ func Test_GenerateCRValidationSchemas(t *testing.T) { }, }, }, + "scheduler-pod": { + fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { + "v1beta1": { + objects: map[string]interface{}{ + "spec": schedulerApi.ArangoSchedulerPod{}.Spec, + }, + }, + }, + }, + "scheduler-deployment": { + fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { + "v1beta1": { + objects: map[string]interface{}{ + "spec": schedulerApi.ArangoSchedulerDeployment{}.Spec, + }, + }, + }, + }, + "scheduler-batchjob": { + fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { + "v1beta1": { + objects: map[string]interface{}{ + "spec": schedulerApi.ArangoSchedulerBatchJob{}.Spec, + }, + }, + }, + }, + "scheduler-cronjob": { + fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { + "v1beta1": { + objects: map[string]interface{}{ + "spec": schedulerApi.ArangoSchedulerCronJob{}.Spec, + }, + }, + }, + }, "ml-extension": { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { "v1alpha1": { diff --git a/pkg/apis/scheduler/definitions.go b/pkg/apis/scheduler/definitions.go index af9e57cb9..e472fffbd 100644 --- a/pkg/apis/scheduler/definitions.go +++ b/pkg/apis/scheduler/definitions.go @@ -25,5 +25,21 @@ const ( ArangoProfileResourceKind = "ArangoProfile" ArangoProfileResourcePlural = "arangoprofiles" + PodCRDName = PodResourcePlural + "." + ArangoSchedulerGroupName + PodResourceKind = "ArangoSchedulerPod" + PodResourcePlural = "arangoschedulerpods" + + DeploymentCRDName = DeploymentResourcePlural + "." + ArangoSchedulerGroupName + DeploymentResourceKind = "ArangoSchedulerDeployment" + DeploymentResourcePlural = "arangoschedulerdeployments" + + BatchJobCRDName = BatchJobResourcePlural + "." + ArangoSchedulerGroupName + BatchJobResourceKind = "ArangoSchedulerBatchJob" + BatchJobResourcePlural = "arangoschedulerbatchjobs" + + CronJobCRDName = CronJobResourcePlural + "." + ArangoSchedulerGroupName + CronJobResourceKind = "ArangoSchedulerCronJob" + CronJobResourcePlural = "arangoschedulercronjobs" + ArangoSchedulerGroupName = "scheduler.arangodb.com" ) diff --git a/pkg/apis/scheduler/v1beta1/profile.go b/pkg/apis/scheduler/v1beta1/profile.go index 843c4639c..7cc0a0fe8 100644 --- a/pkg/apis/scheduler/v1beta1/profile.go +++ b/pkg/apis/scheduler/v1beta1/profile.go @@ -20,7 +20,11 @@ package v1beta1 -import meta "k8s.io/apimachinery/pkg/apis/meta/v1" +import ( + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object @@ -44,6 +48,18 @@ type ArangoProfile struct { Status ProfileStatus `json:"status"` } +// AsOwner creates an OwnerReference for the given ArangoSchedulerBatchJob +func (a *ArangoProfile) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: scheduler.ArangoProfileResourceKind, + Name: a.Name, + UID: a.UID, + Controller: &trueVar, + } +} + func (a *ArangoProfile) GetStatus() ProfileStatus { return a.Status } diff --git a/pkg/apis/scheduler/v1beta1/profile_templates.go b/pkg/apis/scheduler/v1beta1/profile_templates.go index c083bc0d5..4e6e45e5f 100644 --- a/pkg/apis/scheduler/v1beta1/profile_templates.go +++ b/pkg/apis/scheduler/v1beta1/profile_templates.go @@ -55,19 +55,19 @@ func (p ProfileTemplates) Merge() *ProfileTemplate { func (p ProfileTemplates) RenderOnTemplate(pod *core.PodTemplateSpec) error { t := p.Merge() - // Apply Pod Spec + // Apply ArangoSchedulerPod Spec if err := t.GetPod().Apply(pod); err != nil { - return errors.Wrapf(err, "Error while rendering Pod") + return errors.Wrapf(err, "Error while rendering ArangoSchedulerPod") } // Apply Generic Containers Spec if err := t.GetContainer().ApplyGeneric(pod); err != nil { - return errors.Wrapf(err, "Error while rendering Pod") + return errors.Wrapf(err, "Error while rendering ArangoSchedulerPod") } // Apply Containers Spec if err := t.GetContainer().ApplyContainers(pod); err != nil { - return errors.Wrapf(err, "Error while rendering Pod") + return errors.Wrapf(err, "Error while rendering ArangoSchedulerPod") } return nil diff --git a/pkg/apis/scheduler/v1beta1/register.go b/pkg/apis/scheduler/v1beta1/register.go index 4a05cbf69..be97d2ad4 100644 --- a/pkg/apis/scheduler/v1beta1/register.go +++ b/pkg/apis/scheduler/v1beta1/register.go @@ -50,6 +50,14 @@ func addKnownTypes(s *runtime.Scheme) error { s.AddKnownTypes(SchemeGroupVersion, &ArangoProfile{}, &ArangoProfileList{}, + &ArangoSchedulerPod{}, + &ArangoSchedulerPodList{}, + &ArangoSchedulerDeployment{}, + &ArangoSchedulerDeploymentList{}, + &ArangoSchedulerBatchJob{}, + &ArangoSchedulerBatchJobList{}, + &ArangoSchedulerCronJob{}, + &ArangoSchedulerCronJobList{}, ) meta.AddToGroupVersion(s, SchemeGroupVersion) return nil diff --git a/pkg/apis/scheduler/v1beta1/types.go b/pkg/apis/scheduler/v1beta1/types.go new file mode 100644 index 000000000..67737ec01 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/types.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 +// + +package v1beta1 + +import sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + +type ArangoSchedulerStatusMetadata struct { + // Object keeps the information about object + Object *sharedApi.Object `json:"object,omitempty"` + + // Profiles keeps the information about applied profiles + Profiles []string `json:"profiles,omitempty"` +} diff --git a/pkg/apis/scheduler/v1beta1/types_batchjob.go b/pkg/apis/scheduler/v1beta1/types_batchjob.go new file mode 100644 index 000000000..61abd6eb4 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/types_batchjob.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 v1beta1 + +import ( + batch "k8s.io/api/batch/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerBatchJobList is a list of BatchJobs. +type ArangoSchedulerBatchJobList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoSchedulerBatchJob `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerBatchJob wraps batch. ArangoSchedulerBatchJob with profile details +type ArangoSchedulerBatchJob struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoSchedulerBatchJobSpec `json:"spec"` + Status ArangoSchedulerBatchJobStatus `json:"status"` +} + +type ArangoSchedulerBatchJobSpec struct { + // Profiles keeps list of the profiles + Profiles []string `json:"profiles,omitempty"` + + batch.JobSpec `json:",inline"` +} + +type ArangoSchedulerBatchJobStatus struct { + ArangoSchedulerStatusMetadata `json:",inline"` + + batch.JobStatus `json:",inline"` +} + +// AsOwner creates an OwnerReference for the given ArangoSchedulerBatchJob +func (d *ArangoSchedulerBatchJob) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: scheduler.BatchJobResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (d *ArangoSchedulerBatchJob) GetStatus() ArangoSchedulerBatchJobStatus { + return d.Status +} + +func (d *ArangoSchedulerBatchJob) SetStatus(status ArangoSchedulerBatchJobStatus) { + d.Status = status +} diff --git a/pkg/apis/scheduler/v1beta1/types_cronjob.go b/pkg/apis/scheduler/v1beta1/types_cronjob.go new file mode 100644 index 000000000..088f1986b --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/types_cronjob.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 v1beta1 + +import ( + batch "k8s.io/api/batch/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerCronJobList is a list of CronJobs. +type ArangoSchedulerCronJobList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoSchedulerCronJob `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerCronJob wraps batch. ArangoSchedulerCronJob with profile details +type ArangoSchedulerCronJob struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoSchedulerCronJobSpec `json:"spec"` + Status ArangoSchedulerCronJobStatus `json:"status"` +} + +type ArangoSchedulerCronJobSpec struct { + // Profiles keeps list of the profiles + Profiles []string `json:"profiles,omitempty"` + + batch.CronJobSpec `json:",inline"` +} + +type ArangoSchedulerCronJobStatus struct { + ArangoSchedulerStatusMetadata `json:",inline"` + + batch.CronJobStatus `json:",inline"` +} + +// AsOwner creates an OwnerReference for the given ArangoSchedulerCronJob +func (d *ArangoSchedulerCronJob) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: scheduler.CronJobResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (d *ArangoSchedulerCronJob) GetStatus() ArangoSchedulerCronJobStatus { + return d.Status +} + +func (d *ArangoSchedulerCronJob) SetStatus(status ArangoSchedulerCronJobStatus) { + d.Status = status +} diff --git a/pkg/apis/scheduler/v1beta1/types_deployment.go b/pkg/apis/scheduler/v1beta1/types_deployment.go new file mode 100644 index 000000000..ea5ffb6c7 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/types_deployment.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 v1beta1 + +import ( + apps "k8s.io/api/apps/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerDeploymentList is a list of Deployments. +type ArangoSchedulerDeploymentList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoSchedulerDeployment `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerDeployment wraps apps. ArangoSchedulerDeployment with profile details +type ArangoSchedulerDeployment struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoSchedulerDeploymentSpec `json:"spec"` + Status ArangoSchedulerDeploymentStatus `json:"status"` +} + +type ArangoSchedulerDeploymentSpec struct { + // Profiles keeps list of the profiles + Profiles []string `json:"profiles,omitempty"` + + apps.DeploymentSpec `json:",inline"` +} + +type ArangoSchedulerDeploymentStatus struct { + ArangoSchedulerStatusMetadata `json:",inline"` + + apps.DeploymentStatus `json:",inline"` +} + +// AsOwner creates an OwnerReference for the given ArangoSchedulerDeployment +func (d *ArangoSchedulerDeployment) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: scheduler.DeploymentResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (d *ArangoSchedulerDeployment) GetStatus() ArangoSchedulerDeploymentStatus { + return d.Status +} + +func (d *ArangoSchedulerDeployment) SetStatus(status ArangoSchedulerDeploymentStatus) { + d.Status = status +} diff --git a/pkg/apis/scheduler/v1beta1/types_pod.go b/pkg/apis/scheduler/v1beta1/types_pod.go new file mode 100644 index 000000000..f8be4df60 --- /dev/null +++ b/pkg/apis/scheduler/v1beta1/types_pod.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 v1beta1 + +import ( + core "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" +) + +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerPodList is a list of Pods. +type ArangoSchedulerPodList struct { + meta.TypeMeta `json:",inline"` + meta.ListMeta `json:"metadata,omitempty"` + + Items []ArangoSchedulerPod `json:"items"` +} + +// +genclient +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// ArangoSchedulerPod wraps core. ArangoSchedulerPod with profile details +type ArangoSchedulerPod struct { + meta.TypeMeta `json:",inline"` + meta.ObjectMeta `json:"metadata,omitempty"` + + Spec ArangoSchedulerPodSpec `json:"spec"` + Status ArangoSchedulerPodStatus `json:"status"` +} + +type ArangoSchedulerPodSpec struct { + // Profiles keeps list of the profiles + Profiles []string `json:"profiles,omitempty"` + + core.PodSpec `json:",inline"` +} + +type ArangoSchedulerPodStatus struct { + ArangoSchedulerStatusMetadata `json:",inline"` + + core.PodStatus `json:",inline"` +} + +// AsOwner creates an OwnerReference for the given ArangoSchedulerPod +func (d *ArangoSchedulerPod) AsOwner() meta.OwnerReference { + trueVar := true + return meta.OwnerReference{ + APIVersion: SchemeGroupVersion.String(), + Kind: scheduler.PodResourceKind, + Name: d.Name, + UID: d.UID, + Controller: &trueVar, + } +} + +func (d *ArangoSchedulerPod) GetStatus() ArangoSchedulerPodStatus { + return d.Status +} + +func (d *ArangoSchedulerPod) SetStatus(status ArangoSchedulerPodStatus) { + d.Status = status +} diff --git a/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go b/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go index 3b1d48536..798dac8e1 100644 --- a/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/scheduler/v1beta1/zz_generated.deepcopy.go @@ -29,7 +29,8 @@ 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 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -94,6 +95,436 @@ func (in *ArangoProfileList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerBatchJob) DeepCopyInto(out *ArangoSchedulerBatchJob) { + *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 ArangoSchedulerBatchJob. +func (in *ArangoSchedulerBatchJob) DeepCopy() *ArangoSchedulerBatchJob { + if in == nil { + return nil + } + out := new(ArangoSchedulerBatchJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerBatchJob) 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 *ArangoSchedulerBatchJobList) DeepCopyInto(out *ArangoSchedulerBatchJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoSchedulerBatchJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerBatchJobList. +func (in *ArangoSchedulerBatchJobList) DeepCopy() *ArangoSchedulerBatchJobList { + if in == nil { + return nil + } + out := new(ArangoSchedulerBatchJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerBatchJobList) 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 *ArangoSchedulerBatchJobSpec) DeepCopyInto(out *ArangoSchedulerBatchJobSpec) { + *out = *in + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.JobSpec.DeepCopyInto(&out.JobSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerBatchJobSpec. +func (in *ArangoSchedulerBatchJobSpec) DeepCopy() *ArangoSchedulerBatchJobSpec { + if in == nil { + return nil + } + out := new(ArangoSchedulerBatchJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerBatchJobStatus) DeepCopyInto(out *ArangoSchedulerBatchJobStatus) { + *out = *in + in.ArangoSchedulerStatusMetadata.DeepCopyInto(&out.ArangoSchedulerStatusMetadata) + in.JobStatus.DeepCopyInto(&out.JobStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerBatchJobStatus. +func (in *ArangoSchedulerBatchJobStatus) DeepCopy() *ArangoSchedulerBatchJobStatus { + if in == nil { + return nil + } + out := new(ArangoSchedulerBatchJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerCronJob) DeepCopyInto(out *ArangoSchedulerCronJob) { + *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 ArangoSchedulerCronJob. +func (in *ArangoSchedulerCronJob) DeepCopy() *ArangoSchedulerCronJob { + if in == nil { + return nil + } + out := new(ArangoSchedulerCronJob) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerCronJob) 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 *ArangoSchedulerCronJobList) DeepCopyInto(out *ArangoSchedulerCronJobList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoSchedulerCronJob, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerCronJobList. +func (in *ArangoSchedulerCronJobList) DeepCopy() *ArangoSchedulerCronJobList { + if in == nil { + return nil + } + out := new(ArangoSchedulerCronJobList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerCronJobList) 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 *ArangoSchedulerCronJobSpec) DeepCopyInto(out *ArangoSchedulerCronJobSpec) { + *out = *in + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.CronJobSpec.DeepCopyInto(&out.CronJobSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerCronJobSpec. +func (in *ArangoSchedulerCronJobSpec) DeepCopy() *ArangoSchedulerCronJobSpec { + if in == nil { + return nil + } + out := new(ArangoSchedulerCronJobSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerCronJobStatus) DeepCopyInto(out *ArangoSchedulerCronJobStatus) { + *out = *in + in.ArangoSchedulerStatusMetadata.DeepCopyInto(&out.ArangoSchedulerStatusMetadata) + in.CronJobStatus.DeepCopyInto(&out.CronJobStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerCronJobStatus. +func (in *ArangoSchedulerCronJobStatus) DeepCopy() *ArangoSchedulerCronJobStatus { + if in == nil { + return nil + } + out := new(ArangoSchedulerCronJobStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerDeployment) DeepCopyInto(out *ArangoSchedulerDeployment) { + *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 ArangoSchedulerDeployment. +func (in *ArangoSchedulerDeployment) DeepCopy() *ArangoSchedulerDeployment { + if in == nil { + return nil + } + out := new(ArangoSchedulerDeployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerDeployment) 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 *ArangoSchedulerDeploymentList) DeepCopyInto(out *ArangoSchedulerDeploymentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoSchedulerDeployment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerDeploymentList. +func (in *ArangoSchedulerDeploymentList) DeepCopy() *ArangoSchedulerDeploymentList { + if in == nil { + return nil + } + out := new(ArangoSchedulerDeploymentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerDeploymentList) 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 *ArangoSchedulerDeploymentSpec) DeepCopyInto(out *ArangoSchedulerDeploymentSpec) { + *out = *in + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.DeploymentSpec.DeepCopyInto(&out.DeploymentSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerDeploymentSpec. +func (in *ArangoSchedulerDeploymentSpec) DeepCopy() *ArangoSchedulerDeploymentSpec { + if in == nil { + return nil + } + out := new(ArangoSchedulerDeploymentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerDeploymentStatus) DeepCopyInto(out *ArangoSchedulerDeploymentStatus) { + *out = *in + in.ArangoSchedulerStatusMetadata.DeepCopyInto(&out.ArangoSchedulerStatusMetadata) + in.DeploymentStatus.DeepCopyInto(&out.DeploymentStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerDeploymentStatus. +func (in *ArangoSchedulerDeploymentStatus) DeepCopy() *ArangoSchedulerDeploymentStatus { + if in == nil { + return nil + } + out := new(ArangoSchedulerDeploymentStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerPod) DeepCopyInto(out *ArangoSchedulerPod) { + *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 ArangoSchedulerPod. +func (in *ArangoSchedulerPod) DeepCopy() *ArangoSchedulerPod { + if in == nil { + return nil + } + out := new(ArangoSchedulerPod) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerPod) 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 *ArangoSchedulerPodList) DeepCopyInto(out *ArangoSchedulerPodList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ArangoSchedulerPod, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerPodList. +func (in *ArangoSchedulerPodList) DeepCopy() *ArangoSchedulerPodList { + if in == nil { + return nil + } + out := new(ArangoSchedulerPodList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ArangoSchedulerPodList) 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 *ArangoSchedulerPodSpec) DeepCopyInto(out *ArangoSchedulerPodSpec) { + *out = *in + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.PodSpec.DeepCopyInto(&out.PodSpec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerPodSpec. +func (in *ArangoSchedulerPodSpec) DeepCopy() *ArangoSchedulerPodSpec { + if in == nil { + return nil + } + out := new(ArangoSchedulerPodSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerPodStatus) DeepCopyInto(out *ArangoSchedulerPodStatus) { + *out = *in + in.ArangoSchedulerStatusMetadata.DeepCopyInto(&out.ArangoSchedulerStatusMetadata) + in.PodStatus.DeepCopyInto(&out.PodStatus) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerPodStatus. +func (in *ArangoSchedulerPodStatus) DeepCopy() *ArangoSchedulerPodStatus { + if in == nil { + return nil + } + out := new(ArangoSchedulerPodStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ArangoSchedulerStatusMetadata) DeepCopyInto(out *ArangoSchedulerStatusMetadata) { + *out = *in + if in.Object != nil { + in, out := &in.Object, &out.Object + *out = new(v1.Object) + (*in).DeepCopyInto(*out) + } + if in.Profiles != nil { + in, out := &in.Profiles, &out.Profiles + *out = make([]string, len(*in)) + copy(*out, *in) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoSchedulerStatusMetadata. +func (in *ArangoSchedulerStatusMetadata) DeepCopy() *ArangoSchedulerStatusMetadata { + if in == nil { + return nil + } + out := new(ArangoSchedulerStatusMetadata) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProfileAcceptedTemplate) DeepCopyInto(out *ProfileAcceptedTemplate) { *out = *in @@ -148,7 +579,7 @@ func (in *ProfileSelectors) DeepCopyInto(out *ProfileSelectors) { *out = *in if in.Label != nil { in, out := &in.Label, &out.Label - *out = new(v1.LabelSelector) + *out = new(metav1.LabelSelector) (*in).DeepCopyInto(*out) } return diff --git a/pkg/crd/crds/crds.go b/pkg/crd/crds/crds.go index 8158a8745..7bc20920b 100644 --- a/pkg/crd/crds/crds.go +++ b/pkg/crd/crds/crds.go @@ -87,6 +87,10 @@ func AllDefinitions() []Definition { // Scheduler SchedulerProfileDefinitionWithOptions(), + SchedulerPodDefinitionWithOptions(), + SchedulerDeploymentDefinitionWithOptions(), + SchedulerBatchJobDefinitionWithOptions(), + SchedulerCronJobDefinitionWithOptions(), // Analytics AnalyticsGAEDefinitionWithOptions(), diff --git a/pkg/crd/crds/crds_test.go b/pkg/crd/crds/crds_test.go index 60368f107..e5d4f425f 100644 --- a/pkg/crd/crds/crds_test.go +++ b/pkg/crd/crds/crds_test.go @@ -92,6 +92,10 @@ func Test_CRD(t *testing.T) { {ml.ArangoMLCronJobCRDName, MLCronJobDefinitionWithOptions}, {ml.ArangoMLBatchJobCRDName, MLBatchJobDefinitionWithOptions}, {scheduler.ArangoProfileCRDName, SchedulerProfileDefinitionWithOptions}, + {scheduler.PodCRDName, SchedulerPodDefinitionWithOptions}, + {scheduler.DeploymentCRDName, SchedulerDeploymentDefinitionWithOptions}, + {scheduler.BatchJobCRDName, SchedulerBatchJobDefinitionWithOptions}, + {scheduler.CronJobCRDName, SchedulerCronJobDefinitionWithOptions}, } for _, tc := range testCases { @@ -143,6 +147,10 @@ func Test_CRDGetters(t *testing.T) { ReplicationDeploymentReplicationWithOptions, StorageLocalStorageWithOptions, SchedulerProfileWithOptions, + SchedulerPodWithOptions, + SchedulerDeploymentWithOptions, + SchedulerBatchJobWithOptions, + SchedulerCronJobWithOptions, AnalyticsGAEWithOptions, NetworkingRouteWithOptions, } diff --git a/pkg/crd/crds/scheduler-batchjob.go b/pkg/crd/crds/scheduler-batchjob.go new file mode 100644 index 000000000..acf3d3974 --- /dev/null +++ b/pkg/crd/crds/scheduler-batchjob.go @@ -0,0 +1,51 @@ +// +// DISCLAIMER +// +// 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. +// 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 crds + +import ( + _ "embed" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +func SchedulerBatchJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition { + return getCRD(SchedulerBatchJobDefinitionData(), opts...) +} + +func SchedulerBatchJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition { + return Definition{ + DefinitionData: SchedulerBatchJobDefinitionData(), + CRD: SchedulerBatchJobWithOptions(opts...), + } +} + +func SchedulerBatchJobDefinitionData() DefinitionData { + return DefinitionData{ + definition: schedulerBatchJob, + schemaDefinition: schedulerBatchJobSchemaRaw, + } +} + +//go:embed scheduler-batchjob.yaml +var schedulerBatchJob []byte + +//go:embed scheduler-batchjob.schema.generated.yaml +var schedulerBatchJobSchemaRaw []byte diff --git a/pkg/crd/crds/scheduler-batchjob.schema.generated.yaml b/pkg/crd/crds/scheduler-batchjob.schema.generated.yaml new file mode 100644 index 000000000..ffa23976a --- /dev/null +++ b/pkg/crd/crds/scheduler-batchjob.schema.generated.yaml @@ -0,0 +1,2985 @@ +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + backoffLimitPerIndex: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + manualSelector: + type: boolean + maxFailedIndexes: + format: int32 + type: integer + parallelism: + format: int32 + type: integer + podFailurePolicy: + properties: + rules: + items: + properties: + action: + type: string + onExitCodes: + properties: + containerName: + type: string + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + type: object + onPodConditions: + items: + properties: + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + type: object + podReplacementPolicy: + type: string + profiles: + items: + type: string + type: array + 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 + suspend: + type: boolean + template: + 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: + activeDeadlineSeconds: + format: int64 + type: integer + 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 + automountServiceAccountToken: + type: boolean + containers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + os: + properties: + name: + type: string + type: object + overhead: + additionalProperties: + type: string + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + type: object + type: array + resourceClaims: + items: + properties: + name: + type: string + source: + properties: + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + type: object + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + type: object + type: array + securityContext: + 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 + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + 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 + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + 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 + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + type: object + status: + description: Object with preserved fields for backward compatibility + type: object + x-kubernetes-preserve-unknown-fields: true + type: object diff --git a/pkg/crd/crds/scheduler-batchjob.yaml b/pkg/crd/crds/scheduler-batchjob.yaml new file mode 100644 index 000000000..e20a31952 --- /dev/null +++ b/pkg/crd/crds/scheduler-batchjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerbatchjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerBatchJob + listKind: ArangoSchedulerBatchJobList + plural: arangoschedulerbatchjobs + singular: arangoschedulerbatchjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/pkg/crd/crds/scheduler-cronjob.go b/pkg/crd/crds/scheduler-cronjob.go new file mode 100644 index 000000000..f0e41216d --- /dev/null +++ b/pkg/crd/crds/scheduler-cronjob.go @@ -0,0 +1,51 @@ +// +// DISCLAIMER +// +// 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. +// 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 crds + +import ( + _ "embed" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +func SchedulerCronJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition { + return getCRD(SchedulerCronJobDefinitionData(), opts...) +} + +func SchedulerCronJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition { + return Definition{ + DefinitionData: SchedulerCronJobDefinitionData(), + CRD: SchedulerCronJobWithOptions(opts...), + } +} + +func SchedulerCronJobDefinitionData() DefinitionData { + return DefinitionData{ + definition: schedulerCronJob, + schemaDefinition: schedulerCronJobSchemaRaw, + } +} + +//go:embed scheduler-cronjob.yaml +var schedulerCronJob []byte + +//go:embed scheduler-cronjob.schema.generated.yaml +var schedulerCronJobSchemaRaw []byte diff --git a/pkg/crd/crds/scheduler-cronjob.schema.generated.yaml b/pkg/crd/crds/scheduler-cronjob.schema.generated.yaml new file mode 100644 index 000000000..a37961c59 --- /dev/null +++ b/pkg/crd/crds/scheduler-cronjob.schema.generated.yaml @@ -0,0 +1,3084 @@ +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + concurrencyPolicy: + type: string + failedJobsHistoryLimit: + format: int32 + type: integer + jobTemplate: + 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: + activeDeadlineSeconds: + format: int64 + type: integer + backoffLimit: + format: int32 + type: integer + backoffLimitPerIndex: + format: int32 + type: integer + completionMode: + type: string + completions: + format: int32 + type: integer + manualSelector: + type: boolean + maxFailedIndexes: + format: int32 + type: integer + parallelism: + format: int32 + type: integer + podFailurePolicy: + properties: + rules: + items: + properties: + action: + type: string + onExitCodes: + properties: + containerName: + type: string + operator: + type: string + values: + items: + format: int32 + type: integer + type: array + type: object + onPodConditions: + items: + properties: + status: + type: string + type: + type: string + type: object + type: array + type: object + type: array + type: object + podReplacementPolicy: + type: string + 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 + suspend: + type: boolean + template: + 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: + activeDeadlineSeconds: + format: int64 + type: integer + 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 + automountServiceAccountToken: + type: boolean + containers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + os: + properties: + name: + type: string + type: object + overhead: + additionalProperties: + type: string + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + type: object + type: array + resourceClaims: + items: + properties: + name: + type: string + source: + properties: + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + type: object + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + type: object + type: array + securityContext: + 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 + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + 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 + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + 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 + type: object + ttlSecondsAfterFinished: + format: int32 + type: integer + type: object + type: object + profiles: + items: + type: string + type: array + schedule: + type: string + startingDeadlineSeconds: + format: int64 + type: integer + successfulJobsHistoryLimit: + format: int32 + type: integer + suspend: + type: boolean + timeZone: + type: string + type: object + status: + description: Object with preserved fields for backward compatibility + type: object + x-kubernetes-preserve-unknown-fields: true + type: object diff --git a/pkg/crd/crds/scheduler-cronjob.yaml b/pkg/crd/crds/scheduler-cronjob.yaml new file mode 100644 index 000000000..7c6b02d9b --- /dev/null +++ b/pkg/crd/crds/scheduler-cronjob.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulercronjobs.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerCronJob + listKind: ArangoSchedulerCronJobList + plural: arangoschedulercronjobs + singular: arangoschedulercronjob + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/pkg/crd/crds/scheduler-deployment.go b/pkg/crd/crds/scheduler-deployment.go new file mode 100644 index 000000000..4e0557372 --- /dev/null +++ b/pkg/crd/crds/scheduler-deployment.go @@ -0,0 +1,51 @@ +// +// DISCLAIMER +// +// 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. +// 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 crds + +import ( + _ "embed" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +func SchedulerDeploymentWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition { + return getCRD(SchedulerDeploymentDefinitionData(), opts...) +} + +func SchedulerDeploymentDefinitionWithOptions(opts ...func(*CRDOptions)) Definition { + return Definition{ + DefinitionData: SchedulerDeploymentDefinitionData(), + CRD: SchedulerDeploymentWithOptions(opts...), + } +} + +func SchedulerDeploymentDefinitionData() DefinitionData { + return DefinitionData{ + definition: schedulerDeployment, + schemaDefinition: schedulerDeploymentSchemaRaw, + } +} + +//go:embed scheduler-deployment.yaml +var schedulerDeployment []byte + +//go:embed scheduler-deployment.schema.generated.yaml +var schedulerDeploymentSchemaRaw []byte diff --git a/pkg/crd/crds/scheduler-deployment.schema.generated.yaml b/pkg/crd/crds/scheduler-deployment.schema.generated.yaml new file mode 100644 index 000000000..7956b594d --- /dev/null +++ b/pkg/crd/crds/scheduler-deployment.schema.generated.yaml @@ -0,0 +1,2953 @@ +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + minReadySeconds: + format: int32 + type: integer + paused: + type: boolean + profiles: + items: + type: string + type: array + progressDeadlineSeconds: + format: int32 + type: integer + replicas: + format: int32 + type: integer + revisionHistoryLimit: + format: int32 + type: integer + 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 + strategy: + properties: + rollingUpdate: + properties: + maxSurge: + type: string + x-kubernetes-int-or-string: true + maxUnavailable: + type: string + x-kubernetes-int-or-string: true + type: object + type: + type: string + type: object + template: + 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: + activeDeadlineSeconds: + format: int64 + type: integer + 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 + automountServiceAccountToken: + type: boolean + containers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + os: + properties: + name: + type: string + type: object + overhead: + additionalProperties: + type: string + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + readinessGates: + items: + properties: + conditionType: + type: string + type: object + type: array + resourceClaims: + items: + properties: + name: + type: string + source: + properties: + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + type: object + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + type: object + type: array + securityContext: + 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 + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + 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 + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + 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 + type: object + type: object + status: + description: Object with preserved fields for backward compatibility + type: object + x-kubernetes-preserve-unknown-fields: true + type: object diff --git a/pkg/crd/crds/scheduler-deployment.yaml b/pkg/crd/crds/scheduler-deployment.yaml new file mode 100644 index 000000000..0178e1c89 --- /dev/null +++ b/pkg/crd/crds/scheduler-deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerdeployments.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerDeployment + listKind: ArangoSchedulerDeploymentList + plural: arangoschedulerdeployments + singular: arangoschedulerdeployment + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/pkg/crd/crds/scheduler-pod.go b/pkg/crd/crds/scheduler-pod.go new file mode 100644 index 000000000..2052e705c --- /dev/null +++ b/pkg/crd/crds/scheduler-pod.go @@ -0,0 +1,51 @@ +// +// DISCLAIMER +// +// 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. +// 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 crds + +import ( + _ "embed" + + apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +func SchedulerPodWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition { + return getCRD(SchedulerPodDefinitionData(), opts...) +} + +func SchedulerPodDefinitionWithOptions(opts ...func(*CRDOptions)) Definition { + return Definition{ + DefinitionData: SchedulerPodDefinitionData(), + CRD: SchedulerPodWithOptions(opts...), + } +} + +func SchedulerPodDefinitionData() DefinitionData { + return DefinitionData{ + definition: schedulerPod, + schemaDefinition: schedulerPodSchemaRaw, + } +} + +//go:embed scheduler-pod.yaml +var schedulerPod []byte + +//go:embed scheduler-pod.schema.generated.yaml +var schedulerPodSchemaRaw []byte diff --git a/pkg/crd/crds/scheduler-pod.schema.generated.yaml b/pkg/crd/crds/scheduler-pod.schema.generated.yaml new file mode 100644 index 000000000..d38077167 --- /dev/null +++ b/pkg/crd/crds/scheduler-pod.schema.generated.yaml @@ -0,0 +1,2823 @@ +v1beta1: + openAPIV3Schema: + properties: + spec: + properties: + activeDeadlineSeconds: + format: int64 + type: integer + 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 + automountServiceAccountToken: + type: boolean + containers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + enableServiceLinks: + type: boolean + ephemeralContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + targetContainerName: + type: string + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + hostAliases: + items: + properties: + hostnames: + items: + type: string + type: array + ip: + type: string + type: object + type: array + hostIPC: + type: boolean + hostNetwork: + type: boolean + hostPID: + type: boolean + hostUsers: + type: boolean + hostname: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainers: + items: + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + scheme: + type: string + type: object + sleep: + properties: + seconds: + format: int64 + type: integer + type: object + tcpSocket: + properties: + host: + type: string + port: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + name: + type: string + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + resizePolicy: + items: + properties: + resourceName: + type: string + restartPolicy: + type: string + type: object + type: array + 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 + restartPolicy: + 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 + 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: + type: string + x-kubernetes-int-or-string: true + 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: + type: string + x-kubernetes-int-or-string: true + type: object + terminationGracePeriodSeconds: + format: int64 + type: integer + timeoutSeconds: + format: int32 + type: integer + type: object + stdin: + type: boolean + stdinOnce: + type: boolean + terminationMessagePath: + type: string + terminationMessagePolicy: + type: string + tty: + type: boolean + volumeDevices: + items: + properties: + devicePath: + type: string + name: + 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 + workingDir: + type: string + type: object + type: array + nodeName: + type: string + nodeSelector: + additionalProperties: + type: string + type: object + os: + properties: + name: + type: string + type: object + overhead: + additionalProperties: + type: string + type: object + preemptionPolicy: + type: string + priority: + format: int32 + type: integer + priorityClassName: + type: string + profiles: + items: + type: string + type: array + readinessGates: + items: + properties: + conditionType: + type: string + type: object + type: array + resourceClaims: + items: + properties: + name: + type: string + source: + properties: + resourceClaimName: + type: string + resourceClaimTemplateName: + type: string + type: object + type: object + type: array + restartPolicy: + type: string + runtimeClassName: + type: string + schedulerName: + type: string + schedulingGates: + items: + properties: + name: + type: string + type: object + type: array + securityContext: + 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 + serviceAccount: + type: string + serviceAccountName: + type: string + setHostnameAsFQDN: + type: boolean + shareProcessNamespace: + type: boolean + subdomain: + type: string + terminationGracePeriodSeconds: + format: int64 + type: integer + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + topologySpreadConstraints: + 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 + maxSkew: + format: int32 + type: integer + minDomains: + format: int32 + type: integer + nodeAffinityPolicy: + type: string + nodeTaintsPolicy: + type: string + topologyKey: + type: string + whenUnsatisfiable: + 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 + status: + description: Object with preserved fields for backward compatibility + type: object + x-kubernetes-preserve-unknown-fields: true + type: object diff --git a/pkg/crd/crds/scheduler-pod.yaml b/pkg/crd/crds/scheduler-pod.yaml new file mode 100644 index 000000000..97ab5f973 --- /dev/null +++ b/pkg/crd/crds/scheduler-pod.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: arangoschedulerpods.scheduler.arangodb.com +spec: + group: scheduler.arangodb.com + names: + kind: ArangoSchedulerPod + listKind: ArangoSchedulerPodList + plural: arangoschedulerpods + singular: arangoschedulerpod + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + served: true + storage: true + subresources: + status: {} diff --git a/pkg/crd/scheduling.go b/pkg/crd/scheduling.go new file mode 100644 index 000000000..37ae6d5c4 --- /dev/null +++ b/pkg/crd/scheduling.go @@ -0,0 +1,58 @@ +// +// 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 crd + +import ( + "github.com/arangodb/kube-arangodb/pkg/crd/crds" +) + +func init() { + registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { + return crds.SchedulerProfileDefinitionWithOptions(opts.AsFunc()) + }, &crds.CRDOptions{ + WithSchema: true, + WithPreserve: false, + }) + registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { + return crds.SchedulerPodDefinitionWithOptions(opts.AsFunc()) + }, &crds.CRDOptions{ + WithSchema: true, + WithPreserve: false, + }) + registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { + return crds.SchedulerDeploymentDefinitionWithOptions(opts.AsFunc()) + }, &crds.CRDOptions{ + WithSchema: true, + WithPreserve: false, + }) + registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { + return crds.SchedulerBatchJobDefinitionWithOptions(opts.AsFunc()) + }, &crds.CRDOptions{ + WithSchema: true, + WithPreserve: false, + }) + registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { + return crds.SchedulerCronJobDefinitionWithOptions(opts.AsFunc()) + }, &crds.CRDOptions{ + WithSchema: true, + WithPreserve: false, + }) +} diff --git a/pkg/debug_package/generators/kubernetes/lister.go b/pkg/debug_package/generators/kubernetes/lister.go index e4c486733..bbde1f949 100644 --- a/pkg/debug_package/generators/kubernetes/lister.go +++ b/pkg/debug_package/generators/kubernetes/lister.go @@ -22,82 +22,15 @@ package kubernetes import ( "context" - "sort" meta "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic" ) -func Extract[T1, T2 any](in List[T1], ex func(in T1) T2) List[T2] { - r := make(List[T2], len(in)) - - for id := range r { - r[id] = ex(in[id]) - } - - return r -} - -type List[T any] []T - -func (l List[T]) Sort(pred func(a, b T) bool) List[T] { - sort.Slice(l, func(i, j int) bool { - return pred(l[i], l[j]) - }) - - return l -} - -func (l List[T]) Append(obj ...T) List[T] { - r := make(List[T], 0, len(l)+len(obj)) - - r = append(r, l...) - r = append(r, obj...) - - return r -} - -func (l List[T]) Filter(f func(a T) bool) List[T] { - r := make(List[T], 0, len(l)) - - for _, o := range l { - if !f(o) { - continue - } - - r = append(r, o) - } - - return r -} - -func (l List[T]) Contains(f func(a T) bool) bool { - for _, o := range l { - if f(o) { - return true - } - } - - return false -} - -func (l List[T]) Unique(f func(existing List[T], a T) bool) List[T] { - r := make(List[T], 0, len(l)) - - for _, o := range l { - if f(r, o) { - continue - } - - r = append(r, o) - } - - return r -} - type ObjectList[T meta.Object] map[types.UID]T func (d ObjectList[T]) ByName(name string) (T, bool) { @@ -110,7 +43,7 @@ func (d ObjectList[T]) ByName(name string) (T, bool) { return util.Default[T](), false } -func (d ObjectList[T]) AsList() List[T] { +func (d ObjectList[T]) AsList() util.List[T] { list := make([]T, 0, len(d)) for _, p := range d { list = append(list, p) @@ -119,7 +52,7 @@ func (d ObjectList[T]) AsList() List[T] { return list } -func MapObjects[L k8sutil.ListContinue, T meta.Object](ctx context.Context, k k8sutil.ListAPI[L], extract func(result L) []T) (ObjectList[T], error) { +func MapObjects[L generic.ListContinue, T meta.Object](ctx context.Context, k generic.ListInterface[L], extract func(result L) []T) (ObjectList[T], error) { objects := ObjectList[T]{} if err := k8sutil.APIList[L](ctx, k, meta.ListOptions{}, func(result L, err error) error { @@ -140,7 +73,7 @@ func MapObjects[L k8sutil.ListContinue, T meta.Object](ctx context.Context, k k8 return objects, nil } -func ListObjects[L k8sutil.ListContinue, T meta.Object](ctx context.Context, k k8sutil.ListAPI[L], extract func(result L) []T) ([]T, error) { +func ListObjects[L generic.ListContinue, T meta.Object](ctx context.Context, k generic.ListInterface[L], extract func(result L) []T) ([]T, error) { objects, err := MapObjects[L, T](ctx, k, extract) if err != nil { return nil, err diff --git a/pkg/deployment/images.go b/pkg/deployment/images.go index 21caa5a80..0a06c5f6f 100644 --- a/pkg/deployment/images.go +++ b/pkg/deployment/images.go @@ -153,7 +153,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, cac defer cancel() pod, err := ib.Context.ACS().CurrentClusterCache().Pod().V1().Read().Get(ctxChild, podName, meta.GetOptions{}) if err == nil { - // Pod found + // ArangoSchedulerPod found if k8sutil.IsPodFailed(pod, utils.StringList{shared.ServerContainerName}) { // Wait some time before deleting the pod if time.Now().After(pod.GetCreationTimestamp().Add(30 * time.Second)) { @@ -161,14 +161,14 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, cac return ib.Context.ACS().CurrentClusterCache().PodsModInterface().V1().Delete(ctxChild, podName, meta.DeleteOptions{}) }) if err != nil && !kerrors.IsNotFound(err) { - log.Err(err).Warn("Failed to delete Image ID Pod") + log.Err(err).Warn("Failed to delete Image ID ArangoSchedulerPod") return false, nil } } return false, nil } if !k8sutil.IsPodReady(pod) { - log.Debug("Image ID Pod is not yet ready") + log.Debug("Image ID ArangoSchedulerPod is not yet ready") return true, nil } @@ -181,14 +181,14 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, cac // Try fetching the ArangoDB version client, err := arangod.CreateArangodImageIDClient(ctx, ib.APIObject, pod.Status.PodIP, false) if err != nil { - log.Err(err).Warn("Failed to create Image ID Pod client") + log.Err(err).Warn("Failed to create Image ID ArangoSchedulerPod client") return true, nil } ctxChild, cancel = globals.GetGlobalTimeouts().ArangoD().WithTimeout(ctx) defer cancel() v, err := client.Version(ctxChild) if err != nil { - log.Err(err).Debug("Failed to fetch version from Image ID Pod") + log.Err(err).Debug("Failed to fetch version from Image ID ArangoSchedulerPod") return true, nil } version := v.Version @@ -199,7 +199,7 @@ func (ib *imagesBuilder) fetchArangoDBImageIDAndVersion(ctx context.Context, cac return ib.Context.ACS().CurrentClusterCache().PodsModInterface().V1().Delete(ctxChild, podName, meta.DeleteOptions{}) }) if err != nil && !kerrors.IsNotFound(err) { - log.Err(err).Warn("Failed to delete Image ID Pod") + log.Err(err).Warn("Failed to delete Image ID ArangoSchedulerPod") return true, nil } diff --git a/pkg/deployment/resources/arango_profiles.go b/pkg/deployment/resources/arango_profiles.go index 99bab20e8..cfa12fdc0 100644 --- a/pkg/deployment/resources/arango_profiles.go +++ b/pkg/deployment/resources/arango_profiles.go @@ -25,6 +25,7 @@ import ( "fmt" "time" + "k8s.io/apimachinery/pkg/api/equality" meta "k8s.io/apimachinery/pkg/apis/meta/v1" schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" @@ -33,8 +34,11 @@ import ( "github.com/arangodb/kube-arangodb/pkg/integrations/sidecar" "github.com/arangodb/kube-arangodb/pkg/metrics" "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/constants" + "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" inspectorInterface "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher" ) @@ -43,11 +47,22 @@ var ( inspectArangoProfilesDurationGauges = metrics.MustRegisterGaugeVec(metricsComponent, "inspect_arango_profiles_duration", "Amount of time taken by a single inspection of all ArangoProfiles for a deployment (in sec)", metrics.DeploymentName) ) +func matchArangoProfilesLabels(labels map[string]string) *schedulerApi.ProfileSelectors { + if labels == nil { + return nil + } + + return &schedulerApi.ProfileSelectors{ + Label: &meta.LabelSelector{ + MatchLabels: labels, + }, + } +} + // EnsureArangoProfiles creates all ArangoProfiles needed to run the given deployment func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspectorInterface.Inspector) error { start := time.Now() spec := r.context.GetSpec() - arangoProfiles := cachedStatus.ArangoProfileModInterface().V1Beta1() apiObject := r.context.GetAPIObject() deploymentName := apiObject.GetName() @@ -56,74 +71,167 @@ func (r *Resources) EnsureArangoProfiles(ctx context.Context, cachedStatus inspe reconcileRequired := k8sutil.NewReconcile(cachedStatus) - intName := fmt.Sprintf("%s-int", deploymentName) + gen := func(name, version string, integrations ...sidecar.Integration) func() (string, *schedulerApi.ArangoProfile, error) { + return func() (string, *schedulerApi.ArangoProfile, error) { + counterMetric.Inc() + fullName := fmt.Sprintf("%s-int-%s-%s", deploymentName, name, version) - integration, err := sidecar.NewIntegration(&schedulerContainerResourcesApi.Image{ - Image: util.NewType(r.context.GetOperatorImage()), - }, spec.Integration.GetSidecar()) - if err != nil { - return err - } + integration, err := sidecar.NewIntegrationEnablement(integrations...) + if err != nil { + return "", nil, err + } - integrationChecksum, err := integration.Checksum() - if err != nil { - return err - } - - if c, err := cachedStatus.ArangoProfile().V1Beta1(); err == nil { - counterMetric.Inc() - if s, ok := c.GetSimple(intName); !ok { - s = &schedulerApi.ArangoProfile{ + return fullName, &schedulerApi.ArangoProfile{ ObjectMeta: meta.ObjectMeta{ - Name: intName, + Name: fullName, Namespace: apiObject.GetNamespace(), OwnerReferences: []meta.OwnerReference{ apiObject.AsOwner(), }, }, Spec: schedulerApi.ProfileSpec{ + Selectors: matchArangoProfilesLabels(map[string]string{ + constants.ProfilesDeployment: deploymentName, + fmt.Sprintf("%s/%s", constants.ProfilesIntegrationPrefix, name): version, + }), Template: integration, }, + }, nil + } + } + + if changed, err := r.ensureArangoProfilesFactory(ctx, cachedStatus, + func() (string, *schedulerApi.ArangoProfile, error) { + counterMetric.Inc() + name := fmt.Sprintf("%s-int", deploymentName) + + integration, err := sidecar.NewIntegration(&schedulerContainerResourcesApi.Image{ + Image: util.NewType(r.context.GetOperatorImage()), + }, spec.Integration.GetSidecar()) + if err != nil { + return "", nil, err } - if _, err := cachedStatus.ArangoProfileModInterface().V1Beta1().Create(ctx, s, meta.CreateOptions{}); err != nil { - return err - } + return name, &schedulerApi.ArangoProfile{ + ObjectMeta: meta.ObjectMeta{ + Name: name, + Namespace: apiObject.GetNamespace(), + OwnerReferences: []meta.OwnerReference{ + apiObject.AsOwner(), + }, + }, + Spec: schedulerApi.ProfileSpec{ + Selectors: matchArangoProfilesLabels(map[string]string{ + constants.ProfilesDeployment: deploymentName, + }), + Template: integration, + }, + }, nil + }, + gen("authz", "v0", sidecar.IntegrationAuthorizationV0{}), + gen("authn", "v1", sidecar.IntegrationAuthenticationV1{Spec: spec, DeploymentName: apiObject.GetName()}), + ); err != nil { + return err + } else if changed { + reconcileRequired.Required() + } - reconcileRequired.Required() + return reconcileRequired.Reconcile(ctx) +} + +func (r *Resources) ensureArangoProfilesFactory(ctx context.Context, cachedStatus inspectorInterface.Inspector, expected ...func() (string, *schedulerApi.ArangoProfile, error)) (bool, error) { + var changed bool + + for _, e := range expected { + name, profile, err := e() + if err != nil { + return false, err + } + if c, err := r.ensureArangoProfile(ctx, cachedStatus, name, profile); err != nil { + return false, err + } else if c { + changed = true + } + } + + return changed, nil +} + +func (r *Resources) ensureArangoProfile(ctx context.Context, cachedStatus inspectorInterface.Inspector, name string, expected *schedulerApi.ArangoProfile) (bool, error) { + arangoProfiles := cachedStatus.ArangoProfileModInterface().V1Beta1() + + if expected.GetName() != name { + return false, errors.Errorf("Name mismatch") + } + + if c, err := cachedStatus.ArangoProfile().V1Beta1(); err == nil { + if s, ok := c.GetSimple(name); !ok { + if expected != nil { + if _, err := arangoProfiles.Create(ctx, expected, meta.CreateOptions{}); err != nil { + return false, err + } + + return true, nil + } } else { + if expected == nil { + if err := arangoProfiles.Delete(ctx, s.GetName(), meta.DeleteOptions{}); err != nil { + if !kerrors.IsNotFound(err) { + return false, err + } + } + + return true, nil + } + expectedChecksum, err := expected.Spec.Template.Checksum() + if err != nil { + return false, err + } + currChecksum, err := s.Spec.Template.Checksum() if err != nil { - return err + return false, err } - if s.Spec.Selectors != nil { + if expected.Spec.Selectors == nil && s.Spec.Selectors != nil { + // Remove if _, changed, err := patcher.Patcher[*schedulerApi.ArangoProfile](ctx, arangoProfiles, s, meta.PatchOptions{}, func(in *schedulerApi.ArangoProfile) []patch.Item { return []patch.Item{ patch.ItemRemove(patch.NewPath("spec", "selectors")), } }); err != nil { - return err + return false, err } else if changed { - reconcileRequired.Required() + return true, nil } - } - - if currChecksum != integrationChecksum { + } else if !equality.Semantic.DeepEqual(expected.Spec.Selectors, s.Spec.Selectors) { if _, changed, err := patcher.Patcher[*schedulerApi.ArangoProfile](ctx, arangoProfiles, s, meta.PatchOptions{}, func(in *schedulerApi.ArangoProfile) []patch.Item { return []patch.Item{ - patch.ItemReplace(patch.NewPath("spec", "template"), integration), + patch.ItemReplace(patch.NewPath("spec", "selectors"), expected.Spec.Selectors), } }); err != nil { - return err + return false, err } else if changed { - reconcileRequired.Required() + return true, nil + } + } + + if currChecksum != expectedChecksum { + if _, changed, err := patcher.Patcher[*schedulerApi.ArangoProfile](ctx, arangoProfiles, s, meta.PatchOptions{}, + func(in *schedulerApi.ArangoProfile) []patch.Item { + return []patch.Item{ + patch.ItemReplace(patch.NewPath("spec", "template"), util.TypeOrDefault(expected.Spec.Template)), + } + }); err != nil { + return false, err + } else if changed { + return true, nil } } } } - return reconcileRequired.Reconcile(ctx) + return false, nil } diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerbatchjob.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerbatchjob.go new file mode 100644 index 000000000..cb6e72dca --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerbatchjob.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" +) + +// ArangoSchedulerBatchJobsGetter has a method to return a ArangoSchedulerBatchJobInterface. +// A group's client should implement this interface. +type ArangoSchedulerBatchJobsGetter interface { + ArangoSchedulerBatchJobs(namespace string) ArangoSchedulerBatchJobInterface +} + +// ArangoSchedulerBatchJobInterface has methods to work with ArangoSchedulerBatchJob resources. +type ArangoSchedulerBatchJobInterface interface { + Create(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.CreateOptions) (*v1beta1.ArangoSchedulerBatchJob, error) + Update(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerBatchJob, error) + UpdateStatus(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerBatchJob, 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.ArangoSchedulerBatchJob, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoSchedulerBatchJobList, 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.ArangoSchedulerBatchJob, err error) + ArangoSchedulerBatchJobExpansion +} + +// arangoSchedulerBatchJobs implements ArangoSchedulerBatchJobInterface +type arangoSchedulerBatchJobs struct { + client rest.Interface + ns string +} + +// newArangoSchedulerBatchJobs returns a ArangoSchedulerBatchJobs +func newArangoSchedulerBatchJobs(c *SchedulerV1beta1Client, namespace string) *arangoSchedulerBatchJobs { + return &arangoSchedulerBatchJobs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoSchedulerBatchJob, and returns the corresponding arangoSchedulerBatchJob object, and an error if there is any. +func (c *arangoSchedulerBatchJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + result = &v1beta1.ArangoSchedulerBatchJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerBatchJobs that match those selectors. +func (c *arangoSchedulerBatchJobs) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerBatchJobList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoSchedulerBatchJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoSchedulerBatchJobs. +func (c *arangoSchedulerBatchJobs) 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("arangoschedulerbatchjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoSchedulerBatchJob and creates it. Returns the server's representation of the arangoSchedulerBatchJob, and an error, if there is any. +func (c *arangoSchedulerBatchJobs) Create(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + result = &v1beta1.ArangoSchedulerBatchJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerBatchJob). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoSchedulerBatchJob and updates it. Returns the server's representation of the arangoSchedulerBatchJob, and an error, if there is any. +func (c *arangoSchedulerBatchJobs) Update(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + result = &v1beta1.ArangoSchedulerBatchJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + Name(arangoSchedulerBatchJob.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerBatchJob). + 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 *arangoSchedulerBatchJobs) UpdateStatus(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + result = &v1beta1.ArangoSchedulerBatchJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + Name(arangoSchedulerBatchJob.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerBatchJob). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoSchedulerBatchJob and deletes it. Returns an error if one occurs. +func (c *arangoSchedulerBatchJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoSchedulerBatchJobs) 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("arangoschedulerbatchjobs"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoSchedulerBatchJob. +func (c *arangoSchedulerBatchJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + result = &v1beta1.ArangoSchedulerBatchJob{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangoschedulerbatchjobs"). + 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/arangoschedulercronjob.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulercronjob.go new file mode 100644 index 000000000..e0a06dc30 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulercronjob.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" +) + +// ArangoSchedulerCronJobsGetter has a method to return a ArangoSchedulerCronJobInterface. +// A group's client should implement this interface. +type ArangoSchedulerCronJobsGetter interface { + ArangoSchedulerCronJobs(namespace string) ArangoSchedulerCronJobInterface +} + +// ArangoSchedulerCronJobInterface has methods to work with ArangoSchedulerCronJob resources. +type ArangoSchedulerCronJobInterface interface { + Create(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.CreateOptions) (*v1beta1.ArangoSchedulerCronJob, error) + Update(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerCronJob, error) + UpdateStatus(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerCronJob, 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.ArangoSchedulerCronJob, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoSchedulerCronJobList, 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.ArangoSchedulerCronJob, err error) + ArangoSchedulerCronJobExpansion +} + +// arangoSchedulerCronJobs implements ArangoSchedulerCronJobInterface +type arangoSchedulerCronJobs struct { + client rest.Interface + ns string +} + +// newArangoSchedulerCronJobs returns a ArangoSchedulerCronJobs +func newArangoSchedulerCronJobs(c *SchedulerV1beta1Client, namespace string) *arangoSchedulerCronJobs { + return &arangoSchedulerCronJobs{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoSchedulerCronJob, and returns the corresponding arangoSchedulerCronJob object, and an error if there is any. +func (c *arangoSchedulerCronJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + result = &v1beta1.ArangoSchedulerCronJob{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerCronJobs that match those selectors. +func (c *arangoSchedulerCronJobs) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerCronJobList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoSchedulerCronJobList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoSchedulerCronJobs. +func (c *arangoSchedulerCronJobs) 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("arangoschedulercronjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoSchedulerCronJob and creates it. Returns the server's representation of the arangoSchedulerCronJob, and an error, if there is any. +func (c *arangoSchedulerCronJobs) Create(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + result = &v1beta1.ArangoSchedulerCronJob{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerCronJob). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoSchedulerCronJob and updates it. Returns the server's representation of the arangoSchedulerCronJob, and an error, if there is any. +func (c *arangoSchedulerCronJobs) Update(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + result = &v1beta1.ArangoSchedulerCronJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + Name(arangoSchedulerCronJob.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerCronJob). + 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 *arangoSchedulerCronJobs) UpdateStatus(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + result = &v1beta1.ArangoSchedulerCronJob{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + Name(arangoSchedulerCronJob.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerCronJob). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoSchedulerCronJob and deletes it. Returns an error if one occurs. +func (c *arangoSchedulerCronJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoSchedulerCronJobs) 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("arangoschedulercronjobs"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoSchedulerCronJob. +func (c *arangoSchedulerCronJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerCronJob, err error) { + result = &v1beta1.ArangoSchedulerCronJob{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangoschedulercronjobs"). + 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/arangoschedulerdeployment.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerdeployment.go new file mode 100644 index 000000000..e2f9cb6af --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerdeployment.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" +) + +// ArangoSchedulerDeploymentsGetter has a method to return a ArangoSchedulerDeploymentInterface. +// A group's client should implement this interface. +type ArangoSchedulerDeploymentsGetter interface { + ArangoSchedulerDeployments(namespace string) ArangoSchedulerDeploymentInterface +} + +// ArangoSchedulerDeploymentInterface has methods to work with ArangoSchedulerDeployment resources. +type ArangoSchedulerDeploymentInterface interface { + Create(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.CreateOptions) (*v1beta1.ArangoSchedulerDeployment, error) + Update(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerDeployment, error) + UpdateStatus(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerDeployment, 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.ArangoSchedulerDeployment, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoSchedulerDeploymentList, 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.ArangoSchedulerDeployment, err error) + ArangoSchedulerDeploymentExpansion +} + +// arangoSchedulerDeployments implements ArangoSchedulerDeploymentInterface +type arangoSchedulerDeployments struct { + client rest.Interface + ns string +} + +// newArangoSchedulerDeployments returns a ArangoSchedulerDeployments +func newArangoSchedulerDeployments(c *SchedulerV1beta1Client, namespace string) *arangoSchedulerDeployments { + return &arangoSchedulerDeployments{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoSchedulerDeployment, and returns the corresponding arangoSchedulerDeployment object, and an error if there is any. +func (c *arangoSchedulerDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + result = &v1beta1.ArangoSchedulerDeployment{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerDeployments that match those selectors. +func (c *arangoSchedulerDeployments) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerDeploymentList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoSchedulerDeploymentList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoSchedulerDeployments. +func (c *arangoSchedulerDeployments) 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("arangoschedulerdeployments"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoSchedulerDeployment and creates it. Returns the server's representation of the arangoSchedulerDeployment, and an error, if there is any. +func (c *arangoSchedulerDeployments) Create(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + result = &v1beta1.ArangoSchedulerDeployment{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerDeployment). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoSchedulerDeployment and updates it. Returns the server's representation of the arangoSchedulerDeployment, and an error, if there is any. +func (c *arangoSchedulerDeployments) Update(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + result = &v1beta1.ArangoSchedulerDeployment{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + Name(arangoSchedulerDeployment.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerDeployment). + 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 *arangoSchedulerDeployments) UpdateStatus(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + result = &v1beta1.ArangoSchedulerDeployment{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + Name(arangoSchedulerDeployment.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerDeployment). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoSchedulerDeployment and deletes it. Returns an error if one occurs. +func (c *arangoSchedulerDeployments) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoSchedulerDeployments) 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("arangoschedulerdeployments"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoSchedulerDeployment. +func (c *arangoSchedulerDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerDeployment, err error) { + result = &v1beta1.ArangoSchedulerDeployment{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangoschedulerdeployments"). + 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/arangoschedulerpod.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerpod.go new file mode 100644 index 000000000..55703b9db --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/arangoschedulerpod.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" +) + +// ArangoSchedulerPodsGetter has a method to return a ArangoSchedulerPodInterface. +// A group's client should implement this interface. +type ArangoSchedulerPodsGetter interface { + ArangoSchedulerPods(namespace string) ArangoSchedulerPodInterface +} + +// ArangoSchedulerPodInterface has methods to work with ArangoSchedulerPod resources. +type ArangoSchedulerPodInterface interface { + Create(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.CreateOptions) (*v1beta1.ArangoSchedulerPod, error) + Update(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerPod, error) + UpdateStatus(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerPod, 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.ArangoSchedulerPod, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.ArangoSchedulerPodList, 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.ArangoSchedulerPod, err error) + ArangoSchedulerPodExpansion +} + +// arangoSchedulerPods implements ArangoSchedulerPodInterface +type arangoSchedulerPods struct { + client rest.Interface + ns string +} + +// newArangoSchedulerPods returns a ArangoSchedulerPods +func newArangoSchedulerPods(c *SchedulerV1beta1Client, namespace string) *arangoSchedulerPods { + return &arangoSchedulerPods{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the arangoSchedulerPod, and returns the corresponding arangoSchedulerPod object, and an error if there is any. +func (c *arangoSchedulerPods) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + result = &v1beta1.ArangoSchedulerPod{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerPods that match those selectors. +func (c *arangoSchedulerPods) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerPodList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.ArangoSchedulerPodList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested arangoSchedulerPods. +func (c *arangoSchedulerPods) 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("arangoschedulerpods"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a arangoSchedulerPod and creates it. Returns the server's representation of the arangoSchedulerPod, and an error, if there is any. +func (c *arangoSchedulerPods) Create(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + result = &v1beta1.ArangoSchedulerPod{} + err = c.client.Post(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerPod). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a arangoSchedulerPod and updates it. Returns the server's representation of the arangoSchedulerPod, and an error, if there is any. +func (c *arangoSchedulerPods) Update(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + result = &v1beta1.ArangoSchedulerPod{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + Name(arangoSchedulerPod.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerPod). + 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 *arangoSchedulerPods) UpdateStatus(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + result = &v1beta1.ArangoSchedulerPod{} + err = c.client.Put(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + Name(arangoSchedulerPod.Name). + SubResource("status"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(arangoSchedulerPod). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the arangoSchedulerPod and deletes it. Returns an error if one occurs. +func (c *arangoSchedulerPods) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("arangoschedulerpods"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *arangoSchedulerPods) 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("arangoschedulerpods"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched arangoSchedulerPod. +func (c *arangoSchedulerPods) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerPod, err error) { + result = &v1beta1.ArangoSchedulerPod{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("arangoschedulerpods"). + 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/fake/fake_arangoschedulerbatchjob.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerbatchjob.go new file mode 100644 index 000000000..50830d6f3 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerbatchjob.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" +) + +// FakeArangoSchedulerBatchJobs implements ArangoSchedulerBatchJobInterface +type FakeArangoSchedulerBatchJobs struct { + Fake *FakeSchedulerV1beta1 + ns string +} + +var arangoschedulerbatchjobsResource = v1beta1.SchemeGroupVersion.WithResource("arangoschedulerbatchjobs") + +var arangoschedulerbatchjobsKind = v1beta1.SchemeGroupVersion.WithKind("ArangoSchedulerBatchJob") + +// Get takes name of the arangoSchedulerBatchJob, and returns the corresponding arangoSchedulerBatchJob object, and an error if there is any. +func (c *FakeArangoSchedulerBatchJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangoschedulerbatchjobsResource, c.ns, name), &v1beta1.ArangoSchedulerBatchJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), err +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerBatchJobs that match those selectors. +func (c *FakeArangoSchedulerBatchJobs) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerBatchJobList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangoschedulerbatchjobsResource, arangoschedulerbatchjobsKind, c.ns, opts), &v1beta1.ArangoSchedulerBatchJobList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoSchedulerBatchJobList{ListMeta: obj.(*v1beta1.ArangoSchedulerBatchJobList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoSchedulerBatchJobList).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 arangoSchedulerBatchJobs. +func (c *FakeArangoSchedulerBatchJobs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangoschedulerbatchjobsResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoSchedulerBatchJob and creates it. Returns the server's representation of the arangoSchedulerBatchJob, and an error, if there is any. +func (c *FakeArangoSchedulerBatchJobs) Create(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangoschedulerbatchjobsResource, c.ns, arangoSchedulerBatchJob), &v1beta1.ArangoSchedulerBatchJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), err +} + +// Update takes the representation of a arangoSchedulerBatchJob and updates it. Returns the server's representation of the arangoSchedulerBatchJob, and an error, if there is any. +func (c *FakeArangoSchedulerBatchJobs) Update(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangoschedulerbatchjobsResource, c.ns, arangoSchedulerBatchJob), &v1beta1.ArangoSchedulerBatchJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), 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 *FakeArangoSchedulerBatchJobs) UpdateStatus(ctx context.Context, arangoSchedulerBatchJob *v1beta1.ArangoSchedulerBatchJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerBatchJob, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangoschedulerbatchjobsResource, "status", c.ns, arangoSchedulerBatchJob), &v1beta1.ArangoSchedulerBatchJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), err +} + +// Delete takes name of the arangoSchedulerBatchJob and deletes it. Returns an error if one occurs. +func (c *FakeArangoSchedulerBatchJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangoschedulerbatchjobsResource, c.ns, name, opts), &v1beta1.ArangoSchedulerBatchJob{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoSchedulerBatchJobs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangoschedulerbatchjobsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoSchedulerBatchJobList{}) + return err +} + +// Patch applies the patch and returns the patched arangoSchedulerBatchJob. +func (c *FakeArangoSchedulerBatchJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerBatchJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangoschedulerbatchjobsResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoSchedulerBatchJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), err +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulercronjob.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulercronjob.go new file mode 100644 index 000000000..d3866c951 --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulercronjob.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" +) + +// FakeArangoSchedulerCronJobs implements ArangoSchedulerCronJobInterface +type FakeArangoSchedulerCronJobs struct { + Fake *FakeSchedulerV1beta1 + ns string +} + +var arangoschedulercronjobsResource = v1beta1.SchemeGroupVersion.WithResource("arangoschedulercronjobs") + +var arangoschedulercronjobsKind = v1beta1.SchemeGroupVersion.WithKind("ArangoSchedulerCronJob") + +// Get takes name of the arangoSchedulerCronJob, and returns the corresponding arangoSchedulerCronJob object, and an error if there is any. +func (c *FakeArangoSchedulerCronJobs) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangoschedulercronjobsResource, c.ns, name), &v1beta1.ArangoSchedulerCronJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerCronJob), err +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerCronJobs that match those selectors. +func (c *FakeArangoSchedulerCronJobs) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerCronJobList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangoschedulercronjobsResource, arangoschedulercronjobsKind, c.ns, opts), &v1beta1.ArangoSchedulerCronJobList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoSchedulerCronJobList{ListMeta: obj.(*v1beta1.ArangoSchedulerCronJobList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoSchedulerCronJobList).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 arangoSchedulerCronJobs. +func (c *FakeArangoSchedulerCronJobs) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangoschedulercronjobsResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoSchedulerCronJob and creates it. Returns the server's representation of the arangoSchedulerCronJob, and an error, if there is any. +func (c *FakeArangoSchedulerCronJobs) Create(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangoschedulercronjobsResource, c.ns, arangoSchedulerCronJob), &v1beta1.ArangoSchedulerCronJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerCronJob), err +} + +// Update takes the representation of a arangoSchedulerCronJob and updates it. Returns the server's representation of the arangoSchedulerCronJob, and an error, if there is any. +func (c *FakeArangoSchedulerCronJobs) Update(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerCronJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangoschedulercronjobsResource, c.ns, arangoSchedulerCronJob), &v1beta1.ArangoSchedulerCronJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerCronJob), 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 *FakeArangoSchedulerCronJobs) UpdateStatus(ctx context.Context, arangoSchedulerCronJob *v1beta1.ArangoSchedulerCronJob, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerCronJob, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangoschedulercronjobsResource, "status", c.ns, arangoSchedulerCronJob), &v1beta1.ArangoSchedulerCronJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerCronJob), err +} + +// Delete takes name of the arangoSchedulerCronJob and deletes it. Returns an error if one occurs. +func (c *FakeArangoSchedulerCronJobs) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangoschedulercronjobsResource, c.ns, name, opts), &v1beta1.ArangoSchedulerCronJob{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoSchedulerCronJobs) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangoschedulercronjobsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoSchedulerCronJobList{}) + return err +} + +// Patch applies the patch and returns the patched arangoSchedulerCronJob. +func (c *FakeArangoSchedulerCronJobs) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerCronJob, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangoschedulercronjobsResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoSchedulerCronJob{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerCronJob), err +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerdeployment.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerdeployment.go new file mode 100644 index 000000000..e8c0ba6ab --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerdeployment.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" +) + +// FakeArangoSchedulerDeployments implements ArangoSchedulerDeploymentInterface +type FakeArangoSchedulerDeployments struct { + Fake *FakeSchedulerV1beta1 + ns string +} + +var arangoschedulerdeploymentsResource = v1beta1.SchemeGroupVersion.WithResource("arangoschedulerdeployments") + +var arangoschedulerdeploymentsKind = v1beta1.SchemeGroupVersion.WithKind("ArangoSchedulerDeployment") + +// Get takes name of the arangoSchedulerDeployment, and returns the corresponding arangoSchedulerDeployment object, and an error if there is any. +func (c *FakeArangoSchedulerDeployments) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangoschedulerdeploymentsResource, c.ns, name), &v1beta1.ArangoSchedulerDeployment{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerDeployment), err +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerDeployments that match those selectors. +func (c *FakeArangoSchedulerDeployments) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerDeploymentList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangoschedulerdeploymentsResource, arangoschedulerdeploymentsKind, c.ns, opts), &v1beta1.ArangoSchedulerDeploymentList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoSchedulerDeploymentList{ListMeta: obj.(*v1beta1.ArangoSchedulerDeploymentList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoSchedulerDeploymentList).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 arangoSchedulerDeployments. +func (c *FakeArangoSchedulerDeployments) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangoschedulerdeploymentsResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoSchedulerDeployment and creates it. Returns the server's representation of the arangoSchedulerDeployment, and an error, if there is any. +func (c *FakeArangoSchedulerDeployments) Create(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangoschedulerdeploymentsResource, c.ns, arangoSchedulerDeployment), &v1beta1.ArangoSchedulerDeployment{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerDeployment), err +} + +// Update takes the representation of a arangoSchedulerDeployment and updates it. Returns the server's representation of the arangoSchedulerDeployment, and an error, if there is any. +func (c *FakeArangoSchedulerDeployments) Update(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerDeployment, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangoschedulerdeploymentsResource, c.ns, arangoSchedulerDeployment), &v1beta1.ArangoSchedulerDeployment{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerDeployment), 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 *FakeArangoSchedulerDeployments) UpdateStatus(ctx context.Context, arangoSchedulerDeployment *v1beta1.ArangoSchedulerDeployment, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerDeployment, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangoschedulerdeploymentsResource, "status", c.ns, arangoSchedulerDeployment), &v1beta1.ArangoSchedulerDeployment{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerDeployment), err +} + +// Delete takes name of the arangoSchedulerDeployment and deletes it. Returns an error if one occurs. +func (c *FakeArangoSchedulerDeployments) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangoschedulerdeploymentsResource, c.ns, name, opts), &v1beta1.ArangoSchedulerDeployment{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoSchedulerDeployments) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangoschedulerdeploymentsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoSchedulerDeploymentList{}) + return err +} + +// Patch applies the patch and returns the patched arangoSchedulerDeployment. +func (c *FakeArangoSchedulerDeployments) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerDeployment, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangoschedulerdeploymentsResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoSchedulerDeployment{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerDeployment), err +} diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerpod.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerpod.go new file mode 100644 index 000000000..b9edcc57d --- /dev/null +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/fake/fake_arangoschedulerpod.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" +) + +// FakeArangoSchedulerPods implements ArangoSchedulerPodInterface +type FakeArangoSchedulerPods struct { + Fake *FakeSchedulerV1beta1 + ns string +} + +var arangoschedulerpodsResource = v1beta1.SchemeGroupVersion.WithResource("arangoschedulerpods") + +var arangoschedulerpodsKind = v1beta1.SchemeGroupVersion.WithKind("ArangoSchedulerPod") + +// Get takes name of the arangoSchedulerPod, and returns the corresponding arangoSchedulerPod object, and an error if there is any. +func (c *FakeArangoSchedulerPods) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(arangoschedulerpodsResource, c.ns, name), &v1beta1.ArangoSchedulerPod{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerPod), err +} + +// List takes label and field selectors, and returns the list of ArangoSchedulerPods that match those selectors. +func (c *FakeArangoSchedulerPods) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.ArangoSchedulerPodList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(arangoschedulerpodsResource, arangoschedulerpodsKind, c.ns, opts), &v1beta1.ArangoSchedulerPodList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.ArangoSchedulerPodList{ListMeta: obj.(*v1beta1.ArangoSchedulerPodList).ListMeta} + for _, item := range obj.(*v1beta1.ArangoSchedulerPodList).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 arangoSchedulerPods. +func (c *FakeArangoSchedulerPods) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(arangoschedulerpodsResource, c.ns, opts)) + +} + +// Create takes the representation of a arangoSchedulerPod and creates it. Returns the server's representation of the arangoSchedulerPod, and an error, if there is any. +func (c *FakeArangoSchedulerPods) Create(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.CreateOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(arangoschedulerpodsResource, c.ns, arangoSchedulerPod), &v1beta1.ArangoSchedulerPod{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerPod), err +} + +// Update takes the representation of a arangoSchedulerPod and updates it. Returns the server's representation of the arangoSchedulerPod, and an error, if there is any. +func (c *FakeArangoSchedulerPods) Update(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (result *v1beta1.ArangoSchedulerPod, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(arangoschedulerpodsResource, c.ns, arangoSchedulerPod), &v1beta1.ArangoSchedulerPod{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerPod), 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 *FakeArangoSchedulerPods) UpdateStatus(ctx context.Context, arangoSchedulerPod *v1beta1.ArangoSchedulerPod, opts v1.UpdateOptions) (*v1beta1.ArangoSchedulerPod, error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateSubresourceAction(arangoschedulerpodsResource, "status", c.ns, arangoSchedulerPod), &v1beta1.ArangoSchedulerPod{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerPod), err +} + +// Delete takes name of the arangoSchedulerPod and deletes it. Returns an error if one occurs. +func (c *FakeArangoSchedulerPods) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(arangoschedulerpodsResource, c.ns, name, opts), &v1beta1.ArangoSchedulerPod{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeArangoSchedulerPods) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(arangoschedulerpodsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.ArangoSchedulerPodList{}) + return err +} + +// Patch applies the patch and returns the patched arangoSchedulerPod. +func (c *FakeArangoSchedulerPods) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.ArangoSchedulerPod, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(arangoschedulerpodsResource, c.ns, name, pt, data, subresources...), &v1beta1.ArangoSchedulerPod{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.ArangoSchedulerPod), 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 index b00b03e6b..f6e278220 100644 --- 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 @@ -36,6 +36,22 @@ func (c *FakeSchedulerV1beta1) ArangoProfiles(namespace string) v1beta1.ArangoPr return &FakeArangoProfiles{c, namespace} } +func (c *FakeSchedulerV1beta1) ArangoSchedulerBatchJobs(namespace string) v1beta1.ArangoSchedulerBatchJobInterface { + return &FakeArangoSchedulerBatchJobs{c, namespace} +} + +func (c *FakeSchedulerV1beta1) ArangoSchedulerCronJobs(namespace string) v1beta1.ArangoSchedulerCronJobInterface { + return &FakeArangoSchedulerCronJobs{c, namespace} +} + +func (c *FakeSchedulerV1beta1) ArangoSchedulerDeployments(namespace string) v1beta1.ArangoSchedulerDeploymentInterface { + return &FakeArangoSchedulerDeployments{c, namespace} +} + +func (c *FakeSchedulerV1beta1) ArangoSchedulerPods(namespace string) v1beta1.ArangoSchedulerPodInterface { + return &FakeArangoSchedulerPods{c, namespace} +} + // RESTClient returns a RESTClient that is used to communicate // with API server by this client implementation. func (c *FakeSchedulerV1beta1) RESTClient() rest.Interface { diff --git a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go index 5d703a84e..7ee5d874a 100644 --- a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/generated_expansion.go @@ -23,3 +23,11 @@ package v1beta1 type ArangoProfileExpansion interface{} + +type ArangoSchedulerBatchJobExpansion interface{} + +type ArangoSchedulerCronJobExpansion interface{} + +type ArangoSchedulerDeploymentExpansion interface{} + +type ArangoSchedulerPodExpansion 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 index c2d911e0b..ada000f18 100644 --- a/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go +++ b/pkg/generated/clientset/versioned/typed/scheduler/v1beta1/scheduler_client.go @@ -33,6 +33,10 @@ import ( type SchedulerV1beta1Interface interface { RESTClient() rest.Interface ArangoProfilesGetter + ArangoSchedulerBatchJobsGetter + ArangoSchedulerCronJobsGetter + ArangoSchedulerDeploymentsGetter + ArangoSchedulerPodsGetter } // SchedulerV1beta1Client is used to interact with features provided by the scheduler.arangodb.com group. @@ -44,6 +48,22 @@ func (c *SchedulerV1beta1Client) ArangoProfiles(namespace string) ArangoProfileI return newArangoProfiles(c, namespace) } +func (c *SchedulerV1beta1Client) ArangoSchedulerBatchJobs(namespace string) ArangoSchedulerBatchJobInterface { + return newArangoSchedulerBatchJobs(c, namespace) +} + +func (c *SchedulerV1beta1Client) ArangoSchedulerCronJobs(namespace string) ArangoSchedulerCronJobInterface { + return newArangoSchedulerCronJobs(c, namespace) +} + +func (c *SchedulerV1beta1Client) ArangoSchedulerDeployments(namespace string) ArangoSchedulerDeploymentInterface { + return newArangoSchedulerDeployments(c, namespace) +} + +func (c *SchedulerV1beta1Client) ArangoSchedulerPods(namespace string) ArangoSchedulerPodInterface { + return newArangoSchedulerPods(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). diff --git a/pkg/generated/informers/externalversions/generic.go b/pkg/generated/informers/externalversions/generic.go index 00f3e40c3..1dabd1a59 100644 --- a/pkg/generated/informers/externalversions/generic.go +++ b/pkg/generated/informers/externalversions/generic.go @@ -137,6 +137,14 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=scheduler.arangodb.com, Version=v1beta1 case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoprofiles"): return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoProfiles().Informer()}, nil + case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoschedulerbatchjobs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoSchedulerBatchJobs().Informer()}, nil + case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoschedulercronjobs"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoSchedulerCronJobs().Informer()}, nil + case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoschedulerdeployments"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoSchedulerDeployments().Informer()}, nil + case schedulerv1beta1.SchemeGroupVersion.WithResource("arangoschedulerpods"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Scheduler().V1beta1().ArangoSchedulerPods().Informer()}, nil // Group=storage.arangodb.com, Version=v1alpha case v1alpha.SchemeGroupVersion.WithResource("arangolocalstorages"): diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerbatchjob.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerbatchjob.go new file mode 100644 index 000000000..fc93eea7e --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerbatchjob.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" +) + +// ArangoSchedulerBatchJobInformer provides access to a shared informer and lister for +// ArangoSchedulerBatchJobs. +type ArangoSchedulerBatchJobInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoSchedulerBatchJobLister +} + +type arangoSchedulerBatchJobInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoSchedulerBatchJobInformer constructs a new informer for ArangoSchedulerBatchJob 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 NewArangoSchedulerBatchJobInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerBatchJobInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoSchedulerBatchJobInformer constructs a new informer for ArangoSchedulerBatchJob 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 NewFilteredArangoSchedulerBatchJobInformer(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().ArangoSchedulerBatchJobs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoSchedulerBatchJobs(namespace).Watch(context.TODO(), options) + }, + }, + &schedulerv1beta1.ArangoSchedulerBatchJob{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoSchedulerBatchJobInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerBatchJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoSchedulerBatchJobInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulerv1beta1.ArangoSchedulerBatchJob{}, f.defaultInformer) +} + +func (f *arangoSchedulerBatchJobInformer) Lister() v1beta1.ArangoSchedulerBatchJobLister { + return v1beta1.NewArangoSchedulerBatchJobLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulercronjob.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulercronjob.go new file mode 100644 index 000000000..59b27a269 --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulercronjob.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" +) + +// ArangoSchedulerCronJobInformer provides access to a shared informer and lister for +// ArangoSchedulerCronJobs. +type ArangoSchedulerCronJobInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoSchedulerCronJobLister +} + +type arangoSchedulerCronJobInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoSchedulerCronJobInformer constructs a new informer for ArangoSchedulerCronJob 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 NewArangoSchedulerCronJobInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerCronJobInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoSchedulerCronJobInformer constructs a new informer for ArangoSchedulerCronJob 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 NewFilteredArangoSchedulerCronJobInformer(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().ArangoSchedulerCronJobs(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoSchedulerCronJobs(namespace).Watch(context.TODO(), options) + }, + }, + &schedulerv1beta1.ArangoSchedulerCronJob{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoSchedulerCronJobInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerCronJobInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoSchedulerCronJobInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulerv1beta1.ArangoSchedulerCronJob{}, f.defaultInformer) +} + +func (f *arangoSchedulerCronJobInformer) Lister() v1beta1.ArangoSchedulerCronJobLister { + return v1beta1.NewArangoSchedulerCronJobLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerdeployment.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerdeployment.go new file mode 100644 index 000000000..214fe6e08 --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerdeployment.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" +) + +// ArangoSchedulerDeploymentInformer provides access to a shared informer and lister for +// ArangoSchedulerDeployments. +type ArangoSchedulerDeploymentInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoSchedulerDeploymentLister +} + +type arangoSchedulerDeploymentInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoSchedulerDeploymentInformer constructs a new informer for ArangoSchedulerDeployment 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 NewArangoSchedulerDeploymentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerDeploymentInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoSchedulerDeploymentInformer constructs a new informer for ArangoSchedulerDeployment 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 NewFilteredArangoSchedulerDeploymentInformer(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().ArangoSchedulerDeployments(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoSchedulerDeployments(namespace).Watch(context.TODO(), options) + }, + }, + &schedulerv1beta1.ArangoSchedulerDeployment{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoSchedulerDeploymentInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerDeploymentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoSchedulerDeploymentInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulerv1beta1.ArangoSchedulerDeployment{}, f.defaultInformer) +} + +func (f *arangoSchedulerDeploymentInformer) Lister() v1beta1.ArangoSchedulerDeploymentLister { + return v1beta1.NewArangoSchedulerDeploymentLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerpod.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerpod.go new file mode 100644 index 000000000..9c302b729 --- /dev/null +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/arangoschedulerpod.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" +) + +// ArangoSchedulerPodInformer provides access to a shared informer and lister for +// ArangoSchedulerPods. +type ArangoSchedulerPodInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.ArangoSchedulerPodLister +} + +type arangoSchedulerPodInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewArangoSchedulerPodInformer constructs a new informer for ArangoSchedulerPod 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 NewArangoSchedulerPodInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerPodInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredArangoSchedulerPodInformer constructs a new informer for ArangoSchedulerPod 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 NewFilteredArangoSchedulerPodInformer(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().ArangoSchedulerPods(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.SchedulerV1beta1().ArangoSchedulerPods(namespace).Watch(context.TODO(), options) + }, + }, + &schedulerv1beta1.ArangoSchedulerPod{}, + resyncPeriod, + indexers, + ) +} + +func (f *arangoSchedulerPodInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredArangoSchedulerPodInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *arangoSchedulerPodInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&schedulerv1beta1.ArangoSchedulerPod{}, f.defaultInformer) +} + +func (f *arangoSchedulerPodInformer) Lister() v1beta1.ArangoSchedulerPodLister { + return v1beta1.NewArangoSchedulerPodLister(f.Informer().GetIndexer()) +} diff --git a/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go b/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go index 1f5e0f743..94009ca55 100644 --- a/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go +++ b/pkg/generated/informers/externalversions/scheduler/v1beta1/interface.go @@ -30,6 +30,14 @@ import ( type Interface interface { // ArangoProfiles returns a ArangoProfileInformer. ArangoProfiles() ArangoProfileInformer + // ArangoSchedulerBatchJobs returns a ArangoSchedulerBatchJobInformer. + ArangoSchedulerBatchJobs() ArangoSchedulerBatchJobInformer + // ArangoSchedulerCronJobs returns a ArangoSchedulerCronJobInformer. + ArangoSchedulerCronJobs() ArangoSchedulerCronJobInformer + // ArangoSchedulerDeployments returns a ArangoSchedulerDeploymentInformer. + ArangoSchedulerDeployments() ArangoSchedulerDeploymentInformer + // ArangoSchedulerPods returns a ArangoSchedulerPodInformer. + ArangoSchedulerPods() ArangoSchedulerPodInformer } type version struct { @@ -47,3 +55,23 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList func (v *version) ArangoProfiles() ArangoProfileInformer { return &arangoProfileInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } + +// ArangoSchedulerBatchJobs returns a ArangoSchedulerBatchJobInformer. +func (v *version) ArangoSchedulerBatchJobs() ArangoSchedulerBatchJobInformer { + return &arangoSchedulerBatchJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ArangoSchedulerCronJobs returns a ArangoSchedulerCronJobInformer. +func (v *version) ArangoSchedulerCronJobs() ArangoSchedulerCronJobInformer { + return &arangoSchedulerCronJobInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ArangoSchedulerDeployments returns a ArangoSchedulerDeploymentInformer. +func (v *version) ArangoSchedulerDeployments() ArangoSchedulerDeploymentInformer { + return &arangoSchedulerDeploymentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + +// ArangoSchedulerPods returns a ArangoSchedulerPodInformer. +func (v *version) ArangoSchedulerPods() ArangoSchedulerPodInformer { + return &arangoSchedulerPodInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} diff --git a/pkg/generated/listers/scheduler/v1beta1/arangoschedulerbatchjob.go b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerbatchjob.go new file mode 100644 index 000000000..d2eb5f9a2 --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerbatchjob.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" +) + +// ArangoSchedulerBatchJobLister helps list ArangoSchedulerBatchJobs. +// All objects returned here must be treated as read-only. +type ArangoSchedulerBatchJobLister interface { + // List lists all ArangoSchedulerBatchJobs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerBatchJob, err error) + // ArangoSchedulerBatchJobs returns an object that can list and get ArangoSchedulerBatchJobs. + ArangoSchedulerBatchJobs(namespace string) ArangoSchedulerBatchJobNamespaceLister + ArangoSchedulerBatchJobListerExpansion +} + +// arangoSchedulerBatchJobLister implements the ArangoSchedulerBatchJobLister interface. +type arangoSchedulerBatchJobLister struct { + indexer cache.Indexer +} + +// NewArangoSchedulerBatchJobLister returns a new ArangoSchedulerBatchJobLister. +func NewArangoSchedulerBatchJobLister(indexer cache.Indexer) ArangoSchedulerBatchJobLister { + return &arangoSchedulerBatchJobLister{indexer: indexer} +} + +// List lists all ArangoSchedulerBatchJobs in the indexer. +func (s *arangoSchedulerBatchJobLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerBatchJob, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerBatchJob)) + }) + return ret, err +} + +// ArangoSchedulerBatchJobs returns an object that can list and get ArangoSchedulerBatchJobs. +func (s *arangoSchedulerBatchJobLister) ArangoSchedulerBatchJobs(namespace string) ArangoSchedulerBatchJobNamespaceLister { + return arangoSchedulerBatchJobNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoSchedulerBatchJobNamespaceLister helps list and get ArangoSchedulerBatchJobs. +// All objects returned here must be treated as read-only. +type ArangoSchedulerBatchJobNamespaceLister interface { + // List lists all ArangoSchedulerBatchJobs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerBatchJob, err error) + // Get retrieves the ArangoSchedulerBatchJob from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoSchedulerBatchJob, error) + ArangoSchedulerBatchJobNamespaceListerExpansion +} + +// arangoSchedulerBatchJobNamespaceLister implements the ArangoSchedulerBatchJobNamespaceLister +// interface. +type arangoSchedulerBatchJobNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoSchedulerBatchJobs in the indexer for a given namespace. +func (s arangoSchedulerBatchJobNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerBatchJob, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerBatchJob)) + }) + return ret, err +} + +// Get retrieves the ArangoSchedulerBatchJob from the indexer for a given namespace and name. +func (s arangoSchedulerBatchJobNamespaceLister) Get(name string) (*v1beta1.ArangoSchedulerBatchJob, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangoschedulerbatchjob"), name) + } + return obj.(*v1beta1.ArangoSchedulerBatchJob), nil +} diff --git a/pkg/generated/listers/scheduler/v1beta1/arangoschedulercronjob.go b/pkg/generated/listers/scheduler/v1beta1/arangoschedulercronjob.go new file mode 100644 index 000000000..cc4e86c97 --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/arangoschedulercronjob.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" +) + +// ArangoSchedulerCronJobLister helps list ArangoSchedulerCronJobs. +// All objects returned here must be treated as read-only. +type ArangoSchedulerCronJobLister interface { + // List lists all ArangoSchedulerCronJobs in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerCronJob, err error) + // ArangoSchedulerCronJobs returns an object that can list and get ArangoSchedulerCronJobs. + ArangoSchedulerCronJobs(namespace string) ArangoSchedulerCronJobNamespaceLister + ArangoSchedulerCronJobListerExpansion +} + +// arangoSchedulerCronJobLister implements the ArangoSchedulerCronJobLister interface. +type arangoSchedulerCronJobLister struct { + indexer cache.Indexer +} + +// NewArangoSchedulerCronJobLister returns a new ArangoSchedulerCronJobLister. +func NewArangoSchedulerCronJobLister(indexer cache.Indexer) ArangoSchedulerCronJobLister { + return &arangoSchedulerCronJobLister{indexer: indexer} +} + +// List lists all ArangoSchedulerCronJobs in the indexer. +func (s *arangoSchedulerCronJobLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerCronJob, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerCronJob)) + }) + return ret, err +} + +// ArangoSchedulerCronJobs returns an object that can list and get ArangoSchedulerCronJobs. +func (s *arangoSchedulerCronJobLister) ArangoSchedulerCronJobs(namespace string) ArangoSchedulerCronJobNamespaceLister { + return arangoSchedulerCronJobNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoSchedulerCronJobNamespaceLister helps list and get ArangoSchedulerCronJobs. +// All objects returned here must be treated as read-only. +type ArangoSchedulerCronJobNamespaceLister interface { + // List lists all ArangoSchedulerCronJobs in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerCronJob, err error) + // Get retrieves the ArangoSchedulerCronJob from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoSchedulerCronJob, error) + ArangoSchedulerCronJobNamespaceListerExpansion +} + +// arangoSchedulerCronJobNamespaceLister implements the ArangoSchedulerCronJobNamespaceLister +// interface. +type arangoSchedulerCronJobNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoSchedulerCronJobs in the indexer for a given namespace. +func (s arangoSchedulerCronJobNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerCronJob, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerCronJob)) + }) + return ret, err +} + +// Get retrieves the ArangoSchedulerCronJob from the indexer for a given namespace and name. +func (s arangoSchedulerCronJobNamespaceLister) Get(name string) (*v1beta1.ArangoSchedulerCronJob, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangoschedulercronjob"), name) + } + return obj.(*v1beta1.ArangoSchedulerCronJob), nil +} diff --git a/pkg/generated/listers/scheduler/v1beta1/arangoschedulerdeployment.go b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerdeployment.go new file mode 100644 index 000000000..227ad243d --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerdeployment.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" +) + +// ArangoSchedulerDeploymentLister helps list ArangoSchedulerDeployments. +// All objects returned here must be treated as read-only. +type ArangoSchedulerDeploymentLister interface { + // List lists all ArangoSchedulerDeployments in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerDeployment, err error) + // ArangoSchedulerDeployments returns an object that can list and get ArangoSchedulerDeployments. + ArangoSchedulerDeployments(namespace string) ArangoSchedulerDeploymentNamespaceLister + ArangoSchedulerDeploymentListerExpansion +} + +// arangoSchedulerDeploymentLister implements the ArangoSchedulerDeploymentLister interface. +type arangoSchedulerDeploymentLister struct { + indexer cache.Indexer +} + +// NewArangoSchedulerDeploymentLister returns a new ArangoSchedulerDeploymentLister. +func NewArangoSchedulerDeploymentLister(indexer cache.Indexer) ArangoSchedulerDeploymentLister { + return &arangoSchedulerDeploymentLister{indexer: indexer} +} + +// List lists all ArangoSchedulerDeployments in the indexer. +func (s *arangoSchedulerDeploymentLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerDeployment, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerDeployment)) + }) + return ret, err +} + +// ArangoSchedulerDeployments returns an object that can list and get ArangoSchedulerDeployments. +func (s *arangoSchedulerDeploymentLister) ArangoSchedulerDeployments(namespace string) ArangoSchedulerDeploymentNamespaceLister { + return arangoSchedulerDeploymentNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoSchedulerDeploymentNamespaceLister helps list and get ArangoSchedulerDeployments. +// All objects returned here must be treated as read-only. +type ArangoSchedulerDeploymentNamespaceLister interface { + // List lists all ArangoSchedulerDeployments in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerDeployment, err error) + // Get retrieves the ArangoSchedulerDeployment from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoSchedulerDeployment, error) + ArangoSchedulerDeploymentNamespaceListerExpansion +} + +// arangoSchedulerDeploymentNamespaceLister implements the ArangoSchedulerDeploymentNamespaceLister +// interface. +type arangoSchedulerDeploymentNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoSchedulerDeployments in the indexer for a given namespace. +func (s arangoSchedulerDeploymentNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerDeployment, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerDeployment)) + }) + return ret, err +} + +// Get retrieves the ArangoSchedulerDeployment from the indexer for a given namespace and name. +func (s arangoSchedulerDeploymentNamespaceLister) Get(name string) (*v1beta1.ArangoSchedulerDeployment, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangoschedulerdeployment"), name) + } + return obj.(*v1beta1.ArangoSchedulerDeployment), nil +} diff --git a/pkg/generated/listers/scheduler/v1beta1/arangoschedulerpod.go b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerpod.go new file mode 100644 index 000000000..40de6ef0f --- /dev/null +++ b/pkg/generated/listers/scheduler/v1beta1/arangoschedulerpod.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" +) + +// ArangoSchedulerPodLister helps list ArangoSchedulerPods. +// All objects returned here must be treated as read-only. +type ArangoSchedulerPodLister interface { + // List lists all ArangoSchedulerPods in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerPod, err error) + // ArangoSchedulerPods returns an object that can list and get ArangoSchedulerPods. + ArangoSchedulerPods(namespace string) ArangoSchedulerPodNamespaceLister + ArangoSchedulerPodListerExpansion +} + +// arangoSchedulerPodLister implements the ArangoSchedulerPodLister interface. +type arangoSchedulerPodLister struct { + indexer cache.Indexer +} + +// NewArangoSchedulerPodLister returns a new ArangoSchedulerPodLister. +func NewArangoSchedulerPodLister(indexer cache.Indexer) ArangoSchedulerPodLister { + return &arangoSchedulerPodLister{indexer: indexer} +} + +// List lists all ArangoSchedulerPods in the indexer. +func (s *arangoSchedulerPodLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerPod, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerPod)) + }) + return ret, err +} + +// ArangoSchedulerPods returns an object that can list and get ArangoSchedulerPods. +func (s *arangoSchedulerPodLister) ArangoSchedulerPods(namespace string) ArangoSchedulerPodNamespaceLister { + return arangoSchedulerPodNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// ArangoSchedulerPodNamespaceLister helps list and get ArangoSchedulerPods. +// All objects returned here must be treated as read-only. +type ArangoSchedulerPodNamespaceLister interface { + // List lists all ArangoSchedulerPods in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerPod, err error) + // Get retrieves the ArangoSchedulerPod from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.ArangoSchedulerPod, error) + ArangoSchedulerPodNamespaceListerExpansion +} + +// arangoSchedulerPodNamespaceLister implements the ArangoSchedulerPodNamespaceLister +// interface. +type arangoSchedulerPodNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all ArangoSchedulerPods in the indexer for a given namespace. +func (s arangoSchedulerPodNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.ArangoSchedulerPod, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.ArangoSchedulerPod)) + }) + return ret, err +} + +// Get retrieves the ArangoSchedulerPod from the indexer for a given namespace and name. +func (s arangoSchedulerPodNamespaceLister) Get(name string) (*v1beta1.ArangoSchedulerPod, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("arangoschedulerpod"), name) + } + return obj.(*v1beta1.ArangoSchedulerPod), nil +} diff --git a/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go b/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go index accfa66ce..5a7a420fc 100644 --- a/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go +++ b/pkg/generated/listers/scheduler/v1beta1/expansion_generated.go @@ -29,3 +29,35 @@ type ArangoProfileListerExpansion interface{} // ArangoProfileNamespaceListerExpansion allows custom methods to be added to // ArangoProfileNamespaceLister. type ArangoProfileNamespaceListerExpansion interface{} + +// ArangoSchedulerBatchJobListerExpansion allows custom methods to be added to +// ArangoSchedulerBatchJobLister. +type ArangoSchedulerBatchJobListerExpansion interface{} + +// ArangoSchedulerBatchJobNamespaceListerExpansion allows custom methods to be added to +// ArangoSchedulerBatchJobNamespaceLister. +type ArangoSchedulerBatchJobNamespaceListerExpansion interface{} + +// ArangoSchedulerCronJobListerExpansion allows custom methods to be added to +// ArangoSchedulerCronJobLister. +type ArangoSchedulerCronJobListerExpansion interface{} + +// ArangoSchedulerCronJobNamespaceListerExpansion allows custom methods to be added to +// ArangoSchedulerCronJobNamespaceLister. +type ArangoSchedulerCronJobNamespaceListerExpansion interface{} + +// ArangoSchedulerDeploymentListerExpansion allows custom methods to be added to +// ArangoSchedulerDeploymentLister. +type ArangoSchedulerDeploymentListerExpansion interface{} + +// ArangoSchedulerDeploymentNamespaceListerExpansion allows custom methods to be added to +// ArangoSchedulerDeploymentNamespaceLister. +type ArangoSchedulerDeploymentNamespaceListerExpansion interface{} + +// ArangoSchedulerPodListerExpansion allows custom methods to be added to +// ArangoSchedulerPodLister. +type ArangoSchedulerPodListerExpansion interface{} + +// ArangoSchedulerPodNamespaceListerExpansion allows custom methods to be added to +// ArangoSchedulerPodNamespaceLister. +type ArangoSchedulerPodNamespaceListerExpansion interface{} diff --git a/pkg/handlers/generic/parent/parent.go b/pkg/handlers/generic/parent/parent.go new file mode 100644 index 000000000..cb72e56e3 --- /dev/null +++ b/pkg/handlers/generic/parent/parent.go @@ -0,0 +1,114 @@ +// +// 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 parent + +import ( + "context" + + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/logging" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" +) + +var logger = logging.Global().RegisterAndGetLogger("generic-parent-operator", logging.Info) + +type NotifyHandlerClientFactory[T meta.Object, C NotifyHandlerClient[T]] func(namespace string) C + +type NotifyHandlerClient[T meta.Object] interface { + generic.GetInterface[T] +} + +func NewNotifyHandler[T meta.Object, C NotifyHandlerClient[T]](name string, operator operator.Operator, client NotifyHandlerClientFactory[T, C], gvk schema.GroupVersionKind, notifiable ...schema.GroupVersionKind) operator.Handler { + return notifyHandler[T, C]{ + name: name, + client: client, + gvk: gvk, + operator: operator, + notifiable: notifiable, + } +} + +type notifyHandler[T meta.Object, C NotifyHandlerClient[T]] struct { + operator operator.Operator + name string + client NotifyHandlerClientFactory[T, C] + gvk schema.GroupVersionKind + notifiable []schema.GroupVersionKind +} + +func (p notifyHandler[T, C]) Name() string { + return p.name +} + +func (p notifyHandler[T, C]) Handle(ctx context.Context, item operation.Item) error { + logger := logger.WrapObj(item) + if item.Operation == operation.Update { + obj, err := p.client(item.Namespace).Get(ctx, item.Name, meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + logger.Debug("Not Found") + return nil + } + logger.Err(err).Warn("Unexpected Error") + return err + } + + for _, owner := range obj.GetOwnerReferences() { + if i, err := operation.NewItemFromGVKObject(item.Operation, schema.FromAPIVersionAndKind(owner.APIVersion, owner.Kind), obj); err == nil { + if p.isNotifiable(i) { + logger.Debug("Parent notified") + p.operator.EnqueueItem(i) + } else { + logger.Debug("Parent notify skipped") + } + } + } + } + + return nil +} + +func (p notifyHandler[T, C]) isNotifiable(i operation.Item) bool { + for _, g := range p.notifiable { + if version := g.Version; version != "" && version != i.Version { + continue + } + if kind := g.Kind; kind != "" && kind != i.Kind { + continue + } + if group := g.Group; group != "" && group != i.Group { + continue + } + + return true + } + + return false +} + +func (p notifyHandler[T, C]) CanBeHandled(item operation.Item) bool { + return item.GVK(p.gvk) +} diff --git a/pkg/handlers/scheduler/batchjob/handler.go b/pkg/handlers/scheduler/batchjob/handler.go new file mode 100644 index 000000000..57b1b42c1 --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/handler.go @@ -0,0 +1,228 @@ +// +// 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 batchjob + +import ( + "context" + "fmt" + + batch "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/equality" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/patch" + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + "github.com/arangodb/kube-arangodb/pkg/logging" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher" +) + +var logger = logging.Global().RegisterAndGetLogger("scheduler-batchjob-operator", logging.Info) + +type handler struct { + client arangoClientSet.Interface + kubeClient kubernetes.Interface + + eventRecorder event.RecorderInstance + + operator operator.Operator +} + +func (h *handler) Name() string { + return Kind() +} + +func (h *handler) Handle(ctx context.Context, item operation.Item) error { + // Get Backup object. It also covers NotFound case + + object, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.SchedulerV1beta1().ArangoSchedulerBatchJobs(item.Namespace).Get, item.Name, meta.GetOptions{}) + if err != nil { + if apiErrors.IsNotFound(err) { + return nil + } + + return err + } + + status := object.Status.DeepCopy() + + changed, reconcileErr := operator.HandleP3WithStop(ctx, item, object, status, h.handle) + if reconcileErr != nil && !operator.IsReconcile(reconcileErr) { + logger.Err(reconcileErr).Warn("Fail for %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + return reconcileErr + } + + if !changed { + return reconcileErr + } + + logger.Debug("Updating %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + if _, err := operator.WithSchedulerBatchJobUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoSchedulerBatchJobs(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { + return err + } + + return reconcileErr +} + +func (h *handler) handle(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerBatchJob, status *schedulerApi.ArangoSchedulerBatchJobStatus) (bool, error) { + return operator.HandleP3(ctx, item, extension, status, h.HandleObject) +} + +func (h *handler) HandleObject(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerBatchJob, status *schedulerApi.ArangoSchedulerBatchJobStatus) (bool, error) { + calculatedProfiles, profilesChecksum, err := scheduler.Profiles(ctx, h.client.SchedulerV1beta1().ArangoProfiles(extension.GetNamespace()), extension.GetLabels(), extension.Spec.Profiles...) + if err != nil { + return false, err + } + + var batchJobTemplate batch.Job + batchJobTemplate.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + + extension.Spec.JobSpec.DeepCopyInto(&batchJobTemplate.Spec) + + deploymentSpecHash, err := util.SHA256FromJSON(batchJobTemplate) + if err != nil { + return false, err + } + + hash := util.SHA256FromString(fmt.Sprintf("%s|%s", profilesChecksum, deploymentSpecHash)) + + if err := schedulerApi.ProfileTemplates(util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) *schedulerApi.ProfileTemplate { + return a.V.Template + })).RenderOnTemplate(&batchJobTemplate.Spec.Template); err != nil { + return false, err + } + + if status.Object == nil { + // Create + + obj := &batch.Job{} + obj.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + batchJobTemplate.Spec.DeepCopyInto(&obj.Spec) + + obj.OwnerReferences = append(obj.OwnerReferences, extension.AsOwner()) + + newObj, err := h.kubeClient.BatchV1().Jobs(extension.GetNamespace()).Create(ctx, obj, meta.CreateOptions{}) + if err != nil { + h.eventRecorder.Warning(extension, "Create Failed", "Unable to create Job: %s", err.Error()) + return false, err + } + + h.eventRecorder.Normal(extension, "Created", "Job %s created", newObj.GetName()) + + status.Object = util.NewType(sharedApi.NewObjectWithChecksum(newObj, hash)) + return true, operator.Reconcile("Job Reference Changed") + } + + // Find existing + obj, err := h.kubeClient.BatchV1().Jobs(status.Object.GetNamespace(extension)).Get(ctx, status.Object.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + // Object removed + h.eventRecorder.Warning(extension, "Removed", "Job %s is gone", status.Object.GetName()) + status.Object = nil + return true, operator.Reconcile("Job Reference Removed") + } + return false, err + } + + profileNames := util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) string { + return a.K + }) + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.Profiles, profileNames) { + status.Profiles = profileNames + return true, operator.Reconcile("Status Changed") + } + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.JobStatus, obj.Status) { + obj.Status.DeepCopyInto(&status.JobStatus) + return true, operator.Reconcile("Status Changed") + } + + if obj.GetDeletionTimestamp() != nil { + // Object is deleting, check later + return false, operator.Reconcile("Job Deleting") + } + + if !status.Object.Equals(obj) { + // Object changed or was recreated + h.eventRecorder.Warning(extension, "Removed", "Job %s reference is invalid", status.Object.GetName()) + if err := h.kubeClient.BatchV1().Jobs(status.Object.GetNamespace(extension)).Delete(ctx, status.Object.GetName(), meta.DeleteOptions{}); err != nil { + return false, err + } + + return false, operator.Reconcile("Job Deleted") + } + + // Object is equal, lets check if changed + if hash != status.Object.GetChecksum() { + // Checksum changed, lets apply changes + _, _, err := patcher.Patcher[*batch.Job](ctx, h.kubeClient.BatchV1().Jobs(status.Object.GetNamespace(extension)), obj, meta.PatchOptions{}, func(in *batch.Job) []patch.Item { + return []patch.Item{ + patch.ItemReplace(patch.NewPath("spec"), batchJobTemplate.Spec), + } + }, patcher.PatchMetadata(obj)) + if err != nil { + h.eventRecorder.Warning(extension, "Patch Failed", "Unable to patch Job: %s", err.Error()) + return false, err + } + h.eventRecorder.Normal(extension, "Updated", "Job %s patched", obj.GetName()) + status.Object.Checksum = util.NewType(hash) + return true, nil + } + + return false, nil +} + +func (h *handler) CanBeHandled(item operation.Item) bool { + return item.Group == Group() && + item.Version == Version() && + item.Kind == Kind() +} + +func (h *handler) init() {} diff --git a/pkg/handlers/scheduler/batchjob/handler_manage_test.go b/pkg/handlers/scheduler/batchjob/handler_manage_test.go new file mode 100644 index 000000000..ccd96c49c --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/handler_manage_test.go @@ -0,0 +1,230 @@ +// +// 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 batchjob + +import ( + "testing" + + "github.com/stretchr/testify/require" + batch "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/types" + + 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" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_Handler_Create(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c12919994bb3b13dfc1cd7903bd2020a4da93064d93b068171d1567a203c62c4", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Update(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c12919994bb3b13dfc1cd7903bd2020a4da93064d93b068171d1567a203c62c4", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) { + obj.Spec.Completions = util.NewType[int32](2) + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "65257e9b53283da2bfc00caeca08eee9cfbc465a3032119cb95c113efdf62b25", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Recreate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c12919994bb3b13dfc1cd7903bd2020a4da93064d93b068171d1567a203c62c4", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) { + obj.Status.Object.UID = util.NewType[types.UID]("TEST") + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c12919994bb3b13dfc1cd7903bd2020a4da93064d93b068171d1567a203c62c4", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Parent(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) {}) + batchJob := tests.NewMetaObject[*batch.Job](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &batchJob) + + require.Len(t, batchJob.OwnerReferences, 1) +} + +func Test_Handler_Propagate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) {}) + batchJob := tests.NewMetaObject[*batch.Job](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &batchJob) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c12919994bb3b13dfc1cd7903bd2020a4da93064d93b068171d1567a203c62c4", extension.Status.Object.GetChecksum()) + require.Nil(t, batchJob.Spec.Completions) + require.EqualValues(t, 0, extension.Status.Active) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) { + obj.Spec.Completions = util.NewType[int32](2) + }) + tests.Apply(t, batchJob, func(t *testing.T, obj *batch.Job) { + obj.Status.Active = 1 + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension, &batchJob) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &batchJob) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "65257e9b53283da2bfc00caeca08eee9cfbc465a3032119cb95c113efdf62b25", extension.Status.Object.GetChecksum()) + require.NotNil(t, batchJob.Spec.Completions) + require.EqualValues(t, 2, *batchJob.Spec.Completions) + require.EqualValues(t, 1, extension.Status.Active) +} + +func Test_Handler_Profile(t *testing.T) { + handler := newFakeHandler() + + // Arrange + profile := tests.NewMetaObject[*schedulerApi.ArangoProfile](t, tests.FakeNamespace, "test", tests.MarkArangoProfileAsReady) + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerBatchJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerBatchJob) { + obj.Spec.Profiles = []string{profile.GetName()} + }) + batchJob := tests.NewMetaObject[*batch.Job](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.EqualError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)), "Profile with name `test` is missing") + + tests.CreateObjects(t, handler.kubeClient, handler.client, &profile) + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &batchJob) + require.NotNil(t, batchJob) + + require.Len(t, extension.Status.Profiles, 1) + require.Equal(t, profile.GetName(), extension.Status.Profiles[0]) +} diff --git a/pkg/handlers/scheduler/batchjob/handler_test.go b/pkg/handlers/scheduler/batchjob/handler_test.go new file mode 100644 index 000000000..e5ef5638e --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/handler_test.go @@ -0,0 +1,59 @@ +// +// 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 batchjob + +import ( + "testing" + + "github.com/stretchr/testify/require" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_ObjectNotFound(t *testing.T) { + // Arrange + handler := newFakeHandler() + + i := newItem(operation.Add, "test", "test") + + actions := map[operation.Operation]bool{ + operation.Add: false, + operation.Update: false, + operation.Delete: false, + } + + // Act + for op, shouldFail := range actions { + t.Run(string(op), func(t *testing.T) { + err := tests.Handle(handler, i) + + // Assert + if shouldFail { + require.Error(t, err) + require.True(t, apiErrors.IsNotFound(err)) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/handlers/scheduler/batchjob/local.go b/pkg/handlers/scheduler/batchjob/local.go new file mode 100644 index 000000000..3f63dfa2f --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/local.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 +// + +package batchjob + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" +) + +func GVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: Group(), + Version: Version(), + Kind: Kind(), + } +} + +func Kind() string { + return scheduler.BatchJobResourceKind +} + +func Group() string { + return schedulerApi.SchemeGroupVersion.Group +} + +func Version() string { + return schedulerApi.SchemeGroupVersion.Version +} diff --git a/pkg/handlers/scheduler/batchjob/register.go b/pkg/handlers/scheduler/batchjob/register.go new file mode 100644 index 000000000..b5156a5c1 --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/register.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 batchjob + +import ( + batch "k8s.io/api/batch/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions" + "github.com/arangodb/kube-arangodb/pkg/handlers/generic/parent" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" +) + +// RegisterInformer into operator +func RegisterInformer(operator operator.Operator, recorder event.Recorder, client arangoClientSet.Interface, + kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) error { + + if err := operator.RegisterInformer(informer.Scheduler().V1beta1().ArangoSchedulerBatchJobs().Informer(), + Group(), + Version(), + Kind()); err != nil { + return err + } + + h := &handler{ + client: client, + kubeClient: kubeClient, + + eventRecorder: recorder.NewInstance(Group(), Version(), Kind()), + + operator: operator, + } + + h.init() + + if err := operator.RegisterHandler(h); err != nil { + return err + } + + { + batchJob := k8sutil.BatchV1JobGVK() + + if err := operator.RegisterInformer(kubeInformer.Batch().V1().Jobs().Informer(), + batchJob.Group, + batchJob.Version, + batchJob.Kind); err != nil { + return err + } + + batchJobHandler := parent.NewNotifyHandler[*batch.Job]("batch-job-v1-parent", operator, kubeClient.BatchV1().Jobs, batchJob, GVK()) + + if err := operator.RegisterHandler(batchJobHandler); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/handlers/scheduler/batchjob/suite_test.go b/pkg/handlers/scheduler/batchjob/suite_test.go new file mode 100644 index 000000000..749aa5009 --- /dev/null +++ b/pkg/handlers/scheduler/batchjob/suite_test.go @@ -0,0 +1,61 @@ +// +// 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 batchjob + +import ( + "k8s.io/client-go/kubernetes/fake" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + fakeClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" +) + +func newFakeHandler() *handler { + f := fakeClientSet.NewSimpleClientset() + k := fake.NewSimpleClientset() + + h := &handler{ + client: f, + kubeClient: k, + eventRecorder: event.NewEventRecorder("mock", k).NewInstance(Group(), Version(), Kind()), + operator: operator.NewOperator("mock", "mock", "mock"), + } + + h.init() + + return h +} + +func newItem(o operation.Operation, namespace, name string) operation.Item { + return operation.Item{ + Group: schedulerApi.SchemeGroupVersion.Group, + Version: schedulerApi.SchemeGroupVersion.Version, + Kind: scheduler.BatchJobResourceKind, + + Operation: o, + + Namespace: namespace, + Name: name, + } +} diff --git a/pkg/handlers/scheduler/cronjob/handler.go b/pkg/handlers/scheduler/cronjob/handler.go new file mode 100644 index 000000000..9666bf9d7 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/handler.go @@ -0,0 +1,228 @@ +// +// 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 cronjob + +import ( + "context" + "fmt" + + batch "k8s.io/api/batch/v1" + "k8s.io/apimachinery/pkg/api/equality" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/patch" + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + "github.com/arangodb/kube-arangodb/pkg/logging" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher" +) + +var logger = logging.Global().RegisterAndGetLogger("scheduler-cronjob-operator", logging.Info) + +type handler struct { + client arangoClientSet.Interface + kubeClient kubernetes.Interface + + eventRecorder event.RecorderInstance + + operator operator.Operator +} + +func (h *handler) Name() string { + return Kind() +} + +func (h *handler) Handle(ctx context.Context, item operation.Item) error { + // Get Backup object. It also covers NotFound case + + object, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.SchedulerV1beta1().ArangoSchedulerCronJobs(item.Namespace).Get, item.Name, meta.GetOptions{}) + if err != nil { + if apiErrors.IsNotFound(err) { + return nil + } + + return err + } + + status := object.Status.DeepCopy() + + changed, reconcileErr := operator.HandleP3WithStop(ctx, item, object, status, h.handle) + if reconcileErr != nil && !operator.IsReconcile(reconcileErr) { + logger.Err(reconcileErr).Warn("Fail for %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + return reconcileErr + } + + if !changed { + return reconcileErr + } + + logger.Debug("Updating %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + if _, err := operator.WithSchedulerCronJobUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoSchedulerCronJobs(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { + return err + } + + return reconcileErr +} + +func (h *handler) handle(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerCronJob, status *schedulerApi.ArangoSchedulerCronJobStatus) (bool, error) { + return operator.HandleP3(ctx, item, extension, status, h.HandleObject) +} + +func (h *handler) HandleObject(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerCronJob, status *schedulerApi.ArangoSchedulerCronJobStatus) (bool, error) { + calculatedProfiles, profilesChecksum, err := scheduler.Profiles(ctx, h.client.SchedulerV1beta1().ArangoProfiles(extension.GetNamespace()), extension.GetLabels(), extension.Spec.Profiles...) + if err != nil { + return false, err + } + + var cronJobTemplate batch.CronJob + cronJobTemplate.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + + extension.Spec.CronJobSpec.DeepCopyInto(&cronJobTemplate.Spec) + + deploymentSpecHash, err := util.SHA256FromJSON(cronJobTemplate) + if err != nil { + return false, err + } + + hash := util.SHA256FromString(fmt.Sprintf("%s|%s", profilesChecksum, deploymentSpecHash)) + + if err := schedulerApi.ProfileTemplates(util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) *schedulerApi.ProfileTemplate { + return a.V.Template + })).RenderOnTemplate(&cronJobTemplate.Spec.JobTemplate.Spec.Template); err != nil { + return false, err + } + + if status.Object == nil { + // Create + + obj := &batch.CronJob{} + obj.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + cronJobTemplate.Spec.DeepCopyInto(&obj.Spec) + + obj.OwnerReferences = append(obj.OwnerReferences, extension.AsOwner()) + + newObj, err := h.kubeClient.BatchV1().CronJobs(extension.GetNamespace()).Create(ctx, obj, meta.CreateOptions{}) + if err != nil { + h.eventRecorder.Warning(extension, "Create Failed", "Unable to create CronJob: %s", err.Error()) + return false, err + } + + h.eventRecorder.Normal(extension, "Created", "CronJob %s created", newObj.GetName()) + + status.Object = util.NewType(sharedApi.NewObjectWithChecksum(newObj, hash)) + return true, operator.Reconcile("Job Reference Changed") + } + + // Find existing + obj, err := h.kubeClient.BatchV1().CronJobs(status.Object.GetNamespace(extension)).Get(ctx, status.Object.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + // Object removed + h.eventRecorder.Warning(extension, "Removed", "CronJob %s is gone", status.Object.GetName()) + status.Object = nil + return true, operator.Reconcile("CronJob Reference Removed") + } + return false, err + } + + profileNames := util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) string { + return a.K + }) + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.Profiles, profileNames) { + status.Profiles = profileNames + return true, operator.Reconcile("Status Changed") + } + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.CronJobStatus, obj.Status) { + obj.Status.DeepCopyInto(&status.CronJobStatus) + return true, operator.Reconcile("Status Changed") + } + + if obj.GetDeletionTimestamp() != nil { + // Object is deleting, check later + return false, operator.Reconcile("Job Deleting") + } + + if !status.Object.Equals(obj) { + // Object changed or was recreated + h.eventRecorder.Warning(extension, "Removed", "CronJob %s reference is invalid", status.Object.GetName()) + if err := h.kubeClient.BatchV1().CronJobs(status.Object.GetNamespace(extension)).Delete(ctx, status.Object.GetName(), meta.DeleteOptions{}); err != nil { + return false, err + } + + return false, operator.Reconcile("CronJob Deleted") + } + + // Object is equal, lets check if changed + if hash != status.Object.GetChecksum() { + // Checksum changed, lets apply changes + _, _, err := patcher.Patcher[*batch.CronJob](ctx, h.kubeClient.BatchV1().CronJobs(status.Object.GetNamespace(extension)), obj, meta.PatchOptions{}, func(in *batch.CronJob) []patch.Item { + return []patch.Item{ + patch.ItemReplace(patch.NewPath("spec"), cronJobTemplate.Spec), + } + }, patcher.PatchMetadata(obj)) + if err != nil { + h.eventRecorder.Warning(extension, "Patch Failed", "Unable to patch CronJob: %s", err.Error()) + return false, err + } + h.eventRecorder.Normal(extension, "Updated", "CronJob %s patched", obj.GetName()) + status.Object.Checksum = util.NewType(hash) + return true, nil + } + + return false, nil +} + +func (h *handler) CanBeHandled(item operation.Item) bool { + return item.Group == Group() && + item.Version == Version() && + item.Kind == Kind() +} + +func (h *handler) init() {} diff --git a/pkg/handlers/scheduler/cronjob/handler_manage_test.go b/pkg/handlers/scheduler/cronjob/handler_manage_test.go new file mode 100644 index 000000000..811b03994 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/handler_manage_test.go @@ -0,0 +1,231 @@ +// +// 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 cronjob + +import ( + "testing" + + "github.com/stretchr/testify/require" + batch "k8s.io/api/batch/v1" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + + 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" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_Handler_Create(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "2f9e4c718f8bf1f0880e64aa44c10142acb59ca88a4c08d89ab7daadc93b115e", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Update(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "2f9e4c718f8bf1f0880e64aa44c10142acb59ca88a4c08d89ab7daadc93b115e", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) { + obj.Spec.StartingDeadlineSeconds = util.NewType[int64](2) + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "5411ac008bce56d38b0d0e36d8bbbbb904c02c01dc3e8052f4467d6f24f9c7b5", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Recreate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "2f9e4c718f8bf1f0880e64aa44c10142acb59ca88a4c08d89ab7daadc93b115e", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) { + obj.Status.Object.UID = util.NewType[types.UID]("TEST") + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "2f9e4c718f8bf1f0880e64aa44c10142acb59ca88a4c08d89ab7daadc93b115e", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Parent(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) {}) + cronJob := tests.NewMetaObject[*batch.CronJob](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &cronJob) + + require.Len(t, cronJob.OwnerReferences, 1) +} + +func Test_Handler_Propagate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) {}) + cronJob := tests.NewMetaObject[*batch.CronJob](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &cronJob) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "2f9e4c718f8bf1f0880e64aa44c10142acb59ca88a4c08d89ab7daadc93b115e", extension.Status.Object.GetChecksum()) + require.Nil(t, cronJob.Spec.StartingDeadlineSeconds) + require.Len(t, extension.Status.Active, 0) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) { + obj.Spec.StartingDeadlineSeconds = util.NewType[int64](2) + }) + tests.Apply(t, cronJob, func(t *testing.T, obj *batch.CronJob) { + obj.Status.Active = []core.ObjectReference{{}} + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension, &cronJob) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &cronJob) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "5411ac008bce56d38b0d0e36d8bbbbb904c02c01dc3e8052f4467d6f24f9c7b5", extension.Status.Object.GetChecksum()) + require.NotNil(t, cronJob.Spec.StartingDeadlineSeconds) + require.EqualValues(t, 2, *cronJob.Spec.StartingDeadlineSeconds) + require.Len(t, extension.Status.Active, 1) +} + +func Test_Handler_Profile(t *testing.T) { + handler := newFakeHandler() + + // Arrange + profile := tests.NewMetaObject[*schedulerApi.ArangoProfile](t, tests.FakeNamespace, "test", tests.MarkArangoProfileAsReady) + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerCronJob](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerCronJob) { + obj.Spec.Profiles = []string{profile.GetName()} + }) + cronJob := tests.NewMetaObject[*batch.CronJob](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.EqualError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)), "Profile with name `test` is missing") + + tests.CreateObjects(t, handler.kubeClient, handler.client, &profile) + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &cronJob) + require.NotNil(t, cronJob) + + require.Len(t, extension.Status.Profiles, 1) + require.Equal(t, profile.GetName(), extension.Status.Profiles[0]) +} diff --git a/pkg/handlers/scheduler/cronjob/handler_test.go b/pkg/handlers/scheduler/cronjob/handler_test.go new file mode 100644 index 000000000..5af91bf46 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/handler_test.go @@ -0,0 +1,59 @@ +// +// 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 cronjob + +import ( + "testing" + + "github.com/stretchr/testify/require" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_ObjectNotFound(t *testing.T) { + // Arrange + handler := newFakeHandler() + + i := newItem(operation.Add, "test", "test") + + actions := map[operation.Operation]bool{ + operation.Add: false, + operation.Update: false, + operation.Delete: false, + } + + // Act + for op, shouldFail := range actions { + t.Run(string(op), func(t *testing.T) { + err := tests.Handle(handler, i) + + // Assert + if shouldFail { + require.Error(t, err) + require.True(t, apiErrors.IsNotFound(err)) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/handlers/scheduler/cronjob/local.go b/pkg/handlers/scheduler/cronjob/local.go new file mode 100644 index 000000000..4f7bd9c44 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/local.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 +// + +package cronjob + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" +) + +func GVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: Group(), + Version: Version(), + Kind: Kind(), + } +} + +func Kind() string { + return scheduler.CronJobResourceKind +} + +func Group() string { + return schedulerApi.SchemeGroupVersion.Group +} + +func Version() string { + return schedulerApi.SchemeGroupVersion.Version +} diff --git a/pkg/handlers/scheduler/cronjob/register.go b/pkg/handlers/scheduler/cronjob/register.go new file mode 100644 index 000000000..51a868486 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/register.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 cronjob + +import ( + batch "k8s.io/api/batch/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions" + "github.com/arangodb/kube-arangodb/pkg/handlers/generic/parent" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" +) + +// RegisterInformer into operator +func RegisterInformer(operator operator.Operator, recorder event.Recorder, client arangoClientSet.Interface, + kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) error { + + if err := operator.RegisterInformer(informer.Scheduler().V1beta1().ArangoSchedulerCronJobs().Informer(), + Group(), + Version(), + Kind()); err != nil { + return err + } + + h := &handler{ + client: client, + kubeClient: kubeClient, + + eventRecorder: recorder.NewInstance(Group(), Version(), Kind()), + + operator: operator, + } + + h.init() + + if err := operator.RegisterHandler(h); err != nil { + return err + } + + { + cronJob := k8sutil.BatchV1CronJobGVK() + + if err := operator.RegisterInformer(kubeInformer.Batch().V1().CronJobs().Informer(), + cronJob.Group, + cronJob.Version, + cronJob.Kind); err != nil { + return err + } + + cronJobHandler := parent.NewNotifyHandler[*batch.CronJob]("batch-cronjob-v1-parent", operator, kubeClient.BatchV1().CronJobs, cronJob, GVK()) + + if err := operator.RegisterHandler(cronJobHandler); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/handlers/scheduler/cronjob/suite_test.go b/pkg/handlers/scheduler/cronjob/suite_test.go new file mode 100644 index 000000000..5be3356c0 --- /dev/null +++ b/pkg/handlers/scheduler/cronjob/suite_test.go @@ -0,0 +1,61 @@ +// +// 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 cronjob + +import ( + "k8s.io/client-go/kubernetes/fake" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + fakeClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" +) + +func newFakeHandler() *handler { + f := fakeClientSet.NewSimpleClientset() + k := fake.NewSimpleClientset() + + h := &handler{ + client: f, + kubeClient: k, + eventRecorder: event.NewEventRecorder("mock", k).NewInstance(Group(), Version(), Kind()), + operator: operator.NewOperator("mock", "mock", "mock"), + } + + h.init() + + return h +} + +func newItem(o operation.Operation, namespace, name string) operation.Item { + return operation.Item{ + Group: schedulerApi.SchemeGroupVersion.Group, + Version: schedulerApi.SchemeGroupVersion.Version, + Kind: scheduler.CronJobResourceKind, + + Operation: o, + + Namespace: namespace, + Name: name, + } +} diff --git a/pkg/handlers/scheduler/deployment/handler.go b/pkg/handlers/scheduler/deployment/handler.go new file mode 100644 index 000000000..05828f1df --- /dev/null +++ b/pkg/handlers/scheduler/deployment/handler.go @@ -0,0 +1,229 @@ +// +// 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 deployment + +import ( + "context" + "fmt" + + apps "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/api/equality" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/patch" + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + "github.com/arangodb/kube-arangodb/pkg/logging" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher" +) + +var logger = logging.Global().RegisterAndGetLogger("scheduler-deployment-operator", logging.Info) + +type handler struct { + client arangoClientSet.Interface + kubeClient kubernetes.Interface + + eventRecorder event.RecorderInstance + + operator operator.Operator +} + +func (h *handler) Name() string { + return Kind() +} + +func (h *handler) Handle(ctx context.Context, item operation.Item) error { + // Get Backup object. It also covers NotFound case + + object, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.SchedulerV1beta1().ArangoSchedulerDeployments(item.Namespace).Get, item.Name, meta.GetOptions{}) + if err != nil { + if apiErrors.IsNotFound(err) { + return nil + } + + return err + } + + status := object.Status.DeepCopy() + + changed, reconcileErr := operator.HandleP3WithStop(ctx, item, object, status, h.handle) + if reconcileErr != nil && !operator.IsReconcile(reconcileErr) { + logger.Err(reconcileErr).Warn("Fail for %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + return reconcileErr + } + + if !changed { + return reconcileErr + } + + logger.Debug("Updating %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + if _, err := operator.WithSchedulerDeploymentUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoSchedulerDeployments(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { + return err + } + + return reconcileErr +} + +func (h *handler) handle(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerDeployment, status *schedulerApi.ArangoSchedulerDeploymentStatus) (bool, error) { + return operator.HandleP3(ctx, item, extension, status, h.HandleObject) +} + +func (h *handler) HandleObject(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerDeployment, status *schedulerApi.ArangoSchedulerDeploymentStatus) (bool, error) { + calculatedProfiles, profilesChecksum, err := scheduler.Profiles(ctx, h.client.SchedulerV1beta1().ArangoProfiles(extension.GetNamespace()), extension.GetLabels(), extension.Spec.Profiles...) + if err != nil { + return false, err + } + + var deploymentTemplate apps.Deployment + deploymentTemplate.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + + extension.Spec.DeploymentSpec.DeepCopyInto(&deploymentTemplate.Spec) + + deploymentSpecHash, err := util.SHA256FromJSON(deploymentTemplate) + if err != nil { + return false, err + } + + hash := util.SHA256FromString(fmt.Sprintf("%s|%s", profilesChecksum, deploymentSpecHash)) + + if err := schedulerApi.ProfileTemplates(util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) *schedulerApi.ProfileTemplate { + return a.V.Template + })).RenderOnTemplate(&deploymentTemplate.Spec.Template); err != nil { + return false, err + } + + if status.Object == nil { + // Create + + obj := &apps.Deployment{} + obj.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + extension.Spec.DeploymentSpec.DeepCopyInto(&obj.Spec) + extension.Spec.DeploymentSpec.Template.DeepCopyInto(&obj.Spec.Template) + + obj.OwnerReferences = append(obj.OwnerReferences, extension.AsOwner()) + + newObj, err := h.kubeClient.AppsV1().Deployments(extension.GetNamespace()).Create(ctx, obj, meta.CreateOptions{}) + if err != nil { + h.eventRecorder.Warning(extension, "Create Failed", "Unable to create Deployment: %s", err.Error()) + return false, err + } + + h.eventRecorder.Normal(extension, "Created", "Deployment %s created", newObj.GetName()) + + status.Object = util.NewType(sharedApi.NewObjectWithChecksum(newObj, hash)) + return true, operator.Reconcile("Job Reference Changed") + } + + // Find existing + obj, err := h.kubeClient.AppsV1().Deployments(status.Object.GetNamespace(extension)).Get(ctx, status.Object.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + // Object removed + h.eventRecorder.Warning(extension, "Removed", "Deployment %s is gone", status.Object.GetName()) + status.Object = nil + return true, operator.Reconcile("Deployment Reference Removed") + } + return false, err + } + + profileNames := util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) string { + return a.K + }) + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.Profiles, profileNames) { + status.Profiles = profileNames + return true, operator.Reconcile("Status Changed") + } + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.DeploymentStatus, obj.Status) { + obj.Status.DeepCopyInto(&status.DeploymentStatus) + return true, operator.Reconcile("Status Changed") + } + + if obj.GetDeletionTimestamp() != nil { + // Object is deleting, check later + return false, operator.Reconcile("Deployment Deleting") + } + + if !status.Object.Equals(obj) { + // Object changed or was recreated + h.eventRecorder.Warning(extension, "Removed", "Deployment %s reference is invalid", status.Object.GetName()) + if err := h.kubeClient.AppsV1().Deployments(status.Object.GetNamespace(extension)).Delete(ctx, status.Object.GetName(), meta.DeleteOptions{}); err != nil { + return false, err + } + + return false, operator.Reconcile("Deployment Deleted") + } + + // Object is equal, lets check if changed + if hash != status.Object.GetChecksum() { + // Checksum changed, lets apply changes + _, _, err := patcher.Patcher[*apps.Deployment](ctx, h.kubeClient.AppsV1().Deployments(status.Object.GetNamespace(extension)), obj, meta.PatchOptions{}, func(in *apps.Deployment) []patch.Item { + return []patch.Item{ + patch.ItemReplace(patch.NewPath("spec"), deploymentTemplate.Spec), + } + }, patcher.PatchMetadata(obj)) + if err != nil { + h.eventRecorder.Warning(extension, "Patch Failed", "Unable to patch Deployment: %s", err.Error()) + return false, err + } + h.eventRecorder.Normal(extension, "Updated", "Deployment %s patched", obj.GetName()) + status.Object.Checksum = util.NewType(hash) + return true, nil + } + + return false, nil +} + +func (h *handler) CanBeHandled(item operation.Item) bool { + return item.Group == Group() && + item.Version == Version() && + item.Kind == Kind() +} + +func (h *handler) init() {} diff --git a/pkg/handlers/scheduler/deployment/handler_manage_test.go b/pkg/handlers/scheduler/deployment/handler_manage_test.go new file mode 100644 index 000000000..e2f2b4927 --- /dev/null +++ b/pkg/handlers/scheduler/deployment/handler_manage_test.go @@ -0,0 +1,227 @@ +// +// 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 deployment + +import ( + "testing" + + "github.com/stretchr/testify/require" + apps "k8s.io/api/apps/v1" + "k8s.io/apimachinery/pkg/types" + + 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" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_Handler_Create(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "df484e6467f4b2445aae3a93ed7da1e374a689ac7e616c86ba31a3b2dc3e3244", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Update(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "df484e6467f4b2445aae3a93ed7da1e374a689ac7e616c86ba31a3b2dc3e3244", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) { + obj.Spec.Replicas = util.NewType[int32](2) + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "6ce82430599f0e4a3dc3983226076179a27559f0f1d87194eaa3c2d482aaceb3", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Recreate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "df484e6467f4b2445aae3a93ed7da1e374a689ac7e616c86ba31a3b2dc3e3244", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) { + obj.Status.Object.UID = util.NewType[types.UID]("TEST") + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "df484e6467f4b2445aae3a93ed7da1e374a689ac7e616c86ba31a3b2dc3e3244", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Parent(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) {}) + deployment := tests.NewMetaObject[*apps.Deployment](t, tests.FakeNamespace, "test", func(t *testing.T, obj *apps.Deployment) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &deployment) + + require.Len(t, deployment.OwnerReferences, 1) +} + +func Test_Handler_Propagate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) {}) + deployment := tests.NewMetaObject[*apps.Deployment](t, tests.FakeNamespace, "test", func(t *testing.T, obj *apps.Deployment) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &deployment) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "df484e6467f4b2445aae3a93ed7da1e374a689ac7e616c86ba31a3b2dc3e3244", extension.Status.Object.GetChecksum()) + require.EqualValues(t, 0, extension.Status.Replicas) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) { + obj.Spec.Replicas = util.NewType[int32](2) + }) + tests.Apply(t, deployment, func(t *testing.T, obj *apps.Deployment) { + obj.Status.Replicas = 5 + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension, &deployment) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &deployment) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "6ce82430599f0e4a3dc3983226076179a27559f0f1d87194eaa3c2d482aaceb3", extension.Status.Object.GetChecksum()) + require.EqualValues(t, 5, extension.Status.Replicas) +} + +func Test_Handler_Profile(t *testing.T) { + handler := newFakeHandler() + + // Arrange + profile := tests.NewMetaObject[*schedulerApi.ArangoProfile](t, tests.FakeNamespace, "test", tests.MarkArangoProfileAsReady) + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerDeployment](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerDeployment) { + obj.Spec.Profiles = []string{profile.GetName()} + }) + deployment := tests.NewMetaObject[*apps.Deployment](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.EqualError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)), "Profile with name `test` is missing") + + tests.CreateObjects(t, handler.kubeClient, handler.client, &profile) + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &deployment) + require.NotNil(t, deployment) + + require.Len(t, extension.Status.Profiles, 1) + require.Equal(t, profile.GetName(), extension.Status.Profiles[0]) +} diff --git a/pkg/handlers/scheduler/deployment/handler_test.go b/pkg/handlers/scheduler/deployment/handler_test.go new file mode 100644 index 000000000..e9c42c83e --- /dev/null +++ b/pkg/handlers/scheduler/deployment/handler_test.go @@ -0,0 +1,59 @@ +// +// 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 deployment + +import ( + "testing" + + "github.com/stretchr/testify/require" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_ObjectNotFound(t *testing.T) { + // Arrange + handler := newFakeHandler() + + i := newItem(operation.Add, "test", "test") + + actions := map[operation.Operation]bool{ + operation.Add: false, + operation.Update: false, + operation.Delete: false, + } + + // Act + for op, shouldFail := range actions { + t.Run(string(op), func(t *testing.T) { + err := tests.Handle(handler, i) + + // Assert + if shouldFail { + require.Error(t, err) + require.True(t, apiErrors.IsNotFound(err)) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/handlers/scheduler/deployment/local.go b/pkg/handlers/scheduler/deployment/local.go new file mode 100644 index 000000000..2932bf197 --- /dev/null +++ b/pkg/handlers/scheduler/deployment/local.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 +// + +package deployment + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" +) + +func GVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: Group(), + Version: Version(), + Kind: Kind(), + } +} + +func Kind() string { + return scheduler.DeploymentResourceKind +} + +func Group() string { + return schedulerApi.SchemeGroupVersion.Group +} + +func Version() string { + return schedulerApi.SchemeGroupVersion.Version +} diff --git a/pkg/handlers/scheduler/deployment/register.go b/pkg/handlers/scheduler/deployment/register.go new file mode 100644 index 000000000..a6d902fa2 --- /dev/null +++ b/pkg/handlers/scheduler/deployment/register.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 deployment + +import ( + apps "k8s.io/api/apps/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions" + "github.com/arangodb/kube-arangodb/pkg/handlers/generic/parent" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" +) + +// RegisterInformer into operator +func RegisterInformer(operator operator.Operator, recorder event.Recorder, client arangoClientSet.Interface, + kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) error { + + if err := operator.RegisterInformer(informer.Scheduler().V1beta1().ArangoSchedulerDeployments().Informer(), + Group(), + Version(), + Kind()); err != nil { + return err + } + + h := &handler{ + client: client, + kubeClient: kubeClient, + + eventRecorder: recorder.NewInstance(Group(), Version(), Kind()), + + operator: operator, + } + + h.init() + + if err := operator.RegisterHandler(h); err != nil { + return err + } + + { + deployment := k8sutil.AppsV1DeploymentGVK() + + if err := operator.RegisterInformer(kubeInformer.Apps().V1().Deployments().Informer(), + deployment.Group, + deployment.Version, + deployment.Kind); err != nil { + return err + } + + deploymentHandler := parent.NewNotifyHandler[*apps.Deployment]("apps-deployment-v1-parent", operator, kubeClient.AppsV1().Deployments, deployment, GVK()) + + if err := operator.RegisterHandler(deploymentHandler); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/handlers/scheduler/deployment/suite_test.go b/pkg/handlers/scheduler/deployment/suite_test.go new file mode 100644 index 000000000..f0b5b69ca --- /dev/null +++ b/pkg/handlers/scheduler/deployment/suite_test.go @@ -0,0 +1,61 @@ +// +// 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 deployment + +import ( + "k8s.io/client-go/kubernetes/fake" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + fakeClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" +) + +func newFakeHandler() *handler { + f := fakeClientSet.NewSimpleClientset() + k := fake.NewSimpleClientset() + + h := &handler{ + client: f, + kubeClient: k, + eventRecorder: event.NewEventRecorder("mock", k).NewInstance(Group(), Version(), Kind()), + operator: operator.NewOperator("mock", "mock", "mock"), + } + + h.init() + + return h +} + +func newItem(o operation.Operation, namespace, name string) operation.Item { + return operation.Item{ + Group: schedulerApi.SchemeGroupVersion.Group, + Version: schedulerApi.SchemeGroupVersion.Version, + Kind: scheduler.DeploymentResourceKind, + + Operation: o, + + Namespace: namespace, + Name: name, + } +} diff --git a/pkg/handlers/scheduler/pod/handler.go b/pkg/handlers/scheduler/pod/handler.go new file mode 100644 index 000000000..bcd471a38 --- /dev/null +++ b/pkg/handlers/scheduler/pod/handler.go @@ -0,0 +1,224 @@ +// +// 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 ( + "context" + "fmt" + + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/equality" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/patch" + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + "github.com/arangodb/kube-arangodb/pkg/logging" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/scheduler" + "github.com/arangodb/kube-arangodb/pkg/util" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/kerrors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/patcher" +) + +var logger = logging.Global().RegisterAndGetLogger("scheduler-pod-operator", logging.Info) + +type handler struct { + client arangoClientSet.Interface + kubeClient kubernetes.Interface + + eventRecorder event.RecorderInstance + + operator operator.Operator +} + +func (h *handler) Name() string { + return Kind() +} + +func (h *handler) Handle(ctx context.Context, item operation.Item) error { + // Get Backup object. It also covers NotFound case + + object, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.SchedulerV1beta1().ArangoSchedulerPods(item.Namespace).Get, item.Name, meta.GetOptions{}) + if err != nil { + if apiErrors.IsNotFound(err) { + return nil + } + + return err + } + + status := object.Status.DeepCopy() + + changed, reconcileErr := operator.HandleP3WithStop(ctx, item, object, status, h.handle) + if reconcileErr != nil && !operator.IsReconcile(reconcileErr) { + logger.Err(reconcileErr).Warn("Fail for %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + return reconcileErr + } + + if !changed { + return reconcileErr + } + + logger.Debug("Updating %s %s/%s", + item.Kind, + item.Namespace, + item.Name) + + if _, err := operator.WithSchedulerPodUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoSchedulerPods(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { + return err + } + + return reconcileErr +} + +func (h *handler) handle(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerPod, status *schedulerApi.ArangoSchedulerPodStatus) (bool, error) { + return operator.HandleP3(ctx, item, extension, status, h.HandleObject) +} + +func (h *handler) HandleObject(ctx context.Context, item operation.Item, extension *schedulerApi.ArangoSchedulerPod, status *schedulerApi.ArangoSchedulerPodStatus) (bool, error) { + calculatedProfiles, profilesChecksum, err := scheduler.Profiles(ctx, h.client.SchedulerV1beta1().ArangoProfiles(extension.GetNamespace()), extension.GetLabels(), extension.Spec.Profiles...) + if err != nil { + return false, err + } + + var podSpecTemplate core.PodTemplateSpec + + podSpecTemplate.ObjectMeta = meta.ObjectMeta{ + Name: extension.ObjectMeta.Name, + Labels: extension.ObjectMeta.Labels, + Annotations: extension.ObjectMeta.Annotations, + } + extension.Spec.PodSpec.DeepCopyInto(&podSpecTemplate.Spec) + + podSpecHash, err := util.SHA256FromJSON(podSpecTemplate) + if err != nil { + return false, err + } + + hash := util.SHA256FromString(fmt.Sprintf("%s|%s", profilesChecksum, podSpecHash)) + + if err := schedulerApi.ProfileTemplates(util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) *schedulerApi.ProfileTemplate { + return a.V.Template + })).RenderOnTemplate(&podSpecTemplate); err != nil { + return false, err + } + + if status.Object == nil { + // Create + + obj := &core.Pod{ + ObjectMeta: podSpecTemplate.ObjectMeta, + Spec: podSpecTemplate.Spec, + } + obj.OwnerReferences = append(obj.OwnerReferences, extension.AsOwner()) + + newObj, err := h.kubeClient.CoreV1().Pods(extension.GetNamespace()).Create(ctx, obj, meta.CreateOptions{}) + if err != nil { + h.eventRecorder.Warning(extension, "Create Failed", "Unable to create Pod: %s", err.Error()) + return false, err + } + + h.eventRecorder.Normal(extension, "Created", "Pod %s created", newObj.GetName()) + + status.Object = util.NewType(sharedApi.NewObjectWithChecksum(newObj, hash)) + return true, operator.Reconcile("Job Reference Changed") + } + + // Find existing + obj, err := h.kubeClient.CoreV1().Pods(status.Object.GetNamespace(extension)).Get(ctx, status.Object.GetName(), meta.GetOptions{}) + if err != nil { + if kerrors.IsNotFound(err) { + // Object removed + h.eventRecorder.Warning(extension, "Removed", "Pod %s is gone", status.Object.GetName()) + status.Object = nil + return true, operator.Reconcile("Pod Reference Removed") + } + return false, err + } + + profileNames := util.FormatList(calculatedProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) string { + return a.K + }) + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.Profiles, profileNames) { + status.Profiles = profileNames + return true, operator.Reconcile("Status Changed") + } + + // Try to fetch status + if !equality.Semantic.DeepEqual(status.PodStatus, obj.Status) { + obj.Status.DeepCopyInto(&status.PodStatus) + return true, operator.Reconcile("Status Changed") + } + + if obj.GetDeletionTimestamp() != nil { + // Object is deleting, check later + return false, operator.Reconcile("Pod Deleting") + } + + if !status.Object.Equals(obj) { + // Object changed or was recreated + h.eventRecorder.Warning(extension, "Removed", "Pod %s reference is invalid", status.Object.GetName()) + if err := h.kubeClient.CoreV1().Pods(status.Object.GetNamespace(extension)).Delete(ctx, status.Object.GetName(), meta.DeleteOptions{}); err != nil { + return false, err + } + + return false, operator.Reconcile("Pod Deleted") + } + + // Object is equal, lets check if changed + if hash != status.Object.GetChecksum() { + // Checksum changed, lets apply changes + _, _, err := patcher.Patcher[*core.Pod](ctx, h.kubeClient.CoreV1().Pods(status.Object.GetNamespace(extension)), obj, meta.PatchOptions{}, func(in *core.Pod) []patch.Item { + return []patch.Item{ + patch.ItemReplace(patch.NewPath("spec"), podSpecTemplate.Spec), + } + }, patcher.PatchMetadata(obj)) + if err != nil { + h.eventRecorder.Warning(extension, "Patch Failed", "Unable to patch Pod: %s", err.Error()) + return false, err + } + h.eventRecorder.Normal(extension, "Updated", "Pod %s patched", obj.GetName()) + status.Object.Checksum = util.NewType(hash) + return true, nil + } + + return false, nil +} + +func (h *handler) CanBeHandled(item operation.Item) bool { + return item.Group == Group() && + item.Version == Version() && + item.Kind == Kind() +} + +func (h *handler) init() {} diff --git a/pkg/handlers/scheduler/pod/handler_manage_test.go b/pkg/handlers/scheduler/pod/handler_manage_test.go new file mode 100644 index 000000000..4d067f337 --- /dev/null +++ b/pkg/handlers/scheduler/pod/handler_manage_test.go @@ -0,0 +1,227 @@ +// +// 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/types" + + 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" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_Handler_Create(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "64759f2e87813091ac4dbb627ee7411316259132ca5a9603786993f122899c2c", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Update(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "64759f2e87813091ac4dbb627ee7411316259132ca5a9603786993f122899c2c", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) { + obj.Spec.HostNetwork = true + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c982d1c7855103125df8330401d993eb1e8de85b2bd605ac61af3c872f4fa51d", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Recreate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "64759f2e87813091ac4dbb627ee7411316259132ca5a9603786993f122899c2c", extension.Status.Object.GetChecksum()) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) { + obj.Status.Object.UID = util.NewType[types.UID]("TEST") + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "64759f2e87813091ac4dbb627ee7411316259132ca5a9603786993f122899c2c", extension.Status.Object.GetChecksum()) +} + +func Test_Handler_Parent(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) {}) + pod := tests.NewMetaObject[*core.Pod](t, tests.FakeNamespace, "test", func(t *testing.T, obj *core.Pod) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + + // Validate + require.NotNil(t, extension.Status.Object) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &pod) + + require.Len(t, pod.OwnerReferences, 1) +} + +func Test_Handler_Propagate(t *testing.T) { + handler := newFakeHandler() + + // Arrange + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) {}) + pod := tests.NewMetaObject[*core.Pod](t, tests.FakeNamespace, "test", func(t *testing.T, obj *core.Pod) {}) + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &pod) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "64759f2e87813091ac4dbb627ee7411316259132ca5a9603786993f122899c2c", extension.Status.Object.GetChecksum()) + require.Equal(t, "", pod.Status.Message) + + // Update + tests.Apply(t, extension, func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) { + obj.Spec.HostNetwork = true + }) + tests.Apply(t, pod, func(t *testing.T, obj *core.Pod) { + obj.Status.Message = "RANDOM" + }) + tests.UpdateObjects(t, handler.kubeClient, handler.client, &extension, &pod) + + // Test + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &pod) + + // Validate + require.NotNil(t, extension.Status.Object) + require.Equal(t, extension.GetName(), extension.Status.Object.GetName()) + require.Equal(t, "c982d1c7855103125df8330401d993eb1e8de85b2bd605ac61af3c872f4fa51d", extension.Status.Object.GetChecksum()) + require.Equal(t, "RANDOM", pod.Status.Message) +} + +func Test_Handler_Profile(t *testing.T) { + handler := newFakeHandler() + + // Arrange + profile := tests.NewMetaObject[*schedulerApi.ArangoProfile](t, tests.FakeNamespace, "test", tests.MarkArangoProfileAsReady) + extension := tests.NewMetaObject[*schedulerApi.ArangoSchedulerPod](t, tests.FakeNamespace, "test", + func(t *testing.T, obj *schedulerApi.ArangoSchedulerPod) { + obj.Spec.Profiles = []string{profile.GetName()} + }) + pod := tests.NewMetaObject[*core.Pod](t, tests.FakeNamespace, "test") + + refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &extension) + + // Test + require.EqualError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)), "Profile with name `test` is missing") + + tests.CreateObjects(t, handler.kubeClient, handler.client, &profile) + require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension))) + + // Refresh + refresh(t) + tests.RefreshObjects(t, handler.kubeClient, handler.client, &pod) + require.NotNil(t, pod) + + require.Len(t, extension.Status.Profiles, 1) + require.Equal(t, profile.GetName(), extension.Status.Profiles[0]) +} diff --git a/pkg/handlers/scheduler/pod/handler_test.go b/pkg/handlers/scheduler/pod/handler_test.go new file mode 100644 index 000000000..2bffb0714 --- /dev/null +++ b/pkg/handlers/scheduler/pod/handler_test.go @@ -0,0 +1,59 @@ +// +// 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" + apiErrors "k8s.io/apimachinery/pkg/api/errors" + + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" + "github.com/arangodb/kube-arangodb/pkg/util/tests" +) + +func Test_ObjectNotFound(t *testing.T) { + // Arrange + handler := newFakeHandler() + + i := newItem(operation.Add, "test", "test") + + actions := map[operation.Operation]bool{ + operation.Add: false, + operation.Update: false, + operation.Delete: false, + } + + // Act + for op, shouldFail := range actions { + t.Run(string(op), func(t *testing.T) { + err := tests.Handle(handler, i) + + // Assert + if shouldFail { + require.Error(t, err) + require.True(t, apiErrors.IsNotFound(err)) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/pkg/handlers/scheduler/pod/local.go b/pkg/handlers/scheduler/pod/local.go new file mode 100644 index 000000000..0dfc44c98 --- /dev/null +++ b/pkg/handlers/scheduler/pod/local.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 +// + +package pod + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" +) + +func GVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: Group(), + Version: Version(), + Kind: Kind(), + } +} + +func Kind() string { + return scheduler.PodResourceKind +} + +func Group() string { + return schedulerApi.SchemeGroupVersion.Group +} + +func Version() string { + return schedulerApi.SchemeGroupVersion.Version +} diff --git a/pkg/handlers/scheduler/pod/register.go b/pkg/handlers/scheduler/pod/register.go new file mode 100644 index 000000000..e0a88e297 --- /dev/null +++ b/pkg/handlers/scheduler/pod/register.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 pod + +import ( + core "k8s.io/api/core/v1" + "k8s.io/client-go/informers" + "k8s.io/client-go/kubernetes" + + arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned" + arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions" + "github.com/arangodb/kube-arangodb/pkg/handlers/generic/parent" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" +) + +// RegisterInformer into operator +func RegisterInformer(operator operator.Operator, recorder event.Recorder, client arangoClientSet.Interface, + kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) error { + + if err := operator.RegisterInformer(informer.Scheduler().V1beta1().ArangoSchedulerPods().Informer(), + Group(), + Version(), + Kind()); err != nil { + return err + } + + h := &handler{ + client: client, + kubeClient: kubeClient, + + eventRecorder: recorder.NewInstance(Group(), Version(), Kind()), + + operator: operator, + } + + h.init() + + if err := operator.RegisterHandler(h); err != nil { + return err + } + + { + pod := k8sutil.CoreV1PodGVK() + + if err := operator.RegisterInformer(kubeInformer.Core().V1().Pods().Informer(), + pod.Group, + pod.Version, + pod.Kind); err != nil { + return err + } + + podHandler := parent.NewNotifyHandler[*core.Pod]("core-pod-v1-parent", operator, kubeClient.CoreV1().Pods, pod, GVK()) + + if err := operator.RegisterHandler(podHandler); err != nil { + return err + } + } + + return nil +} diff --git a/pkg/handlers/scheduler/pod/suite_test.go b/pkg/handlers/scheduler/pod/suite_test.go new file mode 100644 index 000000000..bdbb1150e --- /dev/null +++ b/pkg/handlers/scheduler/pod/suite_test.go @@ -0,0 +1,61 @@ +// +// 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 ( + "k8s.io/client-go/kubernetes/fake" + + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" + fakeClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake" + operator "github.com/arangodb/kube-arangodb/pkg/operatorV2" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/event" + "github.com/arangodb/kube-arangodb/pkg/operatorV2/operation" +) + +func newFakeHandler() *handler { + f := fakeClientSet.NewSimpleClientset() + k := fake.NewSimpleClientset() + + h := &handler{ + client: f, + kubeClient: k, + eventRecorder: event.NewEventRecorder("mock", k).NewInstance(Group(), Version(), Kind()), + operator: operator.NewOperator("mock", "mock", "mock"), + } + + h.init() + + return h +} + +func newItem(o operation.Operation, namespace, name string) operation.Item { + return operation.Item{ + Group: schedulerApi.SchemeGroupVersion.Group, + Version: schedulerApi.SchemeGroupVersion.Version, + Kind: scheduler.PodResourceKind, + + Operation: o, + + Namespace: namespace, + Name: name, + } +} diff --git a/pkg/handlers/scheduler/profile/handler.go b/pkg/handlers/scheduler/profile/handler.go index 7f1b2eb0d..e0413a637 100644 --- a/pkg/handlers/scheduler/profile/handler.go +++ b/pkg/handlers/scheduler/profile/handler.go @@ -84,7 +84,7 @@ func (h *handler) Handle(ctx context.Context, item operation.Item) error { item.Namespace, item.Name) - if _, err := operator.WithNetworkingArangoProfileUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoProfiles(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { + if _, err := operator.WithSchedulerArangoProfileUpdateStatusInterfaceRetry(context.Background(), h.client.SchedulerV1beta1().ArangoProfiles(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil { return err } diff --git a/pkg/handlers/scheduler/profile/local.go b/pkg/handlers/scheduler/profile/local.go index 3fa7f09bc..297dc9780 100644 --- a/pkg/handlers/scheduler/profile/local.go +++ b/pkg/handlers/scheduler/profile/local.go @@ -21,10 +21,20 @@ package profile import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "github.com/arangodb/kube-arangodb/pkg/apis/scheduler" schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" ) +func GVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: Group(), + Version: Version(), + Kind: Kind(), + } +} + func Kind() string { return scheduler.ArangoProfileResourceKind } diff --git a/pkg/integrations/sidecar/integration.go b/pkg/integrations/sidecar/integration.go index 28a040cea..731dbe0c7 100644 --- a/pkg/integrations/sidecar/integration.go +++ b/pkg/integrations/sidecar/integration.go @@ -90,6 +90,7 @@ func NewIntegrationEnablement(integrations ...Integration) (*schedulerApi.Profil } return &schedulerApi.ProfileTemplate{ + Priority: util.NewType(127), Pod: &schedulerPodApi.Pod{ Volumes: &schedulerPodResourcesApi.Volumes{ Volumes: volumes, @@ -186,6 +187,7 @@ func NewIntegration(image *schedulerContainerResourcesApi.Image, integration *sc } pt := schedulerApi.ProfileTemplate{ + Priority: util.NewType(128), Container: &schedulerApi.ProfileContainerTemplate{ All: &schedulerContainerApi.Generic{ Environments: &schedulerContainerResourcesApi.Environments{ diff --git a/pkg/operator/operator.go b/pkg/operator/operator.go index 3d0768819..659509e4b 100644 --- a/pkg/operator/operator.go +++ b/pkg/operator/operator.go @@ -49,7 +49,11 @@ import ( "github.com/arangodb/kube-arangodb/pkg/handlers/job" "github.com/arangodb/kube-arangodb/pkg/handlers/networking/route" "github.com/arangodb/kube-arangodb/pkg/handlers/policy" - "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/profile" + schedulerBatchJobHandler "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/batchjob" + schedulerCronJobHandler "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/cronjob" + schedulerDeploymentHandler "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/deployment" + schedulerPodHandler "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/pod" + schedulerProfileHandler "github.com/arangodb/kube-arangodb/pkg/handlers/scheduler/profile" "github.com/arangodb/kube-arangodb/pkg/logging" "github.com/arangodb/kube-arangodb/pkg/operator/scope" operatorV2 "github.com/arangodb/kube-arangodb/pkg/operatorV2" @@ -380,7 +384,47 @@ func (o *Operator) onStartOperatorV2Scheduler(operator operatorV2.Operator, reco } o.waitForCRD(scheduler.ArangoProfileCRDName, checkFn) - if err := profile.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { + checkFn = func() error { + _, err := o.Client.Arango().SchedulerV1beta1().ArangoSchedulerPods(o.Namespace).List(context.Background(), meta.ListOptions{}) + return err + } + o.waitForCRD(scheduler.PodCRDName, checkFn) + + checkFn = func() error { + _, err := o.Client.Arango().SchedulerV1beta1().ArangoSchedulerDeployments(o.Namespace).List(context.Background(), meta.ListOptions{}) + return err + } + o.waitForCRD(scheduler.DeploymentCRDName, checkFn) + + checkFn = func() error { + _, err := o.Client.Arango().SchedulerV1beta1().ArangoSchedulerBatchJobs(o.Namespace).List(context.Background(), meta.ListOptions{}) + return err + } + o.waitForCRD(scheduler.BatchJobCRDName, checkFn) + + checkFn = func() error { + _, err := o.Client.Arango().SchedulerV1beta1().ArangoSchedulerCronJobs(o.Namespace).List(context.Background(), meta.ListOptions{}) + return err + } + o.waitForCRD(scheduler.CronJobCRDName, checkFn) + + if err := schedulerProfileHandler.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { + panic(err) + } + + if err := schedulerPodHandler.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { + panic(err) + } + + if err := schedulerDeploymentHandler.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { + panic(err) + } + + if err := schedulerBatchJobHandler.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { + panic(err) + } + + if err := schedulerCronJobHandler.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil { panic(err) } } diff --git a/pkg/operatorV2/operation/item.go b/pkg/operatorV2/operation/item.go index 546a8b4b5..2e3e23e49 100644 --- a/pkg/operatorV2/operation/item.go +++ b/pkg/operatorV2/operation/item.go @@ -25,6 +25,7 @@ import ( "github.com/rs/zerolog" meta "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" "github.com/arangodb/kube-arangodb/pkg/util/errors" ) @@ -57,6 +58,11 @@ func NewItemFromString(itemString string) (Item, error) { return NewItem(Operation(parts[0]), parts[1], parts[2], parts[3], parts[4], parts[5]) } +// NewItemFromGVKObject creates new item from Kubernetes Object +func NewItemFromGVKObject(operation Operation, gvk schema.GroupVersionKind, object meta.Object) (Item, error) { + return NewItem(operation, gvk.Group, gvk.Version, gvk.Kind, object.GetNamespace(), object.GetName()) +} + // NewItemFromObject creates new item from Kubernetes Object func NewItemFromObject(operation Operation, group, version, kind string, object meta.Object) (Item, error) { return NewItem(operation, group, version, kind, object.GetNamespace(), object.GetName()) @@ -92,6 +98,12 @@ type Item struct { Name string } +func (i Item) GVK(gvk schema.GroupVersionKind) bool { + return i.Group == gvk.Group && + i.Version == gvk.Version && + i.Kind == gvk.Kind +} + func validateField(name, value string, allowEmpty bool) error { if !allowEmpty && value == "" { return errors.Errorf(emptyError, name) diff --git a/pkg/operatorV2/update.go b/pkg/operatorV2/update.go index cdc16f54e..d82408f3b 100644 --- a/pkg/operatorV2/update.go +++ b/pkg/operatorV2/update.go @@ -28,6 +28,7 @@ import ( "github.com/arangodb/kube-arangodb/pkg/util" "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/globals" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic" "github.com/arangodb/kube-arangodb/pkg/util/timer" ) @@ -39,15 +40,14 @@ type Object[T interface{}] interface { } type GetInterface[S interface{}, T Object[S]] interface { - Get(ctx context.Context, name string, options meta.GetOptions) (T, error) + generic.GetInterface[T] } type UpdateStatusInterfaceClient[S interface{}, T Object[S]] func(namespace string) UpdateStatusInterface[S, T] type UpdateStatusInterface[S interface{}, T Object[S]] interface { - GetInterface[S, T] - - UpdateStatus(ctx context.Context, in T, options meta.UpdateOptions) (T, error) + generic.GetInterface[T] + generic.UpdateStatusInterface[T] } func WithUpdateStatusInterfaceRetry[S interface{}, T Object[S]](ctx context.Context, client UpdateStatusInterface[S, T], obj T, status S, opts meta.UpdateOptions) (T, error) { diff --git a/pkg/operatorV2/update_wraps.go b/pkg/operatorV2/update_wraps.go index 9ec789c27..f2f3c53e1 100644 --- a/pkg/operatorV2/update_wraps.go +++ b/pkg/operatorV2/update_wraps.go @@ -57,10 +57,26 @@ func WithNetworkingArangoRouteUpdateStatusInterfaceRetry(ctx context.Context, cl return WithUpdateStatusInterfaceRetry[networkingApi.ArangoRouteStatus, *networkingApi.ArangoRoute](ctx, client, obj, status, opts) } -func WithNetworkingArangoProfileUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ProfileStatus, *schedulerApi.ArangoProfile], obj *schedulerApi.ArangoProfile, status schedulerApi.ProfileStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoProfile, error) { +func WithSchedulerArangoProfileUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ProfileStatus, *schedulerApi.ArangoProfile], obj *schedulerApi.ArangoProfile, status schedulerApi.ProfileStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoProfile, error) { return WithUpdateStatusInterfaceRetry[schedulerApi.ProfileStatus, *schedulerApi.ArangoProfile](ctx, client, obj, status, opts) } +func WithSchedulerPodUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ArangoSchedulerPodStatus, *schedulerApi.ArangoSchedulerPod], obj *schedulerApi.ArangoSchedulerPod, status schedulerApi.ArangoSchedulerPodStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoSchedulerPod, error) { + return WithUpdateStatusInterfaceRetry[schedulerApi.ArangoSchedulerPodStatus, *schedulerApi.ArangoSchedulerPod](ctx, client, obj, status, opts) +} + +func WithSchedulerDeploymentUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ArangoSchedulerDeploymentStatus, *schedulerApi.ArangoSchedulerDeployment], obj *schedulerApi.ArangoSchedulerDeployment, status schedulerApi.ArangoSchedulerDeploymentStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoSchedulerDeployment, error) { + return WithUpdateStatusInterfaceRetry[schedulerApi.ArangoSchedulerDeploymentStatus, *schedulerApi.ArangoSchedulerDeployment](ctx, client, obj, status, opts) +} + +func WithSchedulerBatchJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ArangoSchedulerBatchJobStatus, *schedulerApi.ArangoSchedulerBatchJob], obj *schedulerApi.ArangoSchedulerBatchJob, status schedulerApi.ArangoSchedulerBatchJobStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoSchedulerBatchJob, error) { + return WithUpdateStatusInterfaceRetry[schedulerApi.ArangoSchedulerBatchJobStatus, *schedulerApi.ArangoSchedulerBatchJob](ctx, client, obj, status, opts) +} + +func WithSchedulerCronJobUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[schedulerApi.ArangoSchedulerCronJobStatus, *schedulerApi.ArangoSchedulerCronJob], obj *schedulerApi.ArangoSchedulerCronJob, status schedulerApi.ArangoSchedulerCronJobStatus, opts meta.UpdateOptions) (*schedulerApi.ArangoSchedulerCronJob, error) { + return WithUpdateStatusInterfaceRetry[schedulerApi.ArangoSchedulerCronJobStatus, *schedulerApi.ArangoSchedulerCronJob](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) { return WithUpdateStatusInterfaceRetry[mlApi.ArangoMLStorageStatus, *mlApi.ArangoMLStorage](ctx, client, obj, status, opts) } diff --git a/pkg/scheduler/input.go b/pkg/scheduler/input.go index 000bfa985..b136b033c 100644 --- a/pkg/scheduler/input.go +++ b/pkg/scheduler/input.go @@ -21,68 +21,43 @@ package scheduler import ( - "math" - 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/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" ) -func baseAsTemplate(in *pbSchedulerV1.Spec) *schedulerApi.ProfileTemplate { - containers := schedulerContainerApi.Containers{} - - for n, c := range in.Containers { +func SpecAsTemplate(in *pbSchedulerV1.Spec) *core.PodTemplateSpec { + var ret core.PodTemplateSpec + for _, c := range in.Containers { if c == nil { continue } - var container schedulerContainerApi.Container + var container core.Container if image := c.Image; image != nil { - container.Image = &schedulerContainerResourcesApi.Image{ - Image: c.Image, - } + container.Image = *image } if len(c.Args) > 0 { - container.Core = &schedulerContainerResourcesApi.Core{ - Args: c.Args, - } + container.Args = c.Args } - if len(c.EnvironmentVariables) > 0 { - container.Environments = &schedulerContainerResourcesApi.Environments{} - - for k, v := range c.EnvironmentVariables { - container.Env = append(container.Env, core.EnvVar{ - Name: k, - Value: v, - }) - } + for k, v := range c.EnvironmentVariables { + container.Env = append(container.Env, core.EnvVar{ + Name: k, + Value: v, + }) } - containers[n] = container + ret.Spec.Containers = append(ret.Spec.Containers, container) } - var t = schedulerApi.ProfileTemplate{ - Priority: util.NewType(math.MaxInt), - Pod: &schedulerPodApi.Pod{}, - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: containers, - }, + if base := in.Base; base != nil { + ret.ObjectMeta.Labels = base.Labels } - if job := in.Job; job != nil { - t.Pod.Metadata = &schedulerPodResourcesApi.Metadata{ - Labels: job.Labels, - } - } + ret.Spec.RestartPolicy = core.RestartPolicyNever - return &t + return &ret } diff --git a/pkg/scheduler/profiles.go b/pkg/scheduler/profiles.go new file mode 100644 index 000000000..25cb34af2 --- /dev/null +++ b/pkg/scheduler/profiles.go @@ -0,0 +1,106 @@ +// +// 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 scheduler + +import ( + "context" + + 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" + "github.com/arangodb/kube-arangodb/pkg/util/errors" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic" + "github.com/arangodb/kube-arangodb/pkg/util/strings" +) + +func Profiles(ctx context.Context, client generic.ListInterface[*schedulerApi.ArangoProfileList], labels map[string]string, profiles ...string) ([]util.KV[string, schedulerApi.ProfileAcceptedTemplate], string, error) { + profileMap, err := kubernetes.MapObjects[*schedulerApi.ArangoProfileList, *schedulerApi.ArangoProfile](ctx, client, func(result *schedulerApi.ArangoProfileList) []*schedulerApi.ArangoProfile { + q := make([]*schedulerApi.ArangoProfile, len(result.Items)) + + for id, e := range result.Items { + q[id] = e.DeepCopy() + } + + return q + }) + + if err != nil { + return nil, "", err + } + + extractedProfiles := profileMap.AsList().Filter(func(a *schedulerApi.ArangoProfile) bool { + return a != nil && a.Spec.Template != nil + }).Filter(func(a *schedulerApi.ArangoProfile) bool { + if a.Spec.Selectors == nil { + return false + } + + if !a.Spec.Selectors.Select(labels) { + return false + } + + return true + }) + + for _, name := range profiles { + p, ok := profileMap.ByName(name) + if !ok { + return nil, "", errors.Errorf("Profile with name `%s` is missing", name) + } + + extractedProfiles = append(extractedProfiles, p) + } + + extractedProfiles = extractedProfiles.Unique(func(existing util.List[*schedulerApi.ArangoProfile], o *schedulerApi.ArangoProfile) bool { + return existing.Contains(func(a *schedulerApi.ArangoProfile) bool { + return a.GetName() == o.GetName() + }) + }) + + extractedProfiles = extractedProfiles.Sort(func(a, b *schedulerApi.ArangoProfile) bool { + return a.Spec.Template.GetPriority() > b.Spec.Template.GetPriority() + }) + + // Check if everything is valid + if err := errors.Errors(util.FormatList(extractedProfiles, func(in *schedulerApi.ArangoProfile) error { + if !in.Status.Conditions.IsTrue(schedulerApi.ReadyCondition) { + return errors.Errorf("ArangoProfile `%s` is not ready", in.GetName()) + } + if in.Status.Accepted == nil { + return errors.Errorf("ArangoProfile `%s` status is nil", in.GetName()) + } + + return nil + })...); err != nil { + return nil, "", err + } + + resultProfiles := util.FormatList(extractedProfiles, func(a *schedulerApi.ArangoProfile) util.KV[string, schedulerApi.ProfileAcceptedTemplate] { + return util.KV[string, schedulerApi.ProfileAcceptedTemplate]{ + K: a.GetName(), + V: *a.Status.Accepted, + } + }) + + return resultProfiles, util.SHA256FromString(strings.Join(util.FormatList(resultProfiles, func(a util.KV[string, schedulerApi.ProfileAcceptedTemplate]) string { + return a.V.Checksum + }), "|")), nil +} diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go deleted file mode 100644 index 53e77d076..000000000 --- a/pkg/scheduler/scheduler.go +++ /dev/null @@ -1,136 +0,0 @@ -// -// 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 scheduler - -import ( - "context" - - 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/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" -) - -func NewScheduler(client kclient.Client, namespace string) Scheduler { - return scheduler{ - client: client, - namespace: namespace, - } -} - -type Scheduler interface { - Render(ctx context.Context, in *pbSchedulerV1.Spec, templates ...*schedulerApi.ProfileTemplate) (*core.PodTemplateSpec, []string, error) -} - -type scheduler struct { - client kclient.Client - namespace string -} - -func (s scheduler) Render(ctx context.Context, in *pbSchedulerV1.Spec, templates ...*schedulerApi.ProfileTemplate) (*core.PodTemplateSpec, []string, error) { - if in == nil { - return nil, nil, errors.Errorf("Unable to parse nil Spec") - } - - 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 { - q[id] = e.DeepCopy() - } - - return q - }) - - if err != nil { - return nil, nil, err - } - - var labels map[string]string - var additionalProfiles []string - - if job := in.Job; job != nil { - labels = job.Labels - additionalProfiles = job.Profiles - } - - if len(in.Containers) == 0 { - return nil, nil, errors.Errorf("Required at least 1 container") - } - - profiles := profileMap.AsList().Filter(func(a *schedulerApi.ArangoProfile) bool { - return a != nil && a.Spec.Template != nil - }).Filter(func(a *schedulerApi.ArangoProfile) bool { - if a.Spec.Selectors == nil { - return false - } - - if !a.Spec.Selectors.Select(labels) { - return false - } - - return true - }) - - for _, name := range additionalProfiles { - p, ok := profileMap.ByName(name) - if !ok { - return nil, nil, errors.Errorf("Profile with name `%s` is missing", name) - } - - profiles = append(profiles, p) - } - - profiles = profiles.Unique(func(existing kubernetes.List[*schedulerApi.ArangoProfile], o *schedulerApi.ArangoProfile) bool { - return existing.Contains(func(a *schedulerApi.ArangoProfile) bool { - return a.GetName() == o.GetName() - }) - }) - - profiles = profiles.Sort(func(a, b *schedulerApi.ArangoProfile) bool { - return a.Spec.Template.GetPriority() > b.Spec.Template.GetPriority() - }) - - if err := errors.Errors(kubernetes.Extract(profiles, func(in *schedulerApi.ArangoProfile) error { - return in.Spec.Validate() - })...); err != nil { - return nil, nil, err - } - - extracted := schedulerApi.ProfileTemplates(kubernetes.Extract(profiles, func(in *schedulerApi.ArangoProfile) *schedulerApi.ProfileTemplate { - return in.Spec.Template - }).Append(templates...).Append(baseAsTemplate(in))) - - names := kubernetes.Extract(profiles, func(in *schedulerApi.ArangoProfile) string { - return in.GetName() - }) - - var pod core.PodTemplateSpec - - if err := extracted.RenderOnTemplate(&pod); err != nil { - return nil, names, err - } - - return &pod, names, nil -} diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go deleted file mode 100644 index c70e16bb9..000000000 --- a/pkg/scheduler/scheduler_test.go +++ /dev/null @@ -1,344 +0,0 @@ -// -// 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 scheduler - -import ( - "context" - "strings" - "testing" - - "github.com/stretchr/testify/require" - core "k8s.io/api/core/v1" - meta "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/yaml" - - pbSchedulerV1 "github.com/arangodb/kube-arangodb/integrations/scheduler/v1/definition" - 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" -) - -const DefaultContainerName = "job" - -func newScheduler(t *testing.T, objects ...*schedulerApi.ArangoProfile) Scheduler { - client := kclient.NewFakeClientBuilder().Client() - - objs := make([]interface{}, len(objects)) - for id := range objs { - objs[id] = &objects[id] - } - - tests.CreateObjects(t, client.Kubernetes(), client.Arango(), objs...) - - return NewScheduler(client, tests.FakeNamespace) -} - -type validatorExec func(in validator) - -type validator func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) - -func getRequest(in ...func(obj *pbSchedulerV1.Spec)) *pbSchedulerV1.Spec { - var r pbSchedulerV1.Spec - for _, i := range in { - i(&r) - } - - return &r -} - -func withProfiles(profiles ...string) func(obj *pbSchedulerV1.Spec) { - return func(obj *pbSchedulerV1.Spec) { - if obj.Job == nil { - obj.Job = &pbSchedulerV1.JobBase{} - } - - obj.Job.Profiles = append(obj.Job.Profiles, profiles...) - } -} - -func withLabels(labels map[string]string) func(obj *pbSchedulerV1.Spec) { - return func(obj *pbSchedulerV1.Spec) { - if obj.Job == nil { - obj.Job = &pbSchedulerV1.JobBase{} - } - - if obj.Job.Labels == nil { - obj.Job.Labels = make(map[string]string) - } - - for k, v := range labels { - obj.Job.Labels[k] = v - } - } -} - -func withDefaultContainer(in ...func(obj *pbSchedulerV1.ContainerBase)) func(obj *pbSchedulerV1.Spec) { - return func(obj *pbSchedulerV1.Spec) { - if obj.Containers == nil { - obj.Containers = make(map[string]*pbSchedulerV1.ContainerBase) - } - - var c pbSchedulerV1.ContainerBase - - for _, i := range in { - i(&c) - } - - obj.Containers[DefaultContainerName] = &c - } -} - -func render(t *testing.T, s Scheduler, in *pbSchedulerV1.Spec, templates ...*schedulerApi.ProfileTemplate) validatorExec { - pod, accepted, err := s.Render(context.Background(), in, templates...) - t.Logf("Accepted templates: %s", strings.Join(accepted, ", ")) - if err != nil { - return runValidate(t, err, pod, accepted) - } - require.NoError(t, err) - - data, err := yaml.Marshal(pod) - require.NoError(t, err) - - t.Logf("Rendered Template:\n%s", string(data)) - - return runValidate(t, nil, pod, accepted) -} - -func runValidate(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) validatorExec { - return func(in validator) { - t.Run("Validate", func(t *testing.T) { - in(t, err, template, accepted) - }) - } -} - -func Test_Nil(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test")), nil)(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.EqualError(t, err, "Unable to parse nil Spec") - }) -} - -func Test_NoProfiles(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test")), &pbSchedulerV1.Spec{})(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.EqualError(t, err, "Required at least 1 container") - }) -} - -func Test_MissingSelectedProfile(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test")), - getRequest(withProfiles("missing"), withDefaultContainer()), - )(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.EqualError(t, err, "Profile with name `missing` is missing") - }) -} - -func Test_SelectorWithoutSelector(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:1"), - }, - }, - }, - }, - } - })), getRequest(withDefaultContainer(func(obj *pbSchedulerV1.ContainerBase) { - obj.Image = util.NewType("") - })))(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.NoError(t, err) - - require.Len(t, accepted, 0) - - c := tests.GetContainerByNameT(t, template.Spec.Containers, DefaultContainerName) - require.Equal(t, "", c.Image) - }) -} - -func Test_SelectorWithSelectorAll(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Selectors = &schedulerApi.ProfileSelectors{ - Label: &meta.LabelSelector{}, - } - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:1"), - }, - }, - }, - }, - } - })), getRequest(withDefaultContainer()))(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.NoError(t, err) - - require.Len(t, accepted, 1) - require.Equal(t, []string{ - "test", - }, accepted) - - c := tests.GetContainerByNameT(t, template.Spec.Containers, DefaultContainerName) - require.Equal(t, "image:1", c.Image) - }) -} - -func Test_SelectorWithSpecificSelector_MissingLabel(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Selectors = &schedulerApi.ProfileSelectors{ - Label: &meta.LabelSelector{ - MatchExpressions: []meta.LabelSelectorRequirement{ - { - Key: "ml.arangodb.com/type", - Operator: meta.LabelSelectorOpExists, - }, - }, - }, - } - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:1"), - }, - }, - }, - }, - } - })), getRequest(withDefaultContainer()))(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.NoError(t, err) - - require.Len(t, accepted, 0) - - c := tests.GetContainerByNameT(t, template.Spec.Containers, DefaultContainerName) - require.Equal(t, "", c.Image) - }) -} - -func Test_SelectorWithSpecificSelector_PresentLabel(t *testing.T) { - render(t, newScheduler(t, tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Selectors = &schedulerApi.ProfileSelectors{ - Label: &meta.LabelSelector{ - MatchExpressions: []meta.LabelSelectorRequirement{ - { - Key: "ml.arangodb.com/type", - Operator: meta.LabelSelectorOpExists, - }, - }, - }, - } - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:1"), - }, - }, - }, - }, - } - })), getRequest(withDefaultContainer(), withLabels(map[string]string{ - "ml.arangodb.com/type": "training", - })), nil)(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.NoError(t, err) - - require.Len(t, accepted, 1) - require.Equal(t, []string{ - "test", - }, accepted) - - c := tests.GetContainerByNameT(t, template.Spec.Containers, DefaultContainerName) - require.Equal(t, "image:1", c.Image) - }) -} - -func Test_SelectorWithSpecificSelector_PresentLabel_ByPriority(t *testing.T) { - render(t, newScheduler(t, - tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Selectors = &schedulerApi.ProfileSelectors{ - Label: &meta.LabelSelector{ - MatchExpressions: []meta.LabelSelectorRequirement{ - { - Key: "ml.arangodb.com/type", - Operator: meta.LabelSelectorOpExists, - }, - }, - }, - } - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Priority: util.NewType(1), - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:1"), - }, - }, - }, - }, - } - }), tests.NewMetaObjectInDefaultNamespace[*schedulerApi.ArangoProfile](t, "test2", func(t *testing.T, obj *schedulerApi.ArangoProfile) { - obj.Spec.Selectors = &schedulerApi.ProfileSelectors{ - Label: &meta.LabelSelector{ - MatchExpressions: []meta.LabelSelectorRequirement{ - { - Key: "ml.arangodb.com/type", - Operator: meta.LabelSelectorOpExists, - }, - }, - }, - } - obj.Spec.Template = &schedulerApi.ProfileTemplate{ - Priority: util.NewType(2), - Container: &schedulerApi.ProfileContainerTemplate{ - Containers: schedulerContainerApi.Containers{ - DefaultContainerName: { - Image: &schedulerContainerResourcesApi.Image{ - Image: util.NewType("image:2"), - }, - }, - }, - }, - } - })), getRequest(withDefaultContainer(), withLabels(map[string]string{ - "ml.arangodb.com/type": "training", - }, - )))(func(t *testing.T, err error, template *core.PodTemplateSpec, accepted []string) { - require.NoError(t, err) - - require.Len(t, accepted, 2) - require.Equal(t, []string{ - "test2", - "test", - }, accepted) - - c := tests.GetContainerByNameT(t, template.Spec.Containers, DefaultContainerName) - require.Equal(t, "image:2", c.Image) - }) -} diff --git a/pkg/crd/arangoprofile.go b/pkg/util/constants/profiles.go similarity index 69% rename from pkg/crd/arangoprofile.go rename to pkg/util/constants/profiles.go index e421e9940..b603fca0a 100644 --- a/pkg/crd/arangoprofile.go +++ b/pkg/util/constants/profiles.go @@ -18,17 +18,9 @@ // Copyright holder is ArangoDB GmbH, Cologne, Germany // -package crd +package constants -import ( - "github.com/arangodb/kube-arangodb/pkg/crd/crds" -) +const ProfileGroup = "profiles.arangodb.com" -func init() { - registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { - return crds.SchedulerProfileDefinitionWithOptions(opts.AsFunc()) - }, &crds.CRDOptions{ - WithSchema: true, - WithPreserve: false, - }) -} +const ProfilesDeployment = ProfileGroup + "/deployment" +const ProfilesIntegrationPrefix = "integration." + ProfileGroup diff --git a/pkg/util/k8sutil/gvk.go b/pkg/util/k8sutil/gvk.go new file mode 100644 index 000000000..be549bd3a --- /dev/null +++ b/pkg/util/k8sutil/gvk.go @@ -0,0 +1,55 @@ +// +// 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 k8sutil + +import "k8s.io/apimachinery/pkg/runtime/schema" + +func CoreV1PodGVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: "", + Version: "v1", + Kind: "Pod", + } +} + +func AppsV1DeploymentGVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + } +} + +func BatchV1JobGVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: "batch", + Version: "v1", + Kind: "Job", + } +} + +func BatchV1CronJobGVK() schema.GroupVersionKind { + return schema.GroupVersionKind{ + Group: "batch", + Version: "v1", + Kind: "CronJob", + } +} diff --git a/pkg/util/k8sutil/inspector/generic/mod.go b/pkg/util/k8sutil/inspector/generic/mod.go index 7efc2c18f..37a0c2e25 100644 --- a/pkg/util/k8sutil/inspector/generic/mod.go +++ b/pkg/util/k8sutil/inspector/generic/mod.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. @@ -27,6 +27,14 @@ import ( "k8s.io/apimachinery/pkg/types" ) +type ListContinue interface { + GetContinue() string +} + +type ListInterface[S ListContinue] interface { + List(ctx context.Context, opts meta.ListOptions) (S, error) +} + type GetInterface[S meta.Object] interface { Get(ctx context.Context, name string, opts meta.GetOptions) (S, error) } diff --git a/pkg/util/k8sutil/list.go b/pkg/util/k8sutil/list.go index b066dd5cd..8202f5d1a 100644 --- a/pkg/util/k8sutil/list.go +++ b/pkg/util/k8sutil/list.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. @@ -24,17 +24,11 @@ import ( "context" meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/inspector/generic" ) -type ListContinue interface { - GetContinue() string -} - -type ListAPI[T ListContinue] interface { - List(ctx context.Context, opts meta.ListOptions) (T, error) -} - -func APIList[T ListContinue](ctx context.Context, api ListAPI[T], opts meta.ListOptions, parser func(result T, err error) error) error { +func APIList[T generic.ListContinue](ctx context.Context, api generic.ListInterface[T], opts meta.ListOptions, parser func(result T, err error) error) error { result, err := api.List(ctx, opts) for { if err := parser(result, err); err != nil { diff --git a/pkg/util/k8sutil/patcher/metadata.go b/pkg/util/k8sutil/patcher/metadata.go new file mode 100644 index 000000000..3dab8c2d1 --- /dev/null +++ b/pkg/util/k8sutil/patcher/metadata.go @@ -0,0 +1,54 @@ +// +// 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 patcher + +import ( + "k8s.io/apimachinery/pkg/api/equality" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/arangodb/kube-arangodb/pkg/deployment/patch" +) + +func PatchMetadata[T meta.Object](expected T) Patch[T] { + return func(in T) []patch.Item { + r := make([]patch.Item, 0, 3) + + if expected := expected.GetFinalizers(); expected != nil && !equality.Semantic.DeepEqual(expected, in.GetFinalizers()) { + r = append(r, + patch.ItemReplace(patch.NewPath("metadata", "finalizers"), expected), + ) + } + + if expected := expected.GetLabels(); expected != nil && !equality.Semantic.DeepEqual(expected, in.GetAnnotations()) { + r = append(r, + patch.ItemReplace(patch.NewPath("metadata", "labels"), expected), + ) + } + + if expected := expected.GetAnnotations(); expected != nil && !equality.Semantic.DeepEqual(expected, in.GetLabels()) { + r = append(r, + patch.ItemReplace(patch.NewPath("metadata", "annotations"), expected), + ) + } + + return r + } +} diff --git a/pkg/util/list.go b/pkg/util/list.go index 13409bc7f..5359f294a 100644 --- a/pkg/util/list.go +++ b/pkg/util/list.go @@ -22,7 +22,7 @@ package util import "sort" -type List[T comparable] []T +type List[T any] []T func (l List[T]) Filter(fn func(T) bool) List[T] { if l == nil { @@ -57,6 +57,30 @@ func (l List[T]) Sort(fn func(T, T) bool) List[T] { return clone } +func (l List[T]) Contains(fn func(T) bool) bool { + for _, e := range l { + if fn(e) { + return true + } + } + + return false +} + +func (l List[T]) Unique(f func(existing List[T], a T) bool) List[T] { + r := make(List[T], 0, len(l)) + + for _, o := range l { + if f(r, o) { + continue + } + + r = append(r, o) + } + + return r +} + func PickFromList[V any](in []V, q func(v V) bool) (V, bool) { for _, v := range in { if q(v) { diff --git a/pkg/util/tests/ap.go b/pkg/util/tests/ap.go new file mode 100644 index 000000000..4fcf8d41a --- /dev/null +++ b/pkg/util/tests/ap.go @@ -0,0 +1,47 @@ +// +// 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 tests + +import ( + "testing" + + "github.com/stretchr/testify/require" + + schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" +) + +func MarkArangoProfileAsReady(t *testing.T, obj *schedulerApi.ArangoProfile) { + if err := obj.Spec.Validate(); err != nil { + obj.Status.Conditions.Update(schedulerApi.SpecValidCondition, false, "Spec Invalid", "Spec Invalid") + obj.Status.Conditions.Update(schedulerApi.ReadyCondition, false, "Spec Invalid", "Spec Invalid") + return + } + obj.Status.Conditions.Update(schedulerApi.SpecValidCondition, true, "Spec Valid", "Spec Valid") + + checksum, err := obj.Spec.Template.Checksum() + require.NoError(t, err) + + obj.Status.Accepted = &schedulerApi.ProfileAcceptedTemplate{ + Checksum: checksum, + Template: obj.Spec.Template.DeepCopy(), + } + obj.Status.Conditions.Update(schedulerApi.ReadyCondition, true, "OK", "OK") +} diff --git a/pkg/util/tests/kubernetes.go b/pkg/util/tests/kubernetes.go index ea5c520a1..6eae5c44a 100644 --- a/pkg/util/tests/kubernetes.go +++ b/pkg/util/tests/kubernetes.go @@ -161,6 +161,12 @@ func CreateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := k8s.AppsV1().StatefulSets(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) + case **apps.Deployment: + require.NotNil(t, v) + + vl := *v + _, err := k8s.AppsV1().Deployments(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) case **api.ArangoDeployment: require.NotNil(t, v) @@ -251,6 +257,30 @@ func CreateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) require.NoError(t, err) + case **schedulerApi.ArangoSchedulerPod: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerPods(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerDeployment: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerDeployments(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerBatchJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerBatchJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerCronJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerCronJobs(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{}) + require.NoError(t, err) case **analyticsApi.GraphAnalyticsEngine: require.NotNil(t, v) @@ -333,6 +363,11 @@ func UpdateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := k8s.AppsV1().StatefulSets(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) + case **apps.Deployment: + require.NotNil(t, v) + vl := *v + _, err := k8s.AppsV1().Deployments(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) case **api.ArangoDeployment: require.NotNil(t, v) @@ -423,6 +458,30 @@ func UpdateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v _, err := arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) require.NoError(t, err) + case **schedulerApi.ArangoSchedulerPod: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerPods(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerDeployment: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerDeployments(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerBatchJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerBatchJobs(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) + case **schedulerApi.ArangoSchedulerCronJob: + require.NotNil(t, v) + + vl := *v + _, err := arango.SchedulerV1beta1().ArangoSchedulerCronJobs(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{}) + require.NoError(t, err) case **analyticsApi.GraphAnalyticsEngine: require.NotNil(t, v) @@ -493,6 +552,11 @@ func DeleteObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v err := k8s.AppsV1().StatefulSets(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{}) require.NoError(t, err) + case **apps.Deployment: + require.NotNil(t, v) + vl := *v + err := k8s.AppsV1().Deployments(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{}) + require.NoError(t, err) case **api.ArangoDeployment: require.NotNil(t, v) @@ -568,6 +632,26 @@ func DeleteObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe vl := *v require.NoError(t, arango.SchedulerV1beta1().ArangoProfiles(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **schedulerApi.ArangoSchedulerPod: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.SchedulerV1beta1().ArangoSchedulerPods(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **schedulerApi.ArangoSchedulerDeployment: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.SchedulerV1beta1().ArangoSchedulerDeployments(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **schedulerApi.ArangoSchedulerBatchJob: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.SchedulerV1beta1().ArangoSchedulerBatchJobs(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) + case **schedulerApi.ArangoSchedulerCronJob: + require.NotNil(t, v) + + vl := *v + require.NoError(t, arango.SchedulerV1beta1().ArangoSchedulerCronJobs(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{})) case **analyticsApi.GraphAnalyticsEngine: require.NotNil(t, v) @@ -725,6 +809,20 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } + case **apps.Deployment: + require.NotNil(t, v) + + vl := *v + vn, err := k8s.AppsV1().Deployments(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 **api.ArangoDeployment: require.NotNil(t, v) @@ -950,6 +1048,66 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS } else { *v = vn } + case **schedulerApi.ArangoSchedulerPod: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.SchedulerV1beta1().ArangoSchedulerPods(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 **schedulerApi.ArangoSchedulerDeployment: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.SchedulerV1beta1().ArangoSchedulerDeployments(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 **schedulerApi.ArangoSchedulerBatchJob: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.SchedulerV1beta1().ArangoSchedulerBatchJobs(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 **schedulerApi.ArangoSchedulerCronJob: + require.NotNil(t, v) + + vl := *v + + vn, err := arango.SchedulerV1beta1().ArangoSchedulerCronJobs(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 **analyticsApi.GraphAnalyticsEngine: require.NotNil(t, v) @@ -988,10 +1146,16 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS type MetaObjectMod[T meta.Object] func(t *testing.T, obj T) +func Apply[T meta.Object](t *testing.T, obj T, mods ...MetaObjectMod[T]) { + for _, m := range mods { + m(t, obj) + } +} + func SetMetaBasedOnType(t *testing.T, object meta.Object) { switch v := object.(type) { case *batch.CronJob: - v.Kind = "CronJob" + v.Kind = " ArangoSchedulerCronJob" v.APIVersion = "batch/v1" v.SetSelfLink(fmt.Sprintf("/api/batch/v1/cronjobs/%s/%s", object.GetNamespace(), @@ -1003,7 +1167,7 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) { object.GetNamespace(), object.GetName())) case *core.Pod: - v.Kind = "Pod" + v.Kind = " ArangoSchedulerPod" v.APIVersion = "v1" v.SetSelfLink(fmt.Sprintf("/api/v1/Pods/%s/%s", object.GetNamespace(), @@ -1044,6 +1208,12 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) { v.SetSelfLink(fmt.Sprintf("/api/apps/v1/statefulsets/%s/%s", object.GetNamespace(), object.GetName())) + case *apps.Deployment: + v.Kind = "Deployment" + v.APIVersion = "v1" + v.SetSelfLink(fmt.Sprintf("/api/apps/v1/deployments/%s/%s", + object.GetNamespace(), + object.GetName())) case *api.ArangoDeployment: v.Kind = deployment.ArangoDeploymentResourceKind v.APIVersion = api.SchemeGroupVersion.String() @@ -1156,6 +1326,38 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) { scheduler.ArangoProfileResourcePlural, object.GetNamespace(), object.GetName())) + case *schedulerApi.ArangoSchedulerPod: + v.Kind = scheduler.PodResourceKind + v.APIVersion = schedulerApi.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + schedulerApi.SchemeGroupVersion.String(), + scheduler.PodResourcePlural, + object.GetNamespace(), + object.GetName())) + case *schedulerApi.ArangoSchedulerDeployment: + v.Kind = scheduler.DeploymentResourceKind + v.APIVersion = schedulerApi.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + schedulerApi.SchemeGroupVersion.String(), + scheduler.DeploymentResourcePlural, + object.GetNamespace(), + object.GetName())) + case *schedulerApi.ArangoSchedulerBatchJob: + v.Kind = scheduler.BatchJobResourceKind + v.APIVersion = schedulerApi.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + schedulerApi.SchemeGroupVersion.String(), + scheduler.BatchJobResourcePlural, + object.GetNamespace(), + object.GetName())) + case *schedulerApi.ArangoSchedulerCronJob: + v.Kind = scheduler.CronJobResourceKind + v.APIVersion = schedulerApi.SchemeGroupVersion.String() + v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s", + schedulerApi.SchemeGroupVersion.String(), + scheduler.CronJobResourcePlural, + object.GetNamespace(), + object.GetName())) case *analyticsApi.GraphAnalyticsEngine: v.Kind = analytics.GraphAnalyticsEngineResourceKind v.APIVersion = analyticsApi.SchemeGroupVersion.String() @@ -1198,9 +1400,7 @@ func NewMetaObject[T meta.Object](t *testing.T, namespace, name string, mods ... SetMetaBasedOnType(t, obj) - for _, mod := range mods { - mod(t, obj) - } + Apply(t, obj, mods...) return obj } @@ -1220,7 +1420,7 @@ func GVK(t *testing.T, object meta.Object) schema.GroupVersionKind { return schema.GroupVersionKind{ Group: "batch", Version: "v1", - Kind: "CronJob", + Kind: " ArangoSchedulerCronJob", } case *batch.Job: return schema.GroupVersionKind{ @@ -1232,7 +1432,7 @@ func GVK(t *testing.T, object meta.Object) schema.GroupVersionKind { return schema.GroupVersionKind{ Group: "", Version: "v1", - Kind: "Pod", + Kind: " ArangoSchedulerPod", } case *core.Secret: return schema.GroupVersionKind{ @@ -1270,6 +1470,12 @@ func GVK(t *testing.T, object meta.Object) schema.GroupVersionKind { Version: "v1", Kind: "StatefulSet", } + case *apps.Deployment: + return schema.GroupVersionKind{ + Group: "apps", + Version: "v1", + Kind: "Deployment", + } case *api.ArangoDeployment: return schema.GroupVersionKind{ Group: deployment.ArangoDeploymentGroupName, @@ -1354,6 +1560,30 @@ func GVK(t *testing.T, object meta.Object) schema.GroupVersionKind { Version: schedulerApi.ArangoSchedulerVersion, Kind: scheduler.ArangoProfileResourceKind, } + case *schedulerApi.ArangoSchedulerPod: + return schema.GroupVersionKind{ + Group: scheduler.ArangoSchedulerGroupName, + Version: schedulerApi.ArangoSchedulerVersion, + Kind: scheduler.PodResourceKind, + } + case *schedulerApi.ArangoSchedulerDeployment: + return schema.GroupVersionKind{ + Group: scheduler.ArangoSchedulerGroupName, + Version: schedulerApi.ArangoSchedulerVersion, + Kind: scheduler.DeploymentResourceKind, + } + case *schedulerApi.ArangoSchedulerBatchJob: + return schema.GroupVersionKind{ + Group: scheduler.ArangoSchedulerGroupName, + Version: schedulerApi.ArangoSchedulerVersion, + Kind: scheduler.BatchJobResourceKind, + } + case *schedulerApi.ArangoSchedulerCronJob: + return schema.GroupVersionKind{ + Group: scheduler.ArangoSchedulerGroupName, + Version: schedulerApi.ArangoSchedulerVersion, + Kind: scheduler.CronJobResourceKind, + } case *analyticsApi.GraphAnalyticsEngine: return schema.GroupVersionKind{ Group: analytics.ArangoAnalyticsGroupName, diff --git a/pkg/util/tests/kubernetes_test.go b/pkg/util/tests/kubernetes_test.go index c29d42215..ffadeb629 100644 --- a/pkg/util/tests/kubernetes_test.go +++ b/pkg/util/tests/kubernetes_test.go @@ -68,6 +68,7 @@ func NewMetaObjectRun[T meta.Object](t *testing.T) { func Test_NewMetaObject(t *testing.T) { NewMetaObjectRun[*batch.Job](t) + NewMetaObjectRun[*batch.CronJob](t) NewMetaObjectRun[*core.Pod](t) NewMetaObjectRun[*core.Secret](t) NewMetaObjectRun[*core.ConfigMap](t) @@ -75,6 +76,7 @@ func Test_NewMetaObject(t *testing.T) { NewMetaObjectRun[*core.Service](t) NewMetaObjectRun[*core.Endpoints](t) NewMetaObjectRun[*apps.StatefulSet](t) + NewMetaObjectRun[*apps.Deployment](t) NewMetaObjectRun[*rbac.Role](t) NewMetaObjectRun[*rbac.RoleBinding](t) NewMetaObjectRun[*rbac.ClusterRole](t) @@ -89,6 +91,10 @@ func Test_NewMetaObject(t *testing.T) { NewMetaObjectRun[*mlApiv1alpha1.ArangoMLBatchJob](t) NewMetaObjectRun[*mlApiv1alpha1.ArangoMLCronJob](t) NewMetaObjectRun[*schedulerApi.ArangoProfile](t) + NewMetaObjectRun[*schedulerApi.ArangoSchedulerPod](t) + NewMetaObjectRun[*schedulerApi.ArangoSchedulerDeployment](t) + NewMetaObjectRun[*schedulerApi.ArangoSchedulerBatchJob](t) + NewMetaObjectRun[*schedulerApi.ArangoSchedulerCronJob](t) NewMetaObjectRun[*analyticsApi.GraphAnalyticsEngine](t) NewMetaObjectRun[*networkingApi.ArangoRoute](t) }