Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ go 1.25.5
require (
github.com/buger/jsonparser v1.1.1
github.com/google/uuid v1.6.0
github.com/meshery/meshery-operator v0.8.11
github.com/meshery/meshkit v0.8.54
github.com/myntra/pipeline v0.0.0-20180618182531-2babf4864ce8
github.com/sirupsen/logrus v1.9.3
Expand All @@ -21,6 +20,7 @@ require (
k8s.io/apimachinery v0.34.2
k8s.io/client-go v0.34.2
k8s.io/kubectl v0.34.2
sigs.k8s.io/controller-runtime v0.20.1
sigs.k8s.io/yaml v1.6.0
)

Expand Down Expand Up @@ -50,6 +50,7 @@ require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
github.com/evanphx/json-patch v5.9.11+incompatible // indirect
github.com/evanphx/json-patch/v5 v5.9.0 // indirect
github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
Expand Down Expand Up @@ -113,6 +114,8 @@ require (
github.com/nats-io/nkeys v0.4.9 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/oapi-codegen/runtime v1.1.2 // indirect
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
github.com/onsi/gomega v1.36.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
Expand Down Expand Up @@ -166,7 +169,6 @@ require (
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b // indirect
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397 // indirect
oras.land/oras-go/v2 v2.6.0 // indirect
sigs.k8s.io/controller-runtime v0.20.1 // indirect
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect
sigs.k8s.io/kustomize/api v0.20.1 // indirect
sigs.k8s.io/kustomize/kyaml v0.20.1 // indirect
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
Expand Down Expand Up @@ -229,8 +231,6 @@ github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/meshery/meshery-operator v0.8.11 h1:eDo2Sw0jjVrXsvvhF8LenADM58pK+7Z68ROPVIejTPc=
github.com/meshery/meshery-operator v0.8.11/go.mod h1:hQEtFKKa5Fr/Mskk6bV5ip3bQ0+3F0u1voYS3XisBp4=
github.com/meshery/meshkit v0.8.54 h1:WxsYNITaK+IwzXFRbTzl2qkcygVVDRA7lVSPoQIA+ZQ=
github.com/meshery/meshkit v0.8.54/go.mod h1:YmqM1i4vRD7W+Agf7KOXJchy6Haq/g1fABy7oYcnYo8=
github.com/meshery/schemas v0.8.93 h1:kCib7RSzph+AbR6r2yQpFnLpK+zxyVxn0B3O6RbtXuM=
Expand Down Expand Up @@ -404,6 +404,10 @@ go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU
go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
Expand Down
71 changes: 53 additions & 18 deletions internal/config/crd_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import (
"errors"
"fmt"

"github.com/meshery/meshery-operator/pkg/client"
"github.com/meshery/meshkit/utils"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/retry"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
)

var (
Expand Down Expand Up @@ -195,24 +197,57 @@ func filterBlacklistedPipelines(pipelines PipelineConfigs, blackList []string) P
return result
}

// PatchCRVersion updates the MeshSync CR version safely.
// It uses Controller Runtime patterns for idempotency and conflict handling.
func PatchCRVersion(config *rest.Config) error {
meshsyncClient, err := client.New(config)
// 1. Init Controller Runtime Client
cl, err := ctrlclient.New(config, ctrlclient.Options{})
if err != nil {
return ErrInitConfig(fmt.Errorf("unable to update MeshSync configuration"))
}
return ErrInitConfig(fmt.Errorf("unable to create controller-runtime client: %w", err))
}

// 2. Define the Object (Using Unstructured to avoid circular dependencies)
obj := &unstructured.Unstructured{}
obj.SetGroupVersionKind(schema.GroupVersionKind{
Group: group,
Version: version,
Kind: "MeshSync",
})

key := types.NamespacedName{Name: crName, Namespace: namespace}

// 3. Retry Logic (Standard Kubernetes RetryOnConflict)
return retry.RetryOnConflict(retry.DefaultRetry, func() error {
// Fetch current CR
if err := cl.Get(context.TODO(), key, obj); err != nil {
if k8serrors.IsNotFound(err) {
// GUARD: CR doesn't exist, so we skip patching (Fixes #422)
return nil
}
// Use existing error pattern
return ErrInitConfig(fmt.Errorf("unable to get MeshSync CR %s/%s: %w", namespace, crName, err))
}

patchedResource := map[string]interface{}{
"spec": map[string]interface{}{
"version": Server["version"],
},
}
byt, err := utils.Marshal(patchedResource)
if err != nil {
return ErrInitConfig(fmt.Errorf("unable to update MeshSync configuration"))
}
_, err = meshsyncClient.CoreV1Alpha1().MeshSyncs("meshery").Patch(context.TODO(), crName, types.MergePatchType, []byte(byt), metav1.PatchOptions{})
if err != nil {
return ErrInitConfig(fmt.Errorf("unable to update MeshSync configuration"))
}
return nil
// Idempotency: Check if version already matches
specVersion, found, _ := unstructured.NestedString(obj.Object, "spec", "version")
if found && specVersion == Server["version"] {
// Version already matches, no update needed
return nil
}

// Prepare Patch (MergeFrom handles JSON generation automatically)
patch := ctrlclient.MergeFrom(obj.DeepCopy())

// Update the version field in the object
if err := unstructured.SetNestedField(obj.Object, Server["version"], "spec", "version"); err != nil {
return ErrInitConfig(fmt.Errorf("unable to set version field: %w", err))
}

// Apply Patch
if err := cl.Patch(context.TODO(), obj, patch); err != nil {
return err // RetryOnConflict will catch this and retry if it's a conflict
}

return nil
})
}
2 changes: 1 addition & 1 deletion internal/config/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func (p PipelineConfigs) Add(pc PipelineConfig) PipelineConfigs {
func (p PipelineConfigs) Delete(pc PipelineConfig) PipelineConfigs {
for index, pipelineConfig := range p {
if pipelineConfig.Name == pc.Name {
p = slices.Delete[PipelineConfigs](p, index, index+1)
p = slices.Delete(p, index, index+1)
break
}
}
Expand Down
10 changes: 7 additions & 3 deletions pkg/lib/meshsync/meshsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,13 @@ func Run(log logger.Handler, optsSetters ...OptionsSetter) error {
}

if useCRDFlag {
// this patch only make sense when CRD is present when in cluster
if errPatchCRVersion := config.PatchCRVersion(&kubeClient.RestConfig); errPatchCRVersion != nil {
log.Warnf("meshsync: %v", errPatchCRVersion)
// Only attempt to patch MeshSync CR/version if the MeshSync CR object exists.
if _, errGetCR := config.GetMeshsyncCRD(kubeClient.DynamicKubeClient); errGetCR == nil {
if errPatchCRVersion := config.PatchCRVersion(&kubeClient.RestConfig); errPatchCRVersion != nil {
log.Warnf("meshsync: %v", errPatchCRVersion)
}
} else {
log.Debugf("meshsync: skipping PatchCRVersion because MeshSync CR not found: %v", errGetCR)
}
}

Expand Down