Skip to content

Commit

Permalink
chore: update configconstraint update (#7382)
Browse files Browse the repository at this point in the history
  • Loading branch information
sophon-zt committed May 21, 2024
1 parent bfa1e9b commit 1f1c36a
Show file tree
Hide file tree
Showing 11 changed files with 410 additions and 60 deletions.
16 changes: 12 additions & 4 deletions cmd/helmhook/hook/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,23 @@ import (
"github.com/apecloud/kubeblocks/pkg/client/clientset/versioned"
)

type Addon struct{}
type Addon struct {
BasedHandler

AddonEnabledUpdated bool
}

const (
helmResourcePolicyKey = "helm.sh/resource-policy"
helmResourcePolicyKeep = "keep"
)

func (p *Addon) IsSkip(*UpgradeContext) (bool, error) {
return p.AddonEnabledUpdated, nil
}

func (p *Addon) Handle(ctx *UpgradeContext) (err error) {
addons, err := ctx.Client.ExtensionsV1alpha1().Addons().List(ctx, metav1.ListOptions{
addons, err := ctx.KBClient.ExtensionsV1alpha1().Addons().List(ctx, metav1.ListOptions{
LabelSelector: toLabelSelector(addonSelectorLabels()),
})

Expand All @@ -50,7 +58,7 @@ func (p *Addon) Handle(ctx *UpgradeContext) (err error) {
continue
}
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
return patchAddon(ctx, ctx.Client, addon)
return patchDisableUpdateAddon(ctx, ctx.KBClient, addon)
})
if err != nil {
return err
Expand All @@ -59,7 +67,7 @@ func (p *Addon) Handle(ctx *UpgradeContext) (err error) {
return nil
}

func patchAddon(ctx context.Context, client *versioned.Clientset, addon extensionsv1alpha1.Addon) error {
func patchDisableUpdateAddon(ctx context.Context, client *versioned.Clientset, addon extensionsv1alpha1.Addon) error {
annotations := addon.GetAnnotations()
if annotations == nil {
annotations = make(map[string]string)
Expand Down
91 changes: 91 additions & 0 deletions cmd/helmhook/hook/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
Copyright (C) 2022-2024 ApeCloud Co., Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package hook

import (
"context"

"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type Conversion struct {
BasedHandler
}

type ConversionHandler interface {
Convert(context.Context, CRClient) ([]client.Object, error)
}

type ConversionMeta struct {
ConversionHandler
FromVersion Version
ToVersion Version
}

var crConversionMaps = map[schema.GroupVersionResource]ConversionMeta{}

func (p *Conversion) IsSkip(ctx *UpgradeContext) (bool, error) {
fromVersion := ctx.From
toVersion := ctx.To

if fromVersion == nil || *fromVersion == toVersion {
Log("not support resource conversion and pass, oldVersion: %v, newVersion: %v", fromVersion, toVersion)
return true, nil
}

for _, meta := range crConversionMaps {
if matchVersion(meta, *fromVersion, toVersion) && meta.ConversionHandler != nil {
return false, nil
}
}
Log("no gvr to convert and pass, oldVersion: %v, newVersion: %v", fromVersion, toVersion)
return true, nil
}

func (p *Conversion) Handle(ctx *UpgradeContext) (err error) {
var (
fromVersion = ctx.From
toVersion = ctx.To
)

for gvr, meta := range crConversionMaps {
if !matchVersion(meta, *fromVersion, toVersion) || meta.ConversionHandler == nil {
continue
}
objs, err := meta.Convert(ctx, ctx.CRClient)
if err != nil {
return err
}
if len(objs) != 0 {
ctx.UpdatedObjects[gvr] = append(ctx.UpdatedObjects[gvr], objs...)
}
}
return nil
}

func matchVersion(meta ConversionMeta, oldVersion Version, newVersion Version) bool {
return meta.FromVersion == oldVersion && meta.ToVersion == newVersion
}

func RegisterCRDConversion(oldVersion Version, newVersion Version, gvr schema.GroupVersionResource, handler ConversionHandler) {
crConversionMaps[gvr] = ConversionMeta{
FromVersion: oldVersion,
ToVersion: newVersion,
ConversionHandler: handler,
}
}
59 changes: 59 additions & 0 deletions cmd/helmhook/hook/cr.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
Copyright (C) 2022-2024 ApeCloud Co., Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package hook

import (
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
apiruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
)

type UpdateCR struct {
BasedHandler
}

func (u *UpdateCR) Handle(context *UpgradeContext) error {
if len(context.UpdatedObjects) == 0 {
return nil
}

for gvr, objects := range context.UpdatedObjects {
Log("update GVR resource: %s", gvr.String())
for _, cr := range objects {
Log("update resource: %s", cr.GetName())
item, err := apiruntime.DefaultUnstructuredConverter.ToUnstructured(cr)
if err != nil {
return err
}
if err = updateOrCreate(context, gvr, &unstructured.Unstructured{Object: item}); err != nil {
return err
}
}
}
return nil
}

func updateOrCreate(context *UpgradeContext, gvr schema.GroupVersionResource, cr *unstructured.Unstructured) error {
_, err := context.Resource(gvr).Update(context, cr, metav1.UpdateOptions{})
if err != nil && apierrors.IsNotFound(err) {
Log("resource not found and create: %s", cr.GetName())
_, err = context.Resource(gvr).Create(context, cr, metav1.CreateOptions{})
}
return err
}
33 changes: 15 additions & 18 deletions cmd/helmhook/hook/crd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ import (
"path/filepath"

apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/controller-runtime/pkg/client"

"k8s.io/apimachinery/pkg/util/sets"
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
)

type UpdateCRD struct {
BasedHandler
}

func (p *UpdateCRD) Handle(ctx *UpgradeContext) (err error) {
Expand All @@ -42,18 +42,15 @@ func (p *UpdateCRD) Handle(ctx *UpgradeContext) (err error) {
}

for _, crd := range crdList {
_, err = ctx.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, crd.GetName(), metav1.GetOptions{})
if err == nil {
Log("create/update CRD: %s", crd.GetName())
existing, err := ctx.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Get(ctx, crd.GetName(), metav1.GetOptions{})
switch {
case err == nil:
crd.SetResourceVersion(existing.GetResourceVersion())
_, err = ctx.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Update(ctx, &crd, metav1.UpdateOptions{})
case apierrors.IsNotFound(err):
_, err = ctx.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Create(ctx, &crd, metav1.CreateOptions{})
if err != nil {
return err
}
continue
}
if client.IgnoreNotFound(err) != nil {
return err
}
_, err = ctx.CRDClient.ApiextensionsV1().CustomResourceDefinitions().Update(ctx, &crd, metav1.UpdateOptions{})
if err != nil {
return err
}
Expand All @@ -74,7 +71,7 @@ func parseCRDs(path string) ([]apiextensionsv1.CustomResourceDefinition, error)
return nil, err
}
if !info.IsDir() {
return nil, fmt.Errorf("require path[%] is directory", path)
return nil, fmt.Errorf("require path[%s] is directory", path)
}

entries, err := os.ReadDir(path)
Expand All @@ -85,7 +82,7 @@ func parseCRDs(path string) ([]apiextensionsv1.CustomResourceDefinition, error)
files = append(files, e.Name())
}

fmt.Printf("reading CRDs from path: %s", path)
Log("reading CRDs from path: %s", path)
crdList, err := readCRDs(filePath, files)
if err != nil {
return nil, err
Expand All @@ -106,20 +103,20 @@ func readCRDs(basePath string, files []string) ([]apiextensionsv1.CustomResource
return nil, err
}
crds = append(crds, docs...)
fmt.Sprintf("read CRDs from file: %s", file)
Log("read CRDs from file: %s", file)
}
return crds, nil
}

func readDocuments(fp string) ([]apiextensionsv1.CustomResourceDefinition, error) {
var objs []apiextensionsv1.CustomResourceDefinition

b, err := os.ReadFile(fp)
if err != nil {
return nil, err
}

reader := k8syaml.NewYAMLToJSONDecoder(bufio.NewReader(bytes.NewReader(b)))

var objs []apiextensionsv1.CustomResourceDefinition
for {
var obj apiextensionsv1.CustomResourceDefinition
if err = reader.Decode(&obj); err != nil {
Expand Down
29 changes: 29 additions & 0 deletions cmd/helmhook/hook/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
Copyright (C) 2022-2024 ApeCloud Co., Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package hook

import (
"fmt"
"strings"
)

func Log(format string, a ...any) {
fmt.Printf(format, a...)
if !strings.HasSuffix(format, "\n") {
fmt.Println("")
}
}
Loading

0 comments on commit 1f1c36a

Please sign in to comment.