1
0
Fork 0
mirror of https://github.com/arangodb/kube-arangodb.git synced 2024-12-14 11:57:37 +00:00

[Feature] Fix Group Schema Type (#1671)

This commit is contained in:
Adam Janikowski 2024-06-17 12:53:18 +02:00 committed by GitHub
parent 34228e9038
commit b67b93d3a4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 1411 additions and 4114 deletions

View file

@ -2,6 +2,7 @@
## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A) ## [master](https://github.com/arangodb/kube-arangodb/tree/master) (N/A)
- (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries - (Maintenance) Go 1.22.4 & Kubernetes 1.29.6 libraries
- (Feature) Fix CRD Schema types
## [1.2.41](https://github.com/arangodb/kube-arangodb/tree/1.2.41) (2024-05-24) ## [1.2.41](https://github.com/arangodb/kube-arangodb/tree/1.2.41) (2024-05-24)
- (Maintenance) Bump Prometheus API Version - (Maintenance) Bump Prometheus API Version

View file

@ -141,7 +141,8 @@ Flags:
--backup-concurrent-uploads int Number of concurrent uploads per deployment (default 4) --backup-concurrent-uploads int Number of concurrent uploads per deployment (default 4)
--chaos.allowed Set to allow chaos in deployments. Only activated when allowed and enabled in deployment --chaos.allowed Set to allow chaos in deployments. Only activated when allowed and enabled in deployment
--crd.install Install missing CRD if access is possible (default true) --crd.install Install missing CRD if access is possible (default true)
--crd.validation-schema stringArray Overrides default set of CRDs which should have validation schema enabled <crd-name>=<true/false>. --crd.preserve-unknown-fields stringArray Controls which CRD should have enabled preserve unknown fields in validation schema <crd-name>=<true/false>. To apply for all, use crd-name 'all'.
--crd.validation-schema stringArray Overrides default set of CRDs which should have validation schema enabled <crd-name>=<true/false>. To apply for all, use crd-name 'all'.
--deployment.feature.agency-poll Enable Agency Poll for Enterprise deployments - Required ArangoDB 3.8.0 or higher (default true) --deployment.feature.agency-poll Enable Agency Poll for Enterprise deployments - Required ArangoDB 3.8.0 or higher (default true)
--deployment.feature.all Enable ALL Features --deployment.feature.all Enable ALL Features
--deployment.feature.async-backup-creation Create backups asynchronously to avoid blocking the operator and reaching the timeout - Required ArangoDB 3.8.0 or higher (default true) --deployment.feature.async-backup-creation Create backups asynchronously to avoid blocking the operator and reaching the timeout - Required ArangoDB 3.8.0 or higher (default true)

View file

@ -136,8 +136,9 @@ var (
timeout time.Duration timeout time.Duration
} }
crdOptions struct { crdOptions struct {
install bool install bool
validationSchema []string preserveUnknownFields []string
validationSchema []string
} }
operatorKubernetesOptions struct { operatorKubernetesOptions struct {
maxBatchSize int64 maxBatchSize int64
@ -242,7 +243,8 @@ func init() {
f.Float32Var(&operatorKubernetesOptions.qps, "kubernetes.qps", kclient.DefaultQPS, "Number of queries per second for k8s API") 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.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.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.StringArrayVar(&crdOptions.preserveUnknownFields, "crd.preserve-unknown-fields", nil, "Controls which CRD should have enabled preserve unknown fields in validation schema <crd-name>=<true/false>. To apply for all, use crd-name 'all'.")
f.StringArrayVar(&crdOptions.validationSchema, "crd.validation-schema", defaultValidationSchemaEnabled, "Overrides default set of CRDs which should have validation schema enabled <crd-name>=<true/false>. To apply for all, use crd-name 'all'.")
f.IntVar(&operatorBackup.concurrentUploads, "backup-concurrent-uploads", globals.DefaultBackupConcurrentUploads, "Number of concurrent uploads per deployment") 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.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") f.StringArrayVar(&metricsOptions.excludedMetricPrefixes, "metrics.excluded-prefixes", nil, "List of the excluded metrics prefixes")
@ -389,7 +391,7 @@ func executeMain(cmd *cobra.Command, args []string) {
ctx, cancel := context.WithTimeout(shutdown.Context(), time.Minute) ctx, cancel := context.WithTimeout(shutdown.Context(), time.Minute)
defer cancel() defer cancel()
crdOpts, err := prepareCRDOptions(crdOptions.validationSchema) crdOpts, err := prepareCRDOptions(crdOptions.validationSchema, crdOptions.preserveUnknownFields)
if err != nil { if err != nil {
logger.Fatal("Invalid --crd.validation-schema args: %s", err) logger.Fatal("Invalid --crd.validation-schema args: %s", err)
} }

View file

@ -37,6 +37,10 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/shutdown" "github.com/arangodb/kube-arangodb/pkg/util/shutdown"
) )
const (
AllSchemasValue = "all"
)
var ( var (
cmdCRD = &cobra.Command{ cmdCRD = &cobra.Command{
Use: "crd", Use: "crd",
@ -48,12 +52,18 @@ var (
Run: cmdCRDInstallRun, Run: cmdCRDInstallRun,
Short: "Install and update all required CRDs", Short: "Install and update all required CRDs",
} }
cmdCRDGenerate = &cobra.Command{
Use: "generate",
Run: cmdCRDGenerateRun,
Short: "Generates YAML of all required CRDs",
}
) )
var ( var (
crdInstallOptions struct { crdInstallOptions struct {
validationSchema []string validationSchema []string
force bool preserveUnknownFields []string
force bool
} }
) )
@ -65,39 +75,107 @@ func init() {
cmdMain.AddCommand(cmdCRD) cmdMain.AddCommand(cmdCRD)
cmdOps.AddCommand(cmdCRD) cmdOps.AddCommand(cmdCRD)
f := cmdCRDInstall.Flags() f := cmdCRD.PersistentFlags()
f.StringArrayVar(&crdInstallOptions.validationSchema, "crd.validation-schema", defaultValidationSchemaEnabled, "Controls which CRD should have validation schema <crd-name>=<true/false>.") f.StringArrayVar(&crdInstallOptions.validationSchema, "crd.validation-schema", defaultValidationSchemaEnabled, "Controls which CRD should have validation schema <crd-name>=<true/false>.")
f.StringArrayVar(&crdInstallOptions.preserveUnknownFields, "crd.preserve-unknown-fields", nil, "Controls which CRD should have enabled preserve unknown fields in validation schema <crd-name>=<true/false>.")
f.BoolVar(&crdInstallOptions.force, "crd.force-update", false, "Enforce CRD Schema update") f.BoolVar(&crdInstallOptions.force, "crd.force-update", false, "Enforce CRD Schema update")
cmdCRD.AddCommand(cmdCRDInstall) cmdCRD.AddCommand(cmdCRDInstall)
cmdCRD.AddCommand(cmdCRDGenerate)
} }
func prepareCRDOptions(schemaEnabledArgs []string) (map[string]crds.CRDOptions, error) { func prepareCRDOptions(schemaEnabledArgs []string, preserveUnknownFieldsArgs []string) (map[string]crds.CRDOptions, error) {
defaultOptions := crd.GetDefaultCRDOptions() defaultOptions := crd.GetDefaultCRDOptions()
result := make(map[string]crds.CRDOptions)
var err error var err error
for _, arg := range schemaEnabledArgs {
parts := strings.Split(arg, "=")
crdName := parts[0] schemaEnabled := map[string]bool{}
opts, ok := defaultOptions[crdName] preserveUnknownFields := map[string]bool{}
if !ok {
return nil, fmt.Errorf("unknown CRD %s", crdName) for _, arg := range schemaEnabledArgs {
} parts := strings.SplitN(arg, "=", 2)
var enabled bool
if len(parts) == 2 { if len(parts) == 2 {
opts.WithSchema, err = strconv.ParseBool(parts[1]) enabled, err = strconv.ParseBool(parts[1])
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "not a bool value: %s", parts[1]) return nil, errors.Wrapf(err, "not a bool value: %s", parts[1])
} }
} }
result[crdName] = opts schemaEnabled[parts[0]] = enabled
} }
return result, nil
for _, arg := range preserveUnknownFieldsArgs {
parts := strings.SplitN(arg, "=", 2)
var enabled bool
if len(parts) == 2 {
enabled, err = strconv.ParseBool(parts[1])
if err != nil {
return nil, errors.Wrapf(err, "not a bool value: %s", parts[1])
}
}
preserveUnknownFields[parts[0]] = enabled
}
for k := range schemaEnabled {
if k == AllSchemasValue {
continue
}
if _, ok := defaultOptions[k]; !ok {
return nil, fmt.Errorf("unknown CRD %s", k)
}
}
for k := range preserveUnknownFields {
if k == AllSchemasValue {
continue
}
if _, ok := defaultOptions[k]; !ok {
return nil, fmt.Errorf("unknown CRD %s", k)
}
}
// Override the defaults
if v, ok := schemaEnabled[AllSchemasValue]; ok {
delete(preserveUnknownFields, AllSchemasValue)
for k := range defaultOptions {
z := defaultOptions[k]
z.WithSchema = v
defaultOptions[k] = z
}
}
if v, ok := preserveUnknownFields[AllSchemasValue]; ok {
delete(preserveUnknownFields, AllSchemasValue)
for k := range defaultOptions {
z := defaultOptions[k]
z.WithPreserve = v
defaultOptions[k] = z
}
}
// Set explicit words
for k, v := range schemaEnabled {
z := defaultOptions[k]
z.WithSchema = v
defaultOptions[k] = z
}
for k, v := range preserveUnknownFields {
z := defaultOptions[k]
z.WithPreserve = v
defaultOptions[k] = z
}
return defaultOptions, nil
} }
func cmdCRDInstallRun(cmd *cobra.Command, args []string) { func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
crdOpts, err := prepareCRDOptions(crdInstallOptions.validationSchema) crdOpts, err := prepareCRDOptions(crdInstallOptions.validationSchema, crdInstallOptions.preserveUnknownFields)
if err != nil { if err != nil {
logger.Fatal("Invalid --crd.validation-schema args: %s", err) logger.Fatal("Invalid --crd.validation-schema args: %s", err)
return return
@ -117,3 +195,16 @@ func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
os.Exit(1) os.Exit(1)
} }
} }
func cmdCRDGenerateRun(cmd *cobra.Command, args []string) {
crdOpts, err := prepareCRDOptions(crdInstallOptions.validationSchema, crdInstallOptions.preserveUnknownFields)
if err != nil {
logger.Fatal("Invalid --crd.validation-schema args: %s", err)
return
}
err = crd.GenerateCRDYAMLWithOptions(crd.EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts, ForceUpdate: crdInstallOptions.force}, cmd.OutOrStdout())
if err != nil {
os.Exit(1)
}
}

View file

@ -10,7 +10,7 @@ title: ArangoMember V1
### .spec.deletion_priority ### .spec.deletion_priority
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L47)</sup> Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L48)</sup>
DeletionPriority define Deletion Priority. DeletionPriority define Deletion Priority.
Higher value means higher priority. Default is 0. Higher value means higher priority. Default is 0.
@ -20,7 +20,7 @@ Example: set 1 for Coordinator which should be deleted first and scale down coor
### .spec.deploymentUID ### .spec.deploymentUID
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L36)</sup> Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L37)</sup>
DeploymentUID define Deployment UID. DeploymentUID define Deployment UID.
@ -28,7 +28,7 @@ DeploymentUID define Deployment UID.
### .spec.group ### .spec.group
Type: `integer` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L31)</sup> Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L32)</sup>
Group define Member Groups. Group define Member Groups.
@ -36,7 +36,7 @@ Group define Member Groups.
### .spec.id ### .spec.id
Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L33)</sup> Type: `string` <sup>[\[ref\]](https://github.com/arangodb/kube-arangodb/blob/1.2.41/pkg/apis/deployment/v1/arango_member_spec.go#L34)</sup>
*** ***

View file

@ -45,7 +45,6 @@ import (
schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1" schedulerApiv1alpha1 "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1alpha1"
schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1" schedulerApi "github.com/arangodb/kube-arangodb/pkg/apis/scheduler/v1beta1"
storagev1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha" storagev1alpha "github.com/arangodb/kube-arangodb/pkg/apis/storage/v1alpha"
"github.com/arangodb/kube-arangodb/pkg/util"
) )
func (def DocDefinition) ApplyToSchema(s *apiextensions.JSONSchemaProps) { func (def DocDefinition) ApplyToSchema(s *apiextensions.JSONSchemaProps) {
@ -65,7 +64,7 @@ func Test_GenerateCRValidationSchemas(t *testing.T) {
require.NotEmpty(t, root) require.NotEmpty(t, root)
type genSpec struct { type genSpec struct {
obj interface{} objects map[string]interface{}
} }
fset := token.NewFileSet() fset := token.NewFileSet()
@ -77,195 +76,280 @@ func Test_GenerateCRValidationSchemas(t *testing.T) {
"apps-job": { "apps-job": {
fmt.Sprintf("%s/pkg/apis/apps/v1", root): { fmt.Sprintf("%s/pkg/apis/apps/v1", root): {
"v1": { "v1": {
appsv1.ArangoJob{}.Spec, objects: map[string]interface{}{
"spec": appsv1.ArangoJob{}.Spec,
},
}, },
}, },
}, },
"backups-backup": { "backups-backup": {
fmt.Sprintf("%s/pkg/apis/backup/v1", root): { fmt.Sprintf("%s/pkg/apis/backup/v1", root): {
"v1": { "v1": {
backupv1.ArangoBackup{}.Spec, objects: map[string]interface{}{
"spec": backupv1.ArangoBackup{}.Spec,
},
}, },
"v1alpha": { "v1alpha": {
backupv1.ArangoBackup{}.Spec, objects: map[string]interface{}{
"spec": backupv1.ArangoBackup{}.Spec,
},
}, },
}, },
}, },
"backups-backuppolicy": { "backups-backuppolicy": {
fmt.Sprintf("%s/pkg/apis/backup/v1", root): { fmt.Sprintf("%s/pkg/apis/backup/v1", root): {
"v1": { "v1": {
backupv1.ArangoBackupPolicy{}.Spec, objects: map[string]interface{}{
"spec": backupv1.ArangoBackupPolicy{}.Spec,
},
}, },
"v1alpha": { "v1alpha": {
backupv1.ArangoBackupPolicy{}.Spec, objects: map[string]interface{}{
"spec": backupv1.ArangoBackupPolicy{}.Spec,
},
}, },
}, },
}, },
"database-deployment": { "database-deployment": {
fmt.Sprintf("%s/pkg/apis/deployment/v1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v1", root): {
"v1": { "v1": {
deploymentv1.ArangoDeployment{}.Spec, objects: map[string]interface{}{
"spec": deploymentv1.ArangoDeployment{}.Spec,
},
}, },
"v1alpha": { "v1alpha": {
deploymentv1.ArangoDeployment{}.Spec, objects: map[string]interface{}{
"spec": deploymentv1.ArangoDeployment{}.Spec,
},
}, },
}, },
fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): {
"v2alpha1": { "v2alpha1": {
deploymentv2alpha1.ArangoDeployment{}.Spec, objects: map[string]interface{}{
"spec": deploymentv2alpha1.ArangoDeployment{}.Spec,
},
}, },
}, },
}, },
"database-member": { "database-member": {
fmt.Sprintf("%s/pkg/apis/deployment/v1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v1", root): {
"v1": { "v1": {
deploymentv1.ArangoMember{}.Spec, objects: map[string]interface{}{
}, "spec": deploymentv1.ArangoMember{}.Spec,
"v1alpha": { },
deploymentv1.ArangoMember{}.Spec,
}, },
}, },
fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): {
"v2alpha1": { "v2alpha1": {
deploymentv2alpha1.ArangoMember{}.Spec, objects: map[string]interface{}{
"spec": deploymentv2alpha1.ArangoMember{}.Spec,
},
}, },
}, },
}, },
"database-clustersynchronization": { "database-clustersynchronization": {
fmt.Sprintf("%s/pkg/apis/deployment/v1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v1", root): {
"v1": { "v1": {
deploymentv1.ArangoClusterSynchronization{}.Spec, objects: map[string]interface{}{
}, "spec": deploymentv1.ArangoClusterSynchronization{}.Spec,
"v1alpha": { },
deploymentv1.ArangoClusterSynchronization{}.Spec,
}, },
}, },
fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): {
"v2alpha1": { "v2alpha1": {
deploymentv2alpha1.ArangoClusterSynchronization{}.Spec, objects: map[string]interface{}{
"spec": deploymentv2alpha1.ArangoClusterSynchronization{}.Spec,
},
}, },
}, },
}, },
"database-task": { "database-task": {
fmt.Sprintf("%s/pkg/apis/deployment/v1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v1", root): {
"v1": { "v1": {
deploymentv1.ArangoTask{}.Spec, objects: map[string]interface{}{
"spec": deploymentv1.ArangoTask{}.Spec,
},
}, },
"v1alpha": { "v1alpha": {
deploymentv1.ArangoTask{}.Spec, objects: map[string]interface{}{
"spec": deploymentv1.ArangoTask{}.Spec,
},
}, },
}, },
fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): { fmt.Sprintf("%s/pkg/apis/deployment/v2alpha1", root): {
"v2alpha1": { "v2alpha1": {
deploymentv2alpha1.ArangoTask{}.Spec, objects: map[string]interface{}{
"spec": deploymentv2alpha1.ArangoTask{}.Spec,
},
}, },
}, },
}, },
"replication-deploymentreplication": { "replication-deploymentreplication": {
fmt.Sprintf("%s/pkg/apis/replication/v1", root): { fmt.Sprintf("%s/pkg/apis/replication/v1", root): {
"v1": { "v1": {
replicationv1.ArangoDeploymentReplication{}.Spec, objects: map[string]interface{}{
"spec": replicationv1.ArangoDeploymentReplication{}.Spec,
},
}, },
"v1alpha": { "v1alpha": {
replicationv1.ArangoDeploymentReplication{}.Spec, objects: map[string]interface{}{
"spec": replicationv1.ArangoDeploymentReplication{}.Spec,
},
}, },
}, },
fmt.Sprintf("%s/pkg/apis/replication/v2alpha1", root): { fmt.Sprintf("%s/pkg/apis/replication/v2alpha1", root): {
"v2alpha1": { "v2alpha1": {
replicationv2alpha1.ArangoDeploymentReplication{}.Spec, objects: map[string]interface{}{
"spec": replicationv2alpha1.ArangoDeploymentReplication{}.Spec,
},
}, },
}, },
}, },
"storage-localstorage": { "storage-localstorage": {
fmt.Sprintf("%s/pkg/apis/storage/v1alpha", root): { fmt.Sprintf("%s/pkg/apis/storage/v1alpha", root): {
"v1alpha": { "v1alpha": {
storagev1alpha.ArangoLocalStorage{}.Spec, objects: map[string]interface{}{
"spec": storagev1alpha.ArangoLocalStorage{}.Spec,
},
}, },
}, },
}, },
"scheduler-profile": { "scheduler-profile": {
fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/scheduler/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
schedulerApiv1alpha1.ArangoProfile{}.Spec, objects: map[string]interface{}{
"spec": schedulerApiv1alpha1.ArangoProfile{}.Spec,
},
}, },
"v1beta1": { "v1beta1": {
schedulerApi.ArangoProfile{}.Spec, objects: map[string]interface{}{
"spec": schedulerApi.ArangoProfile{}.Spec,
},
}, },
}, },
}, },
"ml-extension": { "ml-extension": {
fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
mlApiv1alpha1.ArangoMLExtension{}.Spec, objects: map[string]interface{}{
"spec": mlApiv1alpha1.ArangoMLExtension{}.Spec,
},
}, },
"v1beta1": { "v1beta1": {
mlApi.ArangoMLExtension{}.Spec, objects: map[string]interface{}{
"spec": mlApi.ArangoMLExtension{}.Spec,
},
}, },
}, },
}, },
"ml-storage": { "ml-storage": {
fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
mlApiv1alpha1.ArangoMLStorage{}.Spec, objects: map[string]interface{}{
"spec": mlApiv1alpha1.ArangoMLStorage{}.Spec,
},
}, },
"v1beta1": { "v1beta1": {
mlApi.ArangoMLStorage{}.Spec, objects: map[string]interface{}{
"spec": mlApi.ArangoMLStorage{}.Spec,
},
}, },
}, },
}, },
"ml-job-cron": { "ml-job-cron": {
fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
mlApiv1alpha1.ArangoMLCronJob{}.Spec, objects: map[string]interface{}{
"spec": mlApiv1alpha1.ArangoMLCronJob{}.Spec,
},
}, },
}, },
}, },
"ml-job-batch": { "ml-job-batch": {
fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/ml/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
mlApiv1alpha1.ArangoMLBatchJob{}.Spec, objects: map[string]interface{}{
"spec": mlApiv1alpha1.ArangoMLBatchJob{}.Spec,
},
}, },
}, },
}, },
"analytics-graphanalyticsengine": { "analytics-graphanalyticsengine": {
fmt.Sprintf("%s/pkg/apis/analytics/v1alpha1", root): { fmt.Sprintf("%s/pkg/apis/analytics/v1alpha1", root): {
"v1alpha1": { "v1alpha1": {
analyticsApi.GraphAnalyticsEngine{}.Spec, objects: map[string]interface{}{
"spec": analyticsApi.GraphAnalyticsEngine{}.Spec,
},
}, },
}, },
}, },
} }
for filePrefix, packagesToVersion := range input { for filePrefix, packagesToVersion := range input {
validationPerVersion := make(map[string]apiextensions.CustomResourceValidation, len(packagesToVersion)) t.Run(filePrefix, func(t *testing.T) {
for apiDir, versionMap := range packagesToVersion { // Preload Definition
fields := parseSourceFiles(t, root, fset, apiDir) data, err := os.ReadFile(fmt.Sprintf("%s/pkg/crd/crds/%s.yaml", root, filePrefix))
require.NoError(t, err)
for n, f := range sharedFields { var crd apiextensions.CustomResourceDefinition
require.NotContains(t, fields, n)
fields[n] = f
}
for version, generationSpec := range versionMap { require.NoError(t, yaml.Unmarshal(data, &crd))
sb := newSchemaBuilder(root, fields, fset)
s := sb.TypeToSchema(t, reflect.TypeOf(generationSpec.obj), ".spec")
require.NotNil(t, s, version)
validationPerVersion[version] = apiextensions.CustomResourceValidation{ validationPerVersion := make(map[string]apiextensions.CustomResourceValidation, len(packagesToVersion))
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{ for apiDir, versionMap := range packagesToVersion {
Type: "object", fields := parseSourceFiles(t, root, fset, apiDir)
Properties: map[string]apiextensions.JSONSchemaProps{"spec": *s},
XPreserveUnknownFields: util.NewType(true), for n, f := range sharedFields {
}, require.NotContains(t, fields, n)
fields[n] = f
}
for version, generationSpec := range versionMap {
crdVersion := findCRDVersion(t, crd, version)
t.Log(crdVersion.Schema)
if _, ok := generationSpec.objects["status"]; !ok {
generationSpec.objects["status"] = allowAnyType{}
}
sb := newSchemaBuilder(root, fields, fset)
objects := map[string]apiextensions.JSONSchemaProps{}
for k, obj := range generationSpec.objects {
s := sb.TypeToSchema(t, reflect.TypeOf(obj), fmt.Sprintf(".%s", k))
require.NotNil(t, s, version)
objects[k] = *s
}
validationPerVersion[version] = apiextensions.CustomResourceValidation{
OpenAPIV3Schema: &apiextensions.JSONSchemaProps{
Type: "object",
Properties: objects,
},
}
} }
} }
}
yamlRaw, err := yaml.Marshal(validationPerVersion) yamlRaw, err := yaml.Marshal(validationPerVersion)
require.NoError(t, err) require.NoError(t, err)
outPath := path.Join(root, "pkg/crd/crds", fmt.Sprintf("%s.schema.generated.yaml", filePrefix)) outPath := path.Join(root, "pkg/crd/crds", fmt.Sprintf("%s.schema.generated.yaml", filePrefix))
err = os.WriteFile(outPath, yamlRaw, 0644) err = os.WriteFile(outPath, yamlRaw, 0644)
require.NoError(t, err) require.NoError(t, err)
})
} }
} }
func findCRDVersion(t *testing.T, crd apiextensions.CustomResourceDefinition, version string) apiextensions.CustomResourceDefinitionVersion {
for _, v := range crd.Spec.Versions {
if v.Name == version {
return v
}
}
require.FailNowf(t, "Unable to find version", "Trying to find %s/%s", crd.GetName(), version)
return apiextensions.CustomResourceDefinitionVersion{}
}

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2023 ArangoDB GmbH, Cologne, Germany // Copyright 2023-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -30,6 +30,8 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
openapi "k8s.io/kube-openapi/pkg/common" openapi "k8s.io/kube-openapi/pkg/common"
"github.com/arangodb/kube-arangodb/pkg/util"
) )
type schemaBuilder struct { type schemaBuilder struct {
@ -38,6 +40,8 @@ type schemaBuilder struct {
fs *token.FileSet fs *token.FileSet
} }
type allowAnyType struct{}
func newSchemaBuilder(root string, fields map[string]*ast.Field, fs *token.FileSet) *schemaBuilder { func newSchemaBuilder(root string, fields map[string]*ast.Field, fs *token.FileSet) *schemaBuilder {
return &schemaBuilder{ return &schemaBuilder{
root: root, root: root,
@ -54,6 +58,14 @@ func (b *schemaBuilder) tryGetKubeOpenAPIDefinitions(t *testing.T, obj reflect.T
return b.openAPIDefToSchemaPros(t, o.OpenAPIDefinition()) return b.openAPIDefToSchemaPros(t, o.OpenAPIDefinition())
} }
if obj := b.tryGetKubeOpenAPIV2Definitions(t, reflect.New(obj).Interface()); obj != nil {
return obj
}
return nil
}
func (b *schemaBuilder) tryGetKubeOpenAPIV2Definitions(t *testing.T, obj interface{}) *apiextensions.JSONSchemaProps {
type openAPISchemaTypeGetter interface { type openAPISchemaTypeGetter interface {
OpenAPISchemaType() []string OpenAPISchemaType() []string
} }
@ -61,15 +73,23 @@ func (b *schemaBuilder) tryGetKubeOpenAPIDefinitions(t *testing.T, obj reflect.T
OpenAPISchemaFormat() string OpenAPISchemaFormat() string
} }
var typ, frmt string var typ, frmt string
if o, ok := reflect.New(obj).Interface().(openAPISchemaTypeGetter); ok { if o, ok := obj.(openAPISchemaTypeGetter); ok {
strs := o.OpenAPISchemaType() strs := o.OpenAPISchemaType()
require.Len(t, strs, 1) require.Len(t, strs, 1)
typ = strs[0] typ = strs[0]
} }
if o, ok := reflect.New(obj).Interface().(openAPISchemaFormatGetter); ok { if o, ok := obj.(openAPISchemaFormatGetter); ok {
frmt = o.OpenAPISchemaFormat() frmt = o.OpenAPISchemaFormat()
} }
if typ != "" || frmt != "" { if typ != "" || frmt != "" {
if frmt == "int-or-string" && typ == "string" {
return &apiextensions.JSONSchemaProps{
Type: typ,
XIntOrString: true,
}
}
return &apiextensions.JSONSchemaProps{ return &apiextensions.JSONSchemaProps{
Type: typ, Type: typ,
Format: frmt, Format: frmt,
@ -83,37 +103,42 @@ func (b *schemaBuilder) openAPIDefToSchemaPros(t *testing.T, _ *openapi.OpenAPID
return nil return nil
} }
func (b *schemaBuilder) TypeToSchema(t *testing.T, obj reflect.Type, path string) *apiextensions.JSONSchemaProps { func (b *schemaBuilder) TypeToSchema(t *testing.T, obj reflect.Type, path string) (schema *apiextensions.JSONSchemaProps) {
var schema *apiextensions.JSONSchemaProps // first check if type already implements a method to get OpenAPI schema:
t.Run(obj.Name(), func(t *testing.T) { schema = b.tryGetKubeOpenAPIDefinitions(t, obj)
// first check if type already implements a method to get OpenAPI schema: if schema != nil {
schema = b.tryGetKubeOpenAPIDefinitions(t, obj) return
if schema != nil { }
// fallback to our impl:
switch obj.Kind() {
case reflect.Pointer:
schema = b.TypeToSchema(t, obj.Elem(), path)
case reflect.Struct:
if obj == reflect.TypeOf(allowAnyType{}) || obj == reflect.TypeOf(&allowAnyType{}) {
schema = &apiextensions.JSONSchemaProps{
Type: "object",
Description: "Object with preserved fields for backward compatibility",
XPreserveUnknownFields: util.NewType(true),
}
return return
} }
schema = b.StructToSchema(t, obj, path)
// fallback to our impl: case reflect.Array, reflect.Slice:
switch obj.Kind() { schema = b.ArrayToSchema(t, obj.Elem(), path)
case reflect.Pointer: case reflect.Map:
schema = b.TypeToSchema(t, obj.Elem(), path) schema = b.MapToSchema(t, obj, path)
case reflect.Struct: default:
schema = b.StructToSchema(t, obj, path) if typ, frmt, simple := isSimpleType(obj); simple {
case reflect.Array, reflect.Slice: schema = &apiextensions.JSONSchemaProps{
schema = b.ArrayToSchema(t, obj.Elem(), path) Type: typ,
case reflect.Map: Format: frmt,
schema = b.MapToSchema(t, obj, path)
default:
if typ, frmt, simple := isSimpleType(obj); simple {
schema = &apiextensions.JSONSchemaProps{
Type: typ,
Format: frmt,
}
} else {
t.Fatalf("Unsupported obj kind: %s", obj.Kind())
return
} }
} else {
t.Fatalf("Unsupported obj kind: %s", obj.Kind())
return
} }
}) }
return schema return schema
} }

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import (
type ArangoMemberSpec struct { type ArangoMemberSpec struct {
// Group define Member Groups. // Group define Member Groups.
// +doc/type: string
Group ServerGroup `json:"group,omitempty"` Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -39,6 +39,12 @@ func (s ServerGroups) Contains(group ServerGroup) bool {
type ServerGroup int type ServerGroup int
func (g *ServerGroup) OpenAPISchemaType() []string {
return []string{
"string",
}
}
func (g *ServerGroup) UnmarshalJSON(bytes []byte) error { func (g *ServerGroup) UnmarshalJSON(bytes []byte) error {
if bytes == nil { if bytes == nil {
*g = ServerGroupUnknown *g = ServerGroupUnknown

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -28,6 +28,7 @@ import (
type ArangoMemberSpec struct { type ArangoMemberSpec struct {
// Group define Member Groups. // Group define Member Groups.
// +doc/type: string
Group ServerGroup `json:"group,omitempty"` Group ServerGroup `json:"group,omitempty"`
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2022 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -39,6 +39,12 @@ func (s ServerGroups) Contains(group ServerGroup) bool {
type ServerGroup int type ServerGroup int
func (g *ServerGroup) OpenAPISchemaType() []string {
return []string{
"string",
}
}
func (g *ServerGroup) UnmarshalJSON(bytes []byte) error { func (g *ServerGroup) UnmarshalJSON(bytes []byte) error {
if bytes == nil { if bytes == nil {
*g = ServerGroupUnknown *g = ServerGroupUnknown

View file

@ -22,14 +22,19 @@ package crd
import ( import (
"context" "context"
"io"
"sort"
"strconv"
authorization "k8s.io/api/authorization/v1" authorization "k8s.io/api/authorization/v1"
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/apis/meta/v1" meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
"github.com/arangodb/kube-arangodb/pkg/crd/crds" "github.com/arangodb/kube-arangodb/pkg/crd/crds"
"github.com/arangodb/kube-arangodb/pkg/logging" "github.com/arangodb/kube-arangodb/pkg/logging"
"github.com/arangodb/kube-arangodb/pkg/util"
kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources" kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
"github.com/arangodb/kube-arangodb/pkg/util/kclient" "github.com/arangodb/kube-arangodb/pkg/util/kclient"
) )
@ -57,6 +62,7 @@ func EnsureCRDWithOptions(ctx context.Context, client kclient.Client, opts Ensur
defer crdsLock.Unlock() defer crdsLock.Unlock()
for crdName, crdReg := range registeredCRDs { for crdName, crdReg := range registeredCRDs {
getAccess := verifyCRDAccess(ctx, client, crdName, "get") getAccess := verifyCRDAccess(ctx, client, crdName, "get")
if !getAccess.Allowed { if !getAccess.Allowed {
logger.Str("crd", crdName).Info("Get Operations is not allowed. Continue") logger.Str("crd", crdName).Info("Get Operations is not allowed. Continue")
@ -77,6 +83,90 @@ func EnsureCRDWithOptions(ctx context.Context, client kclient.Client, opts Ensur
return nil return nil
} }
func GenerateCRDYAMLWithOptions(opts EnsureCRDOptions, out io.Writer) error {
crds := GenerateCRDWithOptions(opts)
for id, crd := range crds {
obj := map[string]interface{}{
"apiVersion": "apiextensions.k8s.io/v1",
"kind": "CustomResourceDefinition",
"metadata": map[string]interface{}{
"labels": crd.Labels,
"name": crd.Name,
},
"spec": crd.Spec,
}
data, err := yaml.Marshal(obj)
if err != nil {
return err
}
if id > 0 {
_, err = util.WriteAll(out, []byte("\n\n---\n\n"))
if err != nil {
return err
}
}
_, err = util.WriteAll(out, data)
if err != nil {
return err
}
}
return nil
}
func GenerateCRDWithOptions(opts EnsureCRDOptions) []apiextensions.CustomResourceDefinition {
crdsLock.Lock()
defer crdsLock.Unlock()
ret := make([]apiextensions.CustomResourceDefinition, 0, len(registeredCRDs))
for crdName, crdReg := range registeredCRDs {
var opt = &crdReg.defaultOpts
if o, ok := opts.CRDOptions[crdName]; ok {
opt = &o
}
def := crdReg.getter(opt)
ret = append(ret, *renderCRD(def, opt))
}
sort.Slice(ret, func(i, j int) bool {
return ret[i].GetName() < ret[j].GetName()
})
return ret
}
func renderCRD(def crds.Definition, opts *crds.CRDOptions) *apiextensions.CustomResourceDefinition {
crdName := def.CRD.Name
definitionVersion, definitionSchemaVersion := def.DefinitionData.Checksum()
schema := opts.GetWithSchema()
preserve := !schema || opts.GetWithPreserve()
c := &apiextensions.CustomResourceDefinition{
ObjectMeta: meta.ObjectMeta{
Name: crdName,
Labels: map[string]string{
Version: definitionVersion,
PreserveUnknownFields: strconv.FormatBool(preserve),
},
},
Spec: def.CRD.Spec,
}
if schema {
c.Labels[Schema] = definitionSchemaVersion
}
return c
}
func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition, opts *crds.CRDOptions, forceUpdate bool) error { func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition, opts *crds.CRDOptions, forceUpdate bool) error {
crdDefinitions := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions() crdDefinitions := client.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions()
@ -86,10 +176,15 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition
logger := logger.Str("version", definitionVersion) logger := logger.Str("version", definitionVersion)
if opts.GetWithSchema() { schema := opts.GetWithSchema()
preserve := !schema || opts.GetWithPreserve()
if schema {
logger = logger.Str("schema", definitionSchemaVersion) logger = logger.Str("schema", definitionSchemaVersion)
} }
logger = logger.Bool("preserve", preserve)
c, err := crdDefinitions.Get(ctx, crdName, meta.GetOptions{}) c, err := crdDefinitions.Get(ctx, crdName, meta.GetOptions{})
if err != nil { if err != nil {
if !errors.IsNotFound(err) { if !errors.IsNotFound(err) {
@ -104,19 +199,7 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition
return nil return nil
} }
c = &apiextensions.CustomResourceDefinition{ c = renderCRD(def, opts)
ObjectMeta: meta.ObjectMeta{
Name: crdName,
Labels: map[string]string{
Version: definitionVersion,
},
},
Spec: def.CRD.Spec,
}
if opts.GetWithSchema() {
c.Labels[Schema] = definitionSchemaVersion
}
if _, err := crdDefinitions.Create(ctx, c, meta.CreateOptions{}); err != nil { if _, err := crdDefinitions.Create(ctx, c, meta.CreateOptions{}); err != nil {
logger.Err(err).Str("crd", crdName).Warn("Create Operations is not allowed due to error") logger.Err(err).Str("crd", crdName).Warn("Create Operations is not allowed due to error")
@ -133,24 +216,27 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition
return nil return nil
} }
if c.ObjectMeta.Labels == nil { if c.Labels == nil {
c.ObjectMeta.Labels = map[string]string{} c.Labels = map[string]string{}
} }
if !forceUpdate { if !forceUpdate {
if v, ok := c.ObjectMeta.Labels[Version]; ok && v == definitionVersion { if v, ok := c.Labels[Version]; ok && v == definitionVersion {
if v, ok := c.ObjectMeta.Labels[Schema]; (opts.GetWithSchema() && (ok && v == definitionSchemaVersion)) || (!opts.GetWithSchema() && !ok) { if v, ok := c.Labels[Schema]; (schema && (ok && v == definitionSchemaVersion)) || (!schema && !ok) {
logger.Str("crd", crdName).Info("CRD Update not required") if v, ok := c.Labels[PreserveUnknownFields]; (preserve && ok && v == "true") || (!preserve && (!ok || v != "true")) {
return nil logger.Str("crd", crdName).Info("CRD Update not required")
return nil
}
} }
} }
} }
c.ObjectMeta.Labels[Version] = definitionVersion c.Labels[Version] = definitionVersion
delete(c.ObjectMeta.Labels, Schema) delete(c.Labels, Schema)
if opts.GetWithSchema() { if schema {
c.ObjectMeta.Labels[Schema] = definitionSchemaVersion c.Labels[Schema] = definitionSchemaVersion
} }
c.Labels[PreserveUnknownFields] = strconv.FormatBool(preserve)
c.Spec = def.CRD.Spec c.Spec = def.CRD.Spec
if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil { if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil {

View file

@ -40,13 +40,19 @@ func dropLogMessages(t *testing.T, s tests.LogScanner) map[string]string {
lines := map[string]string{} lines := map[string]string{}
for i := 0; i < len(crds.AllDefinitions()); i++ { for i := 0; i < len(crds.AllDefinitions()); i++ {
var data map[string]string var data map[string]interface{}
require.True(t, s.GetData(t, 500*time.Millisecond, &data)) require.True(t, s.GetData(t, 500*time.Millisecond, &data))
p, ok := data["crd"] pr, ok := data["crd"]
require.True(t, ok) require.True(t, ok)
m, ok := data["message"] p, ok := pr.(string)
require.True(t, ok)
mr, ok := data["message"]
require.True(t, ok)
m, ok := mr.(string)
require.True(t, ok) require.True(t, ok)
lines[p] = m lines[p] = m

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -36,7 +36,8 @@ func init() {
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return defFn(opts.AsFunc()) return defFn(opts.AsFunc())
}, &crds.CRDOptions{ }, &crds.CRDOptions{
WithSchema: true, WithSchema: true,
WithPreserve: false,
}) })
} }
} }

View file

@ -27,5 +27,8 @@ import (
func init() { func init() {
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.SchedulerProfileDefinitionWithOptions(opts.AsFunc()) return crds.SchedulerProfileDefinitionWithOptions(opts.AsFunc())
}, nil) }, &crds.CRDOptions{
WithSchema: true,
WithPreserve: false,
})
} }

View file

@ -1,7 +1,7 @@
// //
// DISCLAIMER // DISCLAIMER
// //
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany // Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -27,5 +27,8 @@ import (
func init() { func init() {
registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition { registerCRDWithPanic(func(opts *crds.CRDOptions) crds.Definition {
return crds.DatabaseTaskDefinitionWithOptions(opts.AsFunc()) return crds.DatabaseTaskDefinitionWithOptions(opts.AsFunc())
}, nil) }, &crds.CRDOptions{
WithSchema: true,
WithPreserve: false,
})
} }

View file

@ -463,8 +463,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -479,8 +479,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -508,8 +508,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -524,8 +524,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -565,8 +565,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -584,8 +584,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -731,8 +731,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -750,8 +750,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -892,8 +892,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -911,8 +911,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1764,8 +1764,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1780,8 +1780,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1809,8 +1809,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1825,8 +1825,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1869,8 +1869,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1888,8 +1888,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1951,8 +1951,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1970,8 +1970,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2093,8 +2093,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2112,8 +2112,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2143,5 +2143,8 @@ v1alpha1:
type: string type: string
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -611,8 +611,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -627,8 +627,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -656,8 +656,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -672,8 +672,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -713,8 +713,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -732,8 +732,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -797,8 +797,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -816,8 +816,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -950,8 +950,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -969,8 +969,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1152,8 +1152,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1168,8 +1168,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1197,8 +1197,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1213,8 +1213,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1254,8 +1254,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1273,8 +1273,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1338,8 +1338,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1357,8 +1357,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1491,8 +1491,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1510,8 +1510,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1699,8 +1699,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1715,8 +1715,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1744,8 +1744,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1760,8 +1760,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1801,8 +1801,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1820,8 +1820,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1885,8 +1885,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1904,8 +1904,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2038,8 +2038,8 @@ v1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2057,8 +2057,8 @@ v1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2981,5 +2981,8 @@ v1:
type: integer type: integer
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -86,8 +86,11 @@ v1:
type: string type: string
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1alpha: v1alpha:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -176,5 +179,8 @@ v1alpha:
type: string type: string
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -92,8 +92,11 @@ v1:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1alpha: v1alpha:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -188,5 +191,8 @@ v1alpha:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -95,8 +95,16 @@ func AllDefinitions() []Definition {
type crdSchemas map[string]apiextensions.CustomResourceValidation type crdSchemas map[string]apiextensions.CustomResourceValidation
func DefaultCRDOptions() *CRDOptions {
return &CRDOptions{
WithSchema: false,
WithPreserve: true,
}
}
type CRDOptions struct { type CRDOptions struct {
WithSchema bool WithSchema bool
WithPreserve bool
} }
func (o *CRDOptions) GetWithSchema() bool { func (o *CRDOptions) GetWithSchema() bool {
@ -107,12 +115,26 @@ func (o *CRDOptions) GetWithSchema() bool {
return o.WithSchema return o.WithSchema
} }
func (o *CRDOptions) GetWithPreserve() bool {
if o == nil {
return false
}
return o.WithPreserve
}
func (o *CRDOptions) AsFunc() func(*CRDOptions) { func (o *CRDOptions) AsFunc() func(*CRDOptions) {
return func(opts *CRDOptions) { return func(opts *CRDOptions) {
if o == nil || opts == nil { if opts == nil {
opts = &CRDOptions{} return
} else { }
opts.WithSchema = o.WithSchema
if o != nil {
opts.WithSchema = o.GetWithSchema()
}
if o != nil {
opts.WithPreserve = o.GetWithPreserve()
} }
} }
} }
@ -123,8 +145,26 @@ func WithSchema() func(*CRDOptions) {
} }
} }
func WithoutSchema() func(*CRDOptions) {
return func(o *CRDOptions) {
o.WithSchema = false
}
}
func WithPreserve() func(*CRDOptions) {
return func(o *CRDOptions) {
o.WithPreserve = true
}
}
func WithoutPreserve() func(*CRDOptions) {
return func(o *CRDOptions) {
o.WithPreserve = false
}
}
func getCRD(data DefinitionData, opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition { func getCRD(data DefinitionData, opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
o := &CRDOptions{} o := DefaultCRDOptions()
for _, fn := range opts { for _, fn := range opts {
fn(o) fn(o)
} }
@ -142,6 +182,11 @@ func getCRD(data DefinitionData, opts ...func(*CRDOptions)) *apiextensions.Custo
panic(fmt.Sprintf("Validation schema is not defined for version %s of %s", v.Name, crd.Name)) panic(fmt.Sprintf("Validation schema is not defined for version %s of %s", v.Name, crd.Name))
} }
crdWithSchema.Spec.Versions[i].Schema = schema.DeepCopy() crdWithSchema.Spec.Versions[i].Schema = schema.DeepCopy()
if s := crdWithSchema.Spec.Versions[i].Schema.OpenAPIV3Schema; s != nil {
if o.GetWithPreserve() {
s.XPreserveUnknownFields = util.NewType(true)
}
}
} }
return crdWithSchema return crdWithSchema

View file

@ -36,7 +36,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/apis/storage" "github.com/arangodb/kube-arangodb/pkg/apis/storage"
) )
func ensureCRDCompliance(t *testing.T, name string, crdDef *apiextensions.CustomResourceDefinition, schemaExpected bool) { func ensureCRDCompliance(t *testing.T, name string, crdDef *apiextensions.CustomResourceDefinition, schemaExpected, preserveExpected bool) {
t.Helper() t.Helper()
require.NotNil(t, crdDef) require.NotNil(t, crdDef)
@ -45,8 +45,25 @@ func ensureCRDCompliance(t *testing.T, name string, crdDef *apiextensions.Custom
t.Run(name+" "+version.Name, func(t *testing.T) { t.Run(name+" "+version.Name, func(t *testing.T) {
require.NotNil(t, version.Schema) require.NotNil(t, version.Schema)
require.Equal(t, "object", version.Schema.OpenAPIV3Schema.Type) require.Equal(t, "object", version.Schema.OpenAPIV3Schema.Type)
require.NotNil(t, version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
require.True(t, *version.Schema.OpenAPIV3Schema.XPreserveUnknownFields) if preserveExpected {
require.NotNil(t, version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
require.True(t, *version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
} else {
require.Nil(t, version.Schema.OpenAPIV3Schema.XPreserveUnknownFields)
if version.Subresources != nil {
if version.Subresources.Status != nil {
t.Run("Status", func(t *testing.T) {
require.Contains(t, version.Schema.OpenAPIV3Schema.Properties, "status")
status := version.Schema.OpenAPIV3Schema.Properties["status"]
require.NotNil(t, status.XPreserveUnknownFields)
require.True(t, *status.XPreserveUnknownFields)
})
}
}
}
if schemaExpected { if schemaExpected {
require.NotEmpty(t, version.Schema.OpenAPIV3Schema.Properties) require.NotEmpty(t, version.Schema.OpenAPIV3Schema.Properties)
} else { } else {
@ -79,10 +96,13 @@ func Test_CRD(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(fmt.Sprintf("%s-no-schema", tc.name), func(t *testing.T) { t.Run(fmt.Sprintf("%s-no-schema", tc.name), func(t *testing.T) {
ensureCRDCompliance(t, tc.name, tc.getter().CRD, false) ensureCRDCompliance(t, tc.name, tc.getter().CRD, false, true)
}) })
t.Run(fmt.Sprintf("%s-with-schema", tc.name), func(t *testing.T) { t.Run(fmt.Sprintf("%s-with-schema", tc.name), func(t *testing.T) {
ensureCRDCompliance(t, tc.name, tc.getter(WithSchema()).CRD, true) ensureCRDCompliance(t, tc.name, tc.getter(WithSchema()).CRD, true, true)
})
t.Run(fmt.Sprintf("%s-with-schema-np", tc.name), func(t *testing.T) {
ensureCRDCompliance(t, tc.name, tc.getter(WithSchema(), WithoutPreserve()).CRD, true, false)
}) })
} }
} }
@ -131,13 +151,13 @@ func Test_CRDGetters(t *testing.T) {
t.Run("no-schema", func(t *testing.T) { t.Run("no-schema", func(t *testing.T) {
crd := g() crd := g()
require.NotNil(t, crd) require.NotNil(t, crd)
ensureCRDCompliance(t, crd.Spec.Names.Plural+"."+crd.Spec.Group, crd, false) ensureCRDCompliance(t, crd.Spec.Names.Plural+"."+crd.Spec.Group, crd, false, true)
}) })
t.Run("with-schema", func(t *testing.T) { t.Run("with-schema", func(t *testing.T) {
crdWithSchema := g(WithSchema()) crdWithSchema := g(WithSchema())
require.NotNil(t, crdWithSchema) require.NotNil(t, crdWithSchema)
ensureCRDCompliance(t, crdWithSchema.Spec.Names.Plural+"."+crdWithSchema.Spec.Group+"", crdWithSchema, true) ensureCRDCompliance(t, crdWithSchema.Spec.Names.Plural+"."+crdWithSchema.Spec.Group+"", crdWithSchema, true, true)
}) })
} }
} }

View file

@ -15,27 +15,11 @@ v1:
type: string type: string
type: object type: object
type: object type: object
type: object status:
x-kubernetes-preserve-unknown-fields: true description: Object with preserved fields for backward compatibility
v1alpha:
openAPIV3Schema:
properties:
spec:
properties:
deploymentName:
type: string
kubeconfig:
properties:
namespace:
type: string
secretKey:
type: string
secretName:
type: string
type: object
type: object type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v2alpha1: v2alpha1:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -53,5 +37,8 @@ v2alpha1:
type: string type: string
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -9,8 +9,11 @@ v1:
type: type:
type: string type: string
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1alpha: v1alpha:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -22,8 +25,11 @@ v1alpha:
type: type:
type: string type: string
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v2alpha1: v2alpha1:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -35,5 +41,8 @@ v2alpha1:
type: type:
type: string type: string
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

File diff suppressed because it is too large Load diff

View file

@ -605,8 +605,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -621,8 +621,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -650,8 +650,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -666,8 +666,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -707,8 +707,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -726,8 +726,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -791,8 +791,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -810,8 +810,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -944,8 +944,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -963,8 +963,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1146,8 +1146,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1162,8 +1162,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1191,8 +1191,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1207,8 +1207,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1248,8 +1248,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1267,8 +1267,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1332,8 +1332,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1351,8 +1351,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1485,8 +1485,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1504,8 +1504,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1693,8 +1693,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1709,8 +1709,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1738,8 +1738,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1754,8 +1754,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1795,8 +1795,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1814,8 +1814,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1879,8 +1879,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1898,8 +1898,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2032,8 +2032,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2051,8 +2051,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2974,5 +2974,8 @@ v1alpha1:
format: int32 format: int32
type: integer type: integer
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -690,8 +690,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -706,8 +706,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -735,8 +735,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -751,8 +751,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -792,8 +792,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -811,8 +811,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -876,8 +876,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -895,8 +895,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1029,8 +1029,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1048,8 +1048,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1231,8 +1231,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1247,8 +1247,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1276,8 +1276,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1292,8 +1292,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1333,8 +1333,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1352,8 +1352,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1417,8 +1417,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1436,8 +1436,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1570,8 +1570,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1589,8 +1589,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1778,8 +1778,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1794,8 +1794,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -1823,8 +1823,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1839,8 +1839,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -1880,8 +1880,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1899,8 +1899,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1964,8 +1964,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1983,8 +1983,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2117,8 +2117,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2136,8 +2136,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -3073,5 +3073,8 @@ v1alpha1:
timeZone: timeZone:
type: string type: string
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -184,8 +184,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -200,8 +200,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -229,8 +229,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -245,8 +245,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -290,8 +290,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -309,8 +309,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -372,8 +372,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -391,8 +391,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -514,8 +514,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -533,8 +533,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -565,8 +565,11 @@ v1alpha1:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1beta1: v1beta1:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -624,5 +627,8 @@ v1beta1:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -108,8 +108,11 @@ v1:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1alpha: v1alpha:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -220,8 +223,11 @@ v1alpha:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v2alpha1: v2alpha1:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -314,5 +320,8 @@ v2alpha1:
type: object type: object
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -229,8 +229,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -245,8 +245,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -274,8 +274,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -290,8 +290,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -331,8 +331,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -350,8 +350,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -413,8 +413,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -432,8 +432,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -555,8 +555,8 @@ v1alpha1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -574,8 +574,8 @@ v1alpha1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -1747,8 +1747,11 @@ v1alpha1:
type: integer type: integer
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true
v1beta1: v1beta1:
openAPIV3Schema: openAPIV3Schema:
properties: properties:
@ -1977,8 +1980,8 @@ v1beta1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -1993,8 +1996,8 @@ v1beta1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
preStop: preStop:
@ -2022,8 +2025,8 @@ v1beta1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2038,8 +2041,8 @@ v1beta1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
type: object type: object
type: object type: object
@ -2079,8 +2082,8 @@ v1beta1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2098,8 +2101,8 @@ v1beta1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2161,8 +2164,8 @@ v1beta1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2180,8 +2183,8 @@ v1beta1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -2303,8 +2306,8 @@ v1beta1:
path: path:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
scheme: scheme:
type: string type: string
type: object type: object
@ -2322,8 +2325,8 @@ v1beta1:
host: host:
type: string type: string
port: port:
format: int-or-string
type: string type: string
x-kubernetes-int-or-string: true
type: object type: object
terminationGracePeriodSeconds: terminationGracePeriodSeconds:
format: int64 format: int64
@ -3495,5 +3498,8 @@ v1beta1:
type: integer type: integer
type: object type: object
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -59,5 +59,8 @@ v1alpha:
type: object type: object
type: array type: array
type: object type: object
status:
description: Object with preserved fields for backward compatibility
type: object
x-kubernetes-preserve-unknown-fields: true
type: object type: object
x-kubernetes-preserve-unknown-fields: true

View file

@ -28,8 +28,9 @@ import (
) )
const ( const (
Version = "arangodb.com/version" Version = "arangodb.com/version"
Schema = "arangodb.com/schema" Schema = "arangodb.com/schema"
PreserveUnknownFields = "arangodb.com/x-preserve-unknown-fields"
) )
type crdDefinitionGetter func(opts *crds.CRDOptions) crds.Definition type crdDefinitionGetter func(opts *crds.CRDOptions) crds.Definition