From 488967365a6c53802cc49ef5d32f898c84c73b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Cvitanovi=C4=87?= <72022639+petar-cvit@users.noreply.github.com> Date: Mon, 4 Nov 2024 13:00:51 +0100 Subject: [PATCH 1/2] set k8s client namespace (#670) --- cyclops-ctrl/cmd/main/main.go | 6 ++-- cyclops-ctrl/pkg/cluster/k8sclient/client.go | 31 +++++++------------ cyclops-ctrl/pkg/cluster/k8sclient/modules.go | 12 +++---- .../cluster/k8sclient/templateauthrules.go | 4 +-- .../pkg/cluster/k8sclient/templatestore.go | 10 +++--- 5 files changed, 28 insertions(+), 35 deletions(-) diff --git a/cyclops-ctrl/cmd/main/main.go b/cyclops-ctrl/cmd/main/main.go index 12fc3773..d9d30029 100644 --- a/cyclops-ctrl/cmd/main/main.go +++ b/cyclops-ctrl/cmd/main/main.go @@ -71,7 +71,9 @@ func main() { ) telemetryClient.InstanceStart() - k8sClient, err := k8sclient.New() + watchNamespace := getWatchNamespace() + + k8sClient, err := k8sclient.New(watchNamespace) if err != nil { fmt.Println("error bootstrapping Kubernetes client", err) panic(err) @@ -113,7 +115,7 @@ func main() { }), Cache: ctrlCache.Options{ DefaultNamespaces: map[string]ctrlCache.Config{ - getWatchNamespace(): {}, + watchNamespace: {}, }, }, }) diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/client.go b/cyclops-ctrl/pkg/cluster/k8sclient/client.go index bc282524..2e1c1fd2 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/client.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/client.go @@ -18,25 +18,15 @@ import ( "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/dto" ) -const ( - cyclopsNamespace = "cyclops" -) - type KubernetesClient struct { - Dynamic dynamic.Interface - - clientset *kubernetes.Clientset - - discovery *discovery.DiscoveryClient - - moduleset *client.CyclopsV1Alpha1Client -} - -func New() (*KubernetesClient, error) { - return createLocalClient() + Dynamic dynamic.Interface + clientset *kubernetes.Clientset + discovery *discovery.DiscoveryClient + moduleset *client.CyclopsV1Alpha1Client + moduleNamespace string } -func createLocalClient() (*KubernetesClient, error) { +func New(moduleNamespace string) (*KubernetesClient, error) { config := ctrl.GetConfigOrDie() clientset, err := kubernetes.NewForConfig(config) if err != nil { @@ -56,10 +46,11 @@ func createLocalClient() (*KubernetesClient, error) { } return &KubernetesClient{ - Dynamic: dynamic, - discovery: discovery, - clientset: clientset, - moduleset: moduleSet, + Dynamic: dynamic, + discovery: discovery, + clientset: clientset, + moduleset: moduleSet, + moduleNamespace: moduleNamespace, }, nil } diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go index e7902a09..7f93b472 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go @@ -30,31 +30,31 @@ const ( ) func (k *KubernetesClient) ListModules() ([]cyclopsv1alpha1.Module, error) { - moduleList, err := k.moduleset.Modules(cyclopsNamespace).List(metav1.ListOptions{}) + moduleList, err := k.moduleset.Modules(k.moduleNamespace).List(metav1.ListOptions{}) return moduleList, err } func (k *KubernetesClient) CreateModule(module cyclopsv1alpha1.Module) error { - _, err := k.moduleset.Modules(cyclopsNamespace).Create(&module) + _, err := k.moduleset.Modules(k.moduleNamespace).Create(&module) return err } func (k *KubernetesClient) UpdateModule(module *cyclopsv1alpha1.Module) error { - _, err := k.moduleset.Modules(cyclopsNamespace).Update(module) + _, err := k.moduleset.Modules(k.moduleNamespace).Update(module) return err } func (k *KubernetesClient) UpdateModuleStatus(module *cyclopsv1alpha1.Module) (*cyclopsv1alpha1.Module, error) { - return k.moduleset.Modules(cyclopsNamespace).PatchStatus(module) + return k.moduleset.Modules(k.moduleNamespace).PatchStatus(module) } func (k *KubernetesClient) DeleteModule(name string) error { - return k.moduleset.Modules(cyclopsNamespace).Delete(name) + return k.moduleset.Modules(k.moduleNamespace).Delete(name) } func (k *KubernetesClient) GetModule(name string) (*cyclopsv1alpha1.Module, error) { - return k.moduleset.Modules(cyclopsNamespace).Get(name) + return k.moduleset.Modules(k.moduleNamespace).Get(name) } func (k *KubernetesClient) GetResourcesForModule(name string) ([]dto.Resource, error) { diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/templateauthrules.go b/cyclops-ctrl/pkg/cluster/k8sclient/templateauthrules.go index 6b00d084..c43c9baf 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/templateauthrules.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/templateauthrules.go @@ -10,11 +10,11 @@ import ( ) func (k *KubernetesClient) ListTemplateAuthRules() ([]cyclopsv1alpha1.TemplateAuthRule, error) { - return k.moduleset.TemplateAuthRules(cyclopsNamespace).List(metav1.ListOptions{}) + return k.moduleset.TemplateAuthRules(k.moduleNamespace).List(metav1.ListOptions{}) } func (k *KubernetesClient) GetTemplateAuthRuleSecret(name, key string) (string, error) { - secret, err := k.clientset.CoreV1().Secrets(cyclopsNamespace).Get(context.Background(), name, metav1.GetOptions{}) + secret, err := k.clientset.CoreV1().Secrets(k.moduleNamespace).Get(context.Background(), name, metav1.GetOptions{}) if err != nil { return "", err } diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/templatestore.go b/cyclops-ctrl/pkg/cluster/k8sclient/templatestore.go index 5cb15274..8d66ec74 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/templatestore.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/templatestore.go @@ -7,26 +7,26 @@ import ( ) func (k *KubernetesClient) ListTemplateStore() ([]cyclopsv1alpha1.TemplateStore, error) { - return k.moduleset.TemplateStore(cyclopsNamespace).List(metav1.ListOptions{}) + return k.moduleset.TemplateStore(k.moduleNamespace).List(metav1.ListOptions{}) } func (k *KubernetesClient) CreateTemplateStore(ts *cyclopsv1alpha1.TemplateStore) error { - _, err := k.moduleset.TemplateStore(cyclopsNamespace).Create(ts) + _, err := k.moduleset.TemplateStore(k.moduleNamespace).Create(ts) return err } func (k *KubernetesClient) UpdateTemplateStore(ts *cyclopsv1alpha1.TemplateStore) error { - curr, err := k.moduleset.TemplateStore(cyclopsNamespace).Get(ts.Name) + curr, err := k.moduleset.TemplateStore(k.moduleNamespace).Get(ts.Name) if err != nil { return err } ts.SetResourceVersion(curr.GetResourceVersion()) - _, err = k.moduleset.TemplateStore(cyclopsNamespace).Update(ts) + _, err = k.moduleset.TemplateStore(k.moduleNamespace).Update(ts) return err } func (k *KubernetesClient) DeleteTemplateStore(name string) error { - return k.moduleset.TemplateStore(cyclopsNamespace).Delete(name) + return k.moduleset.TemplateStore(k.moduleNamespace).Delete(name) } From b0784903b81d1702b9fbaba7f22c39bfbbe5882f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petar=20Cvitanovi=C4=87?= <72022639+petar-cvit@users.noreply.github.com> Date: Mon, 4 Nov 2024 14:37:37 +0100 Subject: [PATCH 2/2] Namespaced resource fetching (#671) * set k8s client namespace * scope resource fetching * scope resource fetching * ckip not found --- cyclops-ctrl/cmd/main/main.go | 5 ++-- .../internal/integrations/helm/helm.go | 2 -- cyclops-ctrl/pkg/cluster/k8sclient/client.go | 28 +++++++++++-------- cyclops-ctrl/pkg/cluster/k8sclient/helm.go | 20 +++++++++---- cyclops-ctrl/pkg/cluster/k8sclient/modules.go | 1 + 5 files changed, 35 insertions(+), 21 deletions(-) diff --git a/cyclops-ctrl/cmd/main/main.go b/cyclops-ctrl/cmd/main/main.go index d9d30029..1f905812 100644 --- a/cyclops-ctrl/cmd/main/main.go +++ b/cyclops-ctrl/cmd/main/main.go @@ -72,8 +72,9 @@ func main() { telemetryClient.InstanceStart() watchNamespace := getWatchNamespace() + helmWatchNamespace := getHelmWatchNamespace() - k8sClient, err := k8sclient.New(watchNamespace) + k8sClient, err := k8sclient.New(watchNamespace, helmWatchNamespace, zap.New(zap.UseFlagOptions(&opts))) if err != nil { fmt.Println("error bootstrapping Kubernetes client", err) panic(err) @@ -93,7 +94,7 @@ func main() { prometheus.StartCacheMetricsUpdater(&monitor, templatesRepo.ReturnCache(), 10*time.Second, setupLog) - helmReleaseClient := helm.NewReleaseClient(getHelmWatchNamespace()) + helmReleaseClient := helm.NewReleaseClient(helmWatchNamespace) handler, err := handler.New(templatesRepo, k8sClient, helmReleaseClient, renderer, telemetryClient, monitor) if err != nil { diff --git a/cyclops-ctrl/internal/integrations/helm/helm.go b/cyclops-ctrl/internal/integrations/helm/helm.go index b6f2795e..41223eba 100644 --- a/cyclops-ctrl/internal/integrations/helm/helm.go +++ b/cyclops-ctrl/internal/integrations/helm/helm.go @@ -4,7 +4,6 @@ import ( "fmt" "io" "log" - "path" "strings" "github.com/pkg/errors" @@ -104,7 +103,6 @@ func (r *ReleaseClient) UpgradeRelease( client.SetRegistryClient(registryClient) for _, dependency := range current.Chart.Metadata.Dependencies { - fmt.Println(dependency.Repository, dependency.Name, path.Join(dependency.Repository, dependency.Name)) fp, err := client.LocateChart(dependency.Repository+"/"+dependency.Name, cli.New()) if err != nil { return errors.Wrap(err, "failed to locate dependency chart") diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/client.go b/cyclops-ctrl/pkg/cluster/k8sclient/client.go index 2e1c1fd2..8d39751e 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/client.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/client.go @@ -3,6 +3,7 @@ package k8sclient import ( "context" + "github.com/go-logr/logr" apiv1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" @@ -19,14 +20,17 @@ import ( ) type KubernetesClient struct { - Dynamic dynamic.Interface - clientset *kubernetes.Clientset - discovery *discovery.DiscoveryClient - moduleset *client.CyclopsV1Alpha1Client - moduleNamespace string + Dynamic dynamic.Interface + clientset *kubernetes.Clientset + discovery *discovery.DiscoveryClient + moduleset *client.CyclopsV1Alpha1Client + moduleNamespace string + helmReleaseNamespace string + + logger logr.Logger } -func New(moduleNamespace string) (*KubernetesClient, error) { +func New(moduleNamespace, helmReleaseNamespace string, logger logr.Logger) (*KubernetesClient, error) { config := ctrl.GetConfigOrDie() clientset, err := kubernetes.NewForConfig(config) if err != nil { @@ -46,11 +50,13 @@ func New(moduleNamespace string) (*KubernetesClient, error) { } return &KubernetesClient{ - Dynamic: dynamic, - discovery: discovery, - clientset: clientset, - moduleset: moduleSet, - moduleNamespace: moduleNamespace, + Dynamic: dynamic, + discovery: discovery, + clientset: clientset, + moduleset: moduleSet, + moduleNamespace: moduleNamespace, + helmReleaseNamespace: helmReleaseNamespace, + logger: logger, }, nil } diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/helm.go b/cyclops-ctrl/pkg/cluster/k8sclient/helm.go index 3d66a8fe..fe22e67e 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/helm.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/helm.go @@ -2,12 +2,15 @@ package k8sclient import ( "context" - "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/dto" + "sort" + + apierrors "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/labels" "k8s.io/apimachinery/pkg/runtime/schema" - "sort" + + "github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/models/dto" ) func (k *KubernetesClient) GetResourcesForRelease(releaseName string) ([]dto.Resource, error) { @@ -36,13 +39,18 @@ func (k *KubernetesClient) GetResourcesForRelease(releaseName string) ([]dto.Res other := make([]unstructured.Unstructured, 0) for _, gvr := range managedGVRs { - rs, err := k.Dynamic.Resource(gvr).List(context.Background(), metav1.ListOptions{ + rs, err := k.Dynamic.Resource(gvr).Namespace(k.helmReleaseNamespace).List(context.Background(), metav1.ListOptions{ LabelSelector: labels.Set(map[string]string{ "app.kubernetes.io/instance": releaseName, "app.kubernetes.io/managed-by": "Helm", }).String(), }) if err != nil { + if apierrors.IsNotFound(err) { + continue + } + + k.logger.Error(err, "failed to list resources", "gvr", gvr, "namespace", k.helmReleaseNamespace) continue } @@ -82,7 +90,7 @@ func (k *KubernetesClient) GetResourcesForRelease(releaseName string) ([]dto.Res func (k *KubernetesClient) GetWorkloadsForRelease(releaseName string) ([]dto.Resource, error) { out := make([]dto.Resource, 0, 0) - deployments, err := k.clientset.AppsV1().Deployments("").List(context.Background(), metav1.ListOptions{ + deployments, err := k.clientset.AppsV1().Deployments(k.helmReleaseNamespace).List(context.Background(), metav1.ListOptions{ LabelSelector: labels.Set(map[string]string{ "app.kubernetes.io/instance": releaseName, "app.kubernetes.io/managed-by": "Helm", @@ -102,7 +110,7 @@ func (k *KubernetesClient) GetWorkloadsForRelease(releaseName string) ([]dto.Res }) } - statefulset, err := k.clientset.AppsV1().StatefulSets("").List(context.Background(), metav1.ListOptions{ + statefulset, err := k.clientset.AppsV1().StatefulSets(k.helmReleaseNamespace).List(context.Background(), metav1.ListOptions{ LabelSelector: labels.Set(map[string]string{ "app.kubernetes.io/instance": releaseName, "app.kubernetes.io/managed-by": "Helm", @@ -122,7 +130,7 @@ func (k *KubernetesClient) GetWorkloadsForRelease(releaseName string) ([]dto.Res }) } - daemonsets, err := k.clientset.AppsV1().DaemonSets("").List(context.Background(), metav1.ListOptions{ + daemonsets, err := k.clientset.AppsV1().DaemonSets(k.helmReleaseNamespace).List(context.Background(), metav1.ListOptions{ LabelSelector: labels.Set(map[string]string{ "app.kubernetes.io/instance": releaseName, "app.kubernetes.io/managed-by": "Helm", diff --git a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go index 7f93b472..db860a96 100644 --- a/cyclops-ctrl/pkg/cluster/k8sclient/modules.go +++ b/cyclops-ctrl/pkg/cluster/k8sclient/modules.go @@ -71,6 +71,7 @@ func (k *KubernetesClient) GetResourcesForModule(name string) ([]dto.Resource, e LabelSelector: "cyclops.module=" + name, }) if err != nil { + k.logger.Error(err, "failed to list resources", "gvr", gvr, "namespace", k.helmReleaseNamespace) continue }