Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add watcher for the secret used in the discovery config #504

Merged
merged 5 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ CRD_OPTIONS ?= "crd:crdVersions=v1"
ENVTEST_K8S_VERSION = 1.25

# Namespace to deploy resources into
NAMESPACE ?= open-cluster-management
NAMESPACE ?= multicluster-engine

# Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set)
ifeq (,$(shell go env GOBIN))
Expand Down Expand Up @@ -88,7 +88,7 @@ secret: ## Generate secret for OCM access
config: ## Create custom resources
cd config/samples && $(KUSTOMIZE) edit set namespace $(NAMESPACE)
$(KUSTOMIZE) build config/samples | kubectl apply -f -
cd config/samples && $(KUSTOMIZE) edit set namespace open-cluster-management
cd config/samples && $(KUSTOMIZE) edit set namespace multicluster-engine

logs: ## Print operator logs
@kubectl logs -f $(shell kubectl get pod -l app=discovery-operator -o jsonpath="{.items[0].metadata.name}")
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,11 @@ The discovery operator generates `DiscoveredClusters` based on a `DiscoveryConfi
make secret OCM_API_TOKEN=<OpenShift Cluster Manager API Token>
```

The OpenShift Cluster Manager API Token can be retrieved from [here](https://cloud.redhat.com/openshift/token). This will create a secret named `ocm-api-token` in the current namespace. With the secret created you can then create the `DiscoveryConfig` resource using the following command:
The OpenShift Cluster Manager API Token can be retrieved from [here](https://cloud.redhat.com/openshift/token). This will create a secret named `ocm-api-token` in the current namespace. With the secret created you can then create the `DiscoveryConfig` resource using the following commands:

```shell
make samples
make secret
make connfig
```

This will create a `DiscoveryConfig` like the example below:
Expand Down
5 changes: 3 additions & 2 deletions controllers/discoveryconfig_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
ref "k8s.io/client-go/tools/reference"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/log"

discovery "github.com/stolostron/discovery/api/v1"
Expand Down Expand Up @@ -107,10 +108,10 @@ func (r *DiscoveryConfigReconciler) Reconcile(ctx context.Context, req ctrl.Requ
}

// SetupWithManager ...
func (r *DiscoveryConfigReconciler) SetupWithManager(mgr ctrl.Manager) error {
func (r *DiscoveryConfigReconciler) SetupWithManager(mgr ctrl.Manager) (controller.Controller, error) {
return ctrl.NewControllerManagedBy(mgr).
For(&discovery.DiscoveryConfig{}).
Complete(r)
Build(r)
}

func (r *DiscoveryConfigReconciler) updateDiscoveredClusters(ctx context.Context, config *discovery.DiscoveryConfig) error {
Expand Down
5 changes: 1 addition & 4 deletions controllers/managedcluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,7 @@ func (r *ManagedClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
return errors.Wrapf(err, "error creating controller")
}

if err := c.Watch(
&source.Channel{Source: r.Trigger},
&handler.EnqueueRequestForObject{},
); err != nil {
if err := c.Watch(source.Channel(r.Trigger, &handler.EnqueueRequestForObject{})); err != nil {
return errors.Wrapf(err, "failed adding a watch channel")
}

Expand Down
2 changes: 1 addition & 1 deletion controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var _ = BeforeSuite(func() {
})
Expect(err).ToNot(HaveOccurred())

err = (&DiscoveryConfigReconciler{
_, err = (&DiscoveryConfigReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
}).SetupWithManager(k8sManager)
Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ require (
github.com/stolostron/klusterlet-addon-controller v0.0.0-20240229083605-8bd4a2ae81c0
github.com/stretchr/testify v1.9.0
go.uber.org/zap v1.27.0
k8s.io/api v0.29.3
k8s.io/apiextensions-apiserver v0.29.3
k8s.io/apimachinery v0.29.3
k8s.io/client-go v0.29.3
k8s.io/api v0.30.1
k8s.io/apiextensions-apiserver v0.30.1
k8s.io/apimachinery v0.30.1
k8s.io/client-go v0.30.1
k8s.io/metrics v0.29.3
open-cluster-management.io/api v0.13.0
sigs.k8s.io/controller-runtime v0.17.2
sigs.k8s.io/controller-runtime v0.18.5
sigs.k8s.io/yaml v1.4.0
)

Expand Down Expand Up @@ -89,7 +89,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/component-base v0.29.3 // indirect
k8s.io/component-base v0.30.1 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kube-openapi v0.0.0-20240403164606-bc84c2ddaf99 // indirect
k8s.io/utils v0.0.0-20240310230437-4693a0247e57 // indirect
Expand Down
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -243,14 +243,24 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
k8s.io/api v0.29.3 h1:2ORfZ7+bGC3YJqGpV0KSDDEVf8hdGQ6A03/50vj8pmw=
k8s.io/api v0.29.3/go.mod h1:y2yg2NTyHUUkIoTC+phinTnEa3KFM6RZ3szxt014a80=
k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY=
k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM=
k8s.io/apiextensions-apiserver v0.29.3 h1:9HF+EtZaVpFjStakF4yVufnXGPRppWFEQ87qnO91YeI=
k8s.io/apiextensions-apiserver v0.29.3/go.mod h1:po0XiY5scnpJfFizNGo6puNU6Fq6D70UJY2Cb2KwAVc=
k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws=
k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4=
k8s.io/apimachinery v0.29.3 h1:2tbx+5L7RNvqJjn7RIuIKu9XTsIZ9Z5wX2G22XAa5EU=
k8s.io/apimachinery v0.29.3/go.mod h1:hx/S4V2PNW4OMg3WizRrHutyB5la0iCUbZym+W0EQIU=
k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U=
k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
k8s.io/client-go v0.29.3 h1:R/zaZbEAxqComZ9FHeQwOh3Y1ZUs7FaHKZdQtIc2WZg=
k8s.io/client-go v0.29.3/go.mod h1:tkDisCvgPfiRpxGnOORfkljmS+UrW+WtXAy2fTvXJB0=
k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q=
k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc=
k8s.io/component-base v0.29.3 h1:Oq9/nddUxlnrCuuR2K/jp6aflVvc0uDvxMzAWxnGzAo=
k8s.io/component-base v0.29.3/go.mod h1:Yuj33XXjuOk2BAaHsIGHhCKZQAgYKhqIxIjIr2UXYio=
k8s.io/component-base v0.30.1 h1:bvAtlPh1UrdaZL20D9+sWxsJljMi0QZ3Lmw+kmZAaxQ=
k8s.io/component-base v0.30.1/go.mod h1:e/X9kDiOebwlI41AvBHuWdqFriSRrX50CdwA9TFaHLI=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=
k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
k8s.io/kube-openapi v0.0.0-20240403164606-bc84c2ddaf99 h1:w6nThEmGo9zcL+xH1Tu6pjxJ3K1jXFW+V0u4peqN8ks=
Expand All @@ -265,6 +275,8 @@ open-cluster-management.io/api v0.13.0/go.mod h1:CuCPEzXDvOyxBB0H1d1eSeajbHqaeGE
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
sigs.k8s.io/controller-runtime v0.17.2 h1:FwHwD1CTUemg0pW2otk7/U5/i5m2ymzvOXdbeGOUvw0=
sigs.k8s.io/controller-runtime v0.17.2/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s=
sigs.k8s.io/controller-runtime v0.18.5 h1:nTHio/W+Q4aBlQMgbnC5hZb4IjIidyrizMai9P6n4Rk=
sigs.k8s.io/controller-runtime v0.18.5/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4=
Expand Down
57 changes: 51 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import (

goruntime "runtime"

"k8s.io/client-go/util/workqueue"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/source"

"go.uber.org/zap/zapcore"
admissionregistration "k8s.io/api/admissionregistration/v1"
apixv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand All @@ -47,10 +52,11 @@ import (
clusterapiv1beta2 "open-cluster-management.io/api/cluster/v1beta2"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/event"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/webhook"

apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
Expand All @@ -69,8 +75,9 @@ const (
)

var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
discoveryConfigController controller.Controller

ControllerError = "unable to create controller"
)
Expand Down Expand Up @@ -159,10 +166,12 @@ func main() {

events := make(chan event.GenericEvent)

if err = (&controllers.DiscoveryConfigReconciler{
discoveryConfigReconciler := &controllers.DiscoveryConfigReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}).SetupWithManager(mgr); err != nil {
}
discoveryConfigController, err = discoveryConfigReconciler.SetupWithManager(mgr)
if err != nil {
setupLog.Error(err, ControllerError, "controller", "DiscoveryConfig")
os.Exit(1)
}
Expand Down Expand Up @@ -208,6 +217,8 @@ func main() {
os.Exit(1)
}

go addDiscoverySecretWatch(context.Background(), mgr, uncachedClient)

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
Expand All @@ -233,7 +244,7 @@ func ensureWebhooks(k8sClient client.Client) error {
// This way if the CRD is deleted the webhook will be removed with it
crdKey := types.NamespacedName{Name: crdName}
owner := &apixv1.CustomResourceDefinition{}
if err := k8sClient.Get(context.TODO(), crdKey, owner); err != nil {
if err := k8sClient.Get(context.Background(), crdKey, owner); err != nil {
setupLog.Error(err, "Failed to get DiscoveredCluster CRD")
time.Sleep(5 * time.Second)
continue
Expand Down Expand Up @@ -284,3 +295,37 @@ func ensureWebhooks(k8sClient client.Client) error {
}
return fmt.Errorf("unable to ensure validatingwebhook exists in allotted time")
}

func addDiscoverySecretWatch(ctx context.Context, mgr ctrl.Manager, uncachedClient client.Client) {
for {
config := &discoveryv1.DiscoveryConfig{}
configName := "discovery"
err := uncachedClient.Get(ctx, types.NamespacedName{Name: configName}, config)
// Create the event handler
if err == nil {
err := discoveryConfigController.Watch(source.Kind(mgr.GetCache(), &corev1.Secret{},
handler.TypedFuncs[*corev1.Secret]{
UpdateFunc: func(ctx context.Context, e event.TypedUpdateEvent[*corev1.Secret], q workqueue.RateLimitingInterface) {
updatedSecret := e.ObjectNew
if updatedSecret.Name == config.Spec.Credential && updatedSecret.Namespace == config.Namespace {
q.Add(
reconcile.Request{
NamespacedName: types.NamespacedName{
Name: config.Name,
Namespace: config.Namespace,
},
},
)
}
},
}))
if err == nil {
setupLog.Info("secret watch added")
return
}
}

// If we encounter an error, wait and retry
time.Sleep(30 * time.Second)
}
}
Loading