Skip to content

Commit

Permalink
Merge branch 'cyclops-ui:main' into feature/add-skipCRDs-toggle
Browse files Browse the repository at this point in the history
  • Loading branch information
kom-senapati authored Oct 14, 2024
2 parents 98fe4d7 + 4dacc0c commit bb61948
Show file tree
Hide file tree
Showing 39 changed files with 5,249 additions and 1,422 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Cyclops can either be installed manually by applying the latest manifest, by usi
To install Cyclops using `kubectl` into your cluster, run the commands below:

```bash
kubectl apply -f https://raw.githubusercontent.com/cyclops-ui/cyclops/v0.13.1/install/cyclops-install.yaml && kubectl apply -f https://raw.githubusercontent.com/cyclops-ui/cyclops/v0.13.1/install/demo-templates.yaml
kubectl apply -f https://raw.githubusercontent.com/cyclops-ui/cyclops/v0.14.1/install/cyclops-install.yaml && kubectl apply -f https://raw.githubusercontent.com/cyclops-ui/cyclops/v0.14.1/install/demo-templates.yaml
```

It will create a new namespace called `cyclops` and deploy everything you need for your Cyclops instance to run.
Expand Down
2 changes: 2 additions & 0 deletions cyclops-ctrl/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
bin
cover.out
cover.html
18 changes: 18 additions & 0 deletions cyclops-ctrl/.mockery.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
quiet: False
disable-version-string: True
with-expecter: True
mockname: "{{.InterfaceName}}"
filename: "{{.MockName}}.go"
outpkg: mocks
dir: mocks
packages:
github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/cluster/k8sclient:
interfaces:
IKubernetesClient:
config:
dir: pkg/mocks
github.com/cyclops-ui/cyclops/cyclops-ctrl/internal/template:
interfaces:
ITemplateRepo:
config:
dir: mocks
10 changes: 10 additions & 0 deletions cyclops-ctrl/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,13 @@ group-imports:

unit-test:
go test -v -tags musl,dynamic ./...

coverage:
go test -v -coverprofile cover.out ./...
go tool cover -html cover.out -o cover.html
open cover.html

mockery:
GOBIN=$(LOCALBIN) go install github.com/vektra/mockery/v2@latest
./bin/mockery

1 change: 1 addition & 0 deletions cyclops-ctrl/cmd/main/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ func main() {
k8sClient,
renderer,
telemetryClient,
monitor,
)).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "Module")
os.Exit(1)
Expand Down
5 changes: 4 additions & 1 deletion cyclops-ctrl/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/posthog/posthog-go v0.0.0-20240315130956-036dfa9f3555
github.com/prometheus/client_golang v1.16.0
github.com/stretchr/testify v1.8.4
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
helm.sh/helm/v3 v3.15.3
Expand All @@ -27,6 +28,7 @@ require (
k8s.io/apimachinery v0.30.1
k8s.io/client-go v0.30.1
sigs.k8s.io/controller-runtime v0.18.4
sigs.k8s.io/yaml v1.4.0
)

require (
Expand Down Expand Up @@ -104,6 +106,7 @@ require (
github.com/opencontainers/image-spec v1.1.0-rc6 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
github.com/prometheus/common v0.44.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
Expand All @@ -113,6 +116,7 @@ require (
github.com/skeema/knownhosts v1.2.1 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.5.0 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
Expand Down Expand Up @@ -151,5 +155,4 @@ require (
oras.land/oras-go v1.2.5 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)
1 change: 1 addition & 0 deletions cyclops-ctrl/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
Expand Down
188 changes: 188 additions & 0 deletions cyclops-ctrl/internal/auth/templates_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package auth

import (
"github.com/cyclops-ui/cyclops/cyclops-ctrl/api/v1alpha1"
"github.com/cyclops-ui/cyclops/cyclops-ctrl/pkg/mocks"
"github.com/pkg/errors"
apiv1 "k8s.io/api/core/v1"
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

func TestTemplatesResolver(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "test templates resolver")
}

var _ = Describe("Templates resolver", func() {
var templatesResolver TemplatesResolver
var k8sClient *mocks.IKubernetesClient

BeforeEach(func() {
k8sClient = &mocks.IKubernetesClient{}
templatesResolver = NewTemplatesResolver(k8sClient)
})

type caseInput struct {
repo string
mockCalls func()
}

type caseOutput struct {
credentials *Credentials
returnsError bool
}

type testCase struct {
description string
in caseInput
out caseOutput
}

tars := []v1alpha1.TemplateAuthRule{
{
Spec: v1alpha1.TemplateAuthRuleSpec{
Repo: "https://github.com/my-org/some-other-team",
Username: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "wrong-secret"},
Key: "username",
},
Password: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "wrong-secret"},
Key: "token",
},
},
},
{
Spec: v1alpha1.TemplateAuthRuleSpec{
Repo: "https://github.com/invalid-org/some))-other-team", // invalid regex should not break resolver
Username: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "wrong-secret"},
Key: "username",
},
Password: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "wrong-secret"},
Key: "token",
},
},
},
{
Spec: v1alpha1.TemplateAuthRuleSpec{
Repo: "https://github.com/my-org/my-team",
Username: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "secret-name"},
Key: "username",
},
Password: apiv1.SecretKeySelector{
LocalObjectReference: apiv1.LocalObjectReference{Name: "secret-name"},
Key: "token",
},
},
},
}

testCases := []testCase{
{
description: "failed to fetch template auth rules",
in: caseInput{
repo: "https://github.com/my-org/my-templates",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(nil, errors.New("some k8s error"))
},
},
out: caseOutput{
credentials: nil,
returnsError: true,
},
},
{
description: "fetches no template auth rules",
in: caseInput{
repo: "https://github.com/my-org/my-templates",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(nil, nil)
},
},
out: caseOutput{
credentials: nil,
returnsError: false,
},
},
{
description: "fetches no matching template auth rules",
in: caseInput{
repo: "https://github.com/my-org/my-templates",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(tars, nil)
},
},
out: caseOutput{
credentials: nil,
returnsError: false,
},
},
{
description: "failed to fetch username secret",
in: caseInput{
repo: "https://github.com/my-org/my-team",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(tars, nil)
k8sClient.On("GetTemplateAuthRuleSecret", "secret-name", "username").Return("", errors.New("some k8s error"))
},
},
out: caseOutput{
credentials: nil,
returnsError: true,
},
},
{
description: "failed to fetch password secret",
in: caseInput{
repo: "https://github.com/my-org/my-team",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(tars, nil)
k8sClient.On("GetTemplateAuthRuleSecret", "secret-name", "username").Return("my-secret-username", nil)
k8sClient.On("GetTemplateAuthRuleSecret", "secret-name", "token").Return("", errors.New("some k8s error"))
},
},
out: caseOutput{
credentials: nil,
returnsError: true,
},
},
{
description: "fetches no matching template auth rules",
in: caseInput{
repo: "https://github.com/my-org/my-team",
mockCalls: func() {
k8sClient.On("ListTemplateAuthRules").Return(tars, nil)
k8sClient.On("GetTemplateAuthRuleSecret", "secret-name", "username").Return("my-secret-username", nil)
k8sClient.On("GetTemplateAuthRuleSecret", "secret-name", "token").Return("my-secret-token", nil)
},
},
out: caseOutput{
credentials: &Credentials{
Username: "my-secret-username",
Password: "my-secret-token",
},
returnsError: false,
},
},
}

for _, t := range testCases {
Describe(t.description, func() {
BeforeEach(func() {
t.in.mockCalls()
})

It("returns correct credentials and error", func() {
actual, err := templatesResolver.RepoAuthCredentials(t.in.repo)
Expect(err != nil).To(BeEquivalentTo(t.out.returnsError))
Expect(actual).To(BeEquivalentTo(t.out.credentials))
})
})
}
})
9 changes: 2 additions & 7 deletions cyclops-ctrl/internal/controller/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import (
)

type Cluster struct {
kubernetesClient *k8sclient.KubernetesClient
kubernetesClient k8sclient.IKubernetesClient
}

func NewClusterController(kubernetes *k8sclient.KubernetesClient) *Cluster {
func NewClusterController(kubernetes k8sclient.IKubernetesClient) *Cluster {
return &Cluster{
kubernetesClient: kubernetes,
}
Expand All @@ -27,7 +27,6 @@ func (c *Cluster) ListNodes(ctx *gin.Context) {

nodes, err := c.kubernetesClient.ListNodes()
if err != nil {
fmt.Println(err)
ctx.Status(http.StatusInternalServerError)
return
}
Expand All @@ -42,22 +41,19 @@ func (c *Cluster) GetNode(ctx *gin.Context) {

node, err := c.kubernetesClient.GetNode(nodeName)
if errors.IsNotFound(err) {
fmt.Printf("Node %s does not exist.\n", nodeName)
ctx.JSON(http.StatusBadRequest, dto.Error{
Message: "Node with name does not exist",
Description: "Check if the provided node name is correct",
})
return
}
if err != nil {
fmt.Println(err)
ctx.Status(http.StatusInternalServerError)
return
}

pods, err := c.kubernetesClient.GetPodsForNode(nodeName)
if err != nil {
fmt.Printf("Error listing pods for node: %v", nodeName)
ctx.JSON(http.StatusInternalServerError, dto.Error{
Message: fmt.Sprintf("Error listing pods for node: %v", nodeName),
})
Expand All @@ -74,7 +70,6 @@ func (c *Cluster) ListNamespaces(ctx *gin.Context) {

namespaces, err := c.kubernetesClient.ListNamespaces()
if err != nil {
fmt.Println(err)
ctx.Status(http.StatusInternalServerError)
return
}
Expand Down
8 changes: 4 additions & 4 deletions cyclops-ctrl/internal/controller/modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ import (
)

type Modules struct {
kubernetesClient *k8sclient.KubernetesClient
templatesRepo *template.Repo
kubernetesClient k8sclient.IKubernetesClient
templatesRepo template.ITemplateRepo
renderer *render.Renderer
telemetryClient telemetry.Client
monitor prometheus.Monitor
}

func NewModulesController(
templatesRepo *template.Repo,
kubernetes *k8sclient.KubernetesClient,
templatesRepo template.ITemplateRepo,
kubernetes k8sclient.IKubernetesClient,
renderer *render.Renderer,
telemetryClient telemetry.Client,
monitor prometheus.Monitor,
Expand Down
4 changes: 2 additions & 2 deletions cyclops-ctrl/internal/controller/sse/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import (
)

type Server struct {
k8sClient *k8sclient.KubernetesClient
k8sClient k8sclient.IKubernetesClient
}

// Initialize event and Start procnteessing requests
func NewServer(k8sClient *k8sclient.KubernetesClient) *Server {
func NewServer(k8sClient k8sclient.IKubernetesClient) *Server {
server := &Server{
k8sClient: k8sClient,
}
Expand Down
Loading

0 comments on commit bb61948

Please sign in to comment.