mirror of
https://github.com/arangodb/kube-arangodb.git
synced 2024-12-14 11:57:37 +00:00
(Feature) Add generator for CRD validation schemas (#1488)
* (Feature) Add generator for CRD validation schemas * Improve docs / log output for crd installation * Add ability to force-update CRDs to allow testing
This commit is contained in:
parent
934039fb41
commit
82cb7f1298
35 changed files with 608 additions and 186 deletions
|
@ -10,6 +10,7 @@
|
|||
- (Maintenance) Bump Go to 1.20.11
|
||||
- (Feature) License ArangoDeployment Fetcher
|
||||
- (Feature) K8S Resources Compare Generic
|
||||
- (Feature) Add support for CRD validation schemas
|
||||
|
||||
## [1.2.35](https://github.com/arangodb/kube-arangodb/tree/1.2.35) (2023-11-06)
|
||||
- (Maintenance) Update go-driver to v1.6.0, update IsNotFound() checks
|
||||
|
|
11
cmd/cmd.go
11
cmd/cmd.go
|
@ -136,7 +136,8 @@ var (
|
|||
timeout time.Duration
|
||||
}
|
||||
crdOptions struct {
|
||||
install bool
|
||||
install bool
|
||||
validationSchema []string
|
||||
}
|
||||
operatorKubernetesOptions struct {
|
||||
maxBatchSize int64
|
||||
|
@ -224,6 +225,7 @@ func init() {
|
|||
f.Float32Var(&operatorKubernetesOptions.qps, "kubernetes.qps", kclient.DefaultQPS, "Number of queries per second for k8s API")
|
||||
f.IntVar(&operatorKubernetesOptions.burst, "kubernetes.burst", kclient.DefaultBurst, "Burst for the k8s API")
|
||||
f.BoolVar(&crdOptions.install, "crd.install", true, "Install missing CRD if access is possible")
|
||||
f.StringArrayVar(&crdOptions.validationSchema, "crd.validation-schema", defaultValidationSchemaEnabled, "Overrides default set of CRDs which should have validation schema enabled <crd-name>=<true/false>.")
|
||||
f.IntVar(&operatorBackup.concurrentUploads, "backup-concurrent-uploads", globals.DefaultBackupConcurrentUploads, "Number of concurrent uploads per deployment")
|
||||
f.Uint64Var(&memoryLimit.hardLimit, "memory-limit", 0, "Define memory limit for hard shutdown and the dump of goroutines. Used for testing")
|
||||
f.StringArrayVar(&metricsOptions.excludedMetricPrefixes, "metrics.excluded-prefixes", nil, "List of the excluded metrics prefixes")
|
||||
|
@ -359,7 +361,12 @@ func executeMain(cmd *cobra.Command, args []string) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
_ = crd.EnsureCRD(ctx, client, true)
|
||||
crdOpts, err := prepareCRDOptions(crdOptions.validationSchema)
|
||||
if err != nil {
|
||||
logger.Fatal("Invalid --crd.validation-schema args: %s", err)
|
||||
}
|
||||
|
||||
_ = crd.EnsureCRDWithOptions(ctx, client, crd.EnsureCRDOptions{IgnoreErrors: true, CRDOptions: crdOpts})
|
||||
}
|
||||
|
||||
secrets := client.Kubernetes().CoreV1().Secrets(namespace)
|
||||
|
|
53
cmd/crd.go
53
cmd/crd.go
|
@ -1,7 +1,7 @@
|
|||
//
|
||||
// DISCLAIMER
|
||||
//
|
||||
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany
|
||||
// Copyright 2016-2023 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,12 +22,17 @@ package cmd
|
|||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/crd"
|
||||
"github.com/arangodb/kube-arangodb/pkg/crd/crds"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
)
|
||||
|
||||
|
@ -44,23 +49,67 @@ var (
|
|||
}
|
||||
)
|
||||
|
||||
var (
|
||||
crdInstallOptions struct {
|
||||
validationSchema []string
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
defaultValidationSchemaEnabled []string
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmdMain.AddCommand(cmdCRD)
|
||||
cmdOps.AddCommand(cmdCRD)
|
||||
|
||||
f := cmdCRDInstall.Flags()
|
||||
f.StringArrayVar(&crdInstallOptions.validationSchema, "crd.validation-schema", defaultValidationSchemaEnabled, "Controls which CRD should have validation schema <crd-name>=<true/false>.")
|
||||
cmdCRD.AddCommand(cmdCRDInstall)
|
||||
}
|
||||
|
||||
func prepareCRDOptions(schemaEnabledArgs []string) (map[string]crds.CRDOptions, error) {
|
||||
defaultOptions := crd.GetDefaultCRDOptions()
|
||||
result := make(map[string]crds.CRDOptions)
|
||||
var err error
|
||||
for _, arg := range schemaEnabledArgs {
|
||||
parts := strings.Split(arg, "=")
|
||||
|
||||
crdName := parts[0]
|
||||
opts, ok := defaultOptions[crdName]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown CRD %s", crdName)
|
||||
}
|
||||
|
||||
if len(parts) == 2 {
|
||||
opts.WithSchema, err = strconv.ParseBool(parts[1])
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "not a bool value: %s", parts[1])
|
||||
}
|
||||
}
|
||||
|
||||
result[crdName] = opts
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
|
||||
crdOpts, err := prepareCRDOptions(crdInstallOptions.validationSchema)
|
||||
if err != nil {
|
||||
logger.Fatal("Invalid --crd.validation-schema args: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
client, ok := kclient.GetDefaultFactory().Client()
|
||||
if !ok {
|
||||
logger.Fatal("Failed to get client")
|
||||
return
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||
defer cancel()
|
||||
|
||||
err := crd.EnsureCRD(ctx, client, false)
|
||||
err = crd.EnsureCRDWithOptions(ctx, client, crd.EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts})
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
- [Operator Metrics & Alerts](generated/metrics/README.md)
|
||||
- [Operator Actions](generated/actions.md)
|
||||
- [Authentication](authentication.md)
|
||||
- Custom resources overview:
|
||||
- [Custom resources overview](crds.md):
|
||||
- [ArangoDeployment](deployment-resource-reference.md)
|
||||
- [ArangoDeploymentReplication](deployment-replication-resource-reference.md)
|
||||
- [ArangoLocalStorage](storage-resource.md)
|
||||
|
|
38
docs/crds.md
Normal file
38
docs/crds.md
Normal file
|
@ -0,0 +1,38 @@
|
|||
# Custom resources overview
|
||||
|
||||
Main CRDs:
|
||||
- [ArangoDeployment](deployment-resource-reference.md)
|
||||
- [ArangoDeploymentReplication](deployment-replication-resource-reference.md)
|
||||
- [ArangoLocalStorage](storage-resource.md)
|
||||
- [Backup](backup-resource.md)
|
||||
- [BackupPolicy](backuppolicy-resource.md)
|
||||
|
||||
Operator manages the CustomResources based on CustomResourceDefinitions installed in your cluster.
|
||||
|
||||
There are different options how CustomResourceDefinitions can be created.
|
||||
|
||||
**Deprecated options:**
|
||||
- Install CRDs directly from `manifests` folder.
|
||||
- Install `kube-arangodb-crd` helm chart before installing `kube-arangodb` chart.
|
||||
- Install CRDs using kustomize `all` or `crd` manifests.
|
||||
|
||||
**Recommended:**
|
||||
Use `kube-arangodb` Helm chart.
|
||||
If you've chosen not to install CRDs automatically (`--skip-crds`), the operator will try to install CRDs automatically.
|
||||
Make sure that ServiceAccount for operator has permissions to `create` CustomResourceDefinitions.
|
||||
|
||||
To disable the automatic creation of CRDs, set `enableCRDManagement=false` template parameter, e.g.:
|
||||
```shell
|
||||
helm install --generate-name https://github.com/arangodb/kube-arangodb/releases/download/$VER/kube-arangodb-$VER.tgz --set "operator.enableCRDManagement=false"
|
||||
```
|
||||
|
||||
## Schema validation
|
||||
|
||||
Starting with v1.2.36, the [schema validation](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation) is supported for all CRDs.
|
||||
|
||||
Schema validation can be enabled only on cluster with no CRDs installed or by upgrading your CR from one CRD version to another.
|
||||
|
||||
To enable creation of CRD with validation schema, pass additional args to operator command line, e.g.:
|
||||
```
|
||||
--crd.validation-schema=arangobackuppolicies.backup.arangodb.com=true --crd.validation-schema=arangodeployments.database.arangodb.com=false
|
||||
```
|
|
@ -3,15 +3,28 @@
|
|||
It is possible to additionally fine-tune operator behavior by
|
||||
providing arguments via `operator.args` chart template value.
|
||||
|
||||
For example, you can specify burst size for k8s API requests or how long the operator
|
||||
The full list of available arguments can be retrieved using
|
||||
```
|
||||
export OPERATOR_IMAGE=arangodb/kube-arangodb:$VER
|
||||
kubectl run arango-operator-help --image=$OPERATOR_IMAGE -i --rm --restart=Never -- --help
|
||||
```
|
||||
|
||||
|
||||
### Example 1: kubernetes.burst
|
||||
|
||||
You can specify burst size for k8s API requests or how long the operator
|
||||
should wait for ArangoDeployment termination after receiving interruption signal:
|
||||
```
|
||||
operator:
|
||||
args: ["--kubernetes.burst=40", --shutdown.timeout=2m"]
|
||||
```
|
||||
|
||||
The full list of available arguments can be retrieved using
|
||||
### Example 2: CRD validation
|
||||
|
||||
You can specify which of installed CRD should have a validation schema enabled:
|
||||
```
|
||||
export OPERATOR_IMAGE=arangodb/kube-arangodb:1.2.9
|
||||
kubectl run arango-operator-help --image=$OPERATOR_IMAGE -i --rm --restart=Never -- --help
|
||||
operator:
|
||||
args:
|
||||
- --crd.validation-schema=arangobackuppolicies.backup.arangodb.com=true
|
||||
- --crd.validation-schema=arangodeployments.database.arangodb.com=false
|
||||
```
|
||||
|
|
2
go.mod
2
go.mod
|
@ -61,6 +61,7 @@ require (
|
|||
k8s.io/apiextensions-apiserver v0.25.13
|
||||
k8s.io/apimachinery v0.25.13
|
||||
k8s.io/client-go v0.25.13
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1
|
||||
sigs.k8s.io/yaml v1.2.0
|
||||
)
|
||||
|
||||
|
@ -126,7 +127,6 @@ require (
|
|||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
k8s.io/klog/v2 v2.70.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
|
|
|
@ -31,70 +31,95 @@ import (
|
|||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/crd/crds"
|
||||
"github.com/arangodb/kube-arangodb/pkg/logging"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
|
||||
)
|
||||
|
||||
var logger = logging.Global().RegisterAndGetLogger("crd", logging.Info)
|
||||
|
||||
// Deprecated: use EnsureCRDWithOptions instead
|
||||
func EnsureCRD(ctx context.Context, client kclient.Client, ignoreErrors bool) error {
|
||||
return EnsureCRDWithOptions(ctx, client, EnsureCRDOptions{
|
||||
IgnoreErrors: ignoreErrors,
|
||||
})
|
||||
}
|
||||
|
||||
type EnsureCRDOptions struct {
|
||||
// IgnoreErrors do not return errors if could not apply CRD
|
||||
IgnoreErrors bool
|
||||
// ForceUpdate if true, CRD will be updated even if definitions versions are the same
|
||||
ForceUpdate bool
|
||||
// CRDOptions defines options per each CRD
|
||||
CRDOptions map[string]crds.CRDOptions
|
||||
}
|
||||
|
||||
func EnsureCRDWithOptions(ctx context.Context, client kclient.Client, opts EnsureCRDOptions) error {
|
||||
crdsLock.Lock()
|
||||
defer crdsLock.Unlock()
|
||||
|
||||
for crd, spec := range registeredCRDs {
|
||||
getAccess := verifyCRDAccess(ctx, client, crd, "get")
|
||||
for crdName, crdReg := range registeredCRDs {
|
||||
getAccess := verifyCRDAccess(ctx, client, crdName, "get")
|
||||
if !getAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Get Operations is not allowed. Continue")
|
||||
logger.Str("crd", crdName).Info("Get Operations is not allowed. Continue")
|
||||
continue
|
||||
}
|
||||
|
||||
err := tryApplyCRD(ctx, client, crd, spec)
|
||||
if !ignoreErrors && err != nil {
|
||||
var opt *crds.CRDOptions
|
||||
if o, ok := opts.CRDOptions[crdName]; ok {
|
||||
opt = &o
|
||||
}
|
||||
def := crdReg.getter(opt)
|
||||
|
||||
err := tryApplyCRD(ctx, client, def, opts.ForceUpdate)
|
||||
if !opts.IgnoreErrors && err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tryApplyCRD(ctx context.Context, client kclient.Client, crd string, spec crd) error {
|
||||
func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition, forceUpdate bool) error {
|
||||
crdDefinitions := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions()
|
||||
|
||||
c, err := crdDefinitions.Get(ctx, crd, meta.GetOptions{})
|
||||
crdName := def.CRD.Name
|
||||
|
||||
c, err := crdDefinitions.Get(ctx, crdName, meta.GetOptions{})
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
logger.Err(err).Str("crd", crd).Warn("Get Operations is not allowed due to error")
|
||||
logger.Err(err).Str("crd", crdName).Warn("Get Operations is not allowed due to error")
|
||||
return err
|
||||
}
|
||||
|
||||
createAccess := verifyCRDAccess(ctx, client, crd, "create")
|
||||
createAccess := verifyCRDAccess(ctx, client, crdName, "create")
|
||||
|
||||
if !createAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Create Operations is not allowed but CRD is missing. Continue")
|
||||
logger.Str("crd", crdName).Info("Create Operations is not allowed but CRD is missing. Continue")
|
||||
return nil
|
||||
}
|
||||
|
||||
c = &apiextensions.CustomResourceDefinition{
|
||||
ObjectMeta: meta.ObjectMeta{
|
||||
Name: crd,
|
||||
Name: crdName,
|
||||
Labels: map[string]string{
|
||||
Version: string(spec.version),
|
||||
Version: string(def.Version),
|
||||
},
|
||||
},
|
||||
Spec: spec.spec,
|
||||
Spec: def.CRD.Spec,
|
||||
}
|
||||
|
||||
if _, err := crdDefinitions.Create(ctx, c, meta.CreateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
|
||||
logger.Err(err).Str("crd", crdName).Warn("Create Operations is not allowed due to error")
|
||||
return err
|
||||
}
|
||||
|
||||
logger.Str("crd", crd).Info("CRD Created")
|
||||
logger.Str("crd", crdName).Info("CRD Created")
|
||||
return nil
|
||||
}
|
||||
|
||||
updateAccess := verifyCRDAccess(ctx, client, crd, "update")
|
||||
updateAccess := verifyCRDAccess(ctx, client, crdName, "update")
|
||||
if !updateAccess.Allowed {
|
||||
logger.Str("crd", crd).Info("Update Operations is not allowed. Continue")
|
||||
logger.Str("crd", crdName).Info("Update Operations is not allowed. Continue")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -102,23 +127,21 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, crd string, spec cr
|
|||
c.ObjectMeta.Labels = map[string]string{}
|
||||
}
|
||||
|
||||
if v, ok := c.ObjectMeta.Labels[Version]; ok {
|
||||
if v != "" {
|
||||
if !isUpdateRequired(spec.version, driver.Version(v)) {
|
||||
logger.Str("crd", crd).Info("CRD Update not required")
|
||||
return nil
|
||||
}
|
||||
if v, ok := c.ObjectMeta.Labels[Version]; ok && v != "" {
|
||||
if !forceUpdate && !isUpdateRequired(def.Version, driver.Version(v)) {
|
||||
logger.Str("crd", crdName).Info("CRD Update not required")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
c.ObjectMeta.Labels[Version] = string(spec.version)
|
||||
c.Spec = spec.spec
|
||||
c.ObjectMeta.Labels[Version] = string(def.Version)
|
||||
c.Spec = def.CRD.Spec
|
||||
|
||||
if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil {
|
||||
logger.Err(err).Str("crd", crd).Warn("Create Operations is not allowed due to error")
|
||||
logger.Err(err).Str("crd", crdName).Warn("Failed to update CRD definition")
|
||||
return err
|
||||
}
|
||||
logger.Str("crd", crd).Info("CRD Updated")
|
||||
logger.Str("crd", crdName).Info("CRD Updated")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,28 @@ func dropLogMessages(t *testing.T, s tests.LogScanner) map[string]string {
|
|||
}
|
||||
|
||||
func Test_Apply(t *testing.T) {
|
||||
t.Run("NoSchema", func(t *testing.T) {
|
||||
crdValidation := make(map[string]crds.CRDOptions)
|
||||
for n := range GetDefaultCRDOptions() {
|
||||
crdValidation[n] = crds.CRDOptions{
|
||||
WithSchema: false,
|
||||
}
|
||||
}
|
||||
runApply(t, crdValidation)
|
||||
})
|
||||
t.Run("WithSchema", func(t *testing.T) {
|
||||
crdValidation := make(map[string]crds.CRDOptions)
|
||||
for n := range GetDefaultCRDOptions() {
|
||||
crdValidation[n] = crds.CRDOptions{
|
||||
WithSchema: true,
|
||||
}
|
||||
}
|
||||
runApply(t, crdValidation)
|
||||
})
|
||||
}
|
||||
|
||||
func runApply(t *testing.T, crdOpts map[string]crds.CRDOptions) {
|
||||
t.Helper()
|
||||
verifyCRDAccessForTests = &authorization.SubjectAccessReviewStatus{
|
||||
Allowed: true,
|
||||
}
|
||||
|
@ -66,7 +88,7 @@ func Test_Apply(t *testing.T) {
|
|||
c := kclient.NewFakeClient()
|
||||
|
||||
t.Run("Ensure", func(t *testing.T) {
|
||||
require.NoError(t, EnsureCRD(context.Background(), c, false))
|
||||
require.NoError(t, EnsureCRDWithOptions(context.Background(), c, EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts}))
|
||||
|
||||
for k, v := range dropLogMessages(t, s) {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
@ -92,7 +114,7 @@ func Test_Apply(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Ensure", func(t *testing.T) {
|
||||
require.NoError(t, EnsureCRD(context.Background(), c, false))
|
||||
require.NoError(t, EnsureCRDWithOptions(context.Background(), c, EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts}))
|
||||
|
||||
for k, v := range dropLogMessages(t, s) {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
@ -120,7 +142,7 @@ func Test_Apply(t *testing.T) {
|
|||
})
|
||||
|
||||
t.Run("Ensure", func(t *testing.T) {
|
||||
require.NoError(t, EnsureCRD(context.Background(), c, false))
|
||||
require.NoError(t, EnsureCRDWithOptions(context.Background(), c, EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts}))
|
||||
|
||||
for k, v := range dropLogMessages(t, s) {
|
||||
t.Run(k, func(t *testing.T) {
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.BackupsBackupDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.BackupsBackupDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.BackupsBackupPolicyDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.BackupsBackupPolicyDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.DatabaseClusterSynchronizationDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.DatabaseClusterSynchronizationDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.ReplicationDeploymentReplicationDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.ReplicationDeploymentReplicationDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.DatabaseDeploymentDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.DatabaseDeploymentDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.AppsJobDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.AppsJobDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -23,5 +23,7 @@ package crd
|
|||
import "github.com/arangodb/kube-arangodb/pkg/crd/crds"
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.StorageLocalStorageDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.StorageLocalStorageDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.DatabaseMemberDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.DatabaseMemberDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -25,8 +25,18 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.MLStorageDefinition())
|
||||
registerCRDWithPanic(crds.MLExtensionDefinition())
|
||||
registerCRDWithPanic(crds.MLCronJobDefinition())
|
||||
registerCRDWithPanic(crds.MLBatchJobDefinition())
|
||||
defs := []func(...func(options *crds.CRDOptions)) crds.Definition{
|
||||
crds.MLExtensionDefinitionWithOptions,
|
||||
crds.MLStorageDefinitionWithOptions,
|
||||
crds.MLCronJobDefinitionWithOptions,
|
||||
crds.MLBatchJobDefinitionWithOptions,
|
||||
}
|
||||
for _, getDef := range defs {
|
||||
defFn := getDef // bring into scope
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return defFn(opts.AsFunc())
|
||||
}, &crds.CRDOptions{
|
||||
WithSchema: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,5 +25,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
registerCRDWithPanic(crds.DatabaseTaskDefinition())
|
||||
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
|
||||
return crds.DatabaseTaskDefinitionWithOptions(opts.AsFunc())
|
||||
}, nil)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(appsJobs, &appsJobsCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(appsJobs, appsJobsSchemaRaw, &appsJobsCRD, &appsJobsCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use AppsJobWithOptions instead
|
||||
func AppsJob() *apiextensions.CustomResourceDefinition {
|
||||
return appsJobsCRD.DeepCopy()
|
||||
return AppsJobWithOptions()
|
||||
}
|
||||
|
||||
func AppsJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(appsJobsCRD, appsJobsCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use AppsJobDefinitionWithOptions instead
|
||||
func AppsJobDefinition() Definition {
|
||||
return AppsJobDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func AppsJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: AppsJobVersion,
|
||||
CRD: appsJobsCRD.DeepCopy(),
|
||||
CRD: AppsJobWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var appsJobsCRD apiextensions.CustomResourceDefinition
|
||||
var appsJobsCRDSchemas crdSchemas
|
||||
|
||||
//go:embed apps-job.yaml
|
||||
var appsJobs []byte
|
||||
|
||||
//go:embed apps-job.schema.generated.yaml
|
||||
var appsJobsSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(backupsBackup, &backupsBackupCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(backupsBackup, backupsBackupSchemaRaw, &backupsBackupCRD, &backupsBackupCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use BackupsBackupWithOptions instead
|
||||
func BackupsBackup() *apiextensions.CustomResourceDefinition {
|
||||
return backupsBackupCRD.DeepCopy()
|
||||
return BackupsBackupWithOptions()
|
||||
}
|
||||
|
||||
func BackupsBackupWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(backupsBackupCRD, backupsBackupCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use BackupsBackupDefinitionWithOptions instead
|
||||
func BackupsBackupDefinition() Definition {
|
||||
return BackupsBackupDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func BackupsBackupDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: BackupsBackupVersion,
|
||||
CRD: backupsBackupCRD.DeepCopy(),
|
||||
CRD: BackupsBackupWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var backupsBackupCRD apiextensions.CustomResourceDefinition
|
||||
var backupsBackupCRDSchemas crdSchemas
|
||||
|
||||
//go:embed backups-backup.yaml
|
||||
var backupsBackup []byte
|
||||
|
||||
//go:embed backups-backup.schema.generated.yaml
|
||||
var backupsBackupSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(backupsBackupPolicy, &backupsBackupPolicyCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(backupsBackupPolicy, backupsBackupPolicySchemaRaw, &backupsBackupPolicyCRD, &backupsBackupPolicyCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use BackupsBackupPolicyPolicyWithOptions instead
|
||||
func BackupsBackupPolicyPolicy() *apiextensions.CustomResourceDefinition {
|
||||
return backupsBackupPolicyCRD.DeepCopy()
|
||||
return BackupsBackupPolicyPolicyWithOptions()
|
||||
}
|
||||
|
||||
func BackupsBackupPolicyPolicyWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(backupsBackupPolicyCRD, backupsBackupPolicyCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use func BackupsBackupPolicyDefinitionWithOptions instead
|
||||
func BackupsBackupPolicyDefinition() Definition {
|
||||
return BackupsBackupPolicyDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func BackupsBackupPolicyDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: BackupsBackupPolicyPolicyVersion,
|
||||
CRD: backupsBackupPolicyCRD.DeepCopy(),
|
||||
CRD: BackupsBackupPolicyPolicyWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var backupsBackupPolicyCRD apiextensions.CustomResourceDefinition
|
||||
var backupsBackupPolicyCRDSchemas crdSchemas
|
||||
|
||||
//go:embed backups-backuppolicy.yaml
|
||||
var backupsBackupPolicy []byte
|
||||
|
||||
//go:embed backups-backuppolicy.schema.generated.yaml
|
||||
var backupsBackupPolicySchemaRaw []byte
|
||||
|
|
|
@ -21,7 +21,10 @@
|
|||
package crds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,31 +37,82 @@ type Definition struct {
|
|||
func AllDefinitions() []Definition {
|
||||
return []Definition{
|
||||
// Deployment
|
||||
DatabaseDeploymentDefinition(),
|
||||
DatabaseMemberDefinition(),
|
||||
DatabaseDeploymentDefinitionWithOptions(),
|
||||
DatabaseMemberDefinitionWithOptions(),
|
||||
|
||||
// ACS
|
||||
DatabaseClusterSynchronizationDefinition(),
|
||||
DatabaseClusterSynchronizationDefinitionWithOptions(),
|
||||
|
||||
// ArangoSync
|
||||
ReplicationDeploymentReplicationDefinition(),
|
||||
ReplicationDeploymentReplicationDefinitionWithOptions(),
|
||||
|
||||
// Storage
|
||||
StorageLocalStorageDefinition(),
|
||||
StorageLocalStorageDefinitionWithOptions(),
|
||||
|
||||
// Apps
|
||||
AppsJobDefinition(),
|
||||
DatabaseTaskDefinition(),
|
||||
AppsJobDefinitionWithOptions(),
|
||||
DatabaseTaskDefinitionWithOptions(),
|
||||
|
||||
// Backups
|
||||
BackupsBackupDefinition(),
|
||||
BackupsBackupPolicyDefinition(),
|
||||
BackupsBackupDefinitionWithOptions(),
|
||||
BackupsBackupPolicyDefinitionWithOptions(),
|
||||
|
||||
// ML
|
||||
MLExtensionDefinition(),
|
||||
MLStorageDefinition(),
|
||||
|
||||
MLCronJobDefinition(),
|
||||
MLBatchJobDefinition(),
|
||||
MLExtensionDefinitionWithOptions(),
|
||||
MLStorageDefinitionWithOptions(),
|
||||
MLCronJobDefinitionWithOptions(),
|
||||
MLBatchJobDefinitionWithOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
func mustLoadCRD(crdRaw, crdSchemasRaw []byte, crd *apiextensions.CustomResourceDefinition, schemas *crdSchemas) {
|
||||
if err := yaml.Unmarshal(crdRaw, crd); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := yaml.Unmarshal(crdSchemasRaw, schemas); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
type crdSchemas map[string]apiextensions.CustomResourceValidation
|
||||
|
||||
type CRDOptions struct {
|
||||
WithSchema bool
|
||||
}
|
||||
|
||||
func (o *CRDOptions) AsFunc() func(*CRDOptions) {
|
||||
return func(opts *CRDOptions) {
|
||||
if o == nil || opts == nil {
|
||||
opts = &CRDOptions{}
|
||||
} else {
|
||||
opts.WithSchema = o.WithSchema
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func WithSchema() func(*CRDOptions) {
|
||||
return func(o *CRDOptions) {
|
||||
o.WithSchema = true
|
||||
}
|
||||
}
|
||||
|
||||
func getCRD(crd apiextensions.CustomResourceDefinition, schemas crdSchemas, opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
o := &CRDOptions{}
|
||||
for _, fn := range opts {
|
||||
fn(o)
|
||||
}
|
||||
if o.WithSchema {
|
||||
crdWithSchema := crd.DeepCopy()
|
||||
for i, v := range crdWithSchema.Spec.Versions {
|
||||
schema, ok := schemas[v.Name]
|
||||
if !ok {
|
||||
panic(fmt.Sprintf("Validation schema is not defined for version %s of %s", v.Name, crd.Name))
|
||||
}
|
||||
crdWithSchema.Spec.Versions[i].Schema = schema.DeepCopy()
|
||||
}
|
||||
|
||||
return crdWithSchema
|
||||
}
|
||||
return crd.DeepCopy()
|
||||
}
|
||||
|
|
|
@ -21,9 +21,11 @@
|
|||
package crds
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/apps"
|
||||
"github.com/arangodb/kube-arangodb/pkg/apis/backup"
|
||||
|
@ -33,24 +35,93 @@ import (
|
|||
"github.com/arangodb/kube-arangodb/pkg/apis/storage"
|
||||
)
|
||||
|
||||
func ensureCRDCompliance(t *testing.T, name string, def Definition) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
require.Equal(t, name, def.CRD.GetName())
|
||||
})
|
||||
func ensureCRDCompliance(t *testing.T, name string, crdDef *apiextensions.CustomResourceDefinition, schemaExpected bool) {
|
||||
t.Helper()
|
||||
|
||||
require.NotNil(t, crdDef)
|
||||
require.Equal(t, name, crdDef.GetName())
|
||||
for _, version := range crdDef.Spec.Versions {
|
||||
t.Run(name+" "+version.Name, func(t *testing.T) {
|
||||
require.NotNil(t, version.Schema)
|
||||
require.Equal(t, "object", version.Schema.OpenAPIV3Schema.Type)
|
||||
require.NotNil(t, version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
|
||||
require.True(t, *version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
|
||||
if schemaExpected {
|
||||
require.NotEmpty(t, version.Schema.OpenAPIV3Schema.Properties)
|
||||
} else {
|
||||
require.Empty(t, version.Schema.OpenAPIV3Schema.Properties)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_CRD(t *testing.T) {
|
||||
ensureCRDCompliance(t, apps.ArangoJobCRDName, AppsJobDefinition())
|
||||
ensureCRDCompliance(t, backup.ArangoBackupCRDName, BackupsBackupDefinition())
|
||||
ensureCRDCompliance(t, backup.ArangoBackupPolicyCRDName, BackupsBackupPolicyDefinition())
|
||||
ensureCRDCompliance(t, deployment.ArangoClusterSynchronizationCRDName, DatabaseClusterSynchronizationDefinition())
|
||||
ensureCRDCompliance(t, deployment.ArangoDeploymentCRDName, DatabaseDeploymentDefinition())
|
||||
ensureCRDCompliance(t, deployment.ArangoMemberCRDName, DatabaseMemberDefinition())
|
||||
ensureCRDCompliance(t, deployment.ArangoTaskCRDName, DatabaseTaskDefinition())
|
||||
ensureCRDCompliance(t, replication.ArangoDeploymentReplicationCRDName, ReplicationDeploymentReplicationDefinition())
|
||||
ensureCRDCompliance(t, storage.ArangoLocalStorageCRDName, StorageLocalStorageDefinition())
|
||||
ensureCRDCompliance(t, ml.ArangoMLExtensionCRDName, MLExtensionDefinition())
|
||||
ensureCRDCompliance(t, ml.ArangoMLStorageCRDName, MLStorageDefinition())
|
||||
ensureCRDCompliance(t, ml.ArangoMLCronJobCRDName, MLCronJobDefinition())
|
||||
ensureCRDCompliance(t, ml.ArangoMLBatchJobCRDName, MLBatchJobDefinition())
|
||||
testCases := []struct {
|
||||
name string
|
||||
getter func(opts ...func(options *CRDOptions)) Definition
|
||||
}{
|
||||
{apps.ArangoJobCRDName, AppsJobDefinitionWithOptions},
|
||||
{backup.ArangoBackupCRDName, BackupsBackupDefinitionWithOptions},
|
||||
{backup.ArangoBackupPolicyCRDName, BackupsBackupPolicyDefinitionWithOptions},
|
||||
{deployment.ArangoClusterSynchronizationCRDName, DatabaseClusterSynchronizationDefinitionWithOptions},
|
||||
{deployment.ArangoDeploymentCRDName, DatabaseDeploymentDefinitionWithOptions},
|
||||
{deployment.ArangoMemberCRDName, DatabaseMemberDefinitionWithOptions},
|
||||
{deployment.ArangoTaskCRDName, DatabaseTaskDefinitionWithOptions},
|
||||
{replication.ArangoDeploymentReplicationCRDName, ReplicationDeploymentReplicationDefinitionWithOptions},
|
||||
{storage.ArangoLocalStorageCRDName, StorageLocalStorageDefinitionWithOptions},
|
||||
{ml.ArangoMLExtensionCRDName, MLExtensionDefinitionWithOptions},
|
||||
{ml.ArangoMLStorageCRDName, MLStorageDefinitionWithOptions},
|
||||
{ml.ArangoMLCronJobCRDName, MLCronJobDefinitionWithOptions},
|
||||
{ml.ArangoMLBatchJobCRDName, MLBatchJobDefinitionWithOptions},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(fmt.Sprintf("%s-no-schema", tc.name), func(t *testing.T) {
|
||||
ensureCRDCompliance(t, tc.name, tc.getter().CRD, false)
|
||||
})
|
||||
t.Run(fmt.Sprintf("%s-with-schema", tc.name), func(t *testing.T) {
|
||||
ensureCRDCompliance(t, tc.name, tc.getter(WithSchema()).CRD, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_AllDefinitionsDefined(t *testing.T) {
|
||||
for _, def := range AllDefinitions() {
|
||||
require.NotEmpty(t, def.Version)
|
||||
require.NotNil(t, def.CRD)
|
||||
}
|
||||
}
|
||||
|
||||
func Test_CRDGetters(t *testing.T) {
|
||||
// getters are exposed for the usage by customers
|
||||
getters := []func(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition{
|
||||
AppsJobWithOptions,
|
||||
BackupsBackupWithOptions,
|
||||
BackupsBackupPolicyPolicyWithOptions,
|
||||
DatabaseClusterSynchronizationWithOptions,
|
||||
DatabaseDeploymentWithOptions,
|
||||
DatabaseMemberWithOptions,
|
||||
DatabaseTaskWithOptions,
|
||||
MLExtensionWithOptions,
|
||||
MLBatchJobWithOptions,
|
||||
MLCronJobWithOptions,
|
||||
MLStorageWithOptions,
|
||||
ReplicationDeploymentReplicationWithOptions,
|
||||
StorageLocalStorageWithOptions,
|
||||
}
|
||||
require.Equal(t, len(AllDefinitions()), len(getters))
|
||||
|
||||
for _, g := range getters {
|
||||
t.Run("no-schema", func(t *testing.T) {
|
||||
crd := g()
|
||||
require.NotNil(t, crd)
|
||||
ensureCRDCompliance(t, crd.Spec.Names.Plural+"."+crd.Spec.Group, crd, false)
|
||||
})
|
||||
|
||||
t.Run("with-schema", func(t *testing.T) {
|
||||
crdWithSchema := g(WithSchema())
|
||||
require.NotNil(t, crdWithSchema)
|
||||
ensureCRDCompliance(t, crdWithSchema.Spec.Names.Plural+"."+crdWithSchema.Spec.Group+"", crdWithSchema, true)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(databaseClusterSynchronization, &databaseClusterSynchronizationCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(databaseClusterSynchronization, databaseClusterSynchronizationSchemaRaw, &databaseClusterSynchronizationCRD, &databaseClusterSynchronizationCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseClusterSynchronizationWithOptions instead
|
||||
func DatabaseClusterSynchronization() *apiextensions.CustomResourceDefinition {
|
||||
return databaseClusterSynchronizationCRD.DeepCopy()
|
||||
return DatabaseClusterSynchronizationWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseClusterSynchronizationWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(databaseClusterSynchronizationCRD, databaseClusterSynchronizationCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseClusterSynchronizationDefinitionWithOptions instead
|
||||
func DatabaseClusterSynchronizationDefinition() Definition {
|
||||
return DatabaseClusterSynchronizationDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseClusterSynchronizationDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: DatabaseClusterSynchronizationVersion,
|
||||
CRD: databaseClusterSynchronizationCRD.DeepCopy(),
|
||||
CRD: DatabaseClusterSynchronizationWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var databaseClusterSynchronizationCRD apiextensions.CustomResourceDefinition
|
||||
var databaseClusterSynchronizationCRDSchemas crdSchemas
|
||||
|
||||
//go:embed database-clustersynchronization.yaml
|
||||
var databaseClusterSynchronization []byte
|
||||
|
||||
//go:embed database-clustersynchronization.schema.generated.yaml
|
||||
var databaseClusterSynchronizationSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(databaseDeployment, &databaseDeploymentCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(databaseDeployment, databaseDeploymentSchemaRaw, &databaseDeploymentCRD, &databaseDeploymentCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseDeploymentWithOptions instead
|
||||
func DatabaseDeployment() *apiextensions.CustomResourceDefinition {
|
||||
return databaseDeploymentCRD.DeepCopy()
|
||||
return DatabaseDeploymentWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseDeploymentWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(databaseDeploymentCRD, databaseDeploymentCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseDeploymentDefinitionWithOptions instead
|
||||
func DatabaseDeploymentDefinition() Definition {
|
||||
return DatabaseDeploymentDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseDeploymentDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: DatabaseDeploymentVersion,
|
||||
CRD: databaseDeploymentCRD.DeepCopy(),
|
||||
CRD: DatabaseDeploymentWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var databaseDeploymentCRD apiextensions.CustomResourceDefinition
|
||||
var databaseDeploymentCRDSchemas crdSchemas
|
||||
|
||||
//go:embed database-deployment.yaml
|
||||
var databaseDeployment []byte
|
||||
|
||||
//go:embed database-deployment.schema.generated.yaml
|
||||
var databaseDeploymentSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(databaseMember, &databaseMemberCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(databaseMember, databaseMemberSchemaRaw, &databaseMemberCRD, &databaseMemberCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseMemberWithOptions instead
|
||||
func DatabaseMember() *apiextensions.CustomResourceDefinition {
|
||||
return databaseMemberCRD.DeepCopy()
|
||||
return DatabaseMemberWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseMemberWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(databaseMemberCRD, databaseMemberCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseMemberDefinitionWithOptions instead
|
||||
func DatabaseMemberDefinition() Definition {
|
||||
return DatabaseMemberDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseMemberDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: DatabaseMemberVersion,
|
||||
CRD: databaseMemberCRD.DeepCopy(),
|
||||
CRD: DatabaseMemberWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var databaseMemberCRD apiextensions.CustomResourceDefinition
|
||||
var databaseMemberCRDSchemas crdSchemas
|
||||
|
||||
//go:embed database-member.yaml
|
||||
var databaseMember []byte
|
||||
|
||||
//go:embed database-member.schema.generated.yaml
|
||||
var databaseMemberSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(databaseTask, &databaseTaskCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(databaseTask, databaseTaskSchemaRaw, &databaseTaskCRD, &databaseTaskCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseTaskWithOptions instead
|
||||
func DatabaseTask() *apiextensions.CustomResourceDefinition {
|
||||
return databaseTaskCRD.DeepCopy()
|
||||
return DatabaseTaskWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseTaskWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(databaseTaskCRD, databaseTaskCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use DatabaseTaskDefinitionWithOptions instead
|
||||
func DatabaseTaskDefinition() Definition {
|
||||
return DatabaseTaskDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func DatabaseTaskDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: DatabaseTaskVersion,
|
||||
CRD: databaseTaskCRD.DeepCopy(),
|
||||
CRD: DatabaseTaskWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var databaseTaskCRD apiextensions.CustomResourceDefinition
|
||||
var databaseTaskCRDSchemas crdSchemas
|
||||
|
||||
//go:embed database-task.yaml
|
||||
var databaseTask []byte
|
||||
|
||||
//go:embed database-task.schema.generated.yaml
|
||||
var databaseTaskSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,25 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(mlExtension, &mlExtensionCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(mlExtension, mlExtensionSchemaRaw, &mlExtensionCRD, &mlExtensionCRDSchemas)
|
||||
}
|
||||
|
||||
func MLExtension() *apiextensions.CustomResourceDefinition {
|
||||
return mlExtensionCRD.DeepCopy()
|
||||
func MLExtensionWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(mlExtensionCRD, mlExtensionCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
func MLExtensionDefinition() Definition {
|
||||
func MLExtensionDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: MLExtensionVersion,
|
||||
CRD: mlExtensionCRD.DeepCopy(),
|
||||
CRD: MLExtensionWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var mlExtensionCRD apiextensions.CustomResourceDefinition
|
||||
var mlExtensionCRDSchemas crdSchemas
|
||||
|
||||
//go:embed ml-extension.yaml
|
||||
var mlExtension []byte
|
||||
|
||||
//go:embed ml-extension.schema.generated.yaml
|
||||
var mlExtensionSchemaRaw []byte
|
||||
|
|
|
@ -37,20 +37,25 @@ func init() {
|
|||
if err := yaml.Unmarshal(mlBatchJob, &mlBatchJobCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(mlBatchJob, mlBatchJobSchemaRow, &mlBatchJobCRD, &mlBatchJobCRDSchemas)
|
||||
}
|
||||
|
||||
func MLBatchJob() *apiextensions.CustomResourceDefinition {
|
||||
return mlBatchJobCRD.DeepCopy()
|
||||
func MLBatchJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(mlBatchJobCRD, mlBatchJobCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
func MLBatchJobDefinition() Definition {
|
||||
func MLBatchJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: MLBatchJobVersion,
|
||||
CRD: mlBatchJobCRD.DeepCopy(),
|
||||
CRD: MLBatchJobWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var mlBatchJobCRD apiextensions.CustomResourceDefinition
|
||||
var mlBatchJobCRDSchemas crdSchemas
|
||||
|
||||
//go:embed ml-job-batch.yaml
|
||||
var mlBatchJob []byte
|
||||
|
||||
//go:embed ml-job-batch.schema.generated.yaml
|
||||
var mlBatchJobSchemaRow []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,25 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(mlCronJob, &mlCronJobCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(mlCronJob, mlCronJobSchemaRaw, &mlCronJobCRD, &mlCronJobCRDSchemas)
|
||||
}
|
||||
|
||||
func MLCronJob() *apiextensions.CustomResourceDefinition {
|
||||
return mlCronJobCRD.DeepCopy()
|
||||
func MLCronJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(mlCronJobCRD, mlCronJobCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
func MLCronJobDefinition() Definition {
|
||||
func MLCronJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: MLCronJobVersion,
|
||||
CRD: mlCronJobCRD.DeepCopy(),
|
||||
CRD: MLCronJobWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var mlCronJobCRD apiextensions.CustomResourceDefinition
|
||||
var mlCronJobCRDSchemas crdSchemas
|
||||
|
||||
//go:embed ml-job-cron.yaml
|
||||
var mlCronJob []byte
|
||||
|
||||
//go:embed ml-job-cron.schema.generated.yaml
|
||||
var mlCronJobSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,25 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(mlStorage, &mlStorageCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(mlStorage, mlStorageSchemaRaw, &mlStorageCRD, &mlStorageCRDSchemas)
|
||||
}
|
||||
|
||||
func MLStorage() *apiextensions.CustomResourceDefinition {
|
||||
return mlStorageCRD.DeepCopy()
|
||||
func MLStorageWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(mlStorageCRD, mlStorageCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
func MLStorageDefinition() Definition {
|
||||
func MLStorageDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: MLStorageVersion,
|
||||
CRD: mlStorageCRD.DeepCopy(),
|
||||
CRD: MLStorageWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var mlStorageCRD apiextensions.CustomResourceDefinition
|
||||
var mlStorageCRDSchemas crdSchemas
|
||||
|
||||
//go:embed ml-storage.yaml
|
||||
var mlStorage []byte
|
||||
|
||||
//go:embed ml-storage.schema.generated.yaml
|
||||
var mlStorageSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(replicationDeploymentReplication, &replicationDeploymentReplicationCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(replicationDeploymentReplication, replicationDeploymentReplicationSchemaRaw, &replicationDeploymentReplicationCRD, &replicationDeploymentReplicationCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use ReplicationDeploymentReplicationWithOptions instead
|
||||
func ReplicationDeploymentReplication() *apiextensions.CustomResourceDefinition {
|
||||
return replicationDeploymentReplicationCRD.DeepCopy()
|
||||
return ReplicationDeploymentReplicationWithOptions()
|
||||
}
|
||||
|
||||
func ReplicationDeploymentReplicationWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(replicationDeploymentReplicationCRD, replicationDeploymentReplicationCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use ReplicationDeploymentReplicationDefinitionWithOptions instead
|
||||
func ReplicationDeploymentReplicationDefinition() Definition {
|
||||
return ReplicationDeploymentReplicationDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func ReplicationDeploymentReplicationDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: ReplicationDeploymentReplicationVersion,
|
||||
CRD: replicationDeploymentReplicationCRD.DeepCopy(),
|
||||
CRD: ReplicationDeploymentReplicationWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var replicationDeploymentReplicationCRD apiextensions.CustomResourceDefinition
|
||||
var replicationDeploymentReplicationCRDSchemas crdSchemas
|
||||
|
||||
//go:embed replication-deploymentreplication.yaml
|
||||
var replicationDeploymentReplication []byte
|
||||
|
||||
//go:embed replication-deploymentreplication.schema.generated.yaml
|
||||
var replicationDeploymentReplicationSchemaRaw []byte
|
||||
|
|
|
@ -24,7 +24,6 @@ import (
|
|||
_ "embed"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
)
|
||||
|
@ -34,23 +33,35 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
if err := yaml.Unmarshal(storageLocalStorage, &storageLocalStorageCRD); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
mustLoadCRD(storageLocalStorage, storageLocalStorageSchemaRaw, &storageLocalStorageCRD, &storageLocalStorageCRDSchemas)
|
||||
}
|
||||
|
||||
// Deprecated: use StorageLocalStorageWithOptions instead
|
||||
func StorageLocalStorage() *apiextensions.CustomResourceDefinition {
|
||||
return storageLocalStorageCRD.DeepCopy()
|
||||
return StorageLocalStorageWithOptions()
|
||||
}
|
||||
|
||||
func StorageLocalStorageWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
|
||||
return getCRD(storageLocalStorageCRD, storageLocalStorageCRDSchemas, opts...)
|
||||
}
|
||||
|
||||
// Deprecated: use StorageLocalStorageDefinitionWithOptions instead
|
||||
func StorageLocalStorageDefinition() Definition {
|
||||
return StorageLocalStorageDefinitionWithOptions()
|
||||
}
|
||||
|
||||
func StorageLocalStorageDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
|
||||
return Definition{
|
||||
Version: StorageLocalStorageVersion,
|
||||
CRD: storageLocalStorageCRD.DeepCopy(),
|
||||
CRD: StorageLocalStorageWithOptions(opts...),
|
||||
}
|
||||
}
|
||||
|
||||
var storageLocalStorageCRD apiextensions.CustomResourceDefinition
|
||||
var storageLocalStorageCRDSchemas crdSchemas
|
||||
|
||||
//go:embed storage-localstorage.yaml
|
||||
var storageLocalStorage []byte
|
||||
|
||||
//go:embed storage-localstorage.schema.generated.yaml
|
||||
var storageLocalStorageSchemaRaw []byte
|
||||
|
|
|
@ -23,45 +23,54 @@ package crd
|
|||
import (
|
||||
"sync"
|
||||
|
||||
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||||
|
||||
"github.com/arangodb/go-driver"
|
||||
|
||||
"github.com/arangodb/kube-arangodb/pkg/crd/crds"
|
||||
"github.com/arangodb/kube-arangodb/pkg/util/errors"
|
||||
)
|
||||
|
||||
const Version = "arangodb.com/version"
|
||||
|
||||
type crdDefinitionGetter func(opts *crds.CRDOptions) crds.Definition
|
||||
|
||||
type crdRegistration struct {
|
||||
getter crdDefinitionGetter
|
||||
defaultOpts crds.CRDOptions
|
||||
}
|
||||
|
||||
var (
|
||||
registeredCRDs = map[string]crd{}
|
||||
registeredCRDs = map[string]crdRegistration{}
|
||||
|
||||
crdsLock sync.Mutex
|
||||
)
|
||||
|
||||
type crd struct {
|
||||
version driver.Version
|
||||
spec apiextensions.CustomResourceDefinitionSpec
|
||||
}
|
||||
|
||||
func registerCRDWithPanic(c crds.Definition) {
|
||||
if err := registerCRD(c.CRD.GetName(), crd{
|
||||
version: c.Version,
|
||||
spec: c.CRD.Spec,
|
||||
}); err != nil {
|
||||
func registerCRDWithPanic(getter crdDefinitionGetter, defaultOpts *crds.CRDOptions) {
|
||||
if defaultOpts == nil {
|
||||
defaultOpts = &crds.CRDOptions{}
|
||||
}
|
||||
if err := registerCRD(getter, *defaultOpts); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func registerCRD(name string, crd crd) error {
|
||||
func registerCRD(getter crdDefinitionGetter, defaultOpts crds.CRDOptions) error {
|
||||
crdsLock.Lock()
|
||||
defer crdsLock.Unlock()
|
||||
|
||||
if _, ok := registeredCRDs[name]; ok {
|
||||
return errors.Newf("CRD %s already exists", name)
|
||||
def := getter(nil)
|
||||
if _, ok := registeredCRDs[def.CRD.GetName()]; ok {
|
||||
return errors.Newf("CRD %s already exists", def.CRD.GetName())
|
||||
}
|
||||
registeredCRDs[def.CRD.GetName()] = crdRegistration{
|
||||
getter: getter,
|
||||
defaultOpts: defaultOpts,
|
||||
}
|
||||
|
||||
registeredCRDs[name] = crd
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetDefaultCRDOptions() map[string]crds.CRDOptions {
|
||||
ret := make(map[string]crds.CRDOptions)
|
||||
for n, s := range registeredCRDs {
|
||||
ret[n] = s.defaultOpts
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue