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

limit target namespaces #673

Merged
merged 6 commits into from
Nov 5, 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
1 change: 1 addition & 0 deletions cyclops-ctrl/.env
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ PORT=8888
WATCH_NAMESPACE=cyclops
WATCH_NAMESPACE_HELM=
CYCLOPS_VERSION=v0.0.0
MODULE_TARGET_NAMESPACE=
14 changes: 12 additions & 2 deletions cyclops-ctrl/cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,14 @@ func main() {

watchNamespace := getWatchNamespace()
helmWatchNamespace := getHelmWatchNamespace()
moduleTargetNamespace := getModuleTargetNamespace()

k8sClient, err := k8sclient.New(watchNamespace, helmWatchNamespace, zap.New(zap.UseFlagOptions(&opts)))
k8sClient, err := k8sclient.New(
watchNamespace,
helmWatchNamespace,
moduleTargetNamespace,
zap.New(zap.UseFlagOptions(&opts)),
)
if err != nil {
fmt.Println("error bootstrapping Kubernetes client", err)
panic(err)
Expand All @@ -96,7 +102,7 @@ func main() {

helmReleaseClient := helm.NewReleaseClient(helmWatchNamespace)

handler, err := handler.New(templatesRepo, k8sClient, helmReleaseClient, renderer, telemetryClient, monitor)
handler, err := handler.New(templatesRepo, k8sClient, helmReleaseClient, renderer, moduleTargetNamespace, telemetryClient, monitor)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -175,6 +181,10 @@ func getWatchNamespace() string {
return value
}

func getModuleTargetNamespace() string {
return os.Getenv("MODULE_TARGET_NAMESPACE")
}

func getHelmWatchNamespace() string {
value := os.Getenv("WATCH_NAMESPACE_HELM")
if value == "" {
Expand Down
11 changes: 4 additions & 7 deletions cyclops-ctrl/internal/controller/cluster.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package controller

import (
"fmt"
"net/http"

"github.com/gin-gonic/gin"
Expand All @@ -27,7 +26,7 @@ func (c *Cluster) ListNodes(ctx *gin.Context) {

nodes, err := c.kubernetesClient.ListNodes()
if err != nil {
ctx.Status(http.StatusInternalServerError)
ctx.JSON(http.StatusInternalServerError, dto.NewError("Error fetching nodes", err.Error()))
return
}

Expand All @@ -48,15 +47,13 @@ func (c *Cluster) GetNode(ctx *gin.Context) {
return
}
if err != nil {
ctx.Status(http.StatusInternalServerError)
ctx.JSON(http.StatusInternalServerError, dto.NewError("Error fetching node", err.Error()))
return
}

pods, err := c.kubernetesClient.GetPodsForNode(nodeName)
if err != nil {
ctx.JSON(http.StatusInternalServerError, dto.Error{
Message: fmt.Sprintf("Error listing pods for node: %v", nodeName),
})
ctx.JSON(http.StatusInternalServerError, dto.NewError("Error fetching pod nodes", err.Error()))
return
}

Expand All @@ -70,7 +67,7 @@ func (c *Cluster) ListNamespaces(ctx *gin.Context) {

namespaces, err := c.kubernetesClient.ListNamespaces()
if err != nil {
ctx.Status(http.StatusInternalServerError)
ctx.JSON(http.StatusInternalServerError, dto.NewError("Error fetching namespaces", err.Error()))
return
}

Expand Down
25 changes: 17 additions & 8 deletions cyclops-ctrl/internal/controller/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,28 @@ type Modules struct {
kubernetesClient k8sclient.IKubernetesClient
templatesRepo template.ITemplateRepo
renderer *render.Renderer
telemetryClient telemetry.Client
monitor prometheus.Monitor

moduleTargetNamespace string

telemetryClient telemetry.Client
monitor prometheus.Monitor
}

func NewModulesController(
templatesRepo template.ITemplateRepo,
kubernetes k8sclient.IKubernetesClient,
renderer *render.Renderer,
moduleTargetNamespace string,
telemetryClient telemetry.Client,
monitor prometheus.Monitor,
) *Modules {
return &Modules{
kubernetesClient: kubernetes,
templatesRepo: templatesRepo,
renderer: renderer,
telemetryClient: telemetryClient,
monitor: monitor,
kubernetesClient: kubernetes,
templatesRepo: templatesRepo,
renderer: renderer,
moduleTargetNamespace: moduleTargetNamespace,
telemetryClient: telemetryClient,
monitor: monitor,
}
}

Expand All @@ -53,7 +58,7 @@ func (m *Modules) GetModule(ctx *gin.Context) {
module, err := m.kubernetesClient.GetModule(ctx.Param("name"))
if err != nil {
fmt.Println(err)
ctx.Status(http.StatusInternalServerError)
ctx.JSON(http.StatusInternalServerError, dto.NewError("Error fetching module", err.Error()))
return
}

Expand Down Expand Up @@ -268,6 +273,10 @@ func (m *Modules) CreateModule(ctx *gin.Context) {
return
}

if len(m.moduleTargetNamespace) > 0 {
module.Spec.TargetNamespace = m.moduleTargetNamespace
}

m.telemetryClient.ModuleCreation()

err = m.kubernetesClient.CreateModule(module)
Expand Down
4 changes: 2 additions & 2 deletions cyclops-ctrl/internal/controller/tests/cluster_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,8 @@ var _ = Describe("Cluster controller test", func() {

Expect(err).To(BeNil())
Expect(w.Code).To(BeEquivalentTo(http.StatusInternalServerError))
Expect(e.Message).To(BeEquivalentTo("Error listing pods for node: my-node"))
Expect(e.Description).To(BeEquivalentTo(""))
Expect(e.Message).To(BeEquivalentTo("Error fetching pod nodes"))
Expect(e.Description).To(BeEquivalentTo("nodes \"whereisit\" not found"))
})
})

Expand Down
20 changes: 12 additions & 8 deletions cyclops-ctrl/internal/handler/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ type Handler struct {
releaseClient *helm.ReleaseClient
renderer *render.Renderer

moduleTargetNamespace string

telemetryClient telemetry.Client
monitor prometheus.Monitor
}
Expand All @@ -31,25 +33,27 @@ func New(
kubernetesClient k8sclient.IKubernetesClient,
releaseClient *helm.ReleaseClient,
renderer *render.Renderer,
moduleTargetNamespace string,
telemetryClient telemetry.Client,
monitor prometheus.Monitor,
) (*Handler, error) {
return &Handler{
templatesRepo: templatesRepo,
k8sClient: kubernetesClient,
renderer: renderer,
releaseClient: releaseClient,
telemetryClient: telemetryClient,
monitor: monitor,
router: gin.New(),
templatesRepo: templatesRepo,
k8sClient: kubernetesClient,
renderer: renderer,
releaseClient: releaseClient,
moduleTargetNamespace: moduleTargetNamespace,
telemetryClient: telemetryClient,
monitor: monitor,
router: gin.New(),
}, nil
}

func (h *Handler) Start() error {
gin.SetMode(gin.DebugMode)

templatesController := controller.NewTemplatesController(h.templatesRepo, h.k8sClient, h.telemetryClient)
modulesController := controller.NewModulesController(h.templatesRepo, h.k8sClient, h.renderer, h.telemetryClient, h.monitor)
modulesController := controller.NewModulesController(h.templatesRepo, h.k8sClient, h.renderer, h.moduleTargetNamespace, h.telemetryClient, h.monitor)
clusterController := controller.NewClusterController(h.k8sClient)
helmController := controller.NewHelmController(h.k8sClient, h.releaseClient, h.telemetryClient)

Expand Down
19 changes: 10 additions & 9 deletions cyclops-ctrl/internal/modulecontroller/module_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,16 @@ func (r *ModuleReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr

if len(installErrors) != 0 {
r.monitor.OnFailedReconciliation()

r.logger.Info("error applying resources",
"module namespaced name",
module.Name,
"number of install errors",
len(installErrors),
"install errors",
installErrors,
)

return ctrl.Result{}, r.setStatus(
ctx,
module,
Expand Down Expand Up @@ -305,15 +315,6 @@ func (r *ModuleReconciler) generateResources(
childrenGVRs = append(childrenGVRs, gvr)

if err := kClient.CreateDynamic(gvr, &obj, module.Spec.TargetNamespace); err != nil {
r.logger.Error(err, "could not apply resource",
"module namespaced name",
module.Name,
"gvk",
obj.GroupVersionKind().String(),
"resource namespaced name",
fmt.Sprintf("%s/%s", obj.GetNamespace(), obj.GetName()),
)

installErrors = append(installErrors, fmt.Sprintf(
"%v%v/%v %v/%v failed to apply: %v",
obj.GroupVersionKind().Group,
Expand Down
36 changes: 22 additions & 14 deletions cyclops-ctrl/pkg/cluster/k8sclient/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,24 @@ import (
)

type KubernetesClient struct {
Dynamic dynamic.Interface
clientset *kubernetes.Clientset
discovery *discovery.DiscoveryClient
moduleset *client.CyclopsV1Alpha1Client
moduleNamespace string
helmReleaseNamespace string
Dynamic dynamic.Interface
clientset *kubernetes.Clientset
discovery *discovery.DiscoveryClient
moduleset *client.CyclopsV1Alpha1Client

moduleNamespace string
helmReleaseNamespace string
moduleTargetNamespace string

logger logr.Logger
}

func New(moduleNamespace, helmReleaseNamespace string, logger logr.Logger) (*KubernetesClient, error) {
func New(
moduleNamespace string,
helmReleaseNamespace string,
moduleTargetNamespace string,
logger logr.Logger,
) (*KubernetesClient, error) {
config := ctrl.GetConfigOrDie()
clientset, err := kubernetes.NewForConfig(config)
if err != nil {
Expand All @@ -50,13 +57,14 @@ func New(moduleNamespace, helmReleaseNamespace string, logger logr.Logger) (*Kub
}

return &KubernetesClient{
Dynamic: dynamic,
discovery: discovery,
clientset: clientset,
moduleset: moduleSet,
moduleNamespace: moduleNamespace,
helmReleaseNamespace: helmReleaseNamespace,
logger: logger,
Dynamic: dynamic,
discovery: discovery,
clientset: clientset,
moduleset: moduleSet,
moduleNamespace: moduleNamespace,
helmReleaseNamespace: helmReleaseNamespace,
moduleTargetNamespace: moduleTargetNamespace,
logger: logger,
}, nil
}

Expand Down
23 changes: 16 additions & 7 deletions cyclops-ctrl/pkg/cluster/k8sclient/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,28 @@ func (k *KubernetesClient) GetResourcesForRelease(releaseName string) ([]dto.Res
}

other := make([]unstructured.Unstructured, 0)
listOptions := metav1.ListOptions{
LabelSelector: labels.Set(map[string]string{
"app.kubernetes.io/instance": releaseName,
"app.kubernetes.io/managed-by": "Helm",
}).String(),
}

for _, gvr := range managedGVRs {
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(),
})
var rs *unstructured.UnstructuredList
var err error
if len(k.helmReleaseNamespace) > 0 {
rs, err = k.Dynamic.Resource(gvr).Namespace(k.helmReleaseNamespace).List(context.Background(), listOptions)
} else {
rs, err = k.Dynamic.Resource(gvr).List(context.Background(), listOptions)
}

if err != nil {
if apierrors.IsNotFound(err) {
continue
}

k.logger.Error(err, "failed to list resources", "gvr", gvr, "namespace", k.helmReleaseNamespace)
k.logger.Info("failed to list resources", "gvr", gvr, "namespace", k.helmReleaseNamespace)
continue
}

Expand Down
Loading
Loading