diff --git a/CHANGELOG.md b/CHANGELOG.md index dc68ac940..f1e06163c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - (Feature) ServerGroup Pointer - (Feature) Envoy AuthV3 Integration - (Maintenance) Switch to ubuntu:24.04 base image +- (Feature) Gateway Group for ArangoDeployment ## [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 62c999662..d33c24fc9 100644 --- a/Makefile +++ b/Makefile @@ -475,7 +475,7 @@ $(BIN): $(VBIN_LINUX_AMD64) $(VBIN_OPS_LINUX_AMD64) $(VBIN_INT_LINUX_AMD64) @cp "$(VBIN_OPS_LINUX_AMD64)" "$(BIN_OPS)" .PHONY: docker -docker: check-vars $(VBIN_LINUX_AMD64) $(VBIN_LINUX_ARM64) +docker: clean check-vars $(VBIN_LINUX_AMD64) $(VBIN_LINUX_ARM64) ifdef PUSHIMAGES docker buildx build --no-cache -f $(DOCKERFILE) --build-arg GOVERSION=$(GOVERSION) --build-arg DISTRIBUTION=$(DISTRIBUTION) \ --build-arg "VERSION=${VERSION_MAJOR_MINOR_PATCH}" --build-arg "RELEASE_MODE=$(RELEASE_MODE)" \ diff --git a/README.md b/README.md index ddcded77c..f863b2e4e 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ covers individual newer features separately. | Feature | Operator Version | Introduced | ArangoDB Version | ArangoDB Edition | State | Enabled | Flag | Remarks | |:------------------------------------------------------------------------------|:-----------------|:-----------|:-----------------|:----------------------|:-------------|:--------|:-------------------------------------------------------|:------------------------------------------------------------------------------------------| +| Gateway | 1.2.43 | 1.2.43 | >= 3.8.0 | Community, Enterprise | Alpha | True | N/A | Support for ArangoDeployment Gateway Group | | Cleanup Imported Backups | 1.2.41 | 1.2.41 | >= 3.8.0 | Community, Enterprise | Production | False | --deployment.feature.backup-cleanup | Cleanup backups created outside of the Operator and imported into Kubernetes ArangoBackup | | Upscale resources spec in init containers | 1.2.36 | 1.2.36 | >= 3.8.0 | Community, Enterprise | Production | True | --deployment.feature.init-containers-upscale-resources | Upscale resources spec to built-in init containers if they are not specified or lower | | Create backups asynchronously | 1.2.35 | 1.2.41 | >= 3.8.0 | Community, Enterprise | Production | True | --deployment.feature.async-backup-creation | Create backups asynchronously to avoid blocking the operator and reaching the timeout | diff --git a/docs/api/ArangoDeployment.V1.md b/docs/api/ArangoDeployment.V1.md index cb4436d8e..8bbbf460d 100644 --- a/docs/api/ArangoDeployment.V1.md +++ b/docs/api/ArangoDeployment.V1.md @@ -973,7 +973,7 @@ Possible Values: ### .spec.architecture -Type: `[]string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L254) +Type: `[]string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L257) Architecture defines the list of supported architectures. First element on the list is marked as default architecture. @@ -1050,7 +1050,7 @@ KillPodProbability is the chance of a pod being killed during an event ### .spec.ClusterDomain -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L226) +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L229) ClusterDomain define domain used in the kubernetes cluster. Required only of domain is not set to default (cluster.local) @@ -1061,7 +1061,7 @@ Default Value: `cluster.local` ### .spec.communicationMethod -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L234) +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L237) CommunicationMethod define communication method used in deployment @@ -3043,6 +3043,932 @@ Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1. *** +### .spec.gateways.affinity + +Type: `core.PodAffinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L185) + +Affinity specified additional affinity settings in ArangoDB Pod definitions + +Links: +* [Documentation of core.PodAffinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#podaffinity-v1-core) + +*** + +### .spec.gateways.allowMemberRecreation + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L227) + +AllowMemberRecreation allows to recreate member. +This setting changes the member recreation logic based on group: +- For Sync Masters, Sync Workers, Coordinator and DB-Servers it determines if a member can be recreated in case of failure (default `true`) +- For Agents and Single this value is hardcoded to `false` and the value provided in spec is ignored. + +*** + +### .spec.gateways.annotations + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L128) + +Annotations specified the annotations added to Pods in this group. +Annotations are merged with `spec.annotations`. + +*** + +### .spec.gateways.annotationsIgnoreList + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L130) + +AnnotationsIgnoreList list regexp or plain definitions which annotations should be ignored + +*** + +### .spec.gateways.annotationsMode + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L132) + +AnnotationsMode Define annotations mode which should be use while overriding annotations + +*** + +### .spec.gateways.antiAffinity + +Type: `core.PodAntiAffinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L181) + +AntiAffinity specified additional antiAffinity settings in ArangoDB Pod definitions + +Links: +* [Documentation of core.Pod.AntiAffinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#podantiaffinity-v1-core) + +*** + +### .spec.gateways.args + +Type: `[]string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L86) + +Args setting specifies additional command-line arguments passed to all servers of this group. + +Default Value: `[]` + +*** + +### .spec.gateways.count + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L78) + +Count setting specifies the number of servers to start for the given group. +For the Agent group, this value must be a positive, odd number. +The default value is `3` for all groups except `single` (there the default is `1` +for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). +For the `syncworkers` group, it is highly recommended to use the same number +as for the `dbservers` group. + +*** + +### .spec.gateways.entrypoint + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L88) + +Entrypoint overrides container executable + +*** + +### .spec.gateways.envs\[int\].name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_env_var.go#L26) + +*** + +### .spec.gateways.envs\[int\].value + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_env_var.go#L27) + +*** + +### .spec.gateways.ephemeralVolumes.apps.size + +Type: `resource.Quantity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_ephemeral_volumes.go#L64) + +Size define size of the ephemeral volume + +Links: +* [Documentation of resource.Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-core) + +*** + +### .spec.gateways.ephemeralVolumes.temp.size + +Type: `resource.Quantity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_ephemeral_volumes.go#L64) + +Size define size of the ephemeral volume + +Links: +* [Documentation of resource.Quantity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#quantity-resource-core) + +*** + +### .spec.gateways.exporterPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L240) + +ExporterPort define Port used by exporter + +*** + +### .spec.gateways.extendedRotationCheck + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L210) + +ExtendedRotationCheck extend checks for rotation + +*** + +### .spec.gateways.externalPortEnabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L222) + +ExternalPortEnabled if external port should be enabled. If is set to false, ports needs to be exposed via sidecar. Only for ArangoD members + +*** + +### .spec.gateways.indexMethod + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L233) + +IndexMethod define group Indexing method + +Possible Values: +* `"random"` (default) - Pick random ID for member. Enforced on the Community Operator. +* `"ordered"` - Use sequential number as Member ID, starting from 0. Enterprise Operator required. + +*** + +### .spec.gateways.initContainers.containers + +Type: `[]core.Container` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_init_containers.go#L91) + +Containers contains list of containers + +Links: +* [Documentation of core.Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#container-v1-core) + +*** + +### .spec.gateways.initContainers.mode + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_init_containers.go#L94) + +Mode keep container replace mode + +*** + +### .spec.gateways.internalPort + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L218) + +InternalPort define port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + +*** + +### .spec.gateways.internalPortProtocol + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L220) + +InternalPortProtocol define protocol of port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + +*** + +### .spec.gateways.labels + +Type: `object` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L134) + +Labels specified the labels added to Pods in this group. + +*** + +### .spec.gateways.labelsIgnoreList + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L136) + +LabelsIgnoreList list regexp or plain definitions which labels should be ignored + +*** + +### .spec.gateways.labelsMode + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L138) + +LabelsMode Define labels mode which should be use while overriding labels + +*** + +### .spec.gateways.maxCount + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L82) + +MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`. + +*** + +### .spec.gateways.memoryReservation + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L110) + +MemoryReservation determines the system reservation of memory while calculating `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` value. +If this field is set, `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` is reduced by a specified value in percent. +Accepted Range <0, 50>. If the value is outside the accepted range, it is adjusted to the closest value. + +Links: +* [Documentation of the ArangoDB Envs](https://docs.arangodb.com/devel/components/arangodb-server/environment-variables/) + +Default Value: `0` + +*** + +### .spec.gateways.minCount + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L80) + +MinCount specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`. + +*** + +### .spec.gateways.nodeAffinity + +Type: `core.NodeAffinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L189) + +NodeAffinity specified additional nodeAffinity settings in ArangoDB Pod definitions + +Links: +* [Documentation of code.NodeAffinity](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#nodeaffinity-v1-core) + +*** + +### .spec.gateways.nodeSelector + +Type: `map[string]string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L153) + +NodeSelector setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + +Links: +* [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/) + +*** + +### .spec.gateways.numactl.args + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_numactl_spec.go#L38) + +Args define list of the numactl process + +Default Value: `[]` + +*** + +### .spec.gateways.numactl.enabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_numactl_spec.go#L30) + +Enabled define if numactl should be enabled + +Default Value: `false` + +*** + +### .spec.gateways.numactl.path + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_numactl_spec.go#L34) + +Path define numactl path within the container + +Default Value: `/usr/bin/numactl` + +*** + +### .spec.gateways.overrideDetectedNumberOfCores + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L116) + +> [!IMPORTANT] +> **Values set by this feature override user-provided `ARANGODB_OVERRIDE_DETECTED_NUMBER_OF_CORES` Container Environment Variable** + +OverrideDetectedNumberOfCores determines if number of cores should be overridden based on values in resources. +If is set to true and Container CPU Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_NUMBER_OF_CORES` to the value from the Container CPU Limits. + +Links: +* [Documentation of the ArangoDB Envs](https://docs.arangodb.com/devel/components/arangodb-server/environment-variables/) + +Default Value: `true` + +*** + +### .spec.gateways.overrideDetectedTotalMemory + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L104) + +> [!IMPORTANT] +> **Values set by this feature override user-provided `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` Container Environment Variable** + +OverrideDetectedTotalMemory determines if memory should be overridden based on values in resources. +If is set to true and Container Memory Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` to the value from the Container Memory Limits. + +Links: +* [Documentation of the ArangoDB Envs](https://docs.arangodb.com/devel/components/arangodb-server/environment-variables/) + +Default Value: `true` + +*** + +### .spec.gateways.podModes.network + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec_pod_modes.go#L31) + +*** + +### .spec.gateways.podModes.pid + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec_pod_modes.go#L32) + +*** + +### .spec.gateways.port + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L238) + +Port define Port used by member + +*** + +### .spec.gateways.priorityClassName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L159) + +PriorityClassName specifies a priority class name +Will be forwarded to the pod spec. + +Links: +* [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/) + +*** + +### .spec.gateways.probes.livenessProbeDisabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L250) + +LivenessProbeDisabled if set to true, the operator does not generate a liveness probe for new pods belonging to this group + +Default Value: `false` + +*** + +### .spec.gateways.probes.livenessProbeSpec.failureThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L300) + +FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. +Giving up means restarting the container. +Minimum value is 1. + +Default Value: `3` + +*** + +### .spec.gateways.probes.livenessProbeSpec.initialDelaySeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L283) + +InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. +Minimum value is 0. + +Default Value: `2` + +*** + +### .spec.gateways.probes.livenessProbeSpec.periodSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L287) + +PeriodSeconds How often (in seconds) to perform the probe. +Minimum value is 1. + +Default Value: `10` + +*** + +### .spec.gateways.probes.livenessProbeSpec.successThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L295) + +SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. +Minimum value is 1. + +Default Value: `1` + +*** + +### .spec.gateways.probes.livenessProbeSpec.timeoutSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L291) + +TimeoutSeconds specifies number of seconds after which the probe times out +Minimum value is 1. + +Default Value: `2` + +*** + +### .spec.gateways.probes.ReadinessProbeDisabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L257) + +> [!WARNING] +> ***DEPRECATED*** +> +> **This field is deprecated, kept only for backward compatibility.** + +OldReadinessProbeDisabled if true readinessProbes are disabled + +*** + +### .spec.gateways.probes.readinessProbeDisabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L259) + +ReadinessProbeDisabled override flag for probe disabled in good manner (lowercase) with backward compatibility + +*** + +### .spec.gateways.probes.readinessProbeSpec.failureThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L300) + +FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. +Giving up means restarting the container. +Minimum value is 1. + +Default Value: `3` + +*** + +### .spec.gateways.probes.readinessProbeSpec.initialDelaySeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L283) + +InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. +Minimum value is 0. + +Default Value: `2` + +*** + +### .spec.gateways.probes.readinessProbeSpec.periodSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L287) + +PeriodSeconds How often (in seconds) to perform the probe. +Minimum value is 1. + +Default Value: `10` + +*** + +### .spec.gateways.probes.readinessProbeSpec.successThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L295) + +SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. +Minimum value is 1. + +Default Value: `1` + +*** + +### .spec.gateways.probes.readinessProbeSpec.timeoutSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L291) + +TimeoutSeconds specifies number of seconds after which the probe times out +Minimum value is 1. + +Default Value: `2` + +*** + +### .spec.gateways.probes.startupProbeDisabled + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L264) + +StartupProbeDisabled if true startupProbes are disabled + +*** + +### .spec.gateways.probes.startupProbeSpec.failureThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L300) + +FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. +Giving up means restarting the container. +Minimum value is 1. + +Default Value: `3` + +*** + +### .spec.gateways.probes.startupProbeSpec.initialDelaySeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L283) + +InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. +Minimum value is 0. + +Default Value: `2` + +*** + +### .spec.gateways.probes.startupProbeSpec.periodSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L287) + +PeriodSeconds How often (in seconds) to perform the probe. +Minimum value is 1. + +Default Value: `10` + +*** + +### .spec.gateways.probes.startupProbeSpec.successThreshold + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L295) + +SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. +Minimum value is 1. + +Default Value: `1` + +*** + +### .spec.gateways.probes.startupProbeSpec.timeoutSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L291) + +TimeoutSeconds specifies number of seconds after which the probe times out +Minimum value is 1. + +Default Value: `2` + +*** + +### .spec.gateways.pvcResizeMode + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L173) + +VolumeResizeMode specified resize mode for PVCs and PVs + +Possible Values: +* `"runtime"` (default) - PVC will be resized in Pod runtime (EKS, GKE) +* `"rotate"` - Pod will be shutdown and PVC will be resized (AKS) + +*** + +### .spec.gateways.resources + +Type: `core.ResourceRequirements` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L98) + +Resources holds resource requests & limits + +Links: +* [Documentation of core.ResourceRequirements](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#resourcerequirements-v1-core) + +*** + +### .spec.gateways.schedulerName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L90) + +SchedulerName define scheduler name used for group + +*** + +### .spec.gateways.securityContext.addCapabilities + +Type: `[]core.Capability` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L41) + +AddCapabilities add new capabilities to containers + +*** + +### .spec.gateways.securityContext.allowPrivilegeEscalation + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L44) + +AllowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process. + +*** + +### .spec.gateways.securityContext.dropAllCapabilities + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L38) + +> [!WARNING] +> ***DEPRECATED*** +> +> **This field is added for backward compatibility. Will be removed in 1.1.0.** + +DropAllCapabilities specifies if capabilities should be dropped for this pod containers + +*** + +### .spec.gateways.securityContext.fsGroup + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L61) + +FSGroup is a special supplemental group that applies to all containers in a pod. + +*** + +### .spec.gateways.securityContext.privileged + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L47) + +Privileged If true, runs container in privileged mode. Processes in privileged containers are +essentially equivalent to root on the host. + +*** + +### .spec.gateways.securityContext.readOnlyRootFilesystem + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L49) + +ReadOnlyRootFilesystem if true, mounts the container's root filesystem as read-only. + +*** + +### .spec.gateways.securityContext.runAsGroup + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L55) + +RunAsGroup is the GID to run the entrypoint of the container process. + +*** + +### .spec.gateways.securityContext.runAsNonRoot + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L51) + +RunAsNonRoot if true, indicates that the container must run as a non-root user. + +*** + +### .spec.gateways.securityContext.runAsUser + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L53) + +RunAsUser is the UID to run the entrypoint of the container process. + +*** + +### .spec.gateways.securityContext.seccompProfile + +Type: `core.SeccompProfile` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L77) + +SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set. + +Links: +* [Documentation of core.SeccompProfile](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#seccompprofile-v1-core) + +*** + +### .spec.gateways.securityContext.seLinuxOptions + +Type: `core.SELinuxOptions` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L82) + +SELinuxOptions are the labels to be applied to the container + +Links: +* [Documentation of core.SELinuxOptions](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#selinuxoptions-v1-core) + +*** + +### .spec.gateways.securityContext.supplementalGroups + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L59) + +SupplementalGroups is a list of groups applied to the first process run in each container, in addition to the container's primary GID, +the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. + +*** + +### .spec.gateways.securityContext.sysctls + +Type: `map[string]intstr.IntOrString` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_security_context_spec.go#L72) + +Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported +sysctls (by the container runtime) might fail to launch. +Map Value can be String or Int + +Links: +* [Documentation](https://kubernetes.io/docs/tasks/administer-cluster/sysctl-cluster/) + +Example: +```yaml +sysctls: + "kernel.shm_rmid_forced": "0" + "net.core.somaxconn": 1024 + "kernel.msgmax": "65536" +``` + +*** + +### .spec.gateways.serviceAccountName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L149) + +ServiceAccountName setting specifies the `serviceAccountName` for the `Pods` created +for each server of this group. If empty, it defaults to using the +`default` service account. +Using an alternative `ServiceAccount` is typically used to separate access rights. +The ArangoDB deployments need some very minimal access rights. With the +deployment of the operator, we grant the rights to 'get' all 'pod' resources. +If you are using a different service account, please grant these rights +to that service account. + +*** + +### .spec.gateways.shutdownDelay + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L216) + +ShutdownDelay define how long operator should delay finalizer removal after shutdown + +*** + +### .spec.gateways.shutdownMethod + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L214) + +ShutdownMethod describe procedure of member shutdown taken by Operator + +*** + +### .spec.gateways.sidecarCoreNames + +Type: `array` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L192) + +SidecarCoreNames is a list of sidecar containers which must run in the pod. +Some names (e.g.: "server", "worker") are reserved, and they don't have any impact. + +*** + +### .spec.gateways.sidecars + +Type: `[]core.Container` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L196) + +Sidecars specifies a list of additional containers to be started + +Links: +* [Documentation of core.Container](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#container-v1-core) + +*** + +### .spec.gateways.storageClassName + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L94) + +> [!WARNING] +> ***DEPRECATED*** +> +> **Use VolumeClaimTemplate instead.** + +StorageClassName specifies the classname for storage of the servers. + +*** + +### .spec.gateways.terminationGracePeriodSeconds + +Type: `integer` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L229) + +TerminationGracePeriodSeconds override default TerminationGracePeriodSeconds for pods - via silent rotation + +*** + +### .spec.gateways.tolerations + +Type: `[]core.Toleration` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L125) + +Tolerations specifies the tolerations added to Pods in this group. +By default, suitable tolerations are set for the following keys with the `NoExecute` effect: +- `node.kubernetes.io/not-ready` +- `node.kubernetes.io/unreachable` +- `node.alpha.kubernetes.io/unreachable` (will be removed in future version) +For more information on tolerations, consult the https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + +Links: +* [Documentation of core.Toleration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#toleration-v1-core) + +*** + +### .spec.gateways.volumeAllowShrink + +Type: `boolean` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L177) + +> [!WARNING] +> ***DEPRECATED*** +> +> **Not used anymore** + +VolumeAllowShrink allows shrinking of the volume + +*** + +### .spec.gateways.volumeClaimTemplate + +Type: `core.PersistentVolumeClaim` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L168) + +VolumeClaimTemplate specifies a volumeClaimTemplate used by operator to create to volume claims for pods of this group. +This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`. +The default value describes a volume with `8Gi` storage, `ReadWriteOnce` access mode and volume mode set to `PersistentVolumeFilesystem`. +If this field is not set and `spec..resources.requests.storage` is set, then a default volume claim +with size as specified by `spec..resources.requests.storage` will be created. In that case `storage` +and `iops` is not forwarded to the pods resource requirements. + +Links: +* [Documentation of core.PersistentVolumeClaim](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#persistentvolumeclaim-v1-core) + +*** + +### .spec.gateways.volumeMounts + +Type: `[]ServerGroupSpecVolumeMount` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_spec.go#L206) + +VolumeMounts define list of volume mounts mounted into server container + +Links: +* [Documentation of ServerGroupSpecVolumeMount](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#volumemount-v1-core) + +*** + +### .spec.gateways.volumes\[int\].configMap + +Type: `core.ConfigMapVolumeSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L138) + +ConfigMap which should be mounted into pod + +Links: +* [Documentation of core.ConfigMapVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#configmapvolumesource-v1-core) + +*** + +### .spec.gateways.volumes\[int\].emptyDir + +Type: `core.EmptyDirVolumeSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L143) + +EmptyDir + +Links: +* [Documentation of core.EmptyDirVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#emptydirvolumesource-v1-core) + +*** + +### .spec.gateways.volumes\[int\].hostPath + +Type: `core.HostPathVolumeSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L148) + +HostPath + +Links: +* [Documentation of core.HostPathVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#hostpathvolumesource-v1-core) + +*** + +### .spec.gateways.volumes\[int\].name + +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L128) + +Name of volume + +*** + +### .spec.gateways.volumes\[int\].persistentVolumeClaim + +Type: `core.PersistentVolumeClaimVolumeSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L153) + +PersistentVolumeClaim + +Links: +* [Documentation of core.PersistentVolumeClaimVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#persistentvolumeclaimvolumesource-v1-core) + +*** + +### .spec.gateways.volumes\[int\].secret + +Type: `core.SecretVolumeSource` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_group_volume.go#L133) + +Secret which should be mounted into pod + +Links: +* [Documentation of core.SecretVolumeSource](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#secretvolumesource-v1-core) + +*** + ### .spec.id.affinity Type: `core.PodAffinity` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/server_id_group_spec.go#L48) @@ -3369,7 +4295,7 @@ Links: ### .spec.memberPropagationMode -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L209) +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L212) MemberPropagationMode defines how changes to pod spec should be propogated. Changes to a pod’s configuration require a restart of that pod in almost all cases. @@ -6605,7 +7531,7 @@ MaintenanceGracePeriod action timeout ### .spec.timezone -Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L258) +Type: `string` [\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/deployment/v1/deployment_spec.go#L261) Timezone if specified, will set a timezone for deployment. Must be in format accepted by "tzdata", e.g. `America/New_York` or `Europe/London` diff --git a/docs/features/README.md b/docs/features/README.md index 5efce638b..c59b17ffb 100644 --- a/docs/features/README.md +++ b/docs/features/README.md @@ -8,6 +8,7 @@ title: List of all features | Feature | Operator Version | Introduced | ArangoDB Version | ArangoDB Edition | State | Enabled | Flag | Remarks | |:----------------------------------------------------------------|:-----------------|:-----------|:-----------------|:----------------------|:-------------|:--------|:-------------------------------------------------------|:------------------------------------------------------------------------------------------| +| Gateway | 1.2.43 | 1.2.43 | >= 3.8.0 | Community, Enterprise | Alpha | True | N/A | Support for ArangoDeployment Gateway Group | | Cleanup Imported Backups | 1.2.41 | 1.2.41 | >= 3.8.0 | Community, Enterprise | Production | False | --deployment.feature.backup-cleanup | Cleanup backups created outside of the Operator and imported into Kubernetes ArangoBackup | | Upscale resources spec in init containers | 1.2.36 | 1.2.36 | >= 3.8.0 | Community, Enterprise | Production | True | --deployment.feature.init-containers-upscale-resources | Upscale resources spec to built-in init containers if they are not specified or lower | | Create backups asynchronously | 1.2.35 | 1.2.41 | >= 3.8.0 | Community, Enterprise | Production | True | --deployment.feature.async-backup-creation | Create backups asynchronously to avoid blocking the operator and reaching the timeout | diff --git a/internal/features.yaml b/internal/features.yaml index 3fce1a5f9..fddd3f509 100644 --- a/internal/features.yaml +++ b/internal/features.yaml @@ -257,3 +257,8 @@ features: releases: - operatorVersion: 1.2.36 state: Alpha + - name: Gateway + remarks: Support for ArangoDeployment Gateway Group + releases: + - operatorVersion: 1.2.43 + state: Alpha diff --git a/pkg/apis/deployment/v1/deployment.go b/pkg/apis/deployment/v1/deployment.go index 4f5d186b8..ec8bb763d 100644 --- a/pkg/apis/deployment/v1/deployment.go +++ b/pkg/apis/deployment/v1/deployment.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ func (d *ArangoDeployment) AsOwner() meta.OwnerReference { // ForeachServerGroup calls the given callback for all server groups. // If the callback returns an error, this error is returned and no other server // groups are processed. -// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers +// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers, gateways func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *DeploymentStatus) error { if status == nil { status = &d.Status @@ -84,7 +84,7 @@ func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *Deploy // ForeachServerGroupAccepted calls the given callback for all accepted server groups. // If the callback returns an error, this error is returned and no other server // groups are processed. -// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers +// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers, gateways func (d *ArangoDeployment) ForeachServerGroupAccepted(cb ServerGroupFunc, status *DeploymentStatus) error { if status == nil { status = &d.Status @@ -115,6 +115,9 @@ func (d *ArangoDeployment) foreachServerGroup(cb ServerGroupFunc, spec Deploymen if err := cb(ServerGroupSyncWorkers, spec.SyncWorkers, &status.Members.SyncWorkers); err != nil { return errors.WithStack(err) } + if err := cb(ServerGroupGateways, spec.Gateways.Get(), &status.Members.Gateways); err != nil { + return errors.WithStack(err) + } return nil } diff --git a/pkg/apis/deployment/v1/deployment_spec.go b/pkg/apis/deployment/v1/deployment_spec.go index 12a8690d6..d25070f04 100644 --- a/pkg/apis/deployment/v1/deployment_spec.go +++ b/pkg/apis/deployment/v1/deployment_spec.go @@ -199,6 +199,9 @@ type DeploymentSpec struct { // SyncWorkers contains specification for Syncworker pods running in deployment mode `Cluster`. SyncWorkers ServerGroupSpec `json:"syncworkers"` + // Gateways contain specification for Gateway pods running in deployment mode `Single` or `Cluster`. + Gateways *ServerGroupSpec `json:"gateways,omitempty"` + // MemberPropagationMode defines how changes to pod spec should be propogated. // Changes to a pod’s configuration require a restart of that pod in almost all cases. // Pods are restarted eagerly by default, which can cause more restarts than desired, especially when updating arangod as well as the operator. @@ -256,6 +259,9 @@ type DeploymentSpec struct { // Timezone if specified, will set a timezone for deployment. // Must be in format accepted by "tzdata", e.g. `America/New_York` or `Europe/London` Timezone *string `json:"timezone,omitempty"` + + // Gateway defined main Gateway configuration. + Gateway *DeploymentSpecGateway `json:"gateway,omitempty"` } // GetAllowMemberRecreation returns member recreation policy based on group and settings @@ -267,6 +273,8 @@ func (s *DeploymentSpec) GetAllowMemberRecreation(group ServerGroup) bool { groupSpec := s.GetServerGroupSpec(group) switch group { + case ServerGroupGateways: + return true case ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: if v := groupSpec.AllowMemberRecreation; v == nil { return true @@ -326,6 +334,11 @@ func (s DeploymentSpec) GetSyncImage() string { return s.GetImage() } +// IsGatewayEnabled returns true when the deployment has gateways enabled. +func (s DeploymentSpec) IsGatewayEnabled() bool { + return s.Gateway.IsEnabled() +} + // GetImagePullPolicy returns the value of imagePullPolicy. func (s DeploymentSpec) GetImagePullPolicy() core.PullPolicy { return util.TypeOrDefault[core.PullPolicy](s.ImagePullPolicy) @@ -364,8 +377,7 @@ func (s DeploymentSpec) IsSecure() bool { return s.TLS.IsSecure() } -// GetServerGroupSpec returns the server group spec (from this -// deployment spec) for the given group. +// GetServerGroupSpec returns the server group spec (from this deployment spec) for the given group. func (s DeploymentSpec) GetServerGroupSpec(group ServerGroup) ServerGroupSpec { switch group { case ServerGroupSingle: @@ -380,13 +392,14 @@ func (s DeploymentSpec) GetServerGroupSpec(group ServerGroup) ServerGroupSpec { return s.SyncMasters.WithGroup(group) case ServerGroupSyncWorkers: return s.SyncWorkers.WithGroup(group) + case ServerGroupGateways: + return s.Gateways.WithGroup(group) default: return ServerGroupSpec{} } } -// UpdateServerGroupSpec returns the server group spec (from this -// deployment spec) for the given group. +// UpdateServerGroupSpec returns the server group spec (from this deployment spec) for the given group. func (s *DeploymentSpec) UpdateServerGroupSpec(group ServerGroup, gspec ServerGroupSpec) { switch group { case ServerGroupSingle: @@ -401,6 +414,8 @@ func (s *DeploymentSpec) UpdateServerGroupSpec(group ServerGroup, gspec ServerGr s.SyncMasters = gspec case ServerGroupSyncWorkers: s.SyncWorkers = gspec + case ServerGroupGateways: + s.Gateways = gspec.DeepCopy() } } @@ -421,6 +436,11 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { if s.GetImagePullPolicy() == "" { s.ImagePullPolicy = util.NewType[core.PullPolicy](core.PullIfNotPresent) } + if s.Gateway.IsEnabled() { + if s.Gateways == nil { + s.Gateways = &ServerGroupSpec{} + } + } s.ExternalAccess.SetDefaults() s.RocksDB.SetDefaults() s.Authentication.SetDefaults(deploymentName + "-jwt") @@ -432,6 +452,7 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { s.Coordinators.SetDefaults(ServerGroupCoordinators, s.GetMode().HasCoordinators(), s.GetMode()) s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.IsEnabled(), s.GetMode()) s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode()) + s.Gateways.SetDefaults(ServerGroupGateways, s.IsGatewayEnabled(), s.GetMode()) s.Metrics.SetDefaults(deploymentName+"-exporter-jwt-token", s.Authentication.IsAuthenticated()) s.Chaos.SetDefaults() s.Bootstrap.SetDefaults(deploymentName) @@ -480,6 +501,7 @@ func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { s.Coordinators.SetDefaultsFrom(source.Coordinators) s.SyncMasters.SetDefaultsFrom(source.SyncMasters) s.SyncWorkers.SetDefaultsFrom(source.SyncWorkers) + s.Gateways.SetDefaultsFrom(source.Gateways.Get()) s.Metrics.SetDefaultsFrom(source.Metrics) s.Lifecycle.SetDefaultsFrom(source.Lifecycle) s.Chaos.SetDefaultsFrom(source.Chaos) @@ -539,6 +561,11 @@ func (s *DeploymentSpec) Validate() error { if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { return errors.WithStack(err) } + if s.IsGatewayEnabled() { + if err := s.Gateways.Validate(ServerGroupGateways, s.IsGatewayEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { + return errors.WithStack(err) + } + } if err := s.Metrics.Validate(); err != nil { return errors.WithStack(errors.Wrap(err, "spec.metrics")) } @@ -554,6 +581,9 @@ func (s *DeploymentSpec) Validate() error { if err := s.Architecture.Validate(); err != nil { return errors.WithStack(errors.Wrap(err, "spec.architecture")) } + if err := s.Gateway.Validate(); err != nil { + return errors.WithStack(errors.Wrap(err, "spec.architecture")) + } return nil } @@ -614,6 +644,14 @@ func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string { if l := s.SyncWorkers.ResetImmutableFields(ServerGroupSyncWorkers, "syncworkers", &target.SyncWorkers); l != nil { resetFields = append(resetFields, l...) } + if s.Gateways != nil { + if target.Gateways == nil { + target.Gateways = &ServerGroupSpec{} + } + if l := s.Gateways.ResetImmutableFields(ServerGroupGateways, "gateways", target.Gateways); l != nil { + resetFields = append(resetFields, l...) + } + } if l := s.Metrics.ResetImmutableFields("metrics", &target.Metrics); l != nil { resetFields = append(resetFields, l...) } diff --git a/pkg/apis/deployment/v1/deployment_spec_gateway.go b/pkg/apis/deployment/v1/deployment_spec_gateway.go new file mode 100644 index 000000000..ecb4f9389 --- /dev/null +++ b/pkg/apis/deployment/v1/deployment_spec_gateway.go @@ -0,0 +1,37 @@ +// +// 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 + +type DeploymentSpecGateway struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func (d *DeploymentSpecGateway) IsEnabled() bool { + if d == nil || d.Enabled == nil { + return false + } + + return *d.Enabled +} + +func (d *DeploymentSpecGateway) Validate() error { + return nil +} diff --git a/pkg/apis/deployment/v1/deployment_status.go b/pkg/apis/deployment/v1/deployment_status.go index d6f0fcd9a..6f422ff8c 100644 --- a/pkg/apis/deployment/v1/deployment_status.go +++ b/pkg/apis/deployment/v1/deployment_status.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -103,6 +103,7 @@ type DeploymentStatus struct { Coordinators *ServerGroupStatus `json:"coordinators,omitempty"` SyncMasters *ServerGroupStatus `json:"syncmasters,omitempty"` SyncWorkers *ServerGroupStatus `json:"syncworkers,omitempty"` + Gateways *ServerGroupStatus `json:"gateways,omitempty"` } // Equal checks for equality @@ -174,6 +175,8 @@ func (ds DeploymentStatus) getServerGroupStatus(group ServerGroup) *ServerGroupS return ds.SyncMasters.DeepCopy() case ServerGroupSyncWorkers: return ds.SyncWorkers.DeepCopy() + case ServerGroupGateways: + return ds.Gateways.DeepCopy() default: return nil } @@ -195,5 +198,7 @@ func (ds *DeploymentStatus) UpdateServerGroupStatus(group ServerGroup, gspec Ser ds.SyncMasters = &gspec case ServerGroupSyncWorkers: ds.SyncWorkers = &gspec + case ServerGroupGateways: + ds.Gateways = &gspec } } diff --git a/pkg/apis/deployment/v1/deployment_status_members.go b/pkg/apis/deployment/v1/deployment_status_members.go index 8215de38e..25fce7f47 100644 --- a/pkg/apis/deployment/v1/deployment_status_members.go +++ b/pkg/apis/deployment/v1/deployment_status_members.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ type DeploymentStatusMembers struct { Coordinators MemberStatusList `json:"coordinators,omitempty"` SyncMasters MemberStatusList `json:"syncmasters,omitempty"` SyncWorkers MemberStatusList `json:"syncworkers,omitempty"` + Gateways MemberStatusList `json:"gateways,omitempty"` } // Equal checks for equality @@ -44,7 +45,8 @@ func (ds DeploymentStatusMembers) Equal(other DeploymentStatusMembers) bool { ds.DBServers.Equal(other.DBServers) && ds.Coordinators.Equal(other.Coordinators) && ds.SyncMasters.Equal(other.SyncMasters) && - ds.SyncWorkers.Equal(other.SyncWorkers) + ds.SyncWorkers.Equal(other.SyncWorkers) && + ds.Gateways.Equal(other.Gateways) } // ContainsID returns true if the given set of members contains a member with given ID. @@ -54,7 +56,8 @@ func (ds DeploymentStatusMembers) ContainsID(id string) bool { ds.DBServers.ContainsID(id) || ds.Coordinators.ContainsID(id) || ds.SyncMasters.ContainsID(id) || - ds.SyncWorkers.ContainsID(id) + ds.SyncWorkers.ContainsID(id) || + ds.Gateways.ContainsID(id) } // ElementByID returns the element in the given list that has the given ID and true. @@ -78,6 +81,9 @@ func (ds DeploymentStatusMembers) ElementByID(id string) (MemberStatus, ServerGr if result, found := ds.SyncWorkers.ElementByID(id); found { return result, ServerGroupSyncWorkers, true } + if result, found := ds.Gateways.ElementByID(id); found { + return result, ServerGroupGateways, true + } return MemberStatus{}, 0, false } @@ -129,6 +135,10 @@ func (ds DeploymentStatusMembers) ForServerGroup(cb MemberStatusFunc, group Serv if err := cb(ServerGroupSyncWorkers, ds.SyncWorkers); err != nil { return errors.WithStack(err) } + case ServerGroupGateways: + if err := cb(ServerGroupGateways, ds.Gateways); err != nil { + return errors.WithStack(err) + } } return nil } @@ -155,6 +165,9 @@ func (ds DeploymentStatusMembers) MemberStatusByPodName(podName string) (MemberS if result, found := ds.SyncWorkers.ElementByPodName(podName); found { return result, ServerGroupSyncWorkers, true } + if result, found := ds.Gateways.ElementByPodName(podName); found { + return result, ServerGroupGateways, true + } return MemberStatus{}, 0, false } @@ -190,6 +203,8 @@ func (ds *DeploymentStatusMembers) Add(status MemberStatus, group ServerGroup) e err = ds.SyncMasters.add(status) case ServerGroupSyncWorkers: err = ds.SyncWorkers.add(status) + case ServerGroupGateways: + err = ds.Gateways.add(status) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -215,6 +230,8 @@ func (ds *DeploymentStatusMembers) Update(status MemberStatus, group ServerGroup err = ds.SyncMasters.update(status) case ServerGroupSyncWorkers: err = ds.SyncWorkers.update(status) + case ServerGroupGateways: + err = ds.Gateways.update(status) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -241,6 +258,8 @@ func (ds *DeploymentStatusMembers) RemoveByID(id string, group ServerGroup) erro err = ds.SyncMasters.removeByID(id) case ServerGroupSyncWorkers: err = ds.SyncWorkers.removeByID(id) + case ServerGroupGateways: + err = ds.Gateways.removeByID(id) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -250,23 +269,30 @@ func (ds *DeploymentStatusMembers) RemoveByID(id string, group ServerGroup) erro return nil } -// AllMembersReady returns true when all members, that must be ready for the given mode, are in the Ready state. -func (ds DeploymentStatusMembers) AllMembersReady(mode DeploymentMode, syncEnabled bool) bool { +// AllMembersReady returns true when all members, that must be ready for the given mode are in the Ready state. +func (ds DeploymentStatusMembers) AllMembersReady(mode DeploymentMode, syncEnabled, gatewayEnabled bool) bool { syncReady := func() bool { if syncEnabled { return ds.SyncMasters.AllMembersReady() && ds.SyncWorkers.AllMembersReady() } return true } + gatewayReady := func() bool { + if gatewayEnabled { + return ds.Gateways.AllMembersReady() + } + return true + } switch mode { case DeploymentModeSingle: - return ds.Single.MembersReady() > 0 + return ds.Single.MembersReady() > 0 && gatewayReady() case DeploymentModeActiveFailover: return ds.Agents.AllMembersReady() && ds.Single.MembersReady() > 0 case DeploymentModeCluster: return ds.Agents.AllMembersReady() && ds.DBServers.AllMembersReady() && ds.Coordinators.AllMembersReady() && + gatewayReady() && syncReady() default: return false @@ -288,6 +314,8 @@ func (ds DeploymentStatusMembers) MembersOfGroup(group ServerGroup) MemberStatus return ds.SyncMasters case ServerGroupSyncWorkers: return ds.SyncWorkers + case ServerGroupGateways: + return ds.Gateways default: return MemberStatusList{} } diff --git a/pkg/apis/deployment/v1/deployment_status_members_test.go b/pkg/apis/deployment/v1/deployment_status_members_test.go index aea0020b7..e88f2a1e9 100644 --- a/pkg/apis/deployment/v1/deployment_status_members_test.go +++ b/pkg/apis/deployment/v1/deployment_status_members_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ func newMemberList() DeploymentStatusMembers { Coordinators: MemberStatusList{{ID: ServerGroupCoordinators.AsRole()}}, SyncMasters: MemberStatusList{{ID: ServerGroupSyncMasters.AsRole()}}, SyncWorkers: MemberStatusList{{ID: ServerGroupSyncWorkers.AsRole()}}, + Gateways: MemberStatusList{{ID: ServerGroupGateways.AsRole()}}, } } diff --git a/pkg/apis/deployment/v1/server_group.go b/pkg/apis/deployment/v1/server_group.go index b504f1cd9..d3795422e 100644 --- a/pkg/apis/deployment/v1/server_group.go +++ b/pkg/apis/deployment/v1/server_group.go @@ -84,6 +84,7 @@ const ( ServerGroupCoordinators ServerGroup = 4 ServerGroupSyncMasters ServerGroup = 5 ServerGroupSyncWorkers ServerGroup = 6 + ServerGroupGateways ServerGroup = 7 ServerGroupImageDiscovery ServerGroup = -1 ServerGroupSingleString = "single" @@ -92,6 +93,7 @@ const ( ServerGroupCoordinatorsString = "coordinator" ServerGroupSyncMastersString = "syncmaster" ServerGroupSyncWorkersString = "syncworker" + ServerGroupGatewaysString = "gateways" ServerGroupImageDiscoveryString = "id" ServerGroupSingleAbbreviatedString = "sngl" @@ -100,6 +102,7 @@ const ( ServerGroupCoordinatorsAbbreviatedString = "crdn" ServerGroupSyncMastersAbbreviatedString = "syma" ServerGroupSyncWorkersAbbreviatedString = "sywo" + ServerGroupGatewaysAbbreviatedString = "gway" ServerGroupImageDiscoveryAbbreviatedString = "id" ) @@ -112,6 +115,7 @@ var ( ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, + ServerGroupGateways, } // AllArangoDServerGroups contains a constant list of all ArangoD server groups AllArangoDServerGroups = []ServerGroup{ @@ -131,6 +135,8 @@ func (g ServerGroup) Type() ServerGroupType { return ServerGroupTypeID case ServerGroupSyncMasters, ServerGroupSyncWorkers: return ServerGroupTypeArangoSync + case ServerGroupGateways: + return ServerGroupTypeGateway default: return ServerGroupTypeUnknown } @@ -151,6 +157,8 @@ func (g ServerGroup) AsRole() string { return ServerGroupSyncMastersString case ServerGroupSyncWorkers: return ServerGroupSyncWorkersString + case ServerGroupGateways: + return ServerGroupGatewaysString case ServerGroupImageDiscovery: return ServerGroupImageDiscoveryString default: @@ -163,14 +171,14 @@ func (g ServerGroup) Enabled(mode DeploymentMode) bool { switch mode { case DeploymentModeSingle: switch g { - case ServerGroupSingle: + case ServerGroupSingle, ServerGroupGateways: return true default: return false } case DeploymentModeCluster: switch g { - case ServerGroupAgents, ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: + case ServerGroupAgents, ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, ServerGroupGateways: return true default: return false @@ -202,6 +210,8 @@ func (g ServerGroup) AsRoleAbbreviated() string { return ServerGroupSyncMastersAbbreviatedString case ServerGroupSyncWorkers: return ServerGroupSyncWorkersAbbreviatedString + case ServerGroupGateways: + return ServerGroupGatewaysAbbreviatedString case ServerGroupImageDiscovery: return ServerGroupImageDiscoveryAbbreviatedString default: @@ -228,7 +238,7 @@ func (g ServerGroup) DefaultTerminationGracePeriod() time.Duration { // IsStateless returns true when the groups runs servers without a persistent volume. func (g ServerGroup) IsStateless() bool { switch g { - case ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: + case ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, ServerGroupGateways: return true default: return false @@ -255,6 +265,16 @@ func (g ServerGroup) IsArangosync() bool { } } +// IsGateway returns true when the group is a gateway group +func (g ServerGroup) IsGateway() bool { + switch g { + case ServerGroupGateways: + return true + default: + return false + } +} + // IsExportMetrics return true when the group can be used with the arangodbexporter func (g ServerGroup) IsExportMetrics() bool { switch g { @@ -280,6 +300,8 @@ func ServerGroupFromAbbreviatedRole(label string) ServerGroup { return ServerGroupSyncMasters case ServerGroupSyncWorkersAbbreviatedString: return ServerGroupSyncWorkers + case ServerGroupGatewaysAbbreviatedString: + return ServerGroupGateways case ServerGroupImageDiscoveryAbbreviatedString: return ServerGroupImageDiscovery default: @@ -287,7 +309,7 @@ func ServerGroupFromAbbreviatedRole(label string) ServerGroup { } } -// ServerGroupFromAbbreviatedRole returns ServerGroup from role +// ServerGroupFromRole returns ServerGroup from role func ServerGroupFromRole(label string) ServerGroup { switch label { case ServerGroupSingleString: @@ -302,6 +324,8 @@ func ServerGroupFromRole(label string) ServerGroup { return ServerGroupSyncMasters case ServerGroupSyncWorkersString: return ServerGroupSyncWorkers + case ServerGroupGatewaysString: + return ServerGroupGateways case ServerGroupImageDiscoveryString: return ServerGroupImageDiscovery default: diff --git a/pkg/apis/deployment/v1/server_group_spec_test.go b/pkg/apis/deployment/v1/server_group_spec_test.go index df285d998..e3ec3e3ce 100644 --- a/pkg/apis/deployment/v1/server_group_spec_test.go +++ b/pkg/apis/deployment/v1/server_group_spec_test.go @@ -46,6 +46,7 @@ func TestServerGroupSpecValidateCount(t *testing.T) { assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupSyncMasters).New().Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupSyncWorkers).New().Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupGateways).New().Validate(ServerGroupGateways, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2), MinCount: util.NewType[int](2), MaxCount: util.NewType[int](5)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](1), MaxCount: util.NewType[int](5)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) @@ -112,6 +113,10 @@ func TestServerGroupSpecDefault(t *testing.T) { assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeActiveFailover).New().GetCount()) assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncWorkers, true, DeploymentModeCluster).New().GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupGateways, false, DeploymentModeSingle).New().GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupGateways, false, DeploymentModeActiveFailover).New().GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupGateways, true, DeploymentModeCluster).New().GetCount()) + for _, g := range AllServerGroups { assert.Equal(t, 0, len(def(ServerGroupSpec{}, g, true, DeploymentModeSingle).Args)) assert.Equal(t, "", def(ServerGroupSpec{}, g, true, DeploymentModeSingle).New().GetStorageClassName()) diff --git a/pkg/apis/deployment/v1/server_group_test.go b/pkg/apis/deployment/v1/server_group_test.go index ef2ddc8d9..d182c2399 100644 --- a/pkg/apis/deployment/v1/server_group_test.go +++ b/pkg/apis/deployment/v1/server_group_test.go @@ -33,6 +33,7 @@ func TestServerGroupAsRole(t *testing.T) { assert.Equal(t, "coordinator", ServerGroupCoordinators.AsRole()) assert.Equal(t, "syncmaster", ServerGroupSyncMasters.AsRole()) assert.Equal(t, "syncworker", ServerGroupSyncWorkers.AsRole()) + assert.Equal(t, "gateways", ServerGroupGateways.AsRole()) } func TestServerGroupAsRoleAbbreviated(t *testing.T) { @@ -42,6 +43,7 @@ func TestServerGroupAsRoleAbbreviated(t *testing.T) { assert.Equal(t, "crdn", ServerGroupCoordinators.AsRoleAbbreviated()) assert.Equal(t, "syma", ServerGroupSyncMasters.AsRoleAbbreviated()) assert.Equal(t, "sywo", ServerGroupSyncWorkers.AsRoleAbbreviated()) + assert.Equal(t, "gway", ServerGroupGateways.AsRoleAbbreviated()) } func TestServerGroupIsArangod(t *testing.T) { @@ -51,6 +53,7 @@ func TestServerGroupIsArangod(t *testing.T) { assert.True(t, ServerGroupCoordinators.IsArangod()) assert.False(t, ServerGroupSyncMasters.IsArangod()) assert.False(t, ServerGroupSyncWorkers.IsArangod()) + assert.False(t, ServerGroupGateways.IsArangod()) } func TestServerGroupIsArangosync(t *testing.T) { @@ -60,6 +63,7 @@ func TestServerGroupIsArangosync(t *testing.T) { assert.False(t, ServerGroupCoordinators.IsArangosync()) assert.True(t, ServerGroupSyncMasters.IsArangosync()) assert.True(t, ServerGroupSyncWorkers.IsArangosync()) + assert.False(t, ServerGroupGateways.IsArangosync()) } func TestServerGroupType(t *testing.T) { @@ -71,4 +75,6 @@ func TestServerGroupType(t *testing.T) { assert.Equal(t, ServerGroupTypeArangoD, ServerGroupCoordinators.Type()) assert.Equal(t, ServerGroupTypeArangoSync, ServerGroupSyncMasters.Type()) assert.Equal(t, ServerGroupTypeArangoSync, ServerGroupSyncWorkers.Type()) + assert.Equal(t, ServerGroupTypeGateway, ServerGroupGateways.Type()) + } diff --git a/pkg/apis/deployment/v1/server_group_type.go b/pkg/apis/deployment/v1/server_group_type.go index 1c3c24f5d..70ce15bc4 100644 --- a/pkg/apis/deployment/v1/server_group_type.go +++ b/pkg/apis/deployment/v1/server_group_type.go @@ -27,4 +27,5 @@ const ( ServerGroupTypeArangoD ServerGroupTypeArangoSync ServerGroupTypeID + ServerGroupTypeGateway ) diff --git a/pkg/apis/deployment/v1/zz_generated.deepcopy.go b/pkg/apis/deployment/v1/zz_generated.deepcopy.go index 2b9c00f0f..6b0d6bae1 100644 --- a/pkg/apis/deployment/v1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v1/zz_generated.deepcopy.go @@ -1101,6 +1101,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { in.Coordinators.DeepCopyInto(&out.Coordinators) in.SyncMasters.DeepCopyInto(&out.SyncMasters) in.SyncWorkers.DeepCopyInto(&out.SyncWorkers) + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = new(ServerGroupSpec) + (*in).DeepCopyInto(*out) + } if in.MemberPropagationMode != nil { in, out := &in.MemberPropagationMode, &out.MemberPropagationMode *out = new(DeploymentMemberPropagationMode) @@ -1148,6 +1153,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = new(string) **out = **in } + if in.Gateway != nil { + in, out := &in.Gateway, &out.Gateway + *out = new(DeploymentSpecGateway) + (*in).DeepCopyInto(*out) + } return } @@ -1161,6 +1171,27 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentSpecGateway) DeepCopyInto(out *DeploymentSpecGateway) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpecGateway. +func (in *DeploymentSpecGateway) DeepCopy() *DeploymentSpecGateway { + if in == nil { + return nil + } + out := new(DeploymentSpecGateway) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in @@ -1291,6 +1322,11 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = new(ServerGroupStatus) (*in).DeepCopyInto(*out) } + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = new(ServerGroupStatus) + (*in).DeepCopyInto(*out) + } return } @@ -1521,6 +1557,13 @@ func (in *DeploymentStatusMembers) DeepCopyInto(out *DeploymentStatusMembers) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = make(MemberStatusList, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/apis/deployment/v2alpha1/deployment.go b/pkg/apis/deployment/v2alpha1/deployment.go index 11c4326ce..53472fcdd 100644 --- a/pkg/apis/deployment/v2alpha1/deployment.go +++ b/pkg/apis/deployment/v2alpha1/deployment.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -73,7 +73,7 @@ func (d *ArangoDeployment) AsOwner() meta.OwnerReference { // ForeachServerGroup calls the given callback for all server groups. // If the callback returns an error, this error is returned and no other server // groups are processed. -// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers +// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers, gateways func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *DeploymentStatus) error { if status == nil { status = &d.Status @@ -84,7 +84,7 @@ func (d *ArangoDeployment) ForeachServerGroup(cb ServerGroupFunc, status *Deploy // ForeachServerGroupAccepted calls the given callback for all accepted server groups. // If the callback returns an error, this error is returned and no other server // groups are processed. -// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers +// Groups are processed in this order: agents, single, dbservers, coordinators, syncmasters, syncworkers, gateways func (d *ArangoDeployment) ForeachServerGroupAccepted(cb ServerGroupFunc, status *DeploymentStatus) error { if status == nil { status = &d.Status @@ -115,6 +115,9 @@ func (d *ArangoDeployment) foreachServerGroup(cb ServerGroupFunc, spec Deploymen if err := cb(ServerGroupSyncWorkers, spec.SyncWorkers, &status.Members.SyncWorkers); err != nil { return errors.WithStack(err) } + if err := cb(ServerGroupGateways, spec.Gateways.Get(), &status.Members.Gateways); err != nil { + return errors.WithStack(err) + } return nil } diff --git a/pkg/apis/deployment/v2alpha1/deployment_spec.go b/pkg/apis/deployment/v2alpha1/deployment_spec.go index 0f0192cb9..4e979fa22 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_spec.go +++ b/pkg/apis/deployment/v2alpha1/deployment_spec.go @@ -199,6 +199,9 @@ type DeploymentSpec struct { // SyncWorkers contains specification for Syncworker pods running in deployment mode `Cluster`. SyncWorkers ServerGroupSpec `json:"syncworkers"` + // Gateways contain specification for Gateway pods running in deployment mode `Single` or `Cluster`. + Gateways *ServerGroupSpec `json:"gateways,omitempty"` + // MemberPropagationMode defines how changes to pod spec should be propogated. // Changes to a pod’s configuration require a restart of that pod in almost all cases. // Pods are restarted eagerly by default, which can cause more restarts than desired, especially when updating arangod as well as the operator. @@ -256,6 +259,9 @@ type DeploymentSpec struct { // Timezone if specified, will set a timezone for deployment. // Must be in format accepted by "tzdata", e.g. `America/New_York` or `Europe/London` Timezone *string `json:"timezone,omitempty"` + + // Gateway defined main Gateway configuration. + Gateway *DeploymentSpecGateway `json:"gateway,omitempty"` } // GetAllowMemberRecreation returns member recreation policy based on group and settings @@ -267,6 +273,8 @@ func (s *DeploymentSpec) GetAllowMemberRecreation(group ServerGroup) bool { groupSpec := s.GetServerGroupSpec(group) switch group { + case ServerGroupGateways: + return true case ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: if v := groupSpec.AllowMemberRecreation; v == nil { return true @@ -326,6 +334,11 @@ func (s DeploymentSpec) GetSyncImage() string { return s.GetImage() } +// IsGatewayEnabled returns true when the deployment has gateways enabled. +func (s DeploymentSpec) IsGatewayEnabled() bool { + return s.Gateway.IsEnabled() +} + // GetImagePullPolicy returns the value of imagePullPolicy. func (s DeploymentSpec) GetImagePullPolicy() core.PullPolicy { return util.TypeOrDefault[core.PullPolicy](s.ImagePullPolicy) @@ -364,8 +377,7 @@ func (s DeploymentSpec) IsSecure() bool { return s.TLS.IsSecure() } -// GetServerGroupSpec returns the server group spec (from this -// deployment spec) for the given group. +// GetServerGroupSpec returns the server group spec (from this deployment spec) for the given group. func (s DeploymentSpec) GetServerGroupSpec(group ServerGroup) ServerGroupSpec { switch group { case ServerGroupSingle: @@ -380,13 +392,14 @@ func (s DeploymentSpec) GetServerGroupSpec(group ServerGroup) ServerGroupSpec { return s.SyncMasters.WithGroup(group) case ServerGroupSyncWorkers: return s.SyncWorkers.WithGroup(group) + case ServerGroupGateways: + return s.Gateways.WithGroup(group) default: return ServerGroupSpec{} } } -// UpdateServerGroupSpec returns the server group spec (from this -// deployment spec) for the given group. +// UpdateServerGroupSpec returns the server group spec (from this deployment spec) for the given group. func (s *DeploymentSpec) UpdateServerGroupSpec(group ServerGroup, gspec ServerGroupSpec) { switch group { case ServerGroupSingle: @@ -401,6 +414,8 @@ func (s *DeploymentSpec) UpdateServerGroupSpec(group ServerGroup, gspec ServerGr s.SyncMasters = gspec case ServerGroupSyncWorkers: s.SyncWorkers = gspec + case ServerGroupGateways: + s.Gateways = gspec.DeepCopy() } } @@ -421,6 +436,11 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { if s.GetImagePullPolicy() == "" { s.ImagePullPolicy = util.NewType[core.PullPolicy](core.PullIfNotPresent) } + if s.Gateway.IsEnabled() { + if s.Gateways == nil { + s.Gateways = &ServerGroupSpec{} + } + } s.ExternalAccess.SetDefaults() s.RocksDB.SetDefaults() s.Authentication.SetDefaults(deploymentName + "-jwt") @@ -432,6 +452,7 @@ func (s *DeploymentSpec) SetDefaults(deploymentName string) { s.Coordinators.SetDefaults(ServerGroupCoordinators, s.GetMode().HasCoordinators(), s.GetMode()) s.SyncMasters.SetDefaults(ServerGroupSyncMasters, s.Sync.IsEnabled(), s.GetMode()) s.SyncWorkers.SetDefaults(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode()) + s.Gateways.SetDefaults(ServerGroupGateways, s.IsGatewayEnabled(), s.GetMode()) s.Metrics.SetDefaults(deploymentName+"-exporter-jwt-token", s.Authentication.IsAuthenticated()) s.Chaos.SetDefaults() s.Bootstrap.SetDefaults(deploymentName) @@ -480,6 +501,7 @@ func (s *DeploymentSpec) SetDefaultsFrom(source DeploymentSpec) { s.Coordinators.SetDefaultsFrom(source.Coordinators) s.SyncMasters.SetDefaultsFrom(source.SyncMasters) s.SyncWorkers.SetDefaultsFrom(source.SyncWorkers) + s.Gateways.SetDefaultsFrom(source.Gateways.Get()) s.Metrics.SetDefaultsFrom(source.Metrics) s.Lifecycle.SetDefaultsFrom(source.Lifecycle) s.Chaos.SetDefaultsFrom(source.Chaos) @@ -539,6 +561,11 @@ func (s *DeploymentSpec) Validate() error { if err := s.SyncWorkers.Validate(ServerGroupSyncWorkers, s.Sync.IsEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { return errors.WithStack(err) } + if s.IsGatewayEnabled() { + if err := s.Gateways.Validate(ServerGroupGateways, s.IsGatewayEnabled(), s.GetMode(), s.GetEnvironment()); err != nil { + return errors.WithStack(err) + } + } if err := s.Metrics.Validate(); err != nil { return errors.WithStack(errors.Wrap(err, "spec.metrics")) } @@ -554,6 +581,9 @@ func (s *DeploymentSpec) Validate() error { if err := s.Architecture.Validate(); err != nil { return errors.WithStack(errors.Wrap(err, "spec.architecture")) } + if err := s.Gateway.Validate(); err != nil { + return errors.WithStack(errors.Wrap(err, "spec.architecture")) + } return nil } @@ -614,6 +644,14 @@ func (s DeploymentSpec) ResetImmutableFields(target *DeploymentSpec) []string { if l := s.SyncWorkers.ResetImmutableFields(ServerGroupSyncWorkers, "syncworkers", &target.SyncWorkers); l != nil { resetFields = append(resetFields, l...) } + if s.Gateways != nil { + if target.Gateways == nil { + target.Gateways = &ServerGroupSpec{} + } + if l := s.Gateways.ResetImmutableFields(ServerGroupGateways, "gateways", target.Gateways); l != nil { + resetFields = append(resetFields, l...) + } + } if l := s.Metrics.ResetImmutableFields("metrics", &target.Metrics); l != nil { resetFields = append(resetFields, l...) } diff --git a/pkg/apis/deployment/v2alpha1/deployment_spec_gateway.go b/pkg/apis/deployment/v2alpha1/deployment_spec_gateway.go new file mode 100644 index 000000000..fba747bbf --- /dev/null +++ b/pkg/apis/deployment/v2alpha1/deployment_spec_gateway.go @@ -0,0 +1,37 @@ +// +// 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 v2alpha1 + +type DeploymentSpecGateway struct { + Enabled *bool `json:"enabled,omitempty"` +} + +func (d *DeploymentSpecGateway) IsEnabled() bool { + if d == nil || d.Enabled == nil { + return false + } + + return *d.Enabled +} + +func (d *DeploymentSpecGateway) Validate() error { + return nil +} diff --git a/pkg/apis/deployment/v2alpha1/deployment_status.go b/pkg/apis/deployment/v2alpha1/deployment_status.go index a765df6ba..b348225f5 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_status.go +++ b/pkg/apis/deployment/v2alpha1/deployment_status.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -103,6 +103,7 @@ type DeploymentStatus struct { Coordinators *ServerGroupStatus `json:"coordinators,omitempty"` SyncMasters *ServerGroupStatus `json:"syncmasters,omitempty"` SyncWorkers *ServerGroupStatus `json:"syncworkers,omitempty"` + Gateways *ServerGroupStatus `json:"gateways,omitempty"` } // Equal checks for equality @@ -174,6 +175,8 @@ func (ds DeploymentStatus) getServerGroupStatus(group ServerGroup) *ServerGroupS return ds.SyncMasters.DeepCopy() case ServerGroupSyncWorkers: return ds.SyncWorkers.DeepCopy() + case ServerGroupGateways: + return ds.Gateways.DeepCopy() default: return nil } @@ -195,5 +198,7 @@ func (ds *DeploymentStatus) UpdateServerGroupStatus(group ServerGroup, gspec Ser ds.SyncMasters = &gspec case ServerGroupSyncWorkers: ds.SyncWorkers = &gspec + case ServerGroupGateways: + ds.Gateways = &gspec } } diff --git a/pkg/apis/deployment/v2alpha1/deployment_status_members.go b/pkg/apis/deployment/v2alpha1/deployment_status_members.go index 54518c4f6..acdedb3cf 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_status_members.go +++ b/pkg/apis/deployment/v2alpha1/deployment_status_members.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -35,6 +35,7 @@ type DeploymentStatusMembers struct { Coordinators MemberStatusList `json:"coordinators,omitempty"` SyncMasters MemberStatusList `json:"syncmasters,omitempty"` SyncWorkers MemberStatusList `json:"syncworkers,omitempty"` + Gateways MemberStatusList `json:"gateways,omitempty"` } // Equal checks for equality @@ -44,7 +45,8 @@ func (ds DeploymentStatusMembers) Equal(other DeploymentStatusMembers) bool { ds.DBServers.Equal(other.DBServers) && ds.Coordinators.Equal(other.Coordinators) && ds.SyncMasters.Equal(other.SyncMasters) && - ds.SyncWorkers.Equal(other.SyncWorkers) + ds.SyncWorkers.Equal(other.SyncWorkers) && + ds.Gateways.Equal(other.Gateways) } // ContainsID returns true if the given set of members contains a member with given ID. @@ -54,7 +56,8 @@ func (ds DeploymentStatusMembers) ContainsID(id string) bool { ds.DBServers.ContainsID(id) || ds.Coordinators.ContainsID(id) || ds.SyncMasters.ContainsID(id) || - ds.SyncWorkers.ContainsID(id) + ds.SyncWorkers.ContainsID(id) || + ds.Gateways.ContainsID(id) } // ElementByID returns the element in the given list that has the given ID and true. @@ -78,6 +81,9 @@ func (ds DeploymentStatusMembers) ElementByID(id string) (MemberStatus, ServerGr if result, found := ds.SyncWorkers.ElementByID(id); found { return result, ServerGroupSyncWorkers, true } + if result, found := ds.Gateways.ElementByID(id); found { + return result, ServerGroupGateways, true + } return MemberStatus{}, 0, false } @@ -129,6 +135,10 @@ func (ds DeploymentStatusMembers) ForServerGroup(cb MemberStatusFunc, group Serv if err := cb(ServerGroupSyncWorkers, ds.SyncWorkers); err != nil { return errors.WithStack(err) } + case ServerGroupGateways: + if err := cb(ServerGroupGateways, ds.Gateways); err != nil { + return errors.WithStack(err) + } } return nil } @@ -155,6 +165,9 @@ func (ds DeploymentStatusMembers) MemberStatusByPodName(podName string) (MemberS if result, found := ds.SyncWorkers.ElementByPodName(podName); found { return result, ServerGroupSyncWorkers, true } + if result, found := ds.Gateways.ElementByPodName(podName); found { + return result, ServerGroupGateways, true + } return MemberStatus{}, 0, false } @@ -190,6 +203,8 @@ func (ds *DeploymentStatusMembers) Add(status MemberStatus, group ServerGroup) e err = ds.SyncMasters.add(status) case ServerGroupSyncWorkers: err = ds.SyncWorkers.add(status) + case ServerGroupGateways: + err = ds.Gateways.add(status) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -215,6 +230,8 @@ func (ds *DeploymentStatusMembers) Update(status MemberStatus, group ServerGroup err = ds.SyncMasters.update(status) case ServerGroupSyncWorkers: err = ds.SyncWorkers.update(status) + case ServerGroupGateways: + err = ds.Gateways.update(status) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -241,6 +258,8 @@ func (ds *DeploymentStatusMembers) RemoveByID(id string, group ServerGroup) erro err = ds.SyncMasters.removeByID(id) case ServerGroupSyncWorkers: err = ds.SyncWorkers.removeByID(id) + case ServerGroupGateways: + err = ds.Gateways.removeByID(id) default: return errors.WithStack(errors.Wrapf(NotFoundError, "ServerGroup %d is not known", group)) } @@ -250,23 +269,30 @@ func (ds *DeploymentStatusMembers) RemoveByID(id string, group ServerGroup) erro return nil } -// AllMembersReady returns true when all members, that must be ready for the given mode, are in the Ready state. -func (ds DeploymentStatusMembers) AllMembersReady(mode DeploymentMode, syncEnabled bool) bool { +// AllMembersReady returns true when all members, that must be ready for the given mode are in the Ready state. +func (ds DeploymentStatusMembers) AllMembersReady(mode DeploymentMode, syncEnabled, gatewayEnabled bool) bool { syncReady := func() bool { if syncEnabled { return ds.SyncMasters.AllMembersReady() && ds.SyncWorkers.AllMembersReady() } return true } + gatewayReady := func() bool { + if gatewayEnabled { + return ds.Gateways.AllMembersReady() + } + return true + } switch mode { case DeploymentModeSingle: - return ds.Single.MembersReady() > 0 + return ds.Single.MembersReady() > 0 && gatewayReady() case DeploymentModeActiveFailover: return ds.Agents.AllMembersReady() && ds.Single.MembersReady() > 0 case DeploymentModeCluster: return ds.Agents.AllMembersReady() && ds.DBServers.AllMembersReady() && ds.Coordinators.AllMembersReady() && + gatewayReady() && syncReady() default: return false @@ -288,6 +314,8 @@ func (ds DeploymentStatusMembers) MembersOfGroup(group ServerGroup) MemberStatus return ds.SyncMasters case ServerGroupSyncWorkers: return ds.SyncWorkers + case ServerGroupGateways: + return ds.Gateways default: return MemberStatusList{} } diff --git a/pkg/apis/deployment/v2alpha1/deployment_status_members_test.go b/pkg/apis/deployment/v2alpha1/deployment_status_members_test.go index 64237784a..723ef50f0 100644 --- a/pkg/apis/deployment/v2alpha1/deployment_status_members_test.go +++ b/pkg/apis/deployment/v2alpha1/deployment_status_members_test.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -34,6 +34,7 @@ func newMemberList() DeploymentStatusMembers { Coordinators: MemberStatusList{{ID: ServerGroupCoordinators.AsRole()}}, SyncMasters: MemberStatusList{{ID: ServerGroupSyncMasters.AsRole()}}, SyncWorkers: MemberStatusList{{ID: ServerGroupSyncWorkers.AsRole()}}, + Gateways: MemberStatusList{{ID: ServerGroupGateways.AsRole()}}, } } diff --git a/pkg/apis/deployment/v2alpha1/server_group.go b/pkg/apis/deployment/v2alpha1/server_group.go index bc3c2be6c..1de521e7e 100644 --- a/pkg/apis/deployment/v2alpha1/server_group.go +++ b/pkg/apis/deployment/v2alpha1/server_group.go @@ -84,6 +84,7 @@ const ( ServerGroupCoordinators ServerGroup = 4 ServerGroupSyncMasters ServerGroup = 5 ServerGroupSyncWorkers ServerGroup = 6 + ServerGroupGateways ServerGroup = 7 ServerGroupImageDiscovery ServerGroup = -1 ServerGroupSingleString = "single" @@ -92,6 +93,7 @@ const ( ServerGroupCoordinatorsString = "coordinator" ServerGroupSyncMastersString = "syncmaster" ServerGroupSyncWorkersString = "syncworker" + ServerGroupGatewaysString = "gateways" ServerGroupImageDiscoveryString = "id" ServerGroupSingleAbbreviatedString = "sngl" @@ -100,6 +102,7 @@ const ( ServerGroupCoordinatorsAbbreviatedString = "crdn" ServerGroupSyncMastersAbbreviatedString = "syma" ServerGroupSyncWorkersAbbreviatedString = "sywo" + ServerGroupGatewaysAbbreviatedString = "gway" ServerGroupImageDiscoveryAbbreviatedString = "id" ) @@ -112,6 +115,7 @@ var ( ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, + ServerGroupGateways, } // AllArangoDServerGroups contains a constant list of all ArangoD server groups AllArangoDServerGroups = []ServerGroup{ @@ -131,6 +135,8 @@ func (g ServerGroup) Type() ServerGroupType { return ServerGroupTypeID case ServerGroupSyncMasters, ServerGroupSyncWorkers: return ServerGroupTypeArangoSync + case ServerGroupGateways: + return ServerGroupTypeGateway default: return ServerGroupTypeUnknown } @@ -151,6 +157,8 @@ func (g ServerGroup) AsRole() string { return ServerGroupSyncMastersString case ServerGroupSyncWorkers: return ServerGroupSyncWorkersString + case ServerGroupGateways: + return ServerGroupGatewaysString case ServerGroupImageDiscovery: return ServerGroupImageDiscoveryString default: @@ -163,14 +171,14 @@ func (g ServerGroup) Enabled(mode DeploymentMode) bool { switch mode { case DeploymentModeSingle: switch g { - case ServerGroupSingle: + case ServerGroupSingle, ServerGroupGateways: return true default: return false } case DeploymentModeCluster: switch g { - case ServerGroupAgents, ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: + case ServerGroupAgents, ServerGroupDBServers, ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, ServerGroupGateways: return true default: return false @@ -202,6 +210,8 @@ func (g ServerGroup) AsRoleAbbreviated() string { return ServerGroupSyncMastersAbbreviatedString case ServerGroupSyncWorkers: return ServerGroupSyncWorkersAbbreviatedString + case ServerGroupGateways: + return ServerGroupGatewaysAbbreviatedString case ServerGroupImageDiscovery: return ServerGroupImageDiscoveryAbbreviatedString default: @@ -228,7 +238,7 @@ func (g ServerGroup) DefaultTerminationGracePeriod() time.Duration { // IsStateless returns true when the groups runs servers without a persistent volume. func (g ServerGroup) IsStateless() bool { switch g { - case ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers: + case ServerGroupCoordinators, ServerGroupSyncMasters, ServerGroupSyncWorkers, ServerGroupGateways: return true default: return false @@ -255,6 +265,16 @@ func (g ServerGroup) IsArangosync() bool { } } +// IsGateway returns true when the group is a gateway group +func (g ServerGroup) IsGateway() bool { + switch g { + case ServerGroupGateways: + return true + default: + return false + } +} + // IsExportMetrics return true when the group can be used with the arangodbexporter func (g ServerGroup) IsExportMetrics() bool { switch g { @@ -280,6 +300,8 @@ func ServerGroupFromAbbreviatedRole(label string) ServerGroup { return ServerGroupSyncMasters case ServerGroupSyncWorkersAbbreviatedString: return ServerGroupSyncWorkers + case ServerGroupGatewaysAbbreviatedString: + return ServerGroupGateways case ServerGroupImageDiscoveryAbbreviatedString: return ServerGroupImageDiscovery default: @@ -287,7 +309,7 @@ func ServerGroupFromAbbreviatedRole(label string) ServerGroup { } } -// ServerGroupFromAbbreviatedRole returns ServerGroup from role +// ServerGroupFromRole returns ServerGroup from role func ServerGroupFromRole(label string) ServerGroup { switch label { case ServerGroupSingleString: @@ -302,6 +324,8 @@ func ServerGroupFromRole(label string) ServerGroup { return ServerGroupSyncMasters case ServerGroupSyncWorkersString: return ServerGroupSyncWorkers + case ServerGroupGatewaysString: + return ServerGroupGateways case ServerGroupImageDiscoveryString: return ServerGroupImageDiscovery default: diff --git a/pkg/apis/deployment/v2alpha1/server_group_spec_test.go b/pkg/apis/deployment/v2alpha1/server_group_spec_test.go index 6383cef37..446db456e 100644 --- a/pkg/apis/deployment/v2alpha1/server_group_spec_test.go +++ b/pkg/apis/deployment/v2alpha1/server_group_spec_test.go @@ -46,6 +46,7 @@ func TestServerGroupSpecValidateCount(t *testing.T) { assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupSyncMasters).New().Validate(ServerGroupSyncMasters, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupSyncWorkers).New().Validate(ServerGroupSyncWorkers, true, DeploymentModeCluster, EnvironmentProduction)) + assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2)}.New().WithGroup(ServerGroupGateways).New().Validate(ServerGroupGateways, true, DeploymentModeCluster, EnvironmentProduction)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](2), MinCount: util.NewType[int](2), MaxCount: util.NewType[int](5)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) assert.Nil(t, ServerGroupSpec{Count: util.NewType[int](1), MaxCount: util.NewType[int](5)}.New().WithGroup(ServerGroupCoordinators).New().Validate(ServerGroupCoordinators, true, DeploymentModeCluster, EnvironmentDevelopment)) @@ -112,6 +113,10 @@ func TestServerGroupSpecDefault(t *testing.T) { assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupSyncWorkers, false, DeploymentModeActiveFailover).New().GetCount()) assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupSyncWorkers, true, DeploymentModeCluster).New().GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupGateways, false, DeploymentModeSingle).New().GetCount()) + assert.Equal(t, 0, def(ServerGroupSpec{}, ServerGroupGateways, false, DeploymentModeActiveFailover).New().GetCount()) + assert.Equal(t, 3, def(ServerGroupSpec{}, ServerGroupGateways, true, DeploymentModeCluster).New().GetCount()) + for _, g := range AllServerGroups { assert.Equal(t, 0, len(def(ServerGroupSpec{}, g, true, DeploymentModeSingle).Args)) assert.Equal(t, "", def(ServerGroupSpec{}, g, true, DeploymentModeSingle).New().GetStorageClassName()) diff --git a/pkg/apis/deployment/v2alpha1/server_group_test.go b/pkg/apis/deployment/v2alpha1/server_group_test.go index 03eae5314..c9bb251e0 100644 --- a/pkg/apis/deployment/v2alpha1/server_group_test.go +++ b/pkg/apis/deployment/v2alpha1/server_group_test.go @@ -33,6 +33,7 @@ func TestServerGroupAsRole(t *testing.T) { assert.Equal(t, "coordinator", ServerGroupCoordinators.AsRole()) assert.Equal(t, "syncmaster", ServerGroupSyncMasters.AsRole()) assert.Equal(t, "syncworker", ServerGroupSyncWorkers.AsRole()) + assert.Equal(t, "gateways", ServerGroupGateways.AsRole()) } func TestServerGroupAsRoleAbbreviated(t *testing.T) { @@ -42,6 +43,7 @@ func TestServerGroupAsRoleAbbreviated(t *testing.T) { assert.Equal(t, "crdn", ServerGroupCoordinators.AsRoleAbbreviated()) assert.Equal(t, "syma", ServerGroupSyncMasters.AsRoleAbbreviated()) assert.Equal(t, "sywo", ServerGroupSyncWorkers.AsRoleAbbreviated()) + assert.Equal(t, "gway", ServerGroupGateways.AsRoleAbbreviated()) } func TestServerGroupIsArangod(t *testing.T) { @@ -51,6 +53,7 @@ func TestServerGroupIsArangod(t *testing.T) { assert.True(t, ServerGroupCoordinators.IsArangod()) assert.False(t, ServerGroupSyncMasters.IsArangod()) assert.False(t, ServerGroupSyncWorkers.IsArangod()) + assert.False(t, ServerGroupGateways.IsArangod()) } func TestServerGroupIsArangosync(t *testing.T) { @@ -60,6 +63,7 @@ func TestServerGroupIsArangosync(t *testing.T) { assert.False(t, ServerGroupCoordinators.IsArangosync()) assert.True(t, ServerGroupSyncMasters.IsArangosync()) assert.True(t, ServerGroupSyncWorkers.IsArangosync()) + assert.False(t, ServerGroupGateways.IsArangosync()) } func TestServerGroupType(t *testing.T) { @@ -71,4 +75,6 @@ func TestServerGroupType(t *testing.T) { assert.Equal(t, ServerGroupTypeArangoD, ServerGroupCoordinators.Type()) assert.Equal(t, ServerGroupTypeArangoSync, ServerGroupSyncMasters.Type()) assert.Equal(t, ServerGroupTypeArangoSync, ServerGroupSyncWorkers.Type()) + assert.Equal(t, ServerGroupTypeGateway, ServerGroupGateways.Type()) + } diff --git a/pkg/apis/deployment/v2alpha1/server_group_type.go b/pkg/apis/deployment/v2alpha1/server_group_type.go index 4b7c6c559..22088eab4 100644 --- a/pkg/apis/deployment/v2alpha1/server_group_type.go +++ b/pkg/apis/deployment/v2alpha1/server_group_type.go @@ -27,4 +27,5 @@ const ( ServerGroupTypeArangoD ServerGroupTypeArangoSync ServerGroupTypeID + ServerGroupTypeGateway ) diff --git a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go index d68e718fe..1e7d72901 100644 --- a/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/deployment/v2alpha1/zz_generated.deepcopy.go @@ -1101,6 +1101,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { in.Coordinators.DeepCopyInto(&out.Coordinators) in.SyncMasters.DeepCopyInto(&out.SyncMasters) in.SyncWorkers.DeepCopyInto(&out.SyncWorkers) + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = new(ServerGroupSpec) + (*in).DeepCopyInto(*out) + } if in.MemberPropagationMode != nil { in, out := &in.MemberPropagationMode, &out.MemberPropagationMode *out = new(DeploymentMemberPropagationMode) @@ -1148,6 +1153,11 @@ func (in *DeploymentSpec) DeepCopyInto(out *DeploymentSpec) { *out = new(string) **out = **in } + if in.Gateway != nil { + in, out := &in.Gateway, &out.Gateway + *out = new(DeploymentSpecGateway) + (*in).DeepCopyInto(*out) + } return } @@ -1161,6 +1171,27 @@ func (in *DeploymentSpec) DeepCopy() *DeploymentSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DeploymentSpecGateway) DeepCopyInto(out *DeploymentSpecGateway) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DeploymentSpecGateway. +func (in *DeploymentSpecGateway) DeepCopy() *DeploymentSpecGateway { + if in == nil { + return nil + } + out := new(DeploymentSpecGateway) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = *in @@ -1291,6 +1322,11 @@ func (in *DeploymentStatus) DeepCopyInto(out *DeploymentStatus) { *out = new(ServerGroupStatus) (*in).DeepCopyInto(*out) } + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = new(ServerGroupStatus) + (*in).DeepCopyInto(*out) + } return } @@ -1521,6 +1557,13 @@ func (in *DeploymentStatusMembers) DeepCopyInto(out *DeploymentStatusMembers) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Gateways != nil { + in, out := &in.Gateways, &out.Gateways + *out = make(MemberStatusList, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/crd/crds/database-deployment.schema.generated.yaml b/pkg/crd/crds/database-deployment.schema.generated.yaml index c5fa1403a..609150ca6 100644 --- a/pkg/crd/crds/database-deployment.schema.generated.yaml +++ b/pkg/crd/crds/database-deployment.schema.generated.yaml @@ -6564,6 +6564,2142 @@ v1: foxx.queues: type: boolean type: object + gateway: + description: Gateway defined main Gateway configuration. + properties: + enabled: + type: boolean + type: object + gateways: + description: Gateways contain specification for Gateway pods running in deployment mode `Single` or `Cluster`. + properties: + affinity: + description: Affinity specified additional affinity settings in ArangoDB Pod definitions + 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 + allowMemberRecreation: + description: |- + AllowMemberRecreation allows to recreate member. + This setting changes the member recreation logic based on group: + - For Sync Masters, Sync Workers, Coordinator and DB-Servers it determines if a member can be recreated in case of failure (default `true`) + - For Agents and Single this value is hardcoded to `false` and the value provided in spec is ignored. + type: boolean + annotations: + additionalProperties: + type: string + description: |- + Annotations specified the annotations added to Pods in this group. + Annotations are merged with `spec.annotations`. + type: object + annotationsIgnoreList: + description: AnnotationsIgnoreList list regexp or plain definitions which annotations should be ignored + items: + type: string + type: array + annotationsMode: + description: AnnotationsMode Define annotations mode which should be use while overriding annotations + type: string + antiAffinity: + description: AntiAffinity specified additional antiAffinity settings in ArangoDB Pod definitions + 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 + args: + description: Args setting specifies additional command-line arguments passed to all servers of this group. + items: + type: string + type: array + count: + description: |- + Count setting specifies the number of servers to start for the given group. + For the Agent group, this value must be a positive, odd number. + The default value is `3` for all groups except `single` (there the default is `1` + for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). + For the `syncworkers` group, it is highly recommended to use the same number + as for the `dbservers` group. + format: int32 + type: integer + entrypoint: + description: Entrypoint overrides container executable + type: string + envs: + description: Envs allow to specify additional envs in this group. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + ephemeralVolumes: + description: EphemeralVolumes keeps information about ephemeral volumes. + properties: + apps: + description: Apps define apps ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + temp: + description: Temp define temp ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + type: object + exporterPort: + description: ExporterPort define Port used by exporter + format: int32 + type: integer + extendedRotationCheck: + description: ExtendedRotationCheck extend checks for rotation + type: boolean + externalPortEnabled: + description: ExternalPortEnabled if external port should be enabled. If is set to false, ports needs to be exposed via sidecar. Only for ArangoD members + type: boolean + indexMethod: + description: IndexMethod define group Indexing method + enum: + - random + - ordered + type: string + initContainers: + description: InitContainers Init containers specification + properties: + containers: + description: Containers contains list of 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 + mode: + description: Mode keep container replace mode + type: string + type: object + internalPort: + description: InternalPort define port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + format: int32 + type: integer + internalPortProtocol: + description: InternalPortProtocol define protocol of port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + type: string + labels: + additionalProperties: + type: string + description: Labels specified the labels added to Pods in this group. + type: object + labelsIgnoreList: + description: LabelsIgnoreList list regexp or plain definitions which labels should be ignored + items: + type: string + type: array + labelsMode: + description: LabelsMode Define labels mode which should be use while overriding labels + type: string + maxCount: + description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`. + format: int32 + type: integer + memoryReservation: + description: |- + MemoryReservation determines the system reservation of memory while calculating `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` value. + If this field is set, `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` is reduced by a specified value in percent. + Accepted Range <0, 50>. If the value is outside the accepted range, it is adjusted to the closest value. + format: int64 + type: integer + minCount: + description: MinCount specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`. + format: int32 + type: integer + nodeAffinity: + description: NodeAffinity specified additional nodeAffinity settings in ArangoDB Pod definitions + 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 + nodeSelector: + additionalProperties: + type: string + description: NodeSelector setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + type: object + numactl: + description: Numactl define Numactl options passed to the process + properties: + args: + description: Args define list of the numactl process + items: + type: string + type: array + enabled: + description: Enabled define if numactl should be enabled + type: boolean + path: + description: Path define numactl path within the container + type: string + type: object + overrideDetectedNumberOfCores: + description: |- + OverrideDetectedNumberOfCores determines if number of cores should be overridden based on values in resources. + If is set to true and Container CPU Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_NUMBER_OF_CORES` to the value from the Container CPU Limits. + type: boolean + overrideDetectedTotalMemory: + description: |- + OverrideDetectedTotalMemory determines if memory should be overridden based on values in resources. + If is set to true and Container Memory Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` to the value from the Container Memory Limits. + type: boolean + podModes: + description: PodModes define additional modes enabled on the Pod level + properties: + network: + type: string + pid: + type: string + type: object + port: + description: Port define Port used by member + format: int32 + type: integer + priorityClassName: + description: |- + PriorityClassName specifies a priority class name + Will be forwarded to the pod spec. + type: string + probes: + description: Probes specifies additional behaviour for probes + properties: + ReadinessProbeDisabled: + description: OldReadinessProbeDisabled if true readinessProbes are disabled + type: boolean + livenessProbeDisabled: + description: LivenessProbeDisabled if set to true, the operator does not generate a liveness probe for new pods belonging to this group + type: boolean + livenessProbeSpec: + description: LivenessProbeSpec override liveness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + readinessProbeDisabled: + description: ReadinessProbeDisabled override flag for probe disabled in good manner (lowercase) with backward compatibility + type: boolean + readinessProbeSpec: + description: ReadinessProbeSpec override readiness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + startupProbeDisabled: + description: StartupProbeDisabled if true startupProbes are disabled + type: boolean + startupProbeSpec: + description: StartupProbeSpec override startup probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + type: object + pvcResizeMode: + description: VolumeResizeMode specified resize mode for PVCs and PVs + enum: + - runtime + - rotate + type: string + resources: + description: Resources holds resource requests & limits + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + description: SchedulerName define scheduler name used for group + type: string + securityContext: + description: |- + SecurityContext specifies additional `securityContext` settings in ArangoDB Pod definitions. + This is similar (but not fully compatible) to k8s SecurityContext definition. + properties: + addCapabilities: + description: AddCapabilities add new capabilities to containers + items: + type: string + type: array + allowPrivilegeEscalation: + description: AllowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process. + type: boolean + dropAllCapabilities: + description: DropAllCapabilities specifies if capabilities should be dropped for this pod containers + type: boolean + fsGroup: + description: FSGroup is a special supplemental group that applies to all containers in a pod. + format: int64 + type: integer + privileged: + description: |- + Privileged If true, runs container in privileged mode. Processes in privileged containers are + essentially equivalent to root on the host. + type: boolean + readOnlyRootFilesystem: + description: ReadOnlyRootFilesystem if true, mounts the container's root filesystem as read-only. + type: boolean + runAsGroup: + description: RunAsGroup is the GID to run the entrypoint of the container process. + format: int64 + type: integer + runAsNonRoot: + description: RunAsNonRoot if true, indicates that the container must run as a non-root user. + type: boolean + runAsUser: + description: RunAsUser is the UID to run the entrypoint of the container process. + format: int64 + type: integer + seLinuxOptions: + description: SELinuxOptions are the labels to be applied to the container + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + description: SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set. + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + description: |- + SupplementalGroups is a list of groups applied to the first process run in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. + items: + format: int64 + type: integer + type: array + sysctls: + additionalProperties: + type: string + x-kubernetes-int-or-string: true + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Map Value can be String or Int + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName setting specifies the `serviceAccountName` for the `Pods` created + for each server of this group. If empty, it defaults to using the + `default` service account. + Using an alternative `ServiceAccount` is typically used to separate access rights. + The ArangoDB deployments need some very minimal access rights. With the + deployment of the operator, we grant the rights to 'get' all 'pod' resources. + If you are using a different service account, please grant these rights + to that service account. + type: string + shutdownDelay: + description: ShutdownDelay define how long operator should delay finalizer removal after shutdown + format: int32 + type: integer + shutdownMethod: + description: ShutdownMethod describe procedure of member shutdown taken by Operator + type: string + sidecarCoreNames: + description: |- + SidecarCoreNames is a list of sidecar containers which must run in the pod. + Some names (e.g.: "server", "worker") are reserved, and they don't have any impact. + items: + type: string + type: array + sidecars: + description: Sidecars specifies a list of additional containers to be started + 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 + storageClassName: + description: StorageClassName specifies the classname for storage of the servers. + type: string + terminationGracePeriodSeconds: + description: TerminationGracePeriodSeconds override default TerminationGracePeriodSeconds for pods - via silent rotation + format: int64 + type: integer + tolerations: + description: |- + Tolerations specifies the tolerations added to Pods in this group. + By default, suitable tolerations are set for the following keys with the `NoExecute` effect: + - `node.kubernetes.io/not-ready` + - `node.kubernetes.io/unreachable` + - `node.alpha.kubernetes.io/unreachable` (will be removed in future version) + For more information on tolerations, consult the https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeAllowShrink: + description: VolumeAllowShrink allows shrinking of the volume + type: boolean + volumeClaimTemplate: + description: |- + VolumeClaimTemplate specifies a volumeClaimTemplate used by operator to create to volume claims for pods of this group. + This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`. + The default value describes a volume with `8Gi` storage, `ReadWriteOnce` access mode and volume mode set to `PersistentVolumeFilesystem`. + If this field is not set and `spec..resources.requests.storage` is set, then a default volume claim + with size as specified by `spec..resources.requests.storage` will be created. In that case `storage` + and `iops` is not forwarded to the pods resource requirements. + properties: + apiVersion: + type: string + kind: + type: string + 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 + status: + properties: + accessModes: + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + allocatedResources: + additionalProperties: + type: string + type: object + capacity: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + type: object + phase: + type: string + type: object + type: object + volumeMounts: + description: VolumeMounts define list of volume mounts mounted into server container + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + description: Volumes define list of volumes mounted to pod + items: + properties: + configMap: + description: ConfigMap which should be mounted into pod + 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 + emptyDir: + description: EmptyDir + properties: + medium: + type: string + sizeLimit: + type: string + type: object + hostPath: + description: HostPath + properties: + path: + type: string + type: + type: string + type: object + name: + description: Name of volume + type: string + persistentVolumeClaim: + description: PersistentVolumeClaim + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + secret: + description: Secret which should be mounted into pod + 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 + type: object + type: array + type: object id: description: ServerIDGroupSpec contains the specification for Image Discovery image. properties: @@ -20447,6 +22583,2142 @@ v1alpha: foxx.queues: type: boolean type: object + gateway: + description: Gateway defined main Gateway configuration. + properties: + enabled: + type: boolean + type: object + gateways: + description: Gateways contain specification for Gateway pods running in deployment mode `Single` or `Cluster`. + properties: + affinity: + description: Affinity specified additional affinity settings in ArangoDB Pod definitions + 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 + allowMemberRecreation: + description: |- + AllowMemberRecreation allows to recreate member. + This setting changes the member recreation logic based on group: + - For Sync Masters, Sync Workers, Coordinator and DB-Servers it determines if a member can be recreated in case of failure (default `true`) + - For Agents and Single this value is hardcoded to `false` and the value provided in spec is ignored. + type: boolean + annotations: + additionalProperties: + type: string + description: |- + Annotations specified the annotations added to Pods in this group. + Annotations are merged with `spec.annotations`. + type: object + annotationsIgnoreList: + description: AnnotationsIgnoreList list regexp or plain definitions which annotations should be ignored + items: + type: string + type: array + annotationsMode: + description: AnnotationsMode Define annotations mode which should be use while overriding annotations + type: string + antiAffinity: + description: AntiAffinity specified additional antiAffinity settings in ArangoDB Pod definitions + 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 + args: + description: Args setting specifies additional command-line arguments passed to all servers of this group. + items: + type: string + type: array + count: + description: |- + Count setting specifies the number of servers to start for the given group. + For the Agent group, this value must be a positive, odd number. + The default value is `3` for all groups except `single` (there the default is `1` + for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). + For the `syncworkers` group, it is highly recommended to use the same number + as for the `dbservers` group. + format: int32 + type: integer + entrypoint: + description: Entrypoint overrides container executable + type: string + envs: + description: Envs allow to specify additional envs in this group. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + ephemeralVolumes: + description: EphemeralVolumes keeps information about ephemeral volumes. + properties: + apps: + description: Apps define apps ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + temp: + description: Temp define temp ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + type: object + exporterPort: + description: ExporterPort define Port used by exporter + format: int32 + type: integer + extendedRotationCheck: + description: ExtendedRotationCheck extend checks for rotation + type: boolean + externalPortEnabled: + description: ExternalPortEnabled if external port should be enabled. If is set to false, ports needs to be exposed via sidecar. Only for ArangoD members + type: boolean + indexMethod: + description: IndexMethod define group Indexing method + enum: + - random + - ordered + type: string + initContainers: + description: InitContainers Init containers specification + properties: + containers: + description: Containers contains list of 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 + mode: + description: Mode keep container replace mode + type: string + type: object + internalPort: + description: InternalPort define port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + format: int32 + type: integer + internalPortProtocol: + description: InternalPortProtocol define protocol of port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + type: string + labels: + additionalProperties: + type: string + description: Labels specified the labels added to Pods in this group. + type: object + labelsIgnoreList: + description: LabelsIgnoreList list regexp or plain definitions which labels should be ignored + items: + type: string + type: array + labelsMode: + description: LabelsMode Define labels mode which should be use while overriding labels + type: string + maxCount: + description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`. + format: int32 + type: integer + memoryReservation: + description: |- + MemoryReservation determines the system reservation of memory while calculating `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` value. + If this field is set, `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` is reduced by a specified value in percent. + Accepted Range <0, 50>. If the value is outside the accepted range, it is adjusted to the closest value. + format: int64 + type: integer + minCount: + description: MinCount specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`. + format: int32 + type: integer + nodeAffinity: + description: NodeAffinity specified additional nodeAffinity settings in ArangoDB Pod definitions + 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 + nodeSelector: + additionalProperties: + type: string + description: NodeSelector setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + type: object + numactl: + description: Numactl define Numactl options passed to the process + properties: + args: + description: Args define list of the numactl process + items: + type: string + type: array + enabled: + description: Enabled define if numactl should be enabled + type: boolean + path: + description: Path define numactl path within the container + type: string + type: object + overrideDetectedNumberOfCores: + description: |- + OverrideDetectedNumberOfCores determines if number of cores should be overridden based on values in resources. + If is set to true and Container CPU Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_NUMBER_OF_CORES` to the value from the Container CPU Limits. + type: boolean + overrideDetectedTotalMemory: + description: |- + OverrideDetectedTotalMemory determines if memory should be overridden based on values in resources. + If is set to true and Container Memory Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` to the value from the Container Memory Limits. + type: boolean + podModes: + description: PodModes define additional modes enabled on the Pod level + properties: + network: + type: string + pid: + type: string + type: object + port: + description: Port define Port used by member + format: int32 + type: integer + priorityClassName: + description: |- + PriorityClassName specifies a priority class name + Will be forwarded to the pod spec. + type: string + probes: + description: Probes specifies additional behaviour for probes + properties: + ReadinessProbeDisabled: + description: OldReadinessProbeDisabled if true readinessProbes are disabled + type: boolean + livenessProbeDisabled: + description: LivenessProbeDisabled if set to true, the operator does not generate a liveness probe for new pods belonging to this group + type: boolean + livenessProbeSpec: + description: LivenessProbeSpec override liveness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + readinessProbeDisabled: + description: ReadinessProbeDisabled override flag for probe disabled in good manner (lowercase) with backward compatibility + type: boolean + readinessProbeSpec: + description: ReadinessProbeSpec override readiness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + startupProbeDisabled: + description: StartupProbeDisabled if true startupProbes are disabled + type: boolean + startupProbeSpec: + description: StartupProbeSpec override startup probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + type: object + pvcResizeMode: + description: VolumeResizeMode specified resize mode for PVCs and PVs + enum: + - runtime + - rotate + type: string + resources: + description: Resources holds resource requests & limits + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + description: SchedulerName define scheduler name used for group + type: string + securityContext: + description: |- + SecurityContext specifies additional `securityContext` settings in ArangoDB Pod definitions. + This is similar (but not fully compatible) to k8s SecurityContext definition. + properties: + addCapabilities: + description: AddCapabilities add new capabilities to containers + items: + type: string + type: array + allowPrivilegeEscalation: + description: AllowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process. + type: boolean + dropAllCapabilities: + description: DropAllCapabilities specifies if capabilities should be dropped for this pod containers + type: boolean + fsGroup: + description: FSGroup is a special supplemental group that applies to all containers in a pod. + format: int64 + type: integer + privileged: + description: |- + Privileged If true, runs container in privileged mode. Processes in privileged containers are + essentially equivalent to root on the host. + type: boolean + readOnlyRootFilesystem: + description: ReadOnlyRootFilesystem if true, mounts the container's root filesystem as read-only. + type: boolean + runAsGroup: + description: RunAsGroup is the GID to run the entrypoint of the container process. + format: int64 + type: integer + runAsNonRoot: + description: RunAsNonRoot if true, indicates that the container must run as a non-root user. + type: boolean + runAsUser: + description: RunAsUser is the UID to run the entrypoint of the container process. + format: int64 + type: integer + seLinuxOptions: + description: SELinuxOptions are the labels to be applied to the container + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + description: SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set. + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + description: |- + SupplementalGroups is a list of groups applied to the first process run in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. + items: + format: int64 + type: integer + type: array + sysctls: + additionalProperties: + type: string + x-kubernetes-int-or-string: true + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Map Value can be String or Int + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName setting specifies the `serviceAccountName` for the `Pods` created + for each server of this group. If empty, it defaults to using the + `default` service account. + Using an alternative `ServiceAccount` is typically used to separate access rights. + The ArangoDB deployments need some very minimal access rights. With the + deployment of the operator, we grant the rights to 'get' all 'pod' resources. + If you are using a different service account, please grant these rights + to that service account. + type: string + shutdownDelay: + description: ShutdownDelay define how long operator should delay finalizer removal after shutdown + format: int32 + type: integer + shutdownMethod: + description: ShutdownMethod describe procedure of member shutdown taken by Operator + type: string + sidecarCoreNames: + description: |- + SidecarCoreNames is a list of sidecar containers which must run in the pod. + Some names (e.g.: "server", "worker") are reserved, and they don't have any impact. + items: + type: string + type: array + sidecars: + description: Sidecars specifies a list of additional containers to be started + 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 + storageClassName: + description: StorageClassName specifies the classname for storage of the servers. + type: string + terminationGracePeriodSeconds: + description: TerminationGracePeriodSeconds override default TerminationGracePeriodSeconds for pods - via silent rotation + format: int64 + type: integer + tolerations: + description: |- + Tolerations specifies the tolerations added to Pods in this group. + By default, suitable tolerations are set for the following keys with the `NoExecute` effect: + - `node.kubernetes.io/not-ready` + - `node.kubernetes.io/unreachable` + - `node.alpha.kubernetes.io/unreachable` (will be removed in future version) + For more information on tolerations, consult the https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeAllowShrink: + description: VolumeAllowShrink allows shrinking of the volume + type: boolean + volumeClaimTemplate: + description: |- + VolumeClaimTemplate specifies a volumeClaimTemplate used by operator to create to volume claims for pods of this group. + This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`. + The default value describes a volume with `8Gi` storage, `ReadWriteOnce` access mode and volume mode set to `PersistentVolumeFilesystem`. + If this field is not set and `spec..resources.requests.storage` is set, then a default volume claim + with size as specified by `spec..resources.requests.storage` will be created. In that case `storage` + and `iops` is not forwarded to the pods resource requirements. + properties: + apiVersion: + type: string + kind: + type: string + 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 + status: + properties: + accessModes: + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + allocatedResources: + additionalProperties: + type: string + type: object + capacity: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + type: object + phase: + type: string + type: object + type: object + volumeMounts: + description: VolumeMounts define list of volume mounts mounted into server container + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + description: Volumes define list of volumes mounted to pod + items: + properties: + configMap: + description: ConfigMap which should be mounted into pod + 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 + emptyDir: + description: EmptyDir + properties: + medium: + type: string + sizeLimit: + type: string + type: object + hostPath: + description: HostPath + properties: + path: + type: string + type: + type: string + type: object + name: + description: Name of volume + type: string + persistentVolumeClaim: + description: PersistentVolumeClaim + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + secret: + description: Secret which should be mounted into pod + 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 + type: object + type: array + type: object id: description: ServerIDGroupSpec contains the specification for Image Discovery image. properties: @@ -34330,6 +38602,2142 @@ v2alpha1: foxx.queues: type: boolean type: object + gateway: + description: Gateway defined main Gateway configuration. + properties: + enabled: + type: boolean + type: object + gateways: + description: Gateways contain specification for Gateway pods running in deployment mode `Single` or `Cluster`. + properties: + affinity: + description: Affinity specified additional affinity settings in ArangoDB Pod definitions + 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 + allowMemberRecreation: + description: |- + AllowMemberRecreation allows to recreate member. + This setting changes the member recreation logic based on group: + - For Sync Masters, Sync Workers, Coordinator and DB-Servers it determines if a member can be recreated in case of failure (default `true`) + - For Agents and Single this value is hardcoded to `false` and the value provided in spec is ignored. + type: boolean + annotations: + additionalProperties: + type: string + description: |- + Annotations specified the annotations added to Pods in this group. + Annotations are merged with `spec.annotations`. + type: object + annotationsIgnoreList: + description: AnnotationsIgnoreList list regexp or plain definitions which annotations should be ignored + items: + type: string + type: array + annotationsMode: + description: AnnotationsMode Define annotations mode which should be use while overriding annotations + type: string + antiAffinity: + description: AntiAffinity specified additional antiAffinity settings in ArangoDB Pod definitions + 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 + args: + description: Args setting specifies additional command-line arguments passed to all servers of this group. + items: + type: string + type: array + count: + description: |- + Count setting specifies the number of servers to start for the given group. + For the Agent group, this value must be a positive, odd number. + The default value is `3` for all groups except `single` (there the default is `1` + for `spec.mode: Single` and `2` for `spec.mode: ActiveFailover`). + For the `syncworkers` group, it is highly recommended to use the same number + as for the `dbservers` group. + format: int32 + type: integer + entrypoint: + description: Entrypoint overrides container executable + type: string + envs: + description: Envs allow to specify additional envs in this group. + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + ephemeralVolumes: + description: EphemeralVolumes keeps information about ephemeral volumes. + properties: + apps: + description: Apps define apps ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + temp: + description: Temp define temp ephemeral volume in case if `ephemeral-volumes` feature is enabled. + properties: + size: + description: Size define size of the ephemeral volume + type: string + type: object + type: object + exporterPort: + description: ExporterPort define Port used by exporter + format: int32 + type: integer + extendedRotationCheck: + description: ExtendedRotationCheck extend checks for rotation + type: boolean + externalPortEnabled: + description: ExternalPortEnabled if external port should be enabled. If is set to false, ports needs to be exposed via sidecar. Only for ArangoD members + type: boolean + indexMethod: + description: IndexMethod define group Indexing method + enum: + - random + - ordered + type: string + initContainers: + description: InitContainers Init containers specification + properties: + containers: + description: Containers contains list of 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 + mode: + description: Mode keep container replace mode + type: string + type: object + internalPort: + description: InternalPort define port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + format: int32 + type: integer + internalPortProtocol: + description: InternalPortProtocol define protocol of port used in internal communication, can be accessed over localhost via sidecar. Only for ArangoD members + type: string + labels: + additionalProperties: + type: string + description: Labels specified the labels added to Pods in this group. + type: object + labelsIgnoreList: + description: LabelsIgnoreList list regexp or plain definitions which labels should be ignored + items: + type: string + type: array + labelsMode: + description: LabelsMode Define labels mode which should be use while overriding labels + type: string + maxCount: + description: MaxCount specifies a maximum for the count of servers. If set, a specification is invalid if `count > maxCount`. + format: int32 + type: integer + memoryReservation: + description: |- + MemoryReservation determines the system reservation of memory while calculating `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` value. + If this field is set, `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` is reduced by a specified value in percent. + Accepted Range <0, 50>. If the value is outside the accepted range, it is adjusted to the closest value. + format: int64 + type: integer + minCount: + description: MinCount specifies a minimum for the count of servers. If set, a specification is invalid if `count < minCount`. + format: int32 + type: integer + nodeAffinity: + description: NodeAffinity specified additional nodeAffinity settings in ArangoDB Pod definitions + 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 + nodeSelector: + additionalProperties: + type: string + description: NodeSelector setting specifies a set of labels to be used as `nodeSelector` for Pods of this node. + type: object + numactl: + description: Numactl define Numactl options passed to the process + properties: + args: + description: Args define list of the numactl process + items: + type: string + type: array + enabled: + description: Enabled define if numactl should be enabled + type: boolean + path: + description: Path define numactl path within the container + type: string + type: object + overrideDetectedNumberOfCores: + description: |- + OverrideDetectedNumberOfCores determines if number of cores should be overridden based on values in resources. + If is set to true and Container CPU Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_NUMBER_OF_CORES` to the value from the Container CPU Limits. + type: boolean + overrideDetectedTotalMemory: + description: |- + OverrideDetectedTotalMemory determines if memory should be overridden based on values in resources. + If is set to true and Container Memory Limits are set, it sets Container Environment Variable `ARANGODB_OVERRIDE_DETECTED_TOTAL_MEMORY` to the value from the Container Memory Limits. + type: boolean + podModes: + description: PodModes define additional modes enabled on the Pod level + properties: + network: + type: string + pid: + type: string + type: object + port: + description: Port define Port used by member + format: int32 + type: integer + priorityClassName: + description: |- + PriorityClassName specifies a priority class name + Will be forwarded to the pod spec. + type: string + probes: + description: Probes specifies additional behaviour for probes + properties: + ReadinessProbeDisabled: + description: OldReadinessProbeDisabled if true readinessProbes are disabled + type: boolean + livenessProbeDisabled: + description: LivenessProbeDisabled if set to true, the operator does not generate a liveness probe for new pods belonging to this group + type: boolean + livenessProbeSpec: + description: LivenessProbeSpec override liveness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + readinessProbeDisabled: + description: ReadinessProbeDisabled override flag for probe disabled in good manner (lowercase) with backward compatibility + type: boolean + readinessProbeSpec: + description: ReadinessProbeSpec override readiness probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + startupProbeDisabled: + description: StartupProbeDisabled if true startupProbes are disabled + type: boolean + startupProbeSpec: + description: StartupProbeSpec override startup probe configuration + properties: + failureThreshold: + description: |- + FailureThreshold when a Pod starts and the probe fails, Kubernetes will try failureThreshold times before giving up. + Giving up means restarting the container. + Minimum value is 1. + format: int32 + type: integer + initialDelaySeconds: + description: |- + InitialDelaySeconds specifies number of seconds after the container has started before liveness or readiness probes are initiated. + Minimum value is 0. + format: int32 + type: integer + periodSeconds: + description: |- + PeriodSeconds How often (in seconds) to perform the probe. + Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: |- + SuccessThreshold Minimum consecutive successes for the probe to be considered successful after having failed. + Minimum value is 1. + format: int32 + type: integer + timeoutSeconds: + description: |- + TimeoutSeconds specifies number of seconds after which the probe times out + Minimum value is 1. + format: int32 + type: integer + type: object + type: object + pvcResizeMode: + description: VolumeResizeMode specified resize mode for PVCs and PVs + enum: + - runtime + - rotate + type: string + resources: + description: Resources holds resource requests & limits + properties: + claims: + items: + properties: + name: + type: string + type: object + type: array + limits: + additionalProperties: + type: string + type: object + requests: + additionalProperties: + type: string + type: object + type: object + schedulerName: + description: SchedulerName define scheduler name used for group + type: string + securityContext: + description: |- + SecurityContext specifies additional `securityContext` settings in ArangoDB Pod definitions. + This is similar (but not fully compatible) to k8s SecurityContext definition. + properties: + addCapabilities: + description: AddCapabilities add new capabilities to containers + items: + type: string + type: array + allowPrivilegeEscalation: + description: AllowPrivilegeEscalation Controls whether a process can gain more privileges than its parent process. + type: boolean + dropAllCapabilities: + description: DropAllCapabilities specifies if capabilities should be dropped for this pod containers + type: boolean + fsGroup: + description: FSGroup is a special supplemental group that applies to all containers in a pod. + format: int64 + type: integer + privileged: + description: |- + Privileged If true, runs container in privileged mode. Processes in privileged containers are + essentially equivalent to root on the host. + type: boolean + readOnlyRootFilesystem: + description: ReadOnlyRootFilesystem if true, mounts the container's root filesystem as read-only. + type: boolean + runAsGroup: + description: RunAsGroup is the GID to run the entrypoint of the container process. + format: int64 + type: integer + runAsNonRoot: + description: RunAsNonRoot if true, indicates that the container must run as a non-root user. + type: boolean + runAsUser: + description: RunAsUser is the UID to run the entrypoint of the container process. + format: int64 + type: integer + seLinuxOptions: + description: SELinuxOptions are the labels to be applied to the container + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + description: SeccompProfile defines a pod/container's seccomp profile settings. Only one profile source may be set. + properties: + localhostProfile: + type: string + type: + type: string + type: object + supplementalGroups: + description: |- + SupplementalGroups is a list of groups applied to the first process run in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in the container image for the uid of the container process. + items: + format: int64 + type: integer + type: array + sysctls: + additionalProperties: + type: string + x-kubernetes-int-or-string: true + description: |- + Sysctls hold a list of namespaced sysctls used for the pod. Pods with unsupported + sysctls (by the container runtime) might fail to launch. + Map Value can be String or Int + type: object + type: object + serviceAccountName: + description: |- + ServiceAccountName setting specifies the `serviceAccountName` for the `Pods` created + for each server of this group. If empty, it defaults to using the + `default` service account. + Using an alternative `ServiceAccount` is typically used to separate access rights. + The ArangoDB deployments need some very minimal access rights. With the + deployment of the operator, we grant the rights to 'get' all 'pod' resources. + If you are using a different service account, please grant these rights + to that service account. + type: string + shutdownDelay: + description: ShutdownDelay define how long operator should delay finalizer removal after shutdown + format: int32 + type: integer + shutdownMethod: + description: ShutdownMethod describe procedure of member shutdown taken by Operator + type: string + sidecarCoreNames: + description: |- + SidecarCoreNames is a list of sidecar containers which must run in the pod. + Some names (e.g.: "server", "worker") are reserved, and they don't have any impact. + items: + type: string + type: array + sidecars: + description: Sidecars specifies a list of additional containers to be started + 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 + storageClassName: + description: StorageClassName specifies the classname for storage of the servers. + type: string + terminationGracePeriodSeconds: + description: TerminationGracePeriodSeconds override default TerminationGracePeriodSeconds for pods - via silent rotation + format: int64 + type: integer + tolerations: + description: |- + Tolerations specifies the tolerations added to Pods in this group. + By default, suitable tolerations are set for the following keys with the `NoExecute` effect: + - `node.kubernetes.io/not-ready` + - `node.kubernetes.io/unreachable` + - `node.alpha.kubernetes.io/unreachable` (will be removed in future version) + For more information on tolerations, consult the https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/ + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + volumeAllowShrink: + description: VolumeAllowShrink allows shrinking of the volume + type: boolean + volumeClaimTemplate: + description: |- + VolumeClaimTemplate specifies a volumeClaimTemplate used by operator to create to volume claims for pods of this group. + This setting is not available for group `coordinators`, `syncmasters` & `syncworkers`. + The default value describes a volume with `8Gi` storage, `ReadWriteOnce` access mode and volume mode set to `PersistentVolumeFilesystem`. + If this field is not set and `spec..resources.requests.storage` is set, then a default volume claim + with size as specified by `spec..resources.requests.storage` will be created. In that case `storage` + and `iops` is not forwarded to the pods resource requirements. + properties: + apiVersion: + type: string + kind: + type: string + 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 + status: + properties: + accessModes: + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + type: string + type: object + allocatedResources: + additionalProperties: + type: string + type: object + capacity: + additionalProperties: + type: string + type: object + conditions: + items: + properties: + lastProbeTime: + format: date-time + type: string + lastTransitionTime: + format: date-time + type: string + message: + type: string + reason: + type: string + status: + type: string + type: + type: string + type: object + type: array + currentVolumeAttributesClassName: + type: string + modifyVolumeStatus: + properties: + status: + type: string + targetVolumeAttributesClassName: + type: string + type: object + phase: + type: string + type: object + type: object + volumeMounts: + description: VolumeMounts define list of volume mounts mounted into server container + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + type: object + type: array + volumes: + description: Volumes define list of volumes mounted to pod + items: + properties: + configMap: + description: ConfigMap which should be mounted into pod + 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 + emptyDir: + description: EmptyDir + properties: + medium: + type: string + sizeLimit: + type: string + type: object + hostPath: + description: HostPath + properties: + path: + type: string + type: + type: string + type: object + name: + description: Name of volume + type: string + persistentVolumeClaim: + description: PersistentVolumeClaim + properties: + claimName: + type: string + readOnly: + type: boolean + type: object + secret: + description: Secret which should be mounted into pod + 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 + type: object + type: array + type: object id: description: ServerIDGroupSpec contains the specification for Image Discovery image. properties: diff --git a/pkg/deployment/features/gateway.go b/pkg/deployment/features/gateway.go new file mode 100644 index 000000000..40173ef50 --- /dev/null +++ b/pkg/deployment/features/gateway.go @@ -0,0 +1,37 @@ +// +// DISCLAIMER +// +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// 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 features + +func init() { + registerFeature(gateway) +} + +var gateway = &feature{ + name: "gateway", + description: "Defines if gateway extension is enabled", + enterpriseRequired: false, + enabledByDefault: false, + hidden: true, +} + +func Gateway() Feature { + return gateway +} diff --git a/pkg/deployment/images.go b/pkg/deployment/images.go index 2dccae605..2f1e016e0 100644 --- a/pkg/deployment/images.go +++ b/pkg/deployment/images.go @@ -81,6 +81,11 @@ type ArangoSyncIdentity struct { interfaces.ContainerCreator } +// GatewayIdentity helps to resolve the Gateway identity, e.g.: image ID, version of the entrypoint. +type GatewayIdentity struct { + interfaces.ContainerCreator +} + type imagesBuilder struct { Log logging.Logger Context resources.Context diff --git a/pkg/deployment/members.go b/pkg/deployment/members.go index a3d20daa4..88982aaa2 100644 --- a/pkg/deployment/members.go +++ b/pkg/deployment/members.go @@ -210,6 +210,16 @@ func (d *Deployment) renderMember(spec api.DeploymentSpec, status *api.Deploymen Image: apiObject.Status.CurrentImage, Architecture: &arch, }, nil + case api.ServerGroupGateways: + d.log.Str("id", id).Debug("Adding gateway") + return &api.MemberStatus{ + ID: id, + UID: uuid.NewUUID(), + CreatedAt: meta.Now(), + Phase: api.MemberPhaseNone, + Image: apiObject.Status.CurrentImage, + Architecture: &arch, + }, nil default: return nil, errors.WithStack(errors.Errorf("Unknown server group %d", group)) } diff --git a/pkg/deployment/pod/utils.go b/pkg/deployment/pod/utils.go index 3ffa5ffa4..f868a3b1f 100644 --- a/pkg/deployment/pod/utils.go +++ b/pkg/deployment/pod/utils.go @@ -43,7 +43,7 @@ func GenerateMemberEndpoint(services service.Inspector, apiObject meta.Object, s func GenerateMemberEndpointFromService(svc *core.Service, apiObject meta.Object, spec api.DeploymentSpec, group api.ServerGroup, member api.MemberStatus) (string, error) { switch group.Type() { - case api.ServerGroupTypeArangoD: + case api.ServerGroupTypeArangoD, api.ServerGroupTypeGateway: switch method := spec.CommunicationMethod.Get(); method { case api.DeploymentCommunicationMethodDNS, api.DeploymentCommunicationMethodHeadlessDNS: return k8sutil.CreateServiceDNSNameWithDomain(svc, spec.ClusterDomain), nil diff --git a/pkg/deployment/reconcile/plan_builder_rebalancer_v2.go b/pkg/deployment/reconcile/plan_builder_rebalancer_v2.go index de7fc772b..cf76139f2 100644 --- a/pkg/deployment/reconcile/plan_builder_rebalancer_v2.go +++ b/pkg/deployment/reconcile/plan_builder_rebalancer_v2.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import ( "time" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/features" ) func (r *Reconciler) createRebalancerV2GeneratePlan(spec api.DeploymentSpec, status api.DeploymentStatus) api.Plan { @@ -44,7 +45,7 @@ func (r *Reconciler) createRebalancerV2GeneratePlan(spec api.DeploymentSpec, sta r.metrics.Rebalancer.SetEnabled(true) - if !status.Members.AllMembersReady(spec.Mode.Get(), spec.Sync.IsEnabled()) { + if !status.Members.AllMembersReady(spec.Mode.Get(), spec.Sync.IsEnabled(), features.Gateway().Enabled() && spec.IsGatewayEnabled()) { return nil } diff --git a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go index acda2247f..e652d1f4e 100644 --- a/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go +++ b/pkg/deployment/reconcile/plan_builder_rotate_upgrade.go @@ -49,6 +49,7 @@ var ( api.ServerGroupDBServers, api.ServerGroupSyncMasters, api.ServerGroupSyncWorkers, + api.ServerGroupGateways, } ) diff --git a/pkg/deployment/reconcile/plan_builder_scale.go b/pkg/deployment/reconcile/plan_builder_scale.go index 86110481f..8ae98d66f 100644 --- a/pkg/deployment/reconcile/plan_builder_scale.go +++ b/pkg/deployment/reconcile/plan_builder_scale.go @@ -25,6 +25,7 @@ import ( api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" "github.com/arangodb/kube-arangodb/pkg/deployment/actions" + "github.com/arangodb/kube-arangodb/pkg/deployment/features" sharedReconcile "github.com/arangodb/kube-arangodb/pkg/deployment/reconcile/shared" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" ) @@ -69,6 +70,11 @@ func (r *Reconciler) createScaleMemberPlan(ctx context.Context, apiObject k8suti plan = append(plan, r.createScalePlan(status, status.Members.SyncWorkers, api.ServerGroupSyncWorkers, 0, context)...) } } + if features.Gateway().Enabled() && spec.IsGatewayEnabled() { + plan = append(plan, r.createScalePlan(status, status.Members.Gateways, api.ServerGroupGateways, spec.Gateways.GetCount(), context)...) + } else { + plan = append(plan, r.createScalePlan(status, status.Members.Gateways, api.ServerGroupGateways, 0, context)...) + } return plan } diff --git a/pkg/deployment/resilience/member_failure.go b/pkg/deployment/resilience/member_failure.go index 91529cd8e..0dd546f97 100644 --- a/pkg/deployment/resilience/member_failure.go +++ b/pkg/deployment/resilience/member_failure.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -132,6 +132,9 @@ func (r *Resilience) isMemberFailureAcceptable(group api.ServerGroup, m api.Memb case api.ServerGroupSyncMasters, api.ServerGroupSyncWorkers: // Sync masters & workers can be replaced at will return true, "" + case api.ServerGroupGateways: + // Gateways can be replaced at will + return true, "" case api.ServerGroupSingle: return false, "ServerGroupSingle can not marked as a failed" default: diff --git a/pkg/deployment/resources/pdbs.go b/pkg/deployment/resources/pdbs.go index afdf41dec..36530396c 100644 --- a/pkg/deployment/resources/pdbs.go +++ b/pkg/deployment/resources/pdbs.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/util/errors" "github.com/arangodb/kube-arangodb/pkg/util/globals" "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" @@ -72,6 +73,12 @@ func (r *Resources) EnsurePDBs(ctx context.Context) error { currSyncWorker = status.Members.SyncWorkers.MembersReady() } + minGateways, currGateways := 0, 0 + if features.Gateway().Enabled() && spec.IsGatewayEnabled() { + minGateways = spec.GetServerGroupSpec(api.ServerGroupGateways).New().GetCount() - 1 + currGateways = status.Members.Gateways.MembersReady() + } + // Ensure all PDBs as calculated if err := r.ensurePDBForGroup(ctx, api.ServerGroupAgents, minAgents, currAgents); err != nil { return err @@ -88,6 +95,9 @@ func (r *Resources) EnsurePDBs(ctx context.Context) error { if err := r.ensurePDBForGroup(ctx, api.ServerGroupSyncWorkers, minSyncWorker, currSyncWorker); err != nil { return err } + if err := r.ensurePDBForGroup(ctx, api.ServerGroupGateways, minGateways, currGateways); err != nil { + return err + } } return nil diff --git a/pkg/deployment/resources/pod_creator.go b/pkg/deployment/resources/pod_creator.go index 5befe8a2c..36f0ecc27 100644 --- a/pkg/deployment/resources/pod_creator.go +++ b/pkg/deployment/resources/pod_creator.go @@ -286,6 +286,15 @@ func createArangoSyncArgs(apiObject meta.Object, spec api.DeploymentSpec, group return args } +func createArangoGatewayArgs(groupSpec api.ServerGroupSpec) []string { + args := []string{"--config-path", GatewayConfigFilePath} + if len(groupSpec.Args) > 0 { + args = append(args, groupSpec.Args...) + } + + return args +} + // CreatePodTolerations creates a list of tolerations for a pod created for the given group. func (r *Resources) CreatePodTolerations(group api.ServerGroup, groupSpec api.ServerGroupSpec) []core.Toleration { return tolerations.MergeTolerationsIfNotFound(tolerations.CreatePodTolerations(r.context.GetMode(), group), groupSpec.GetTolerations()) @@ -379,6 +388,21 @@ func (r *Resources) RenderPodForMember(ctx context.Context, acs sutil.ACS, spec memberStatus: m, cachedStatus: cache, } + case api.ServerGroupTypeGateway: + imageInfo.Image = r.context.GetOperatorImage() + + podCreator = &MemberGatewayPod{ + podName: podName, + groupSpec: groupSpec, + spec: spec, + group: group, + resources: r, + imageInfo: imageInfo, + arangoMember: *member, + apiObject: apiObject, + memberStatus: m, + cachedStatus: cache, + } default: return nil, assertion.InvalidGroupKey.Assert(true, "Unable to render pod for an unknown group: %s", group.AsRole()) } @@ -548,6 +572,27 @@ func (r *Resources) createPodForMember(ctx context.Context, cachedStatus inspect m.Pod.Propagate(&m) log.Str("pod-name", pod.Name).Debug("Created pod") + case api.ServerGroupTypeGateway: + ctxChild, cancel := globals.GetGlobalTimeouts().Kubernetes().WithTimeout(ctx) + defer cancel() + podName, uid, err := CreateArangoPod(ctxChild, cachedStatus.PodsModInterface().V1(), apiObject, spec, group, CreatePodFromTemplate(template.PodSpec)) + if err != nil { + if uErr := r.context.WithMemberStatusUpdateErr(ctx, m.ID, group, updateMemberPhase(api.MemberPhaseCreationFailed)); uErr != nil { + return errors.WithStack(uErr) + } + return errors.WithStack(err) + } + + var pod api.MemberPodStatus + + pod.Name = podName + pod.UID = uid + pod.SpecVersion = template.PodSpecChecksum + + m.Pod = &pod + m.Pod.Propagate(&m) + + log.Str("pod-name", pod.Name).Debug("Created Gateway pod") default: return assertion.InvalidGroupKey.Assert(true, "Unable to create pod for an unknown group: %s", group.AsRole()) } diff --git a/pkg/deployment/resources/pod_creator_gateway.go b/pkg/deployment/resources/pod_creator_gateway.go new file mode 100644 index 000000000..e46415ccf --- /dev/null +++ b/pkg/deployment/resources/pod_creator_gateway.go @@ -0,0 +1,346 @@ +// +// DISCLAIMER +// +// Copyright 2024 ArangoDB GmbH, Cologne, Germany +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Copyright holder is ArangoDB GmbH, Cologne, Germany +// + +package resources + +import ( + "context" + "fmt" + "math" + + core "k8s.io/api/core/v1" + meta "k8s.io/apimachinery/pkg/apis/meta/v1" + + api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" + shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" + "github.com/arangodb/kube-arangodb/pkg/deployment/features" + "github.com/arangodb/kube-arangodb/pkg/deployment/pod" + "github.com/arangodb/kube-arangodb/pkg/util/collection" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil" + "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/interfaces" + kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" +) + +const ( + ArangoGatewayExecutor string = "/usr/local/bin/envoy" + GatewayVolumeMountDir = "/etc/gateway/" + GatewayVolumeName = "gateway" + GatewayConfigFileName = "gateway.yaml" + GatewayConfigFilePath = GatewayVolumeMountDir + GatewayConfigFileName +) + +type ArangoGatewayContainer struct { + groupSpec api.ServerGroupSpec + spec api.DeploymentSpec + group api.ServerGroup + resources *Resources + imageInfo api.ImageInfo + apiObject meta.Object + memberStatus api.MemberStatus + arangoMember api.ArangoMember +} + +var _ interfaces.PodCreator = &MemberGatewayPod{} +var _ interfaces.ContainerCreator = &ArangoGatewayContainer{} + +type MemberGatewayPod struct { + podName string + + groupSpec api.ServerGroupSpec + spec api.DeploymentSpec + group api.ServerGroup + arangoMember api.ArangoMember + resources *Resources + imageInfo api.ImageInfo + apiObject meta.Object + memberStatus api.MemberStatus + cachedStatus interfaces.Inspector +} + +func GetGatewayConfigMapName(name string) string { + return fmt.Sprintf("%s-gateway", name) +} + +func (a *ArangoGatewayContainer) GetCommand() ([]string, error) { + cmd := make([]string, 0, 128) + cmd = append(cmd, a.GetExecutor()) + cmd = append(cmd, createArangoGatewayArgs(a.groupSpec)...) + return cmd, nil +} + +func (a *ArangoGatewayContainer) GetName() string { + return shared.ServerContainerName +} + +func (a *ArangoGatewayContainer) GetPorts() []core.ContainerPort { + port := shared.ArangoPort + + return []core.ContainerPort{ + { + Name: shared.ServerContainerName, + ContainerPort: int32(port), + Protocol: core.ProtocolTCP, + }, + } +} + +func (a *ArangoGatewayContainer) GetExecutor() string { + return a.groupSpec.GetEntrypoint(ArangoGatewayExecutor) +} + +func (a *ArangoGatewayContainer) GetSecurityContext() *core.SecurityContext { + return k8sutil.CreateSecurityContext(a.groupSpec.SecurityContext) +} + +func (a *ArangoGatewayContainer) GetProbes() (*core.Probe, *core.Probe, *core.Probe, error) { + var liveness, readiness, startup *core.Probe + + probeLivenessConfig, err := a.resources.getLivenessProbe(a.spec, a.group, a.imageInfo) + if err != nil { + return nil, nil, nil, err + } + + probeReadinessConfig, err := a.resources.getReadinessProbe(a.spec, a.group, a.imageInfo) + if err != nil { + return nil, nil, nil, err + } + + probeStartupConfig, err := a.resources.getReadinessProbe(a.spec, a.group, a.imageInfo) + if err != nil { + return nil, nil, nil, err + } + + if probeLivenessConfig != nil { + liveness = probeLivenessConfig.Create() + } + + if probeReadinessConfig != nil { + readiness = probeReadinessConfig.Create() + } + + if probeStartupConfig != nil { + startup = probeStartupConfig.Create() + } + + return liveness, readiness, startup, nil +} + +func (a *ArangoGatewayContainer) GetResourceRequirements() core.ResourceRequirements { + return kresources.ExtractPodAcceptedResourceRequirement(a.arangoMember.Spec.Overrides.GetResources(&a.groupSpec)) +} + +func (a *ArangoGatewayContainer) GetLifecycle() (*core.Lifecycle, error) { + return k8sutil.NewLifecycleFinalizers() +} + +func (a *ArangoGatewayContainer) GetImagePullPolicy() core.PullPolicy { + return a.spec.GetImagePullPolicy() +} + +func (a *ArangoGatewayContainer) GetImage() string { + return a.imageInfo.Image +} + +func (a *ArangoGatewayContainer) GetEnvs() ([]core.EnvVar, []core.EnvFromSource) { + envs := NewEnvBuilder() + + envs.Add(true, k8sutil.GetLifecycleEnv()...) + + if len(a.groupSpec.Envs) > 0 { + for _, env := range a.groupSpec.Envs { + // Do not override preset envs + envs.Add(false, core.EnvVar{ + Name: env.Name, + Value: env.Value, + }) + } + } + + return envs.GetEnvList(), nil +} + +func (a *ArangoGatewayContainer) GetVolumeMounts() []core.VolumeMount { + return createGatewayVolumes(a.apiObject.GetName()).VolumeMounts() +} + +func (m *MemberGatewayPod) GetName() string { + return m.resources.context.GetAPIObject().GetName() +} + +func (m *MemberGatewayPod) GetRole() string { + return m.group.AsRole() +} + +func (m *MemberGatewayPod) GetImagePullSecrets() []string { + return m.spec.ImagePullSecrets +} + +func (m *MemberGatewayPod) GetPodAntiAffinity() *core.PodAntiAffinity { + a := &core.PodAntiAffinity{} + + pod.AppendPodAntiAffinityDefault(m, a) + + a = kresources.MergePodAntiAffinity(a, m.groupSpec.AntiAffinity) + + return kresources.OptionalPodAntiAffinity(a) +} + +func (m *MemberGatewayPod) GetPodAffinity() *core.PodAffinity { + a := &core.PodAffinity{} + + pod.AppendAffinityWithRole(m, a, api.ServerGroupDBServers.AsRole()) + + a = kresources.MergePodAffinity(a, m.groupSpec.Affinity) + + return kresources.OptionalPodAffinity(a) +} + +func (m *MemberGatewayPod) GetNodeAffinity() *core.NodeAffinity { + a := &core.NodeAffinity{} + + pod.AppendArchSelector(a, m.memberStatus.Architecture.Default(m.spec.Architecture.GetDefault()).AsNodeSelectorRequirement()) + + a = kresources.MergeNodeAffinity(a, m.groupSpec.NodeAffinity) + + return kresources.OptionalNodeAffinity(a) +} + +func (m *MemberGatewayPod) GetNodeSelector() map[string]string { + return m.groupSpec.GetNodeSelector() +} + +func (m *MemberGatewayPod) GetServiceAccountName() string { + return m.groupSpec.GetServiceAccountName() +} + +func (m *MemberGatewayPod) GetSidecars(pod *core.Pod) error { + // A sidecar provided by the user + sidecars := m.groupSpec.GetSidecars() + if len(sidecars) > 0 { + addLifecycleSidecar(m.groupSpec.SidecarCoreNames, sidecars) + pod.Spec.Containers = append(pod.Spec.Containers, sidecars...) + } + + return nil +} + +func (m *MemberGatewayPod) GetVolumes() []core.Volume { + return createGatewayVolumes(m.apiObject.GetName()).Volumes() +} + +func (m *MemberGatewayPod) IsDeploymentMode() bool { + return m.spec.IsDevelopment() +} + +func (m *MemberGatewayPod) GetInitContainers(cachedStatus interfaces.Inspector) ([]core.Container, error) { + var initContainers []core.Container + if c := m.groupSpec.InitContainers.GetContainers(); len(c) > 0 { + initContainers = append(initContainers, c...) + } + + res := kresources.ExtractPodInitContainerAcceptedResourceRequirement(m.GetContainerCreator().GetResourceRequirements()) + + initContainers = applyInitContainersResourceResources(initContainers, res) + initContainers = upscaleInitContainersResourceResources(initContainers, res) + + return initContainers, nil +} + +func (m *MemberGatewayPod) GetFinalizers() []string { + return nil +} + +func (m *MemberGatewayPod) GetTolerations() []core.Toleration { + return m.resources.CreatePodTolerations(m.group, m.groupSpec) +} + +func (m *MemberGatewayPod) GetContainerCreator() interfaces.ContainerCreator { + return &ArangoGatewayContainer{ + groupSpec: m.groupSpec, + spec: m.spec, + group: m.group, + resources: m.resources, + imageInfo: m.imageInfo, + apiObject: m.apiObject, + memberStatus: m.memberStatus, + arangoMember: m.arangoMember, + } +} + +func (m *MemberGatewayPod) GetRestartPolicy() core.RestartPolicy { + if features.RestartPolicyAlways().Enabled() { + return core.RestartPolicyAlways + } + return core.RestartPolicyNever +} + +func (m *MemberGatewayPod) Init(ctx context.Context, cachedStatus interfaces.Inspector, pod *core.Pod) error { + terminationGracePeriodSeconds := int64(math.Ceil(m.groupSpec.GetTerminationGracePeriod(m.group).Seconds())) + pod.Spec.TerminationGracePeriodSeconds = &terminationGracePeriodSeconds + pod.Spec.PriorityClassName = m.groupSpec.PriorityClassName + + return nil +} + +func (m *MemberGatewayPod) Validate(_ interfaces.Inspector) error { + if err := validateSidecars(m.groupSpec.SidecarCoreNames, m.groupSpec.GetSidecars()); err != nil { + return err + } + + return nil +} + +func (m *MemberGatewayPod) ApplyPodSpec(spec *core.PodSpec) error { + if s := m.groupSpec.SchedulerName; s != nil { + spec.SchedulerName = *s + } + + m.groupSpec.PodModes.Apply(spec) + + return nil +} + +func (m *MemberGatewayPod) Annotations() map[string]string { + return collection.MergeAnnotations(m.spec.Annotations, m.groupSpec.Annotations) +} + +func (m *MemberGatewayPod) Labels() map[string]string { + return collection.ReservedLabels().Filter(collection.MergeAnnotations(m.spec.Labels, m.groupSpec.Labels)) +} + +func createGatewayVolumes(memberName string) pod.Volumes { + volumes := pod.NewVolumes() + + volumes.AddVolume(k8sutil.LifecycleVolume()) + volumes.AddVolumeMount(k8sutil.LifecycleVolumeMount()) + + volumes.AddVolume(k8sutil.CreateVolumeWithConfigMap(GatewayVolumeName, GetGatewayConfigMapName(memberName))) + volumes.AddVolumeMount(GatewayVolumeMount()) + + return volumes +} + +func GatewayVolumeMount() core.VolumeMount { + return core.VolumeMount{ + Name: GatewayVolumeName, + MountPath: GatewayVolumeMountDir, + ReadOnly: true, + } +} diff --git a/pkg/deployment/resources/pod_inspector.go b/pkg/deployment/resources/pod_inspector.go index 3f50c35dc..1a51f28e3 100644 --- a/pkg/deployment/resources/pod_inspector.go +++ b/pkg/deployment/resources/pod_inspector.go @@ -33,6 +33,7 @@ import ( api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1" shared "github.com/arangodb/kube-arangodb/pkg/apis/shared" "github.com/arangodb/kube-arangodb/pkg/deployment/agency/state" + "github.com/arangodb/kube-arangodb/pkg/deployment/features" "github.com/arangodb/kube-arangodb/pkg/deployment/patch" "github.com/arangodb/kube-arangodb/pkg/metrics" "github.com/arangodb/kube-arangodb/pkg/util" @@ -530,7 +531,7 @@ func (r *Resources) InspectPods(ctx context.Context, cachedStatus inspectorInter } spec := r.context.GetSpec() - allMembersReady := status.Members.AllMembersReady(spec.GetMode(), r.context.IsSyncEnabled()) + allMembersReady := status.Members.AllMembersReady(spec.GetMode(), r.context.IsSyncEnabled(), features.Gateway().Enabled() && spec.IsGatewayEnabled()) status.Conditions.Update(api.ConditionTypeReady, allMembersReady, "", "") // Update conditions diff --git a/pkg/deployment/resources/services.go b/pkg/deployment/resources/services.go index 45fef63b7..869e6b488 100644 --- a/pkg/deployment/resources/services.go +++ b/pkg/deployment/resources/services.go @@ -82,6 +82,10 @@ func (r *Resources) EnsureServices(ctx context.Context, cachedStatus inspectorIn defer metrics.SetDuration(inspectServicesDurationGauges.WithLabelValues(deploymentName), start) counterMetric := inspectedServicesCounters.WithLabelValues(deploymentName) + if features.Gateway().Enabled() && spec.IsGatewayEnabled() { + role = api.ServerGroupGateways.AsRole() + } + // Fetch existing services svcs := cachedStatus.ServicesModInterface().V1() amInspector := cachedStatus.ArangoMember().V1() diff --git a/pkg/util/k8sutil/pods.go b/pkg/util/k8sutil/pods.go index b2215843a..91359295b 100644 --- a/pkg/util/k8sutil/pods.go +++ b/pkg/util/k8sutil/pods.go @@ -641,6 +641,18 @@ func CreateVolumeWithSecret(name, secretName string) core.Volume { }, } } +func CreateVolumeWithConfigMap(name, configMapName string) core.Volume { + return core.Volume{ + Name: name, + VolumeSource: core.VolumeSource{ + ConfigMap: &core.ConfigMapVolumeSource{ + LocalObjectReference: core.LocalObjectReference{ + Name: configMapName, + }, + }, + }, + } +} func CreateVolumeWithPersitantVolumeClaim(name, claimName string) core.Volume { return core.Volume{ diff --git a/pkg/util/k8sutil/tolerations/tolerations.go b/pkg/util/k8sutil/tolerations/tolerations.go index d574f4e59..e0bfa0656 100644 --- a/pkg/util/k8sutil/tolerations/tolerations.go +++ b/pkg/util/k8sutil/tolerations/tolerations.go @@ -1,7 +1,7 @@ // // DISCLAIMER // -// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany +// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -134,6 +134,9 @@ func CreatePodTolerations(mode api.DeploymentMode, group api.ServerGroup) []core case api.ServerGroupSyncWorkers: notReadyDur.TimeSpan = 1 * time.Minute unreachableDur.TimeSpan = 1 * time.Minute + case api.ServerGroupGateways: + notReadyDur.TimeSpan = 15 * time.Second + unreachableDur.TimeSpan = 15 * time.Second } return []core.Toleration{NewNoExecuteToleration(TolerationKeyNodeNotReady, notReadyDur), NewNoExecuteToleration(TolerationKeyNodeUnreachable, unreachableDur), diff --git a/pkg/util/k8sutil/util.go b/pkg/util/k8sutil/util.go index 34ffd78cd..3a8a98419 100644 --- a/pkg/util/k8sutil/util.go +++ b/pkg/util/k8sutil/util.go @@ -44,7 +44,7 @@ const ( LabelKeyArangoScheduled = "deployment.arangodb.com/scheduled" // LabelKeyArangoTopology is the key of the label used to store the ArangoDeployment topology ID in LabelKeyArangoTopology = "deployment.arangodb.com/topology" - // LabelKeyArangoLeader is the key of the label used to store the current leader of a group instances. + // LabelKeyArangoLeader is the key of the label used to store the current leader of a group instances. AF only. LabelKeyArangoLeader = "deployment.arangodb.com/leader" // LabelKeyArangoActive is the key of the label used to mark members as active. LabelKeyArangoActive = "deployment.arangodb.com/active"