Skip to content

Commit

Permalink
customize app addon install namespace (#396)
Browse files Browse the repository at this point in the history
Signed-off-by: Xiangjing Li <xiangli@redhat.com>
  • Loading branch information
xiangjingli committed May 6, 2024
1 parent e6948fc commit 25d7b3d
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 822 deletions.
89 changes: 84 additions & 5 deletions addon/addon.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package addon
import (
"context"
"embed"
"fmt"
"strings"

"github.com/Masterminds/semver/v3"
Expand All @@ -14,6 +15,7 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/klog/v2"
Expand All @@ -26,6 +28,7 @@ import (
clusterv1 "open-cluster-management.io/api/cluster/v1"
appsubutils "open-cluster-management.io/multicloud-operators-subscription/pkg/utils"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/manager"
)

const (
Expand All @@ -36,6 +39,35 @@ const (
AgentImageEnv = "OPERAND_IMAGE_MULTICLUSTER_OPERATORS_SUBSCRIPTION"
)

const (
// AnnotationKlusterletDeployMode is the annotation key of klusterlet deploy mode, it describes the
// klusterlet deploy mode when importing a managed cluster.
// If the value is "Hosted", the HostingClusterNameAnnotation annotation will be required, we use
// AnnotationKlusterletHostingClusterName to determine where to deploy the registration-agent and
// work-agent.
AnnotationKlusterletDeployMode string = "import.open-cluster-management.io/klusterlet-deploy-mode"

// AnnotationKlusterletHostingClusterName is the annotation key of hosting cluster name for klusterlet,
// it is required in Hosted mode, and the hosting cluster MUST be one of the managed cluster of the hub.
// The value of the annotation should be the ManagedCluster name of the hosting cluster.
AnnotationKlusterletHostingClusterName string = "import.open-cluster-management.io/hosting-cluster-name"

// DisableAutoImportAnnotation is an annotation of ManagedCluster.
// If present, the crds.yaml and import.yaml will not be applied on the managed cluster by the hub
// controller automatically. And the bootstrap-hub-kubeconfig secret will not be updated as well
// in the backup-restore case.
DisableAutoImportAnnotation string = "import.open-cluster-management.io/disable-auto-import"

// AnnotationKlusterletConfig is an annotation of ManagedCluster, which references to the name of the
// KlusterletConfig adopted by this managed cluster. If it is missing on a ManagedCluster, no KlusterletConfig
// will be used for this managed cluster.
AnnotationKlusterletConfig string = "agent.open-cluster-management.io/klusterlet-config"

// AnnotationEnableHostedModeAddons is the key of annotation which indicates if the add-ons will be enabled
// in hosted mode automatically for a managed cluster
AnnotationEnableHostedModeAddons = "addon.open-cluster-management.io/enable-hosted-mode-addons"
)

//nolint:all
//go:embed manifests
//go:embed manifests/chart
Expand Down Expand Up @@ -194,7 +226,7 @@ func applyManifestFromFile(file, clusterName, addonName string, kubeClient *kube
return nil
}

func NewAddonManager(kubeConfig *rest.Config, agentImage string, agentInstallAllStrategy bool) (addonmanager.AddonManager, error) {
func NewAddonManager(mgr manager.Manager, kubeConfig *rest.Config, agentImage string) (addonmanager.AddonManager, error) {
AppMgrImage = agentImage

addonMgr, err := addonmanager.New(kubeConfig)
Expand Down Expand Up @@ -234,15 +266,13 @@ func NewAddonManager(kubeConfig *rest.Config, agentImage string, agentInstallAll
addonfactory.ToAddOnProxyConfigValues,
),
).
WithAgentInstallNamespace(AddonInstallNamespaceFunc(
utils.NewAddOnDeploymentConfigGetter(addonClient), mgr.GetClient())).
WithAgentRegistrationOption(newRegistrationOption(kubeClient, AppMgrAddonName)).
WithAgentDeployTriggerClusterFilter(func(old, new *clusterv1.ManagedCluster) bool {
return !equality.Semantic.DeepEqual(old.Annotations, new.Annotations)
})

if agentInstallAllStrategy {
agentFactory.WithInstallStrategy(agent.InstallAllStrategy("open-cluster-management-agent-addon"))
}

agentAddon, err := agentFactory.BuildHelmAgentAddon()
if err != nil {
klog.Errorf("failed to build agent %v", err)
Expand Down Expand Up @@ -322,3 +352,52 @@ func GetMchImage(kubeConfig *rest.Config) (string, error) {

return image, nil
}

// AddonInstallNamespaceFunc reads addonDeploymentConfig to set install namespace for addons in default mode,
// and set install namespace to klusterlet-{cluster name} for addons in hosted mode.
func AddonInstallNamespaceFunc(
addonGetter utils.AddOnDeploymentConfigGetter,
clusterClient client.Client) func(addon *addonapiv1alpha1.ManagedClusterAddOn) (string, error) {
return func(addon *addonapiv1alpha1.ManagedClusterAddOn) (string, error) {
cluster := &clusterv1.ManagedCluster{}
err := clusterClient.Get(context.TODO(), types.NamespacedName{Name: addon.Namespace}, cluster)

if err != nil {
return "", err
}

mode, _ := HostedClusterInfo(addon, cluster)
if mode == "Hosted" {
return fmt.Sprintf("klusterlet-%s", addon.Namespace), nil
}

addonNS, err := utils.AgentInstallNamespaceFromDeploymentConfigFunc(addonGetter)(addon)

if addonNS == "" && err == nil {
addonNS = "open-cluster-management-agent-addon"
}

return addonNS, err
}
}

func HostedClusterInfo(_ *addonapiv1alpha1.ManagedClusterAddOn, cluster *clusterv1.ManagedCluster) (string, string) {
if len(cluster.Annotations) == 0 {
return "Default", ""
}

if cluster.Annotations[AnnotationEnableHostedModeAddons] != "true" {
return "Default", ""
}

if cluster.Annotations[AnnotationKlusterletDeployMode] != "Hosted" {
return "Default", ""
}

hostingClusterName, ok := cluster.Annotations[AnnotationKlusterletHostingClusterName]
if !ok || len(hostingClusterName) == 0 {
return "Default", ""
}

return "Hosted", hostingClusterName
}
89 changes: 89 additions & 0 deletions addon/addon_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package addon

import (
"context"
"testing"

appsv1 "k8s.io/api/apps/v1"
Expand All @@ -9,8 +10,10 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
"open-cluster-management.io/addon-framework/pkg/addonfactory"
"open-cluster-management.io/addon-framework/pkg/agent"
"open-cluster-management.io/addon-framework/pkg/utils"
addonapiv1alpha1 "open-cluster-management.io/api/addon/v1alpha1"
clusterv1 "open-cluster-management.io/api/cluster/v1"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

var (
Expand Down Expand Up @@ -128,3 +131,89 @@ func TestManifest(t *testing.T) {
})
}
}

type testConfigGetter struct {
config *addonapiv1alpha1.AddOnDeploymentConfig
}

func newTestConfigGetter(config *addonapiv1alpha1.AddOnDeploymentConfig) *testConfigGetter {
return &testConfigGetter{
config: config,
}
}

func (t *testConfigGetter) Get(_ context.Context, _ string, _ string) (*addonapiv1alpha1.AddOnDeploymentConfig, error) {
return t.config, nil
}

func newAddonConfigWithNamespace(namespace string) *addonapiv1alpha1.AddOnDeploymentConfig {
return &addonapiv1alpha1.AddOnDeploymentConfig{
ObjectMeta: metav1.ObjectMeta{
Namespace: "test",
Name: "test",
},
Spec: addonapiv1alpha1.AddOnDeploymentConfigSpec{
AgentInstallNamespace: namespace,
},
}
}

func newAddonWithConfig(name, cluster, annotationValue string, config *addonapiv1alpha1.AddOnDeploymentConfig) *addonapiv1alpha1.ManagedClusterAddOn {
specHash, _ := utils.GetAddOnDeploymentConfigSpecHash(config)
addon := newAddon(name, cluster, "", annotationValue)
addon.Status = addonapiv1alpha1.ManagedClusterAddOnStatus{
ConfigReferences: []addonapiv1alpha1.ConfigReference{
{
ConfigGroupResource: addonapiv1alpha1.ConfigGroupResource{
Group: utils.AddOnDeploymentConfigGVR.Group,
Resource: utils.AddOnDeploymentConfigGVR.Resource,
},
DesiredConfig: &addonapiv1alpha1.ConfigSpecHash{
SpecHash: specHash,
},
},
},
}

return addon
}

func TestAddonInstallNamespaceFunc(t *testing.T) {
tests := []struct {
name string
addon *addonapiv1alpha1.ManagedClusterAddOn
cluster *clusterv1.ManagedCluster
config *addonapiv1alpha1.AddOnDeploymentConfig
expectedNamespace string
}{
{
name: "default namespace",
addon: newAddon("test", "cluster1", "", ""),
cluster: newCluster("cluster1"),
expectedNamespace: "open-cluster-management-agent-addon",
},
{
name: "customized namespace",
addon: newAddonWithConfig("test", "cluster1", "", newAddonConfigWithNamespace("ns1")),
cluster: newCluster("cluster1"),
config: newAddonConfigWithNamespace("ns1"),
expectedNamespace: "ns1",
},
}

scheme := runtime.NewScheme()
clusterv1.Install(scheme)

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
client := fake.NewClientBuilder().WithScheme(scheme).WithObjects(test.cluster).Build()
getter := newTestConfigGetter(test.config)
nsFunc := AddonInstallNamespaceFunc(getter, client)
namespace, _ := nsFunc(test.addon)

if namespace != test.expectedNamespace {
t.Errorf("namespace should be %s, but get %s", test.expectedNamespace, namespace)
}
})
}
}
2 changes: 1 addition & 1 deletion cmd/manager/exec/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ func RunManager() {

klog.Infof("Agent image: %v", agentImage)

adddonmgr, err := agentaddon.NewAddonManager(cfg, agentImage, Options.AgentInstallAll)
adddonmgr, err := agentaddon.NewAddonManager(mgr, cfg, agentImage)
if err != nil {
klog.Error("Failed to setup addon manager, error:", err)
os.Exit(1)
Expand Down
8 changes: 0 additions & 8 deletions cmd/manager/exec/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ type SubscriptionCMDOptions struct {
LeaderElectionRenewDeadline time.Duration
LeaderElectionRetryPeriod time.Duration
Debug bool
AgentInstallAll bool
}

var Options = SubscriptionCMDOptions{
Expand Down Expand Up @@ -168,11 +167,4 @@ func ProcessFlags() {
Options.DisableTLS,
"Disable TLS on WebHook event listener.",
)

flag.BoolVar(
&Options.AgentInstallAll,
"agent-install-all",
false,
"Configure the install strategy of agent on managed clusters. "+
"Enabling this will automatically install agent on all managed cluster.")
}
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ require (
github.com/go-logr/logr v1.4.1
github.com/google/go-github/v42 v42.0.0
github.com/johannesboyne/gofakes3 v0.0.0-20210819161434-5c8dfcfe5310
github.com/onsi/ginkgo/v2 v2.14.0
github.com/onsi/gomega v1.30.0
github.com/onsi/ginkgo/v2 v2.15.0
github.com/onsi/gomega v1.31.1
github.com/openshift/api v0.0.0-20231218131639-7a5aa77cc72d
github.com/openshift/library-go v0.0.0-20240116081341-964bcb3f545c
github.com/operator-framework/operator-lib v0.11.1-0.20230717184314-6efbe3a22f6f
Expand All @@ -34,7 +34,7 @@ require (
k8s.io/client-go v0.29.4
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.120.1
open-cluster-management.io/addon-framework v0.9.1
open-cluster-management.io/addon-framework v0.9.2
open-cluster-management.io/api v0.13.0
open-cluster-management.io/multicloud-operators-channel v0.13.1-0.20240423040139-ad986cafc6e8
sigs.k8s.io/controller-runtime v0.17.3
Expand Down Expand Up @@ -117,7 +117,7 @@ require (
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/gorilla/mux v1.8.0 // indirect
github.com/gorilla/websocket v1.5.0 // indirect
github.com/gorilla/websocket v1.5.1 // indirect
github.com/gosuri/uitable v0.0.4 // indirect
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
Expand Down Expand Up @@ -196,8 +196,8 @@ require (
golang.org/x/tools v0.20.0 // indirect
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
gomodules.xyz/orderedmap v0.1.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 // indirect
google.golang.org/grpc v1.60.1 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
google.golang.org/grpc v1.62.1 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
Expand All @@ -211,7 +211,7 @@ require (
k8s.io/kube-openapi v0.0.0-20240411171206-dc4e619f62f3 // indirect
k8s.io/kubectl v0.29.0 // indirect
k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect
open-cluster-management.io/sdk-go v0.13.0 // indirect
open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379 // indirect
oras.land/oras-go v1.2.4 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/kube-storage-version-migrator v0.0.6-0.20230721195810-5c8923c5ff96 // indirect
Expand Down
28 changes: 14 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/gosuri/uitable v0.0.4 h1:IG2xLKRvErL3uhY6e1BylFzG+aJiwQviDDTfOKeKTpY=
github.com/gosuri/uitable v0.0.4/go.mod h1:tKR86bXuXPZazfOTG1FIzvjIdXzd0mo4Vtn16vt0PJo=
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 h1:+ngKgrYPPJrOjhax5N+uePQ0Fh1Z7PheYoUI/0nzkPA=
Expand Down Expand Up @@ -396,10 +396,10 @@ github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.14.0 h1:vSmGj2Z5YPb9JwCWT6z6ihcUvDhuXLc3sJiqd3jMKAY=
github.com/onsi/ginkgo/v2 v2.14.0/go.mod h1:JkUdW7JkN0V6rFvsHcJ478egV3XH9NxpD27Hal/PhZw=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
github.com/onsi/gomega v1.31.1 h1:KYppCUK+bUgAZwHOu7EXVBKyQA6ILvOESHkn/tgoqvo=
github.com/onsi/gomega v1.31.1/go.mod h1:y40C95dwAD1Nz36SsEnxvfFe8FFfNxzI5eJ0EYGyAy0=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0-rc5 h1:Ygwkfw9bpDvs+c9E34SdgGOj41dX/cbdlwvlWt0pnFI=
Expand Down Expand Up @@ -660,13 +660,13 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1 h1:gphdwh0npgs8elJ4T6J+DQJHPVF7RsuJHCfwztUb4J4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240108191215-35c7eff3a6b1/go.mod h1:daQN87bsDqDoe316QbbvX60nMoJQa4r6Ds0ZuoAe5yA=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU=
google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk=
google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
Expand Down Expand Up @@ -739,14 +739,14 @@ k8s.io/kubectl v0.29.0 h1:Oqi48gXjikDhrBF67AYuZRTcJV4lg2l42GmvsP7FmYI=
k8s.io/kubectl v0.29.0/go.mod h1:0jMjGWIcMIQzmUaMgAzhSELv5WtHo2a8pq67DtviAJs=
k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY=
k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
open-cluster-management.io/addon-framework v0.9.1 h1:m6n/W29G/4KzMx+8mgC9P/ybuiyNHVy+O6AHEaWbfQg=
open-cluster-management.io/addon-framework v0.9.1/go.mod h1:OEIFCEXhZKO/Grv08CB0T+TGzS0bLshw4G9u7Vw8dw0=
open-cluster-management.io/addon-framework v0.9.2 h1:oQnk6Y6433Fvi/MC8sWoy68lHzkqPsFLj7IEx07kFfU=
open-cluster-management.io/addon-framework v0.9.2/go.mod h1:LDkGLGTQh+sthF1qWlv87iMeAuRPsNEMK31O14kMneA=
open-cluster-management.io/api v0.13.0 h1:dlcJEZlNlE0DmSDctK2s7iWKg9l+Tgb0V78Z040nMuk=
open-cluster-management.io/api v0.13.0/go.mod h1:CuCPEzXDvOyxBB0H1d1eSeajbHqaeGEKq9c63vQc63w=
open-cluster-management.io/multicloud-operators-channel v0.13.1-0.20240423040139-ad986cafc6e8 h1:k4T+YMF29L8xiQ6vVvDSaTiCgmFRkoW8YwaLr4tFUWU=
open-cluster-management.io/multicloud-operators-channel v0.13.1-0.20240423040139-ad986cafc6e8/go.mod h1:OgoSFC50ADV76QRBL6Tm0CGK9oZ2mTmR3nH9702djrw=
open-cluster-management.io/sdk-go v0.13.0 h1:ddMGsPUekQr9z03tVN6vF39Uf+WEKMtGU/xSd81HdoA=
open-cluster-management.io/sdk-go v0.13.0/go.mod h1:UnsjzYOrDTF9a8rHEXksoIAtAdO1o5CD5Jtaw6T5B9w=
open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379 h1:8jXVHfgy+wgXq1mrWC1mTieoP77WsAAHNpzILMIzWB0=
open-cluster-management.io/sdk-go v0.13.1-0.20240416030555-aa744f426379/go.mod h1:w2OaxtCyegxeyFLU42UQ3oxUz01QdsBQkcHI17T/l48=
oras.land/oras-go v1.2.4 h1:djpBY2/2Cs1PV87GSJlxv4voajVOMZxqqtq9AB8YNvY=
oras.land/oras-go v1.2.4/go.mod h1:DYcGfb3YF1nKjcezfX2SNlDAeQFKSXmf+qrFmrh4324=
sigs.k8s.io/controller-runtime v0.17.3 h1:65QmN7r3FWgTxDMz9fvGnO1kbf2nu+acg9p2R9oYYYk=
Expand Down
Loading

0 comments on commit 25d7b3d

Please sign in to comment.