Skip to content

Commit

Permalink
[Bugfix] Fix Schema Apply Checksum (#1652)
Browse files Browse the repository at this point in the history
  • Loading branch information
ajanikow authored Apr 29, 2024
1 parent bb45038 commit 2397c75
Show file tree
Hide file tree
Showing 25 changed files with 284 additions and 340 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
- (Maintenance) Bump Prometheus API Version
- (Bugfix) Prevent unexpected rotation in case of SecurityContext change
- (Bugfix) Ensure PDB is created
- (Bugfix) Fix Schema Apply Checksum

## [1.2.40](https://github.com/arangodb/kube-arangodb/tree/1.2.40) (2024-04-10)
- (Feature) Add Core fields to the Scheduler Container Spec
Expand Down
3 changes: 2 additions & 1 deletion cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/util/metrics"
"github.com/arangodb/kube-arangodb/pkg/util/probe"
"github.com/arangodb/kube-arangodb/pkg/util/retry"
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
"github.com/arangodb/kube-arangodb/pkg/version"
)

Expand Down Expand Up @@ -378,7 +379,7 @@ func executeMain(cmd *cobra.Command, args []string) {
}

if crdOptions.install {
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
ctx, cancel := context.WithTimeout(shutdown.Context(), time.Minute)
defer cancel()

crdOpts, err := prepareCRDOptions(crdOptions.validationSchema)
Expand Down
3 changes: 2 additions & 1 deletion cmd/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
"github.com/arangodb/kube-arangodb/pkg/crd/crds"
"github.com/arangodb/kube-arangodb/pkg/util/errors"
"github.com/arangodb/kube-arangodb/pkg/util/kclient"
"github.com/arangodb/kube-arangodb/pkg/util/shutdown"
)

var (
Expand Down Expand Up @@ -108,7 +109,7 @@ func cmdCRDInstallRun(cmd *cobra.Command, args []string) {
return
}

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
ctx, cancel := context.WithTimeout(shutdown.Context(), time.Minute)
defer cancel()

err = crd.EnsureCRDWithOptions(ctx, client, crd.EnsureCRDOptions{IgnoreErrors: false, CRDOptions: crdOpts, ForceUpdate: crdInstallOptions.force})
Expand Down
38 changes: 27 additions & 11 deletions pkg/crd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/arangodb/go-driver"

"github.com/arangodb/kube-arangodb/pkg/crd/crds"
"github.com/arangodb/kube-arangodb/pkg/logging"
kresources "github.com/arangodb/kube-arangodb/pkg/util/k8sutil/resources"
Expand Down Expand Up @@ -65,25 +63,33 @@ func EnsureCRDWithOptions(ctx context.Context, client kclient.Client, opts Ensur
continue
}

var opt *crds.CRDOptions
var opt = &crdReg.defaultOpts
if o, ok := opts.CRDOptions[crdName]; ok {
opt = &o
}
def := crdReg.getter(opt)

err := tryApplyCRD(ctx, client, def, opts.ForceUpdate)
err := tryApplyCRD(ctx, client, def, opt, opts.ForceUpdate)
if !opts.IgnoreErrors && err != nil {
return err
}
}
return nil
}

func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition, 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()

crdName := def.CRD.Name

definitionVersion, definitionSchemaVersion := def.DefinitionData.Checksum()

logger := logger.Str("version", definitionVersion)

if opts.GetWithSchema() {
logger = logger.Str("schema", definitionSchemaVersion)
}

c, err := crdDefinitions.Get(ctx, crdName, meta.GetOptions{})
if err != nil {
if !errors.IsNotFound(err) {
Expand All @@ -102,12 +108,16 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition
ObjectMeta: meta.ObjectMeta{
Name: crdName,
Labels: map[string]string{
Version: string(def.Version),
Version: definitionVersion,
},
},
Spec: def.CRD.Spec,
}

if opts.GetWithSchema() {
c.Labels[Schema] = definitionSchemaVersion
}

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")
return err
Expand All @@ -127,14 +137,20 @@ func tryApplyCRD(ctx context.Context, client kclient.Client, def crds.Definition
c.ObjectMeta.Labels = map[string]string{}
}

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
if !forceUpdate {
if v, ok := c.ObjectMeta.Labels[Version]; ok && v == definitionVersion {
if v, ok := c.ObjectMeta.Labels[Schema]; (opts.GetWithSchema() && (ok && v == definitionSchemaVersion)) || (!opts.GetWithSchema() && !ok) {
logger.Str("crd", crdName).Info("CRD Update not required")
return nil
}
}
}

c.ObjectMeta.Labels[Version] = string(def.Version)
c.ObjectMeta.Labels[Version] = definitionVersion
delete(c.ObjectMeta.Labels, Schema)
if opts.GetWithSchema() {
c.ObjectMeta.Labels[Schema] = definitionSchemaVersion
}
c.Spec = def.CRD.Spec

if _, err := crdDefinitions.Update(ctx, c, meta.UpdateOptions{}); err != nil {
Expand Down
75 changes: 71 additions & 4 deletions pkg/crd/apply_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// DISCLAIMER
//
// Copyright 2016-2023 ArangoDB GmbH, Cologne, Germany
// Copyright 2016-2024 ArangoDB GmbH, Cologne, Germany
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -22,6 +22,7 @@ package crd

import (
"context"
"encoding/json"
"testing"
"time"

Expand Down Expand Up @@ -51,6 +52,11 @@ func dropLogMessages(t *testing.T, s tests.LogScanner) map[string]string {
lines[p] = m
}

d, err := json.Marshal(lines)
require.NoError(t, err)

t.Logf("Lines: %s", string(d))

return lines
}

Expand Down Expand Up @@ -133,27 +139,88 @@ func runApply(t *testing.T, crdOpts map[string]crds.CRDOptions) {

t.Run("Create", func(t *testing.T) {
d := crds.AllDefinitions()[0]

q := d.CRD.DeepCopy()
q.Labels = map[string]string{
Version: string(d.Version),
Version: "version",
}
_, err := c.KubernetesExtensions().ApiextensionsV1().CustomResourceDefinitions().Create(context.Background(), q, meta.CreateOptions{})
require.NoError(t, err)
})

t.Run("Ensure", func(t *testing.T) {
t.Run("Ensure without schema", func(t *testing.T) {
crdOpts = updateMap(t, crdOpts, func(t *testing.T, key string, el crds.CRDOptions) crds.CRDOptions {
el.WithSchema = false
return el
})

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) {
if k == crds.AllDefinitions()[0].CRD.GetName() {
require.Equal(t, "CRD Update not required", v)
require.Equal(t, "CRD Updated", v)
} else {
require.Equal(t, "CRD Created", v)
}
})
}
})

t.Run("Rerun without schema", func(t *testing.T) {
crdOpts = updateMap(t, crdOpts, func(t *testing.T, key string, el crds.CRDOptions) crds.CRDOptions {
el.WithSchema = false
return el
})

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) {
require.Equal(t, "CRD Update not required", v)
})
}
})

t.Run("Ensure with schema", func(t *testing.T) {
crdOpts = updateMap(t, crdOpts, func(t *testing.T, key string, el crds.CRDOptions) crds.CRDOptions {
el.WithSchema = true
return el
})

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) {
require.Equal(t, "CRD Updated", v)
})
}
})

t.Run("Rerun with schema", func(t *testing.T) {
crdOpts = updateMap(t, crdOpts, func(t *testing.T, key string, el crds.CRDOptions) crds.CRDOptions {
el.WithSchema = true
return el
})

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) {
require.Equal(t, "CRD Update not required", v)
})
}
})
})
})
}

func updateMap[T comparable](t *testing.T, in map[string]T, f func(t *testing.T, key string, el T) T) map[string]T {
r := make(map[string]T, len(in))

for k, v := range in {
r[k] = f(t, k, v)
}

return r
}
22 changes: 9 additions & 13 deletions pkg/crd/crds/apps-job.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ import (
_ "embed"

apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

"github.com/arangodb/go-driver"

"github.com/arangodb/kube-arangodb/pkg/util"
)

const (
AppsJobVersion = driver.Version("1.0.1")
)

// Deprecated: use AppsJobWithOptions instead
Expand All @@ -40,7 +32,7 @@ func AppsJob() *apiextensions.CustomResourceDefinition {
}

func AppsJobWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
return getCRD(appsJobsCRD, appsJobsCRDSchemas, opts...)
return getCRD(AppsJobDefinitionData(), opts...)
}

// Deprecated: use AppsJobDefinitionWithOptions instead
Expand All @@ -50,13 +42,17 @@ func AppsJobDefinition() Definition {

func AppsJobDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
return Definition{
Version: AppsJobVersion,
CRD: AppsJobWithOptions(opts...),
DefinitionData: AppsJobDefinitionData(),
CRD: AppsJobWithOptions(opts...),
}
}

var appsJobsCRD = util.NewYamlLoader[apiextensions.CustomResourceDefinition](appsJobs)
var appsJobsCRDSchemas = util.NewYamlLoader[crdSchemas](appsJobsSchemaRaw)
func AppsJobDefinitionData() DefinitionData {
return DefinitionData{
definition: appsJobs,
schemaDefinition: appsJobsSchemaRaw,
}
}

//go:embed apps-job.yaml
var appsJobs []byte
Expand Down
22 changes: 9 additions & 13 deletions pkg/crd/crds/backups-backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ import (
_ "embed"

apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

"github.com/arangodb/go-driver"

"github.com/arangodb/kube-arangodb/pkg/util"
)

const (
BackupsBackupVersion = driver.Version("1.0.1")
)

// Deprecated: use BackupsBackupWithOptions instead
Expand All @@ -40,7 +32,7 @@ func BackupsBackup() *apiextensions.CustomResourceDefinition {
}

func BackupsBackupWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
return getCRD(backupsBackupCRD, backupsBackupCRDSchemas, opts...)
return getCRD(BackupsBackupDefinitionData(), opts...)
}

// Deprecated: use BackupsBackupDefinitionWithOptions instead
Expand All @@ -50,13 +42,17 @@ func BackupsBackupDefinition() Definition {

func BackupsBackupDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
return Definition{
Version: BackupsBackupVersion,
CRD: BackupsBackupWithOptions(opts...),
DefinitionData: BackupsBackupDefinitionData(),
CRD: BackupsBackupWithOptions(opts...),
}
}

var backupsBackupCRD = util.NewYamlLoader[apiextensions.CustomResourceDefinition](backupsBackup)
var backupsBackupCRDSchemas = util.NewYamlLoader[crdSchemas](backupsBackupSchemaRaw)
func BackupsBackupDefinitionData() DefinitionData {
return DefinitionData{
definition: backupsBackup,
schemaDefinition: backupsBackupSchemaRaw,
}
}

//go:embed backups-backup.yaml
var backupsBackup []byte
Expand Down
22 changes: 9 additions & 13 deletions pkg/crd/crds/backups-backuppolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ import (
_ "embed"

apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

"github.com/arangodb/go-driver"

"github.com/arangodb/kube-arangodb/pkg/util"
)

const (
BackupsBackupPolicyPolicyVersion = driver.Version("1.0.1")
)

// Deprecated: use BackupsBackupPolicyPolicyWithOptions instead
Expand All @@ -40,7 +32,7 @@ func BackupsBackupPolicyPolicy() *apiextensions.CustomResourceDefinition {
}

func BackupsBackupPolicyPolicyWithOptions(opts ...func(*CRDOptions)) *apiextensions.CustomResourceDefinition {
return getCRD(backupsBackupPolicyCRD, backupsBackupPolicyCRDSchemas, opts...)
return getCRD(BackupsBackupPolicyDefinitionData(), opts...)
}

// Deprecated: use func BackupsBackupPolicyDefinitionWithOptions instead
Expand All @@ -50,13 +42,17 @@ func BackupsBackupPolicyDefinition() Definition {

func BackupsBackupPolicyDefinitionWithOptions(opts ...func(*CRDOptions)) Definition {
return Definition{
Version: BackupsBackupPolicyPolicyVersion,
CRD: BackupsBackupPolicyPolicyWithOptions(opts...),
DefinitionData: BackupsBackupPolicyDefinitionData(),
CRD: BackupsBackupPolicyPolicyWithOptions(opts...),
}
}

var backupsBackupPolicyCRD = util.NewYamlLoader[apiextensions.CustomResourceDefinition](backupsBackupPolicy)
var backupsBackupPolicyCRDSchemas = util.NewYamlLoader[crdSchemas](backupsBackupPolicySchemaRaw)
func BackupsBackupPolicyDefinitionData() DefinitionData {
return DefinitionData{
definition: backupsBackupPolicy,
schemaDefinition: backupsBackupPolicySchemaRaw,
}
}

//go:embed backups-backuppolicy.yaml
var backupsBackupPolicy []byte
Expand Down
Loading

0 comments on commit 2397c75

Please sign in to comment.