Skip to content

Commit

Permalink
Merge branch 'cyclops-ui:main' into feat/replicaset-in-deployments
Browse files Browse the repository at this point in the history
  • Loading branch information
naineel1209 authored Nov 7, 2024
2 parents a952656 + 1df8204 commit d18414e
Show file tree
Hide file tree
Showing 34 changed files with 441 additions and 162 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,9 @@ Start your contributing journey at our [CONTRIBUTING.md](./CONTRIBUTING.md) and
- **Support for Kustomize** -> currently, only Helm is supported for creating templates
- **`cyctl` for Windows** -> Chocolatey
- **Customizable Module details page** -> create custom views of resources that your module uses

## 👁️ Share your feedback

**Are you using Cyclops at your company?** We'd love to hear directly from you about how you're using (or planning to use) Cyclops! Chat with us for **30 minutes** about your use case and we'll send you a **50$ Amazon Gift Card** as a thank-you for your time. Please fill in this [form](https://forms.gle/Phu3R1i2gTBM1iAm8), and we will get in touch with you!

Your input will directly influence the direction of Cyclops, and we appreciate every bit of feedback. Thank you for helping us build something great! 🧡
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

0 comments on commit d18414e

Please sign in to comment.