mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
[Feature] ArangoRoute RC (#1690)
This commit is contained in:
parent
ae55994d68
commit
ee5ea98638
70 changed files with 3119 additions and 277 deletions
|
@ -84,7 +84,7 @@ jobs:
|
|||
echo "This is not a pull request. Skipping..."
|
||||
exit 0
|
||||
fi
|
||||
make tidy update-generated synchronize-v2alpha1-with-v1 generate-internal sync fmt yamlfmt
|
||||
make tidy update-generated synchronize-v2alpha1-with-v1 generate-internal sync fmt yamlfmt license
|
||||
git checkout -- go.sum # ignore changes in go.sum
|
||||
if [ ! -z "$(git status --porcelain)" ]; then
|
||||
echo "There are uncommited changes!"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
|
||||
- (Feature) ArangoRoute CRD
|
||||
- (Feature) ArangoRoute Operator
|
||||
|
||||
## [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
|
||||
|
|
2
Makefile
2
Makefile
|
@ -777,7 +777,7 @@ tools-min: update-vendor
|
|||
.PHONY: tools
|
||||
tools: tools-min
|
||||
@echo ">> Fetching gci"
|
||||
@GOBIN=$(GOPATH)/bin go install github.com/daixiang0/gci@v0.3.0
|
||||
@GOBIN=$(GOPATH)/bin go install github.com/daixiang0/gci@v0.13.4
|
||||
@echo ">> Fetching yamlfmt"
|
||||
@GOBIN=$(GOPATH)/bin go install github.com/google/yamlfmt/cmd/yamlfmt@v0.10.0
|
||||
@echo ">> Downloading protobuf compiler..."
|
||||
|
|
|
@ -181,7 +181,7 @@ Flags:
|
|||
--kubernetes.max-batch-size int Size of batch during objects read (default 256)
|
||||
--kubernetes.qps float32 Number of queries per second for k8s API (default 15)
|
||||
--log.format string Set log format. Allowed values: 'pretty', 'JSON'. If empty, default format is used (default "pretty")
|
||||
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, http, inspector, integrations, k8s-client, monitor, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, server, server-authentication (default [info])
|
||||
--log.level stringArray Set log levels in format <level> or <logger>=<level>. Possible loggers: action, agency, api-server, assertion, backup-operator, chaos-monkey, crd, deployment, deployment-ci, deployment-reconcile, deployment-replication, deployment-resilience, deployment-resources, deployment-storage, deployment-storage-pc, deployment-storage-service, http, inspector, integrations, k8s-client, monitor, networking-route-operator, operator, operator-arangojob-handler, operator-v2, operator-v2-event, operator-v2-worker, panics, pod_compare, root, root-event-recorder, server, server-authentication (default [info])
|
||||
--log.sampling If true, operator will try to minimize duplication of logging events (default true)
|
||||
--memory-limit uint Define memory limit for hard shutdown and the dump of goroutines. Used for testing
|
||||
--metrics.excluded-prefixes stringArray List of the excluded metrics prefixes
|
||||
|
@ -192,6 +192,7 @@ Flags:
|
|||
--operator.deployment Enable to run the ArangoDeployment operator
|
||||
--operator.deployment-replication Enable to run the ArangoDeploymentReplication operator
|
||||
--operator.ml Enable to run the ArangoML operator
|
||||
--operator.networking Enable to run the Networking operator
|
||||
--operator.reconciliation.retry.count int Count of retries during Object Update operations in the Reconciliation loop (default 25)
|
||||
--operator.reconciliation.retry.delay duration Delay between Object Update operations in the Reconciliation loop (default 1s)
|
||||
--operator.storage Enable to run the ArangoLocalStorage operator
|
||||
|
|
|
@ -117,6 +117,9 @@ spec:
|
|||
{{ if .Values.operator.features.analytics }}
|
||||
- --operator.analytics
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.networking }}
|
||||
- --operator.networking
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.k8sToK8sClusterSync }}
|
||||
- --operator.k2k-cluster-sync
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,22 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,25 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,68 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "ml.arangodb.com"
|
||||
resources:
|
||||
- "arangomlextensions"
|
||||
- "arangomlextensions/status"
|
||||
- "arangomlbatchjobs"
|
||||
- "arangomlbatchjobs/status"
|
||||
- "arangomlcronjobs"
|
||||
- "arangomlcronjobs/status"
|
||||
- "arangomlstorages"
|
||||
- "arangomlstorages/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "scheduler.arangodb.com"
|
||||
resources:
|
||||
- "arangoprofiles"
|
||||
- "arangoprofiles/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "database.arangodb.com"
|
||||
resources:
|
||||
- "arangodeployments"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- apiGroups:
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- "roles"
|
||||
- "rolebindings"
|
||||
verbs: ["*"]
|
||||
- apiGroups:
|
||||
- "batch"
|
||||
resources:
|
||||
- "cronjobs"
|
||||
- "jobs"
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources:
|
||||
- "statefulsets"
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- "pods"
|
||||
- "secrets"
|
||||
- "services"
|
||||
- "serviceaccounts"
|
||||
verbs: ["*"]
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -117,6 +117,9 @@ spec:
|
|||
{{ if .Values.operator.features.analytics }}
|
||||
- --operator.analytics
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.networking }}
|
||||
- --operator.networking
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.k8sToK8sClusterSync }}
|
||||
- --operator.k2k-cluster-sync
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,22 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,25 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,68 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "ml.arangodb.com"
|
||||
resources:
|
||||
- "arangomlextensions"
|
||||
- "arangomlextensions/status"
|
||||
- "arangomlbatchjobs"
|
||||
- "arangomlbatchjobs/status"
|
||||
- "arangomlcronjobs"
|
||||
- "arangomlcronjobs/status"
|
||||
- "arangomlstorages"
|
||||
- "arangomlstorages/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "scheduler.arangodb.com"
|
||||
resources:
|
||||
- "arangoprofiles"
|
||||
- "arangoprofiles/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "database.arangodb.com"
|
||||
resources:
|
||||
- "arangodeployments"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- apiGroups:
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- "roles"
|
||||
- "rolebindings"
|
||||
verbs: ["*"]
|
||||
- apiGroups:
|
||||
- "batch"
|
||||
resources:
|
||||
- "cronjobs"
|
||||
- "jobs"
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources:
|
||||
- "statefulsets"
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- "pods"
|
||||
- "secrets"
|
||||
- "services"
|
||||
- "serviceaccounts"
|
||||
verbs: ["*"]
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -117,6 +117,9 @@ spec:
|
|||
{{ if .Values.operator.features.analytics }}
|
||||
- --operator.analytics
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.networking }}
|
||||
- --operator.networking
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.k8sToK8sClusterSync }}
|
||||
- --operator.k2k-cluster-sync
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,22 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,25 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,68 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "ml.arangodb.com"
|
||||
resources:
|
||||
- "arangomlextensions"
|
||||
- "arangomlextensions/status"
|
||||
- "arangomlbatchjobs"
|
||||
- "arangomlbatchjobs/status"
|
||||
- "arangomlcronjobs"
|
||||
- "arangomlcronjobs/status"
|
||||
- "arangomlstorages"
|
||||
- "arangomlstorages/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "scheduler.arangodb.com"
|
||||
resources:
|
||||
- "arangoprofiles"
|
||||
- "arangoprofiles/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "database.arangodb.com"
|
||||
resources:
|
||||
- "arangodeployments"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- apiGroups:
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- "roles"
|
||||
- "rolebindings"
|
||||
verbs: ["*"]
|
||||
- apiGroups:
|
||||
- "batch"
|
||||
resources:
|
||||
- "cronjobs"
|
||||
- "jobs"
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources:
|
||||
- "statefulsets"
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- "pods"
|
||||
- "secrets"
|
||||
- "services"
|
||||
- "serviceaccounts"
|
||||
verbs: ["*"]
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -117,6 +117,9 @@ spec:
|
|||
{{ if .Values.operator.features.analytics }}
|
||||
- --operator.analytics
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.networking }}
|
||||
- --operator.networking
|
||||
{{- end }}
|
||||
{{ if .Values.operator.features.k8sToK8sClusterSync }}
|
||||
- --operator.k2k-cluster-sync
|
||||
{{- end }}
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,22 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if not (eq .Values.operator.scope "namespaced") -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac-cluster" . }}-networking
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -0,0 +1,25 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ template "kube-arangodb.operatorName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
|
||||
{{- end }}
|
||||
{{- end }}
|
68
chart/kube-arangodb/templates/networking-operator/role.yaml
Normal file
68
chart/kube-arangodb/templates/networking-operator/role.yaml
Normal file
|
@ -0,0 +1,68 @@
|
|||
{{ if .Values.rbac.enabled -}}
|
||||
{{ if .Values.operator.features.networking -}}
|
||||
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ template "kube-arangodb.rbac" . }}-networking
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
app.kubernetes.io/name: {{ template "kube-arangodb.name" . }}
|
||||
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
release: {{ .Release.Name }}
|
||||
rules:
|
||||
- apiGroups:
|
||||
- "ml.arangodb.com"
|
||||
resources:
|
||||
- "arangomlextensions"
|
||||
- "arangomlextensions/status"
|
||||
- "arangomlbatchjobs"
|
||||
- "arangomlbatchjobs/status"
|
||||
- "arangomlcronjobs"
|
||||
- "arangomlcronjobs/status"
|
||||
- "arangomlstorages"
|
||||
- "arangomlstorages/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "scheduler.arangodb.com"
|
||||
resources:
|
||||
- "arangoprofiles"
|
||||
- "arangoprofiles/status"
|
||||
verbs:
|
||||
- "*"
|
||||
- apiGroups:
|
||||
- "database.arangodb.com"
|
||||
resources:
|
||||
- "arangodeployments"
|
||||
verbs:
|
||||
- "get"
|
||||
- "list"
|
||||
- "watch"
|
||||
- apiGroups:
|
||||
- "rbac.authorization.k8s.io"
|
||||
resources:
|
||||
- "roles"
|
||||
- "rolebindings"
|
||||
verbs: ["*"]
|
||||
- apiGroups:
|
||||
- "batch"
|
||||
resources:
|
||||
- "cronjobs"
|
||||
- "jobs"
|
||||
verbs: ["*"]
|
||||
- apiGroups: ["apps"]
|
||||
resources:
|
||||
- "statefulsets"
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources:
|
||||
- "pods"
|
||||
- "secrets"
|
||||
- "services"
|
||||
- "serviceaccounts"
|
||||
verbs: ["*"]
|
||||
{{- end }}
|
||||
{{- end }}
|
|
@ -34,6 +34,7 @@ operator:
|
|||
k8sToK8sClusterSync: false
|
||||
ml: false
|
||||
analytics: false
|
||||
networking: true
|
||||
tolerations: []
|
||||
rbac:
|
||||
enabled: true
|
||||
|
|
18
cmd/cmd.go
18
cmd/cmd.go
|
@ -119,6 +119,7 @@ var (
|
|||
enableApps bool // Run apps operator
|
||||
enableML bool // Run ml operator
|
||||
enableAnalytics bool // Run analytics operator
|
||||
enableNetworking bool // Run networking operator
|
||||
versionOnly bool // Run only version endpoint, explicitly disabled with other
|
||||
enableK2KClusterSync bool // Run k2kClusterSync operator
|
||||
|
||||
|
@ -184,6 +185,7 @@ var (
|
|||
appsProbe probe.ReadyProbe
|
||||
mlProbe probe.ReadyProbe
|
||||
analyticsProbe probe.ReadyProbe
|
||||
networkingProbe probe.ReadyProbe
|
||||
k2KClusterSyncProbe probe.ReadyProbe
|
||||
)
|
||||
|
||||
|
@ -210,6 +212,7 @@ func init() {
|
|||
f.BoolVar(&operatorOptions.enableApps, "operator.apps", false, "Enable to run the ArangoApps operator")
|
||||
f.BoolVar(&operatorOptions.enableML, "operator.ml", false, "Enable to run the ArangoML operator")
|
||||
f.BoolVar(&operatorOptions.enableAnalytics, "operator.analytics", false, "Enable to run the Analytics operator")
|
||||
f.BoolVar(&operatorOptions.enableNetworking, "operator.networking", false, "Enable to run the Networking operator")
|
||||
f.BoolVar(&operatorOptions.enableK2KClusterSync, "operator.k2k-cluster-sync", false, "Enable to run the ListSimple operator")
|
||||
f.MarkDeprecated("operator.k2k-cluster-sync", "Enabled within deployment operator")
|
||||
f.BoolVar(&operatorOptions.versionOnly, "operator.version", false, "Enable only version endpoint in Operator")
|
||||
|
@ -345,16 +348,17 @@ func executeMain(cmd *cobra.Command, args []string) {
|
|||
|
||||
// Check operating mode
|
||||
if !operatorOptions.enableDeployment && !operatorOptions.enableDeploymentReplication && !operatorOptions.enableStorage &&
|
||||
!operatorOptions.enableBackup && !operatorOptions.enableApps && !operatorOptions.enableK2KClusterSync && !operatorOptions.enableML && !operatorOptions.enableAnalytics {
|
||||
!operatorOptions.enableBackup && !operatorOptions.enableApps && !operatorOptions.enableK2KClusterSync &&
|
||||
!operatorOptions.enableML && !operatorOptions.enableAnalytics && !operatorOptions.enableNetworking {
|
||||
if !operatorOptions.versionOnly {
|
||||
if version.GetVersionV1().IsEnterprise() {
|
||||
logger.Fatal("Turn on --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync, --operator.ml, --operator.analytics or any combination of these")
|
||||
logger.Fatal("Turn on --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync, --operator.ml, --operator.analytics, --operator.networking or any combination of these")
|
||||
} else {
|
||||
logger.Fatal("Turn on --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync or any combination of these")
|
||||
logger.Fatal("Turn on --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync, --operator.networking or any combination of these")
|
||||
}
|
||||
}
|
||||
} else if operatorOptions.versionOnly {
|
||||
logger.Fatal("Options --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync, --operator.ml, --operator.analytics cannot be enabled together with --operator.version")
|
||||
logger.Fatal("Options --operator.deployment, --operator.deployment-replication, --operator.storage, --operator.backup, --operator.apps, --operator.k2k-cluster-sync, --operator.ml, --operator.analytics, --operator.networking cannot be enabled together with --operator.version")
|
||||
} else if !version.GetVersionV1().IsEnterprise() {
|
||||
if operatorOptions.enableML || operatorOptions.enableAnalytics {
|
||||
logger.Fatal("Options --operator.ml, --operator.analytics can be enabled only on the Enterprise Operator")
|
||||
|
@ -492,6 +496,10 @@ func executeMain(cmd *cobra.Command, args []string) {
|
|||
Enabled: cfg.EnableAnalytics,
|
||||
Probe: &analyticsProbe,
|
||||
},
|
||||
Networking: server.OperatorDependency{
|
||||
Enabled: cfg.EnableNetworking,
|
||||
Probe: &analyticsProbe,
|
||||
},
|
||||
ClusterSync: server.OperatorDependency{
|
||||
Enabled: cfg.EnableK2KClusterSync,
|
||||
Probe: &k2KClusterSyncProbe,
|
||||
|
@ -576,6 +584,7 @@ func newOperatorConfigAndDeps(id, namespace, name string) (operator.Config, oper
|
|||
EnableApps: operatorOptions.enableApps,
|
||||
EnableML: operatorOptions.enableML,
|
||||
EnableAnalytics: operatorOptions.enableAnalytics,
|
||||
EnableNetworking: operatorOptions.enableNetworking,
|
||||
EnableK2KClusterSync: operatorOptions.enableK2KClusterSync,
|
||||
AllowChaos: chaosOptions.allowed,
|
||||
ScalingIntegrationEnabled: operatorOptions.scalingIntegrationEnabled,
|
||||
|
@ -596,6 +605,7 @@ func newOperatorConfigAndDeps(id, namespace, name string) (operator.Config, oper
|
|||
AppsProbe: &appsProbe,
|
||||
MlProbe: &mlProbe,
|
||||
AnalyticsProbe: &analyticsProbe,
|
||||
NetworkingProbe: &networkingProbe,
|
||||
K2KClusterSyncProbe: &k2KClusterSyncProbe,
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ title: ArangoRoute V1Alpha1
|
|||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/networking/v1alpha1/route_spec.go#L27)</sup>
|
||||
|
||||
Deployment specifies the ArangoDeployment object name
|
||||
DeploymentName specifies the ArangoDeployment object name
|
||||
|
||||
***
|
||||
|
||||
|
@ -85,7 +85,53 @@ Path specifies the Path route
|
|||
|
||||
### .status.conditions
|
||||
|
||||
Type: `api.Conditions` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/networking/v1alpha1/route_status.go#L28)</sup>
|
||||
Type: `api.Conditions` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/networking/v1alpha1/route_status.go#L31)</sup>
|
||||
|
||||
Conditions specific to the entire extension
|
||||
|
||||
***
|
||||
|
||||
### .status.deployment.checksum
|
||||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/shared/v1/object.go#L61)</sup>
|
||||
|
||||
UID keeps the information about object Checksum
|
||||
|
||||
***
|
||||
|
||||
### .status.deployment.name
|
||||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/shared/v1/object.go#L52)</sup>
|
||||
|
||||
Name of the object
|
||||
|
||||
***
|
||||
|
||||
### .status.deployment.namespace
|
||||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/shared/v1/object.go#L55)</sup>
|
||||
|
||||
Namespace of the object. Should default to the namespace of the parent object
|
||||
|
||||
***
|
||||
|
||||
### .status.deployment.uid
|
||||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/shared/v1/object.go#L58)</sup>
|
||||
|
||||
UID keeps the information about object UID
|
||||
|
||||
***
|
||||
|
||||
### .status.targets\[int\].tls.insecure
|
||||
|
||||
Type: `boolean` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/networking/v1alpha1/route_status_target_tls.go#L27)</sup>
|
||||
|
||||
Insecure allows Insecure traffic
|
||||
|
||||
***
|
||||
|
||||
### .status.targets\[int\].url
|
||||
|
||||
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.42/pkg/apis/networking/v1alpha1/route_status_target.go#L34)</sup>
|
||||
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP{{ .id }}Func{{ .templateVars }} func(ctx context.Context {{- if .inputVars }}, {{ .inputVars }}{{ end }}) (bool, error)
|
||||
|
||||
type HandleP{{ .id }}ConditionFunc{{ .templateVars }} func(ctx context.Context {{- if .inputVars }}, {{ .inputVars }}{{ end }}) (*Condition, bool, error)
|
||||
|
||||
type HandleP{{ .id }}ConditionExtract{{ .templateVars }} func(ctx context.Context {{- if .inputVars }}, {{ .inputVars }}{{ end }}) *api.ConditionList
|
||||
|
||||
func HandleP{{ .id }}{{ .templateVars }}(ctx context.Context{{- if .inputVars }}, {{ .inputVars }}{{ end }}, handler ...HandleP{{ .id }}Func{{ .templateInputVars }}) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx{{- if .cleanRefs }}, {{ .cleanRefs }}{{ end }})
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP{{ .id }}WithStop{{ .templateVars }}(ctx context.Context{{- if .inputVars }}, {{ .inputVars }}{{ end }}, handler ...HandleP{{ .id }}Func{{ .templateInputVars }}) (bool, error) {
|
||||
changed, err := HandleP{{ .id }}{{ .templateInputVars }}(ctx {{- if .cleanRefs }}, {{ .cleanRefs }}{{ end }}, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP{{ .id }}WithCondition{{ .templateVars }}(ctx context.Context, conditions *api.ConditionList, condition api.ConditionType{{- if .inputVars }}, {{ .inputVars }}{{ end }}, handler ...HandleP{{ .id }}Func{{ .templateInputVars }}) (bool, error) {
|
||||
changed, err := HandleP{{ .id }}{{ .templateInputVars }}(ctx{{- if .cleanRefs }}, {{ .cleanRefs }}{{ end }}, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP{{ .id }}Condition{{ .templateVars }}(extract HandleP{{ .id }}ConditionExtract{{ .templateInputVars }}, condition api.ConditionType, handler HandleP{{ .id }}ConditionFunc{{ .templateInputVars }}) HandleP{{ .id }}Func{{ .templateInputVars }} {
|
||||
return func(ctx context.Context {{- if .inputVars }}, {{ .inputVars }}{{ end }}) (bool, error) {
|
||||
c, changed, err := handler(ctx{{- if .cleanRefs }}, {{ .cleanRefs }}{{ end }})
|
||||
return WithConditionChange(extract(ctx{{- if .cleanRefs }}, {{ .cleanRefs }}{{ end }}), condition, c, changed, err)
|
||||
}
|
||||
}
|
90
internal/generators/generator_test.go
Normal file
90
internal/generators/generator_test.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package generators
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/strings"
|
||||
)
|
||||
|
||||
//go:embed generator_pkg_operatorv2_handlers.go.tmpl
|
||||
var generatorPKGOperatorV2Handlers []byte
|
||||
|
||||
func Test_Generate_PKG_OperatorV2_Handlers(t *testing.T) {
|
||||
root := os.Getenv("ROOT")
|
||||
require.NotEmpty(t, root)
|
||||
|
||||
i, err := template.New("metrics").Parse(string(generatorPKGOperatorV2Handlers))
|
||||
require.NoError(t, err)
|
||||
|
||||
for id := 0; id < 10; id++ {
|
||||
t.Run(fmt.Sprintf("%d", id), func(t *testing.T) {
|
||||
out, err := os.OpenFile(path.Join(root, "pkg/operatorV2", fmt.Sprintf("handler_p%d.generated.go", id)), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
require.NoError(t, err)
|
||||
|
||||
var params []string
|
||||
|
||||
for z := 0; z < id; z++ {
|
||||
params = append(params, fmt.Sprintf("P%d", z+1))
|
||||
}
|
||||
|
||||
cleanVars := strings.Join(params, ", ")
|
||||
|
||||
cleanRefs := strings.Join(util.FormatList(params, func(a string) string {
|
||||
return strings.ToLower(a)
|
||||
}), ", ")
|
||||
|
||||
templateVars := strings.Join(params, ", ")
|
||||
templateInputVars := strings.Join(params, ", ")
|
||||
inputVars := strings.Join(util.FormatList(params, func(a string) string {
|
||||
return fmt.Sprintf("%s %s", strings.ToLower(a), a)
|
||||
}), ", ")
|
||||
|
||||
if templateVars != "" {
|
||||
templateVars = fmt.Sprintf("[%s any]", templateVars)
|
||||
}
|
||||
|
||||
if templateInputVars != "" {
|
||||
templateInputVars = fmt.Sprintf("[%s]", templateInputVars)
|
||||
}
|
||||
|
||||
require.NoError(t, i.Execute(out, map[string]interface{}{
|
||||
"id": id,
|
||||
"templateVars": templateVars,
|
||||
"templateInputVars": templateInputVars,
|
||||
"inputVars": inputVars,
|
||||
"cleanVars": cleanVars,
|
||||
"cleanRefs": cleanRefs,
|
||||
}))
|
||||
|
||||
require.NoError(t, out.Close())
|
||||
})
|
||||
}
|
||||
}
|
30
pkg/apis/networking/v1alpha1/conditions.go
Normal file
30
pkg/apis/networking/v1alpha1/conditions.go
Normal file
|
@ -0,0 +1,30 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
|
||||
const (
|
||||
ReadyCondition api.ConditionType = "Ready"
|
||||
DeploymentFoundCondition api.ConditionType = "DeploymentFound"
|
||||
DestinationValidCondition api.ConditionType = "DestinationValid"
|
||||
SpecValidCondition api.ConditionType = "SpecValid"
|
||||
)
|
|
@ -23,8 +23,8 @@ package v1alpha1
|
|||
import shared "github.com/arangodb/kube-arangodb/pkg/apis/shared"
|
||||
|
||||
type ArangoRouteSpec struct {
|
||||
// Deployment specifies the ArangoDeployment object name
|
||||
Deployment string `json:"deployment,omitempty"`
|
||||
// DeploymentName specifies the ArangoDeployment object name
|
||||
DeploymentName *string `json:"deployment,omitempty"`
|
||||
|
||||
// Destination defines the route destination
|
||||
Destination *ArangoRouteSpecDestination `json:"destination,omitempty"`
|
||||
|
@ -33,15 +33,30 @@ type ArangoRouteSpec struct {
|
|||
Route *ArangoRouteSpecRoute `json:"route,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpec) GetDestination() *ArangoRouteSpecDestination {
|
||||
if s == nil || s.Destination == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.Destination
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpec) GetRoute() *ArangoRouteSpecRoute {
|
||||
if s == nil || s.Route == nil {
|
||||
return nil
|
||||
}
|
||||
return s.Route
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpec) Validate() error {
|
||||
if s == nil {
|
||||
s = &ArangoRouteSpec{}
|
||||
}
|
||||
|
||||
if err := shared.WithErrors(shared.PrefixResourceErrors("spec",
|
||||
shared.PrefixResourceError("deployment", shared.ValidateResourceName(s.Deployment)),
|
||||
shared.PrefixResourceErrors("deployment", shared.ValidateResourceNamePointer(s.DeploymentName)),
|
||||
shared.ValidateRequiredInterfacePath("destination", s.Destination),
|
||||
shared.ValidateRequiredInterfacePath("route", s.Route),
|
||||
shared.ValidateOptionalInterfacePath("route", s.Route),
|
||||
)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -33,15 +33,39 @@ type ArangoRouteSpecDestination struct {
|
|||
TLS *ArangoRouteSpecDestinationTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecDestination) Validate() error {
|
||||
if s == nil {
|
||||
s = &ArangoRouteSpecDestination{}
|
||||
func (s *ArangoRouteSpecDestination) GetService() *ArangoRouteSpecDestinationService {
|
||||
if s == nil || s.Service == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.Service
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecDestination) GetSchema() *ArangoRouteSpecDestinationSchema {
|
||||
if s == nil || s.Schema == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.Schema
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecDestination) GetTLS() *ArangoRouteSpecDestinationTLS {
|
||||
if s == nil || s.TLS == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return s.TLS
|
||||
}
|
||||
|
||||
func (a *ArangoRouteSpecDestination) Validate() error {
|
||||
if a == nil {
|
||||
a = &ArangoRouteSpecDestination{}
|
||||
}
|
||||
|
||||
if err := shared.WithErrors(
|
||||
shared.ValidateOptionalInterfacePath("service", s.Service),
|
||||
shared.ValidateOptionalInterfacePath("schema", s.Schema),
|
||||
shared.ValidateOptionalInterfacePath("tls", s.TLS),
|
||||
shared.ValidateOptionalInterfacePath("service", a.Service),
|
||||
shared.ValidateOptionalInterfacePath("schema", a.Schema),
|
||||
shared.ValidateOptionalInterfacePath("tls", a.TLS),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -36,12 +36,22 @@ type ArangoRouteSpecDestinationService struct {
|
|||
Port *intstr.IntOrString `json:"port,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecDestinationService) Validate() error {
|
||||
if s == nil {
|
||||
s = &ArangoRouteSpecDestinationService{}
|
||||
func (a *ArangoRouteSpecDestinationService) GetPort() *intstr.IntOrString {
|
||||
if a == nil || a.Port == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := shared.WithErrors(s.Object.Validate()); err != nil {
|
||||
return a.Port
|
||||
}
|
||||
|
||||
func (a *ArangoRouteSpecDestinationService) Validate() error {
|
||||
if a == nil {
|
||||
a = &ArangoRouteSpecDestinationService{}
|
||||
}
|
||||
|
||||
if err := shared.WithErrors(a.Object.Validate(), shared.ValidateRequiredPath("port", a.Port, func(i intstr.IntOrString) error {
|
||||
return nil
|
||||
})); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,14 @@ type ArangoRouteSpecDestinationTLS struct {
|
|||
Insecure *bool `json:"insecure,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecDestinationTLS) Validate() error {
|
||||
func (a *ArangoRouteSpecDestinationTLS) GetInsecure() bool {
|
||||
if a == nil || a.Insecure == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *ArangoRouteSpecDestinationTLS) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -29,21 +29,21 @@ type ArangoRouteSpecRoute struct {
|
|||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecRoute) GetPath() string {
|
||||
if s == nil && s.Path == nil {
|
||||
func (a *ArangoRouteSpecRoute) GetPath() string {
|
||||
if a == nil || a.Path == nil {
|
||||
return "/"
|
||||
}
|
||||
|
||||
return *s.Path
|
||||
return *a.Path
|
||||
}
|
||||
|
||||
func (s *ArangoRouteSpecRoute) Validate() error {
|
||||
if s == nil {
|
||||
s = &ArangoRouteSpecRoute{}
|
||||
func (a *ArangoRouteSpecRoute) Validate() error {
|
||||
if a == nil {
|
||||
a = &ArangoRouteSpecRoute{}
|
||||
}
|
||||
|
||||
if err := shared.WithErrors(
|
||||
shared.PrefixResourceError("path", shared.ValidateAPIPath(s.GetPath())),
|
||||
shared.PrefixResourceError("path", shared.ValidateAPIPath(a.GetPath())),
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -20,10 +20,19 @@
|
|||
|
||||
package v1alpha1
|
||||
|
||||
import api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
import (
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
)
|
||||
|
||||
type ArangoRouteStatus struct {
|
||||
// Conditions specific to the entire extension
|
||||
// +doc/type: api.Conditions
|
||||
Conditions api.ConditionList `json:"conditions,omitempty"`
|
||||
|
||||
// Deployment keeps the ArangoDeployment reference
|
||||
Deployment *sharedApi.Object `json:"deployment,omitempty"`
|
||||
|
||||
// Targets keeps the target details
|
||||
Targets ArangoRouteStatusTargets `json:"targets,omitempty"`
|
||||
}
|
||||
|
|
44
pkg/apis/networking/v1alpha1/route_status_target.go
Normal file
44
pkg/apis/networking/v1alpha1/route_status_target.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "github.com/arangodb/kube-arangodb/pkg/util"
|
||||
|
||||
type ArangoRouteStatusTargets []ArangoRouteStatusTarget
|
||||
|
||||
func (a ArangoRouteStatusTargets) Hash() string {
|
||||
return util.SHA256FromExtract(func(t ArangoRouteStatusTarget) string {
|
||||
return t.Hash()
|
||||
}, a...)
|
||||
}
|
||||
|
||||
type ArangoRouteStatusTarget struct {
|
||||
Url string `json:"url,omitempty"`
|
||||
|
||||
TLS ArangoRouteStatusTargetTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
func (a *ArangoRouteStatusTarget) Hash() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
return util.SHA256FromStringArray(a.Url, a.TLS.Hash())
|
||||
}
|
36
pkg/apis/networking/v1alpha1/route_status_target_tls.go
Normal file
36
pkg/apis/networking/v1alpha1/route_status_target_tls.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import "github.com/arangodb/kube-arangodb/pkg/util"
|
||||
|
||||
type ArangoRouteStatusTargetTLS struct {
|
||||
// Insecure allows Insecure traffic
|
||||
Insecure bool `json:"insecure"`
|
||||
}
|
||||
|
||||
func (a *ArangoRouteStatusTargetTLS) Hash() string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return util.SHA256FromStringArray(util.BoolSwitch(a.Insecure, "true", "false"))
|
||||
}
|
|
@ -96,6 +96,11 @@ func (in *ArangoRouteList) DeepCopyObject() runtime.Object {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ArangoRouteSpec) DeepCopyInto(out *ArangoRouteSpec) {
|
||||
*out = *in
|
||||
if in.DeploymentName != nil {
|
||||
in, out := &in.DeploymentName, &out.DeploymentName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Destination != nil {
|
||||
in, out := &in.Destination, &out.Destination
|
||||
*out = new(ArangoRouteSpecDestination)
|
||||
|
@ -228,6 +233,16 @@ func (in *ArangoRouteStatus) DeepCopyInto(out *ArangoRouteStatus) {
|
|||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Deployment != nil {
|
||||
in, out := &in.Deployment, &out.Deployment
|
||||
*out = new(v1.Object)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Targets != nil {
|
||||
in, out := &in.Targets, &out.Targets
|
||||
*out = make(ArangoRouteStatusTargets, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -240,3 +255,56 @@ func (in *ArangoRouteStatus) DeepCopy() *ArangoRouteStatus {
|
|||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ArangoRouteStatusTarget) DeepCopyInto(out *ArangoRouteStatusTarget) {
|
||||
*out = *in
|
||||
out.TLS = in.TLS
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoRouteStatusTarget.
|
||||
func (in *ArangoRouteStatusTarget) DeepCopy() *ArangoRouteStatusTarget {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ArangoRouteStatusTarget)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ArangoRouteStatusTargetTLS) DeepCopyInto(out *ArangoRouteStatusTargetTLS) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoRouteStatusTargetTLS.
|
||||
func (in *ArangoRouteStatusTargetTLS) DeepCopy() *ArangoRouteStatusTargetTLS {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ArangoRouteStatusTargetTLS)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in ArangoRouteStatusTargets) DeepCopyInto(out *ArangoRouteStatusTargets) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(ArangoRouteStatusTargets, len(*in))
|
||||
copy(*out, *in)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ArangoRouteStatusTargets.
|
||||
func (in ArangoRouteStatusTargets) DeepCopy() ArangoRouteStatusTargets {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ArangoRouteStatusTargets)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package shared
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
@ -57,6 +58,15 @@ func ValidateResourceName(name string) error {
|
|||
return errors.WithStack(errors.Errorf("Name '%s' is not a valid resource name", name))
|
||||
}
|
||||
|
||||
// ValidateResourceNamePointer validates a kubernetes resource name.
|
||||
// If not valid, an error is returned.
|
||||
func ValidateResourceNamePointer(name *string) error {
|
||||
if name == nil {
|
||||
return errors.WithStack(errors.Errorf("Name is nil"))
|
||||
}
|
||||
return ValidateResourceName(*name)
|
||||
}
|
||||
|
||||
// ValidateOptionalResourceName validates a kubernetes resource name.
|
||||
// If not empty and not valid, an error is returned.
|
||||
func ValidateOptionalResourceName(name string) error {
|
||||
|
@ -98,7 +108,7 @@ func ValidatePullPolicy(in core.PullPolicy) error {
|
|||
return errors.Errorf("Unknown pull policy: '%s'", string(in))
|
||||
}
|
||||
|
||||
func Validate[T interface{}](in T) error {
|
||||
func Validate[T any](in T) error {
|
||||
res, _ := validate(in)
|
||||
return res
|
||||
}
|
||||
|
@ -107,6 +117,9 @@ func validate(in any) (error, bool) {
|
|||
if in == nil {
|
||||
return nil, false
|
||||
}
|
||||
if reflect.ValueOf(in).IsZero() {
|
||||
return nil, false
|
||||
}
|
||||
if v, ok := in.(ValidateInterface); ok {
|
||||
return v.Validate(), true
|
||||
}
|
||||
|
@ -114,7 +127,7 @@ func validate(in any) (error, bool) {
|
|||
}
|
||||
|
||||
// ValidateOptional Validates object if is not nil
|
||||
func ValidateOptional[T interface{}](in *T, validator func(T) error) error {
|
||||
func ValidateOptional[T any](in *T, validator func(T) error) error {
|
||||
if in != nil {
|
||||
return validator(*in)
|
||||
}
|
||||
|
@ -122,6 +135,11 @@ func ValidateOptional[T interface{}](in *T, validator func(T) error) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// ValidateOptionalPath Validates object if is not nil
|
||||
func ValidateOptionalPath[T any](path string, in *T, validator func(T) error) error {
|
||||
return PrefixResourceErrors(path, ValidateOptional(in, validator))
|
||||
}
|
||||
|
||||
// ValidateOptionalInterface Validates object if is not nil
|
||||
func ValidateOptionalInterface[T ValidateInterface](in T) error {
|
||||
res, _ := validate(in)
|
||||
|
@ -130,11 +148,11 @@ func ValidateOptionalInterface[T ValidateInterface](in T) error {
|
|||
|
||||
// ValidateOptionalInterfacePath Validates object if is not nil with path
|
||||
func ValidateOptionalInterfacePath[T ValidateInterface](path string, in T) error {
|
||||
return PrefixResourceError(path, ValidateOptionalInterface(in))
|
||||
return PrefixResourceErrors(path, ValidateOptionalInterface(in))
|
||||
}
|
||||
|
||||
// ValidateRequired Validates object and required not nil value
|
||||
func ValidateRequired[T interface{}](in *T, validator func(T) error) error {
|
||||
func ValidateRequired[T any](in *T, validator func(T) error) error {
|
||||
if in != nil {
|
||||
return validator(*in)
|
||||
}
|
||||
|
@ -142,6 +160,11 @@ func ValidateRequired[T interface{}](in *T, validator func(T) error) error {
|
|||
return errors.Errorf("should be not nil")
|
||||
}
|
||||
|
||||
// ValidateRequiredPath Validates object and required not nil value
|
||||
func ValidateRequiredPath[T any](path string, in *T, validator func(T) error) error {
|
||||
return PrefixResourceErrors(path, ValidateRequired(in, validator))
|
||||
}
|
||||
|
||||
// ValidateRequiredInterface Validates object if is not nil
|
||||
func ValidateRequiredInterface[T ValidateInterface](in T) error {
|
||||
res, ok := validate(in)
|
||||
|
@ -153,11 +176,11 @@ func ValidateRequiredInterface[T ValidateInterface](in T) error {
|
|||
|
||||
// ValidateRequiredInterfacePath Validates object if is not nil with path
|
||||
func ValidateRequiredInterfacePath[T ValidateInterface](path string, in T) error {
|
||||
return PrefixResourceError(path, ValidateRequiredInterface(in))
|
||||
return PrefixResourceErrors(path, ValidateRequiredInterface(in))
|
||||
}
|
||||
|
||||
// ValidateList validates all elements on the list
|
||||
func ValidateList[T interface{}](in []T, validator func(T) error) error {
|
||||
func ValidateList[T any](in []T, validator func(T) error) error {
|
||||
errors := make([]error, len(in))
|
||||
|
||||
for id := range in {
|
||||
|
|
|
@ -4,7 +4,7 @@ v1alpha1:
|
|||
spec:
|
||||
properties:
|
||||
deployment:
|
||||
description: Deployment specifies the ArangoDeployment object name
|
||||
description: DeploymentName specifies the ArangoDeployment object name
|
||||
type: string
|
||||
destination:
|
||||
description: Destination defines the route destination
|
||||
|
|
123
pkg/handlers/networking/route/handler.go
Normal file
123
pkg/handlers/networking/route/handler.go
Normal file
|
@ -0,0 +1,123 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apiErrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/event"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
)
|
||||
|
||||
var logger = logging.Global().RegisterAndGetLogger("networking-route-operator", logging.Info)
|
||||
|
||||
type handler struct {
|
||||
client arangoClientSet.Interface
|
||||
kubeClient kubernetes.Interface
|
||||
|
||||
eventRecorder event.RecorderInstance
|
||||
|
||||
operator operator.Operator
|
||||
}
|
||||
|
||||
func (h *handler) Name() string {
|
||||
return Kind()
|
||||
}
|
||||
|
||||
func (h *handler) Handle(ctx context.Context, item operation.Item) error {
|
||||
// Get Backup object. It also covers NotFound case
|
||||
|
||||
object, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.NetworkingV1alpha1().ArangoRoutes(item.Namespace).Get, item.Name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
if apiErrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
status := object.Status.DeepCopy()
|
||||
|
||||
changed, reconcileErr := operator.HandleP3WithStop(ctx, item, object, status, h.handle)
|
||||
if reconcileErr != nil && !operator.IsReconcile(reconcileErr) {
|
||||
logger.Err(reconcileErr).Warn("Fail for %s %s/%s",
|
||||
item.Kind,
|
||||
item.Namespace,
|
||||
item.Name)
|
||||
|
||||
return reconcileErr
|
||||
}
|
||||
|
||||
if !changed {
|
||||
return reconcileErr
|
||||
}
|
||||
|
||||
logger.Debug("Updating %s %s/%s",
|
||||
item.Kind,
|
||||
item.Namespace,
|
||||
item.Name)
|
||||
|
||||
if _, err := operator.WithNetworkingArangoRouteUpdateStatusInterfaceRetry(context.Background(), h.client.NetworkingV1alpha1().ArangoRoutes(object.GetNamespace()), object, *status, meta.UpdateOptions{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return reconcileErr
|
||||
}
|
||||
|
||||
func (h *handler) handle(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus) (bool, error) {
|
||||
return operator.HandleP3WithCondition(ctx, &status.Conditions, networkingApi.ReadyCondition, item, extension, status, h.HandleSpecValidity, h.HandleArangoDeployment)
|
||||
}
|
||||
|
||||
func (h *handler) HandleSpecValidity(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus) (bool, error) {
|
||||
if err := extension.Spec.Validate(); err != nil {
|
||||
// We have received an error in the spec!
|
||||
|
||||
logger.Err(err).Warn("Invalid Spec on %s", item.String())
|
||||
|
||||
if status.Conditions.Update(networkingApi.SpecValidCondition, false, "Spec is invalid", "Spec is invalid") {
|
||||
return true, operator.Stop("Invalid spec")
|
||||
}
|
||||
return false, operator.Stop("Invalid spec")
|
||||
}
|
||||
|
||||
if status.Conditions.Update(networkingApi.SpecValidCondition, true, "Spec is valid", "Spec is valid") {
|
||||
return true, operator.Reconcile("Conditions updated")
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (h *handler) CanBeHandled(item operation.Item) bool {
|
||||
return item.Group == Group() &&
|
||||
item.Version == Version() &&
|
||||
item.Kind == Kind()
|
||||
}
|
||||
|
||||
func (h *handler) init() {}
|
82
pkg/handlers/networking/route/handler_deployment.go
Normal file
82
pkg/handlers/networking/route/handler_deployment.go
Normal file
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
apiErrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
)
|
||||
|
||||
func (h *handler) HandleArangoDeployment(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus) (bool, error) {
|
||||
var name = util.WithDefault(extension.Spec.DeploymentName)
|
||||
|
||||
if status.Deployment != nil {
|
||||
name = status.Deployment.GetName()
|
||||
}
|
||||
|
||||
deployment, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.client.DatabaseV1().ArangoDeployments(item.Namespace).Get, name, meta.GetOptions{})
|
||||
if err != nil {
|
||||
if apiErrors.IsNotFound(err) {
|
||||
// Condition for Found should be set to false
|
||||
if util.Or(
|
||||
status.Conditions.Update(networkingApi.DeploymentFoundCondition, false, "ArangoDeployment not found", "ArangoDeployment not found"),
|
||||
) {
|
||||
return true, operator.Reconcile("Conditions updated")
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return false, err
|
||||
}
|
||||
|
||||
if status.Deployment == nil {
|
||||
status.Deployment = util.NewType(sharedApi.NewObject(deployment))
|
||||
return true, operator.Reconcile("Deployment saved")
|
||||
} else if !status.Deployment.Equals(deployment) {
|
||||
if util.Or(
|
||||
status.Conditions.Update(networkingApi.DeploymentFoundCondition, false, "ArangoDeployment changed", "ArangoDeployment changed"),
|
||||
) {
|
||||
return true, operator.Reconcile("Conditions updated")
|
||||
}
|
||||
|
||||
return false, operator.Stop("ArangoDeployment Changed")
|
||||
}
|
||||
|
||||
// Condition for Found should be set to true
|
||||
|
||||
if status.Conditions.Update(networkingApi.DeploymentFoundCondition, true, "ArangoDeployment found", "ArangoDeployment found") {
|
||||
return true, operator.Reconcile("Conditions updated")
|
||||
}
|
||||
|
||||
return operator.HandleP4(ctx, item, extension, status, deployment,
|
||||
operator.HandleP4Condition(func(_ context.Context, _ operation.Item, _ *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus, _ *api.ArangoDeployment) *api.ConditionList {
|
||||
return &status.Conditions
|
||||
}, networkingApi.DestinationValidCondition, h.HandleArangoDestinationWithTargets), h.HandleDestinationRequired)
|
||||
}
|
145
pkg/handlers/networking/route/handler_deployment_test.go
Normal file
145
pkg/handlers/networking/route/handler_deployment_test.go
Normal file
|
@ -0,0 +1,145 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"k8s.io/apimachinery/pkg/util/uuid"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
)
|
||||
|
||||
func Test_Handler_Deployment(t *testing.T) {
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.SpecValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DeploymentFoundCondition))
|
||||
}
|
||||
|
||||
func Test_Handler_MissingDeployment(t *testing.T) {
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test", func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment-missing")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.SpecValidCondition))
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.DeploymentFoundCondition))
|
||||
}
|
||||
|
||||
func Test_Handler_Deployment_Changed(t *testing.T) {
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test", func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DeploymentFoundCondition))
|
||||
|
||||
deployment.UID = uuid.NewUUID()
|
||||
|
||||
tests.UpdateObjects(t, handler.kubeClient, handler.client, &deployment)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.SpecValidCondition))
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.DeploymentFoundCondition))
|
||||
}
|
171
pkg/handlers/networking/route/handler_destination.go
Normal file
171
pkg/handlers/networking/route/handler_destination.go
Normal file
|
@ -0,0 +1,171 @@
|
|||
//
|
||||
// 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 route
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
core "k8s.io/api/core/v1"
|
||||
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
)
|
||||
|
||||
func (h *handler) HandleArangoDestination(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus, _ *api.ArangoDeployment) (*operator.Condition, bool, error) {
|
||||
if dest := extension.Spec.GetDestination(); dest != nil {
|
||||
if svc := dest.GetService(); svc != nil {
|
||||
port := svc.Port
|
||||
|
||||
if port == nil {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: "Missing Port definition",
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
s, err := util.WithKubernetesContextTimeoutP2A2(ctx, h.kubeClient.CoreV1().Services(svc.GetNamespace(extension)).Get, svc.GetName(), meta.GetOptions{})
|
||||
if err != nil {
|
||||
if api.IsNotFound(err) {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Service `%s/%s` Not found", svc.GetNamespace(extension), svc.GetName()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Unknown error for service `%s/%s`: %s", svc.GetNamespace(extension), svc.GetName(), err.Error()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
if !svc.Equals(s) {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Service `%s/%s` Changed", svc.GetNamespace(extension), svc.GetName()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
var destPort int32
|
||||
|
||||
if port.Type == intstr.Int {
|
||||
p, ok := util.PickFromList(s.Spec.Ports, func(v core.ServicePort) bool {
|
||||
return v.Port == port.IntVal
|
||||
})
|
||||
if !ok {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Port `%d` not defined on Service `%s/%s`", port.IntVal, svc.GetNamespace(extension), svc.GetName()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
destPort = p.Port
|
||||
} else if port.Type == intstr.String && port.StrVal != "" {
|
||||
p, ok := util.PickFromList(s.Spec.Ports, func(v core.ServicePort) bool {
|
||||
return v.Name == port.StrVal
|
||||
})
|
||||
if !ok {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Port `%s` not defined on Service `%s/%s`", port.StrVal, svc.GetNamespace(extension), svc.GetName()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
destPort = p.Port
|
||||
} else {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: "Unknown Port definition",
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
if destPort == -1 {
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: fmt.Sprintf("Unable to discover port on Service `%s/%s`", svc.GetNamespace(extension), svc.GetName()),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
var targets = networkingApi.ArangoRouteStatusTargets{
|
||||
networkingApi.ArangoRouteStatusTarget{
|
||||
Url: fmt.Sprintf("%s://%s.%s.svc:%d%s", dest.GetSchema().String(), s.GetName(), s.GetNamespace(), destPort, extension.Spec.GetRoute().GetPath()),
|
||||
TLS: networkingApi.ArangoRouteStatusTargetTLS{
|
||||
Insecure: extension.Spec.Destination.GetTLS().GetInsecure(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if status.Targets.Hash() == targets.Hash() {
|
||||
return &operator.Condition{
|
||||
Status: true,
|
||||
Reason: "Destination Found",
|
||||
Message: "Destination Found",
|
||||
Hash: targets.Hash(),
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
status.Targets = targets
|
||||
return &operator.Condition{
|
||||
Status: true,
|
||||
Reason: "Destination Found",
|
||||
Message: "Destination Found",
|
||||
Hash: targets.Hash(),
|
||||
}, true, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &operator.Condition{
|
||||
Status: false,
|
||||
Reason: "Destination Not Found",
|
||||
Message: "Destination Not Found",
|
||||
}, false, nil
|
||||
}
|
||||
|
||||
func (h *handler) HandleArangoDestinationWithTargets(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus, depl *api.ArangoDeployment) (*operator.Condition, bool, error) {
|
||||
c, changed, err := h.HandleArangoDestination(ctx, item, extension, status, depl)
|
||||
if c == nil && !c.Status && status.Targets != nil {
|
||||
status.Targets = nil
|
||||
changed = true
|
||||
}
|
||||
|
||||
return c, changed, err
|
||||
}
|
||||
|
||||
func (h *handler) HandleDestinationRequired(ctx context.Context, item operation.Item, extension *networkingApi.ArangoRoute, status *networkingApi.ArangoRouteStatus, _ *api.ArangoDeployment) (bool, error) {
|
||||
if !status.Conditions.IsTrue(networkingApi.DestinationValidCondition) {
|
||||
return false, operator.Stop("Destination is not ready")
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
422
pkg/handlers/networking/route/handler_destination_test.go
Normal file
422
pkg/handlers/networking/route/handler_destination_test.go
Normal file
|
@ -0,0 +1,422 @@
|
|||
//
|
||||
// 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 route
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
core "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
sharedApi "github.com/arangodb/kube-arangodb/pkg/apis/shared/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
)
|
||||
|
||||
func Test_Handler_Destination_Service_Missing(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Not Found")
|
||||
require.EqualValues(t, c.Message, "Unknown error for service `fake/deployment`: services \"deployment\" not found")
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_Valid(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10244,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Hash, extension.Status.Targets.Hash())
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_ValidName(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromString("test")),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10241,
|
||||
Name: "test1",
|
||||
},
|
||||
{
|
||||
Port: 10244,
|
||||
Name: "test",
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Hash, extension.Status.Targets.Hash())
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_WrongPort(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10245,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Not Found")
|
||||
require.EqualValues(t, c.Message, "Port `10244` not defined on Service `fake/deployment`")
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_WrongPortName(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromString("test")),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10245,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.False(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Not Found")
|
||||
require.EqualValues(t, c.Message, "Port `test` not defined on Service `fake/deployment`")
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_Insecure_Default(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10244,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Testcense
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Hash, extension.Status.Targets.Hash())
|
||||
|
||||
require.Len(t, extension.Status.Targets, 1)
|
||||
require.False(t, extension.Status.Targets[0].TLS.Insecure)
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_Insecure_Nil(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
TLS: &networkingApi.ArangoRouteSpecDestinationTLS{
|
||||
Insecure: nil,
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10244,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Hash, extension.Status.Targets.Hash())
|
||||
|
||||
require.Len(t, extension.Status.Targets, 1)
|
||||
require.False(t, extension.Status.Targets[0].TLS.Insecure)
|
||||
}
|
||||
|
||||
func Test_Handler_Destination_Service_Insecure_Override(t *testing.T) {
|
||||
// Setup
|
||||
handler := newFakeHandler()
|
||||
|
||||
// Arrange
|
||||
extension := tests.NewMetaObject[*networkingApi.ArangoRoute](t, tests.FakeNamespace, "test",
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.DeploymentName = util.NewType("deployment")
|
||||
},
|
||||
func(t *testing.T, obj *networkingApi.ArangoRoute) {
|
||||
obj.Spec.Destination = &networkingApi.ArangoRouteSpecDestination{
|
||||
Service: &networkingApi.ArangoRouteSpecDestinationService{
|
||||
Object: &sharedApi.Object{
|
||||
Name: "deployment",
|
||||
},
|
||||
Port: util.NewType(intstr.FromInt32(10244)),
|
||||
},
|
||||
TLS: &networkingApi.ArangoRouteSpecDestinationTLS{
|
||||
Insecure: util.NewType(true),
|
||||
},
|
||||
}
|
||||
})
|
||||
deployment := tests.NewMetaObject[*api.ArangoDeployment](t, tests.FakeNamespace, "deployment")
|
||||
svc := tests.NewMetaObject[*core.Service](t, tests.FakeNamespace, "deployment", func(t *testing.T, obj *core.Service) {
|
||||
obj.Spec.Ports = []core.ServicePort{
|
||||
{
|
||||
Port: 10244,
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
refresh := tests.CreateObjects(t, handler.kubeClient, handler.client, &deployment, &extension, &svc)
|
||||
|
||||
// Test
|
||||
require.NoError(t, tests.Handle(handler, tests.NewItem(t, operation.Update, extension)))
|
||||
|
||||
// Refresh
|
||||
refresh(t)
|
||||
|
||||
// Assert
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.DestinationValidCondition))
|
||||
require.True(t, extension.Status.Conditions.IsTrue(networkingApi.ReadyCondition))
|
||||
|
||||
c, ok := extension.Status.Conditions.Get(networkingApi.DestinationValidCondition)
|
||||
require.True(t, ok)
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Reason, "Destination Found")
|
||||
require.EqualValues(t, c.Hash, extension.Status.Targets.Hash())
|
||||
|
||||
require.Len(t, extension.Status.Targets, 1)
|
||||
require.True(t, extension.Status.Targets[0].TLS.Insecure)
|
||||
}
|
59
pkg/handlers/networking/route/handler_test.go
Normal file
59
pkg/handlers/networking/route/handler_test.go
Normal file
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
apiErrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/tests"
|
||||
)
|
||||
|
||||
func Test_ObjectNotFound(t *testing.T) {
|
||||
// Arrange
|
||||
handler := newFakeHandler()
|
||||
|
||||
i := newItem(operation.Add, "test", "test")
|
||||
|
||||
actions := map[operation.Operation]bool{
|
||||
operation.Add: false,
|
||||
operation.Update: false,
|
||||
operation.Delete: false,
|
||||
}
|
||||
|
||||
// Act
|
||||
for op, shouldFail := range actions {
|
||||
t.Run(string(op), func(t *testing.T) {
|
||||
err := tests.Handle(handler, i)
|
||||
|
||||
// Assert
|
||||
if shouldFail {
|
||||
require.Error(t, err)
|
||||
require.True(t, apiErrors.IsNotFound(err))
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
38
pkg/handlers/networking/route/local.go
Normal file
38
pkg/handlers/networking/route/local.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/networking"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
)
|
||||
|
||||
func Kind() string {
|
||||
return networking.ArangoRouteResourceKind
|
||||
}
|
||||
|
||||
func Group() string {
|
||||
return networkingApi.SchemeGroupVersion.Group
|
||||
}
|
||||
|
||||
func Version() string {
|
||||
return networkingApi.SchemeGroupVersion.Version
|
||||
}
|
60
pkg/handlers/networking/route/register.go
Normal file
60
pkg/handlers/networking/route/register.go
Normal file
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// 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 route
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
arangoClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned"
|
||||
arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/event"
|
||||
)
|
||||
|
||||
// RegisterInformer into operator
|
||||
func RegisterInformer(operator operator.Operator, recorder event.Recorder, client arangoClientSet.Interface,
|
||||
kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) error {
|
||||
|
||||
if err := operator.RegisterInformer(informer.Networking().V1alpha1().ArangoRoutes().Informer(),
|
||||
Group(),
|
||||
Version(),
|
||||
Kind()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
h := &handler{
|
||||
client: client,
|
||||
kubeClient: kubeClient,
|
||||
|
||||
eventRecorder: recorder.NewInstance(Group(), Version(), Kind()),
|
||||
|
||||
operator: operator,
|
||||
}
|
||||
|
||||
h.init()
|
||||
|
||||
if err := operator.RegisterHandler(h); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
61
pkg/handlers/networking/route/suite_test.go
Normal file
61
pkg/handlers/networking/route/suite_test.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package route
|
||||
|
||||
import (
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/analytics"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
fakeClientSet "github.com/arangodb/kube-arangodb/pkg/generated/clientset/versioned/fake"
|
||||
operator "github.com/arangodb/kube-arangodb/pkg/operatorV2"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/event"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
)
|
||||
|
||||
func newFakeHandler() *handler {
|
||||
f := fakeClientSet.NewSimpleClientset()
|
||||
k := fake.NewSimpleClientset()
|
||||
|
||||
h := &handler{
|
||||
client: f,
|
||||
kubeClient: k,
|
||||
eventRecorder: event.NewEventRecorder("mock", k).NewInstance(Group(), Version(), Kind()),
|
||||
operator: operator.NewOperator("mock", "mock", "mock"),
|
||||
}
|
||||
|
||||
h.init()
|
||||
|
||||
return h
|
||||
}
|
||||
|
||||
func newItem(o operation.Operation, namespace, name string) operation.Item {
|
||||
return operation.Item{
|
||||
Group: networkingApi.SchemeGroupVersion.Group,
|
||||
Version: networkingApi.SchemeGroupVersion.Version,
|
||||
Kind: analytics.GraphAnalyticsEngineResourceKind,
|
||||
|
||||
Operation: o,
|
||||
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import (
|
|||
backupdef "github.com/arangodb/kube-arangodb/pkg/apis/backup"
|
||||
depldef "github.com/arangodb/kube-arangodb/pkg/apis/deployment"
|
||||
deplapi "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/networking"
|
||||
repldef "github.com/arangodb/kube-arangodb/pkg/apis/replication"
|
||||
replapi "github.com/arangodb/kube-arangodb/pkg/apis/replication/v1"
|
||||
lsapi "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha"
|
||||
|
@ -45,6 +46,7 @@ import (
|
|||
arangoInformer "github.com/arangodb/kube-arangodb/pkg/generated/informers/externalversions"
|
||||
"github.com/arangodb/kube-arangodb/pkg/handlers/backup"
|
||||
"github.com/arangodb/kube-arangodb/pkg/handlers/job"
|
||||
"github.com/arangodb/kube-arangodb/pkg/handlers/networking/route"
|
||||
"github.com/arangodb/kube-arangodb/pkg/handlers/policy"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operator/scope"
|
||||
|
@ -68,10 +70,11 @@ var logger = logging.Global().RegisterAndGetLogger("operator", logging.Info)
|
|||
type operatorV2type string
|
||||
|
||||
const (
|
||||
backupOperator operatorV2type = "backup"
|
||||
mlOperator operatorV2type = "ml"
|
||||
analyticsOperator operatorV2type = "analytics"
|
||||
appsOperator operatorV2type = "apps"
|
||||
backupOperator operatorV2type = "backup"
|
||||
mlOperator operatorV2type = "ml"
|
||||
analyticsOperator operatorV2type = "analytics"
|
||||
networkingOperator operatorV2type = "networking"
|
||||
appsOperator operatorV2type = "apps"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
|
@ -102,6 +105,7 @@ type Config struct {
|
|||
EnableStorage bool
|
||||
EnableML bool
|
||||
EnableAnalytics bool
|
||||
EnableNetworking bool
|
||||
EnableBackup bool
|
||||
EnableApps bool
|
||||
EnableK2KClusterSync bool
|
||||
|
@ -124,6 +128,7 @@ type Dependencies struct {
|
|||
BackupProbe *probe.ReadyProbe
|
||||
MlProbe *probe.ReadyProbe
|
||||
AnalyticsProbe *probe.ReadyProbe
|
||||
NetworkingProbe *probe.ReadyProbe
|
||||
AppsProbe *probe.ReadyProbe
|
||||
K2KClusterSyncProbe *probe.ReadyProbe
|
||||
}
|
||||
|
@ -192,6 +197,13 @@ func (o *Operator) Run() {
|
|||
go o.runWithoutLeaderElection("arango-analytics-operator", constants.AnalyticsLabelRole, o.onStartAnalytics, o.Dependencies.AnalyticsProbe)
|
||||
}
|
||||
}
|
||||
if o.Config.EnableNetworking {
|
||||
if !o.Config.SingleMode {
|
||||
go o.runLeaderElection("arango-networking-operator", constants.NetworkingLabelRole, o.onStartNetworking, o.Dependencies.NetworkingProbe)
|
||||
} else {
|
||||
go o.runWithoutLeaderElection("arango-networking-operator", constants.NetworkingLabelRole, o.onStartNetworking, o.Dependencies.NetworkingProbe)
|
||||
}
|
||||
}
|
||||
if o.Config.EnableK2KClusterSync {
|
||||
// Nothing to do
|
||||
o.log.Warn("K2K Cluster sync is permanently disabled")
|
||||
|
@ -262,6 +274,11 @@ func (o *Operator) onStartApps(stop <-chan struct{}) {
|
|||
o.onStartOperatorV2(appsOperator, stop)
|
||||
}
|
||||
|
||||
// onStartNetworking starts the operator and run till given channel is closed.
|
||||
func (o *Operator) onStartNetworking(stop <-chan struct{}) {
|
||||
o.onStartOperatorV2(networkingOperator, stop)
|
||||
}
|
||||
|
||||
// onStartOperatorV2 run the operatorV2 type
|
||||
func (o *Operator) onStartOperatorV2(operatorType operatorV2type, stop <-chan struct{}) {
|
||||
operatorName := fmt.Sprintf("arangodb-%s-operator", operatorType)
|
||||
|
@ -290,6 +307,9 @@ func (o *Operator) onStartOperatorV2(operatorType operatorV2type, stop <-chan st
|
|||
case analyticsOperator:
|
||||
o.onStartOperatorV2Analytics(operator, eventRecorder, o.Client.Arango(), o.Client.Kubernetes(), arangoInformer, kubeInformer)
|
||||
o.Dependencies.AnalyticsProbe.SetReady()
|
||||
case networkingOperator:
|
||||
o.onStartOperatorV2Networking(operator, eventRecorder, o.Client.Arango(), o.Client.Kubernetes(), arangoInformer, kubeInformer)
|
||||
o.Dependencies.NetworkingProbe.SetReady()
|
||||
}
|
||||
|
||||
if err := operator.RegisterStarter(arangoInformer); err != nil {
|
||||
|
@ -321,6 +341,18 @@ func (o *Operator) onStartOperatorV2Apps(operator operatorV2.Operator, recorder
|
|||
}
|
||||
}
|
||||
|
||||
func (o *Operator) onStartOperatorV2Networking(operator operatorV2.Operator, recorder event.Recorder, client arangoClientSet.Interface, kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory, kubeInformer informers.SharedInformerFactory) {
|
||||
checkFn := func() error {
|
||||
_, err := o.Client.Arango().NetworkingV1alpha1().ArangoRoutes(o.Namespace).List(context.Background(), meta.ListOptions{})
|
||||
return err
|
||||
}
|
||||
o.waitForCRD(networking.ArangoRouteCRDName, checkFn)
|
||||
|
||||
if err := route.RegisterInformer(operator, recorder, client, kubeClient, informer, kubeInformer); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Operator) onStartOperatorV2Backup(operator operatorV2.Operator, recorder event.Recorder, client arangoClientSet.Interface, kubeClient kubernetes.Interface, informer arangoInformer.SharedInformerFactory) {
|
||||
checkFn := func() error {
|
||||
_, err := o.Client.Arango().BackupV1().ArangoBackups(o.Namespace).List(context.Background(), meta.ListOptions{})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -21,19 +21,26 @@
|
|||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type Condition struct {
|
||||
Status bool
|
||||
Reason string
|
||||
Message string
|
||||
Hash string
|
||||
}
|
||||
|
||||
func WithCondition(conditions *api.ConditionList, condition api.ConditionType, changed bool, err error) (bool, error) {
|
||||
var hash string
|
||||
|
||||
if changed || err != nil {
|
||||
// Condition should be false
|
||||
if conditions.Update(condition, false, "Not ready", "Not ready") {
|
||||
if conditions.UpdateWithHash(condition, false, "Not ready", "Not ready", hash) {
|
||||
changed = true
|
||||
}
|
||||
} else {
|
||||
if conditions.Update(condition, true, "Ready", "Ready") {
|
||||
if conditions.UpdateWithHash(condition, true, "Ready", "Ready", hash) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
@ -47,234 +54,26 @@ func WithCondition(conditions *api.ConditionList, condition api.ConditionType, c
|
|||
return changed, err
|
||||
}
|
||||
|
||||
type HandleP0Func func(ctx context.Context) (bool, error)
|
||||
|
||||
type HandleP1Func[P1 interface{}] func(ctx context.Context, p1 P1) (bool, error)
|
||||
|
||||
type HandleP2Func[P1, P2 interface{}] func(ctx context.Context, p1 P1, p2 P2) (bool, error)
|
||||
|
||||
type HandleP3Func[P1, P2, P3 interface{}] func(ctx context.Context, p1 P1, p2 P2, p3 P3) (bool, error)
|
||||
|
||||
type HandleP4Func[P1, P2, P3, P4 interface{}] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (bool, error)
|
||||
|
||||
type HandleP5Func[P1, P2, P3, P4, P5 interface{}] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (bool, error)
|
||||
|
||||
type HandleP6Func[P1, P2, P3, P4, P5, P6 interface{}] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6) (bool, error)
|
||||
|
||||
type HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9 interface{}] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9) (bool, error)
|
||||
|
||||
func HandleP0(ctx context.Context, handler ...HandleP0Func) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx)
|
||||
if changed {
|
||||
isChanged = true
|
||||
func WithConditionChange(conditions *api.ConditionList, condition api.ConditionType, c *Condition, changed bool, err error) (bool, error) {
|
||||
if c == nil {
|
||||
if conditions.Remove(condition) {
|
||||
changed = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
} else {
|
||||
if conditions.UpdateWithHash(condition, c.Status, c.Reason, c.Message, c.Hash) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP1[P1 interface{}](ctx context.Context, p1 P1, handler ...HandleP1Func[P1]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1)
|
||||
if err == nil || IsStop(err) {
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
err = Reconcile("Condition changed")
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP1WithStop[P1 interface{}](ctx context.Context, p1 P1, handler ...HandleP1Func[P1]) (bool, error) {
|
||||
changed, err := HandleP1[P1](ctx, p1, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
if err == nil && changed {
|
||||
err = Reconcile("Condition changed")
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP2[P1, P2 interface{}](ctx context.Context, p1 P1, p2 P2, handler ...HandleP2Func[P1, P2]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP2WithStop[P1, P2 interface{}](ctx context.Context, p1 P1, p2 P2, handler ...HandleP2Func[P1, P2]) (bool, error) {
|
||||
changed, err := HandleP2[P1, P2](ctx, p1, p2, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP3[P1, P2, P3 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP3WithStop[P1, P2, P3 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
changed, err := HandleP3[P1, P2, P3](ctx, p1, p2, p3, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP3WithCondition[P1, P2, P3 interface{}](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
changed, err := HandleP3[P1, P2, P3](ctx, p1, p2, p3, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP4[P1, P2, P3, P4 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP4WithStop[P1, P2, P3, P4 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
changed, err := HandleP4[P1, P2, P3, P4](ctx, p1, p2, p3, p4, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP4WithCondition[P1, P2, P3, P4 interface{}](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
changed, err := HandleP4[P1, P2, P3, P4](ctx, p1, p2, p3, p4, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP5[P1, P2, P3, P4, P5 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP5WithStop[P1, P2, P3, P4, P5 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
changed, err := HandleP5[P1, P2, P3, P4, P5](ctx, p1, p2, p3, p4, p5, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP5WithCondition[P1, P2, P3, P4, P5 interface{}](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
changed, err := HandleP5[P1, P2, P3, P4, P5](ctx, p1, p2, p3, p4, p5, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP6[P1, P2, P3, P4, P5, P6 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP6WithStop[P1, P2, P3, P4, P5, P6 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
changed, err := HandleP6[P1, P2, P3, P4, P5, P6](ctx, p1, p2, p3, p4, p5, p6, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP6WithCondition[P1, P2, P3, P4, P5, P6 interface{}](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
changed, err := HandleP6[P1, P2, P3, P4, P5, P6](ctx, p1, p2, p3, p4, p5, p6, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP9WithStop[P1, P2, P3, P4, P5, P6, P7, P8, P9 interface{}](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
changed, err := HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9](ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP9WithCondition[P1, P2, P3, P4, P5, P6, P7, P8, P9 interface{}](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
changed, err := HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9](ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
|
70
pkg/operatorV2/handler_p0.generated.go
Normal file
70
pkg/operatorV2/handler_p0.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP0Func func(ctx context.Context) (bool, error)
|
||||
|
||||
type HandleP0ConditionFunc func(ctx context.Context) (*Condition, bool, error)
|
||||
|
||||
type HandleP0ConditionExtract func(ctx context.Context) *api.ConditionList
|
||||
|
||||
func HandleP0(ctx context.Context, handler ...HandleP0Func) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP0WithStop(ctx context.Context, handler ...HandleP0Func) (bool, error) {
|
||||
changed, err := HandleP0(ctx, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP0WithCondition(ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, handler ...HandleP0Func) (bool, error) {
|
||||
changed, err := HandleP0(ctx, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP0Condition(extract HandleP0ConditionExtract, condition api.ConditionType, handler HandleP0ConditionFunc) HandleP0Func {
|
||||
return func(ctx context.Context) (bool, error) {
|
||||
c, changed, err := handler(ctx)
|
||||
return WithConditionChange(extract(ctx), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p1.generated.go
Normal file
70
pkg/operatorV2/handler_p1.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP1Func[P1 any] func(ctx context.Context, p1 P1) (bool, error)
|
||||
|
||||
type HandleP1ConditionFunc[P1 any] func(ctx context.Context, p1 P1) (*Condition, bool, error)
|
||||
|
||||
type HandleP1ConditionExtract[P1 any] func(ctx context.Context, p1 P1) *api.ConditionList
|
||||
|
||||
func HandleP1[P1 any](ctx context.Context, p1 P1, handler ...HandleP1Func[P1]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP1WithStop[P1 any](ctx context.Context, p1 P1, handler ...HandleP1Func[P1]) (bool, error) {
|
||||
changed, err := HandleP1[P1](ctx, p1, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP1WithCondition[P1 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, handler ...HandleP1Func[P1]) (bool, error) {
|
||||
changed, err := HandleP1[P1](ctx, p1, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP1Condition[P1 any](extract HandleP1ConditionExtract[P1], condition api.ConditionType, handler HandleP1ConditionFunc[P1]) HandleP1Func[P1] {
|
||||
return func(ctx context.Context, p1 P1) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1)
|
||||
return WithConditionChange(extract(ctx, p1), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p2.generated.go
Normal file
70
pkg/operatorV2/handler_p2.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP2Func[P1, P2 any] func(ctx context.Context, p1 P1, p2 P2) (bool, error)
|
||||
|
||||
type HandleP2ConditionFunc[P1, P2 any] func(ctx context.Context, p1 P1, p2 P2) (*Condition, bool, error)
|
||||
|
||||
type HandleP2ConditionExtract[P1, P2 any] func(ctx context.Context, p1 P1, p2 P2) *api.ConditionList
|
||||
|
||||
func HandleP2[P1, P2 any](ctx context.Context, p1 P1, p2 P2, handler ...HandleP2Func[P1, P2]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP2WithStop[P1, P2 any](ctx context.Context, p1 P1, p2 P2, handler ...HandleP2Func[P1, P2]) (bool, error) {
|
||||
changed, err := HandleP2[P1, P2](ctx, p1, p2, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP2WithCondition[P1, P2 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, handler ...HandleP2Func[P1, P2]) (bool, error) {
|
||||
changed, err := HandleP2[P1, P2](ctx, p1, p2, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP2Condition[P1, P2 any](extract HandleP2ConditionExtract[P1, P2], condition api.ConditionType, handler HandleP2ConditionFunc[P1, P2]) HandleP2Func[P1, P2] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2)
|
||||
return WithConditionChange(extract(ctx, p1, p2), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p3.generated.go
Normal file
70
pkg/operatorV2/handler_p3.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP3Func[P1, P2, P3 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3) (bool, error)
|
||||
|
||||
type HandleP3ConditionFunc[P1, P2, P3 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3) (*Condition, bool, error)
|
||||
|
||||
type HandleP3ConditionExtract[P1, P2, P3 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3) *api.ConditionList
|
||||
|
||||
func HandleP3[P1, P2, P3 any](ctx context.Context, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP3WithStop[P1, P2, P3 any](ctx context.Context, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
changed, err := HandleP3[P1, P2, P3](ctx, p1, p2, p3, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP3WithCondition[P1, P2, P3 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, handler ...HandleP3Func[P1, P2, P3]) (bool, error) {
|
||||
changed, err := HandleP3[P1, P2, P3](ctx, p1, p2, p3, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP3Condition[P1, P2, P3 any](extract HandleP3ConditionExtract[P1, P2, P3], condition api.ConditionType, handler HandleP3ConditionFunc[P1, P2, P3]) HandleP3Func[P1, P2, P3] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p4.generated.go
Normal file
70
pkg/operatorV2/handler_p4.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP4Func[P1, P2, P3, P4 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (bool, error)
|
||||
|
||||
type HandleP4ConditionFunc[P1, P2, P3, P4 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (*Condition, bool, error)
|
||||
|
||||
type HandleP4ConditionExtract[P1, P2, P3, P4 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) *api.ConditionList
|
||||
|
||||
func HandleP4[P1, P2, P3, P4 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP4WithStop[P1, P2, P3, P4 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
changed, err := HandleP4[P1, P2, P3, P4](ctx, p1, p2, p3, p4, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP4WithCondition[P1, P2, P3, P4 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, handler ...HandleP4Func[P1, P2, P3, P4]) (bool, error) {
|
||||
changed, err := HandleP4[P1, P2, P3, P4](ctx, p1, p2, p3, p4, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP4Condition[P1, P2, P3, P4 any](extract HandleP4ConditionExtract[P1, P2, P3, P4], condition api.ConditionType, handler HandleP4ConditionFunc[P1, P2, P3, P4]) HandleP4Func[P1, P2, P3, P4] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p5.generated.go
Normal file
70
pkg/operatorV2/handler_p5.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP5Func[P1, P2, P3, P4, P5 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (bool, error)
|
||||
|
||||
type HandleP5ConditionFunc[P1, P2, P3, P4, P5 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (*Condition, bool, error)
|
||||
|
||||
type HandleP5ConditionExtract[P1, P2, P3, P4, P5 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) *api.ConditionList
|
||||
|
||||
func HandleP5[P1, P2, P3, P4, P5 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP5WithStop[P1, P2, P3, P4, P5 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
changed, err := HandleP5[P1, P2, P3, P4, P5](ctx, p1, p2, p3, p4, p5, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP5WithCondition[P1, P2, P3, P4, P5 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, handler ...HandleP5Func[P1, P2, P3, P4, P5]) (bool, error) {
|
||||
changed, err := HandleP5[P1, P2, P3, P4, P5](ctx, p1, p2, p3, p4, p5, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP5Condition[P1, P2, P3, P4, P5 any](extract HandleP5ConditionExtract[P1, P2, P3, P4, P5], condition api.ConditionType, handler HandleP5ConditionFunc[P1, P2, P3, P4, P5]) HandleP5Func[P1, P2, P3, P4, P5] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4, p5)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4, p5), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p6.generated.go
Normal file
70
pkg/operatorV2/handler_p6.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP6Func[P1, P2, P3, P4, P5, P6 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6) (bool, error)
|
||||
|
||||
type HandleP6ConditionFunc[P1, P2, P3, P4, P5, P6 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6) (*Condition, bool, error)
|
||||
|
||||
type HandleP6ConditionExtract[P1, P2, P3, P4, P5, P6 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6) *api.ConditionList
|
||||
|
||||
func HandleP6[P1, P2, P3, P4, P5, P6 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP6WithStop[P1, P2, P3, P4, P5, P6 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
changed, err := HandleP6[P1, P2, P3, P4, P5, P6](ctx, p1, p2, p3, p4, p5, p6, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP6WithCondition[P1, P2, P3, P4, P5, P6 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, handler ...HandleP6Func[P1, P2, P3, P4, P5, P6]) (bool, error) {
|
||||
changed, err := HandleP6[P1, P2, P3, P4, P5, P6](ctx, p1, p2, p3, p4, p5, p6, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP6Condition[P1, P2, P3, P4, P5, P6 any](extract HandleP6ConditionExtract[P1, P2, P3, P4, P5, P6], condition api.ConditionType, handler HandleP6ConditionFunc[P1, P2, P3, P4, P5, P6]) HandleP6Func[P1, P2, P3, P4, P5, P6] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4, p5, p6)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4, p5, p6), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p7.generated.go
Normal file
70
pkg/operatorV2/handler_p7.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP7Func[P1, P2, P3, P4, P5, P6, P7 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7) (bool, error)
|
||||
|
||||
type HandleP7ConditionFunc[P1, P2, P3, P4, P5, P6, P7 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7) (*Condition, bool, error)
|
||||
|
||||
type HandleP7ConditionExtract[P1, P2, P3, P4, P5, P6, P7 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7) *api.ConditionList
|
||||
|
||||
func HandleP7[P1, P2, P3, P4, P5, P6, P7 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, handler ...HandleP7Func[P1, P2, P3, P4, P5, P6, P7]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6, p7)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP7WithStop[P1, P2, P3, P4, P5, P6, P7 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, handler ...HandleP7Func[P1, P2, P3, P4, P5, P6, P7]) (bool, error) {
|
||||
changed, err := HandleP7[P1, P2, P3, P4, P5, P6, P7](ctx, p1, p2, p3, p4, p5, p6, p7, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP7WithCondition[P1, P2, P3, P4, P5, P6, P7 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, handler ...HandleP7Func[P1, P2, P3, P4, P5, P6, P7]) (bool, error) {
|
||||
changed, err := HandleP7[P1, P2, P3, P4, P5, P6, P7](ctx, p1, p2, p3, p4, p5, p6, p7, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP7Condition[P1, P2, P3, P4, P5, P6, P7 any](extract HandleP7ConditionExtract[P1, P2, P3, P4, P5, P6, P7], condition api.ConditionType, handler HandleP7ConditionFunc[P1, P2, P3, P4, P5, P6, P7]) HandleP7Func[P1, P2, P3, P4, P5, P6, P7] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4, p5, p6, p7)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4, p5, p6, p7), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p8.generated.go
Normal file
70
pkg/operatorV2/handler_p8.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP8Func[P1, P2, P3, P4, P5, P6, P7, P8 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8) (bool, error)
|
||||
|
||||
type HandleP8ConditionFunc[P1, P2, P3, P4, P5, P6, P7, P8 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8) (*Condition, bool, error)
|
||||
|
||||
type HandleP8ConditionExtract[P1, P2, P3, P4, P5, P6, P7, P8 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8) *api.ConditionList
|
||||
|
||||
func HandleP8[P1, P2, P3, P4, P5, P6, P7, P8 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, handler ...HandleP8Func[P1, P2, P3, P4, P5, P6, P7, P8]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP8WithStop[P1, P2, P3, P4, P5, P6, P7, P8 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, handler ...HandleP8Func[P1, P2, P3, P4, P5, P6, P7, P8]) (bool, error) {
|
||||
changed, err := HandleP8[P1, P2, P3, P4, P5, P6, P7, P8](ctx, p1, p2, p3, p4, p5, p6, p7, p8, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP8WithCondition[P1, P2, P3, P4, P5, P6, P7, P8 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, handler ...HandleP8Func[P1, P2, P3, P4, P5, P6, P7, P8]) (bool, error) {
|
||||
changed, err := HandleP8[P1, P2, P3, P4, P5, P6, P7, P8](ctx, p1, p2, p3, p4, p5, p6, p7, p8, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP8Condition[P1, P2, P3, P4, P5, P6, P7, P8 any](extract HandleP8ConditionExtract[P1, P2, P3, P4, P5, P6, P7, P8], condition api.ConditionType, handler HandleP8ConditionFunc[P1, P2, P3, P4, P5, P6, P7, P8]) HandleP8Func[P1, P2, P3, P4, P5, P6, P7, P8] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4, p5, p6, p7, p8)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4, p5, p6, p7, p8), condition, c, changed, err)
|
||||
}
|
||||
}
|
70
pkg/operatorV2/handler_p9.generated.go
Normal file
70
pkg/operatorV2/handler_p9.generated.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
|
||||
package operator
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
)
|
||||
|
||||
type HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9) (bool, error)
|
||||
|
||||
type HandleP9ConditionFunc[P1, P2, P3, P4, P5, P6, P7, P8, P9 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9) (*Condition, bool, error)
|
||||
|
||||
type HandleP9ConditionExtract[P1, P2, P3, P4, P5, P6, P7, P8, P9 any] func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9) *api.ConditionList
|
||||
|
||||
func HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
isChanged := false
|
||||
for _, h := range handler {
|
||||
changed, err := h(ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9)
|
||||
if changed {
|
||||
isChanged = true
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return isChanged, err
|
||||
}
|
||||
}
|
||||
|
||||
return isChanged, nil
|
||||
}
|
||||
|
||||
func HandleP9WithStop[P1, P2, P3, P4, P5, P6, P7, P8, P9 any](ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
changed, err := HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9](ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9, handler...)
|
||||
if IsStop(err) {
|
||||
return changed, nil
|
||||
}
|
||||
|
||||
return changed, err
|
||||
}
|
||||
|
||||
func HandleP9WithCondition[P1, P2, P3, P4, P5, P6, P7, P8, P9 any](ctx context.Context, conditions *api.ConditionList, condition api.ConditionType, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9, handler ...HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9]) (bool, error) {
|
||||
changed, err := HandleP9[P1, P2, P3, P4, P5, P6, P7, P8, P9](ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9, handler...)
|
||||
return WithCondition(conditions, condition, changed, err)
|
||||
}
|
||||
|
||||
func HandleP9Condition[P1, P2, P3, P4, P5, P6, P7, P8, P9 any](extract HandleP9ConditionExtract[P1, P2, P3, P4, P5, P6, P7, P8, P9], condition api.ConditionType, handler HandleP9ConditionFunc[P1, P2, P3, P4, P5, P6, P7, P8, P9]) HandleP9Func[P1, P2, P3, P4, P5, P6, P7, P8, P9] {
|
||||
return func(ctx context.Context, p1 P1, p2 P2, p3 P3, p4 P4, p5 P5, p6 P6, p7 P7, p8 P8, p9 P9) (bool, error) {
|
||||
c, changed, err := handler(ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9)
|
||||
return WithConditionChange(extract(ctx, p1, p2, p3, p4, p5, p6, p7, p8, p9), condition, c, changed, err)
|
||||
}
|
||||
}
|
|
@ -29,6 +29,7 @@ import (
|
|||
backupApi "github.com/arangodb/kube-arangodb/pkg/apis/backup/v1"
|
||||
mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1"
|
||||
mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
)
|
||||
|
||||
func WithArangoBackupUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[backupApi.ArangoBackupStatus, *backupApi.ArangoBackup], obj *backupApi.ArangoBackup, status backupApi.ArangoBackupStatus, opts meta.UpdateOptions) (*backupApi.ArangoBackup, error) {
|
||||
|
@ -51,6 +52,10 @@ func WithAnalyticsGAEUpdateStatusInterfaceRetry(ctx context.Context, client Upda
|
|||
return WithUpdateStatusInterfaceRetry[analyticsApi.GraphAnalyticsEngineStatus, *analyticsApi.GraphAnalyticsEngine](ctx, client, obj, status, opts)
|
||||
}
|
||||
|
||||
func WithNetworkingArangoRouteUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[networkingApi.ArangoRouteStatus, *networkingApi.ArangoRoute], obj *networkingApi.ArangoRoute, status networkingApi.ArangoRouteStatus, opts meta.UpdateOptions) (*networkingApi.ArangoRoute, error) {
|
||||
return WithUpdateStatusInterfaceRetry[networkingApi.ArangoRouteStatus, *networkingApi.ArangoRoute](ctx, client, obj, status, opts)
|
||||
}
|
||||
|
||||
func WithArangoStorageUpdateStatusInterfaceRetry(ctx context.Context, client UpdateStatusInterface[mlApi.ArangoMLStorageStatus, *mlApi.ArangoMLStorage], obj *mlApi.ArangoMLStorage, status mlApi.ArangoMLStorageStatus, opts meta.UpdateOptions) (*mlApi.ArangoMLStorage, error) {
|
||||
return WithUpdateStatusInterfaceRetry[mlApi.ArangoMLStorageStatus, *mlApi.ArangoMLStorage](ctx, client, obj, status, opts)
|
||||
}
|
||||
|
|
|
@ -70,6 +70,7 @@ type Dependencies struct {
|
|||
Apps OperatorDependency
|
||||
ML OperatorDependency
|
||||
Analytics OperatorDependency
|
||||
Networking OperatorDependency
|
||||
ClusterSync OperatorDependency
|
||||
Operators Operators
|
||||
Secrets typedCore.SecretInterface
|
||||
|
@ -194,6 +195,10 @@ func NewServer(cli typedCore.CoreV1Interface, cfg Config, deps Dependencies) (*S
|
|||
r.GET("/ready/analytics", gin.WrapF(deps.Analytics.Probe.ReadyHandler))
|
||||
readyProbes = append(readyProbes, deps.Analytics.Probe)
|
||||
}
|
||||
if deps.Networking.Enabled {
|
||||
r.GET("/ready/networking", gin.WrapF(deps.Networking.Probe.ReadyHandler))
|
||||
readyProbes = append(readyProbes, deps.Networking.Probe)
|
||||
}
|
||||
r.GET("/ready", gin.WrapF(ready(readyProbes...)))
|
||||
r.GET("/metrics", gin.WrapF(metrics.Handler()))
|
||||
r.POST("/login", s.auth.handleLogin)
|
||||
|
|
|
@ -26,8 +26,28 @@ import (
|
|||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/strings"
|
||||
)
|
||||
|
||||
type Hash interface {
|
||||
Hash() string
|
||||
}
|
||||
|
||||
func SHA256FromExtract[T any](extract func(T) string, obj ...T) string {
|
||||
return SHA256FromStringArray(strings.Join(FormatList(obj, extract), "|"))
|
||||
}
|
||||
|
||||
func SHA256FromHashArray[T Hash](data []T) string {
|
||||
return SHA256FromExtract(func(t T) string {
|
||||
return t.Hash()
|
||||
}, data...)
|
||||
}
|
||||
|
||||
func SHA256FromStringArray(data ...string) string {
|
||||
return SHA256FromString(strings.Join(data, "|"))
|
||||
}
|
||||
|
||||
func SHA256FromString(data string) string {
|
||||
return SHA256([]byte(data))
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ const (
|
|||
BackupLabelRole = "backup/role"
|
||||
MLLabelRole = "ml/role"
|
||||
AnalyticsLabelRole = "analytics/role"
|
||||
NetworkingLabelRole = "networking/role"
|
||||
AppsLabelRole = "apps/role"
|
||||
ClusterSyncLabelRole = "clustersync/role"
|
||||
LabelRole = "role"
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"maps"
|
||||
"reflect"
|
||||
"sort"
|
||||
)
|
||||
|
@ -50,7 +51,7 @@ func CopyFullMap[K comparable, V any](src map[K]V) map[K]V {
|
|||
|
||||
r := map[K]V{}
|
||||
|
||||
CopyMap(r, src)
|
||||
maps.Copy(r, src)
|
||||
|
||||
return r
|
||||
}
|
||||
|
@ -73,13 +74,6 @@ func MergeMaps[K comparable, V any](override bool, maps ...map[K]V) map[K]V {
|
|||
return r
|
||||
}
|
||||
|
||||
func CopyMap[K comparable, V any](dst, src map[K]V) {
|
||||
// TODO: replace with maps.Copy when switching to go1.21
|
||||
for k, v := range src {
|
||||
dst[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
func IterateSorted[V any](m map[string]V, cb func(string, V)) {
|
||||
for _, k := range SortKeys(m) {
|
||||
cb(k, m[k])
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2023 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -22,7 +22,7 @@ package util
|
|||
|
||||
import "sort"
|
||||
|
||||
type List[T any] []T
|
||||
type List[T comparable] []T
|
||||
|
||||
func (l List[T]) Filter(fn func(T) bool) List[T] {
|
||||
if l == nil {
|
||||
|
@ -57,6 +57,16 @@ func (l List[T]) Sort(fn func(T, T) bool) List[T] {
|
|||
return clone
|
||||
}
|
||||
|
||||
func PickFromList[V any](in []V, q func(v V) bool) (V, bool) {
|
||||
for _, v := range in {
|
||||
if q(v) {
|
||||
return v, true
|
||||
}
|
||||
}
|
||||
|
||||
return Default[V](), false
|
||||
}
|
||||
|
||||
func MapList[T, V comparable](in List[T], fn func(T) V) List[V] {
|
||||
if in == nil {
|
||||
return nil
|
||||
|
@ -67,3 +77,27 @@ func MapList[T, V comparable](in List[T], fn func(T) V) List[V] {
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func FormatList[A, B any](in []A, format func(A) B) []B {
|
||||
var r = make([]B, len(in))
|
||||
|
||||
for id := range in {
|
||||
r[id] = format(in[id])
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
func FormatListErr[A, B any](in []A, format func(A) (B, error)) ([]B, error) {
|
||||
var r = make([]B, len(in))
|
||||
|
||||
for id := range in {
|
||||
if o, err := format(in[id]); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
r[id] = o
|
||||
}
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/apis/ml"
|
||||
mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1"
|
||||
mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/networking"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/scheduler"
|
||||
schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1"
|
||||
schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1"
|
||||
|
@ -243,6 +245,12 @@ func CreateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe
|
|||
vl := *v
|
||||
_, err := arango.AnalyticsV1alpha1().GraphAnalyticsEngines(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
case **networkingApi.ArangoRoute:
|
||||
require.NotNil(t, v)
|
||||
|
||||
vl := *v
|
||||
_, err := arango.NetworkingV1alpha1().ArangoRoutes(vl.GetNamespace()).Create(context.Background(), vl, meta.CreateOptions{})
|
||||
require.NoError(t, err)
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String()))
|
||||
}
|
||||
|
@ -397,6 +405,12 @@ func UpdateObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe
|
|||
vl := *v
|
||||
_, err := arango.AnalyticsV1alpha1().GraphAnalyticsEngines(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
case **networkingApi.ArangoRoute:
|
||||
require.NotNil(t, v)
|
||||
|
||||
vl := *v
|
||||
_, err := arango.NetworkingV1alpha1().ArangoRoutes(vl.GetNamespace()).Update(context.Background(), vl, meta.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String()))
|
||||
}
|
||||
|
@ -525,6 +539,11 @@ func DeleteObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientSe
|
|||
|
||||
vl := *v
|
||||
require.NoError(t, arango.AnalyticsV1alpha1().GraphAnalyticsEngines(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{}))
|
||||
case **networkingApi.ArangoRoute:
|
||||
require.NotNil(t, v)
|
||||
|
||||
vl := *v
|
||||
require.NoError(t, arango.NetworkingV1alpha1().ArangoRoutes(vl.GetNamespace()).Delete(context.Background(), vl.GetName(), meta.DeleteOptions{}))
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to delete object: %s", reflect.TypeOf(v).String()))
|
||||
}
|
||||
|
@ -882,6 +901,21 @@ func RefreshObjects(t *testing.T, k8s kubernetes.Interface, arango arangoClientS
|
|||
} else {
|
||||
*v = vn
|
||||
}
|
||||
case **networkingApi.ArangoRoute:
|
||||
require.NotNil(t, v)
|
||||
|
||||
vl := *v
|
||||
|
||||
vn, err := arango.NetworkingV1alpha1().ArangoRoutes(vl.GetNamespace()).Get(context.Background(), vl.GetName(), meta.GetOptions{})
|
||||
if err != nil {
|
||||
if kerrors.IsNotFound(err) {
|
||||
*v = nil
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
} else {
|
||||
*v = vn
|
||||
}
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to get object: %s", reflect.TypeOf(v).String()))
|
||||
}
|
||||
|
@ -1054,6 +1088,14 @@ func SetMetaBasedOnType(t *testing.T, object meta.Object) {
|
|||
analytics.GraphAnalyticsEngineResourcePlural,
|
||||
object.GetNamespace(),
|
||||
object.GetName()))
|
||||
case *networkingApi.ArangoRoute:
|
||||
v.Kind = networking.ArangoRouteResourceKind
|
||||
v.APIVersion = networkingApi.SchemeGroupVersion.String()
|
||||
v.SetSelfLink(fmt.Sprintf("/api/%s/%s/%s/%s",
|
||||
networkingApi.SchemeGroupVersion.String(),
|
||||
networking.ArangoRouteResourcePlural,
|
||||
object.GetNamespace(),
|
||||
object.GetName()))
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String()))
|
||||
}
|
||||
|
@ -1230,6 +1272,12 @@ func GVK(t *testing.T, object meta.Object) schema.GroupVersionKind {
|
|||
Version: analyticsApi.ArangoAnalyticsVersion,
|
||||
Kind: analytics.GraphAnalyticsEngineResourceKind,
|
||||
}
|
||||
case *networkingApi.ArangoRoute:
|
||||
return schema.GroupVersionKind{
|
||||
Group: networking.ArangoNetworkingGroupName,
|
||||
Version: networkingApi.ArangoNetworkingVersion,
|
||||
Kind: networking.ArangoRouteResourceKind,
|
||||
}
|
||||
default:
|
||||
require.Fail(t, fmt.Sprintf("Unable to create object: %s", reflect.TypeOf(v).String()))
|
||||
return schema.GroupVersionKind{}
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
api "github.com/arangodb/kube-arangodb/pkg/apis/deployment/v1"
|
||||
mlApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1alpha1"
|
||||
mlApi "github.com/arangodb/kube-arangodb/pkg/apis/ml/v1beta1"
|
||||
networkingApi "github.com/arangodb/kube-arangodb/pkg/apis/networking/v1alpha1"
|
||||
schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1"
|
||||
"github.com/arangodb/kube-arangodb/pkg/operatorV2/operation"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
|
@ -87,4 +88,5 @@ func Test_NewMetaObject(t *testing.T) {
|
|||
NewMetaObjectRun[*mlApiv1alpha1.ArangoMLCronJob](t)
|
||||
NewMetaObjectRun[*schedulerApi.ArangoProfile](t)
|
||||
NewMetaObjectRun[*analyticsApi.GraphAnalyticsEngine](t)
|
||||
NewMetaObjectRun[*networkingApi.ArangoRoute](t)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue