1
0
Fork 0
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:
Nikita Vaniasin 2023-11-15 10:20:18 +01:00 committed by GitHub
parent 934039fb41
commit 82cb7f1298
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 608 additions and 186 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)
}

View file

@ -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
View 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
```

View file

@ -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
View file

@ -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

View file

@ -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
}

View file

@ -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) {

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.BackupsBackupDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.BackupsBackupDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.BackupsBackupPolicyDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.BackupsBackupPolicyDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.DatabaseClusterSynchronizationDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.DatabaseClusterSynchronizationDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.ReplicationDeploymentReplicationDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.ReplicationDeploymentReplicationDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.DatabaseDeploymentDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.DatabaseDeploymentDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.AppsJobDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.AppsJobDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -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)
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.DatabaseMemberDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.DatabaseMemberDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -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,
})
}
}

View file

@ -25,5 +25,7 @@ import (
)
func init() {
registerCRDWithPanic(crds.DatabaseTaskDefinition())
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.DatabaseTaskDefinitionWithOptions(opts.AsFunc())
}, nil)
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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()
}

View file

@ -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)
})
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
}