Skip to content

Commit

Permalink
[ChaosCenter]: Add unit tests to k8s and cluster package in GraphQL s…
Browse files Browse the repository at this point in the history
…erver (litmuschaos#3971)

* feat: add unit tests to k8s package

Signed-off-by: namkyu1999 <[email protected]>

* feat: add unit tests to cluster package

Signed-off-by: namkyu1999 <[email protected]>

* fix: fix codacy analysis

Signed-off-by: namkyu1999 <[email protected]>

* fix: fix test cases

Signed-off-by: namkyu1999 <[email protected]>

* fix: chore

Signed-off-by: namkyu1999 <[email protected]>

* fix: rename function

Signed-off-by: namkyu1999 <[email protected]>

---------

Signed-off-by: namkyu1999 <[email protected]>
Signed-off-by: SohamRatnaparkhi <[email protected]>
  • Loading branch information
namkyu1999 authored and SohamRatnaparkhi committed Jun 30, 2023
1 parent 84680f9 commit fbd7961
Show file tree
Hide file tree
Showing 17 changed files with 1,948 additions and 177 deletions.
1 change: 1 addition & 0 deletions litmus-portal/graphql-server/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ require (
google.golang.org/grpc v1.44.0
google.golang.org/protobuf v1.27.1
gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.23.3
k8s.io/apimachinery v0.23.3
k8s.io/client-go v12.0.0+incompatible
)
Expand Down
2 changes: 0 additions & 2 deletions litmus-portal/graphql-server/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1742,7 +1742,6 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8=
Expand Down Expand Up @@ -2307,7 +2306,6 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10 h1:WIoqL4EROvwiPdUtaip4VcDdpZ4kha7wBWZrbVKCIZg=
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
Expand Down
8 changes: 7 additions & 1 deletion litmus-portal/graphql-server/graph/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import (
dbOperationsWorkflowTemplate "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/database/mongodb/workflowtemplate"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/gitops"
imageRegistry "github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/image_registry"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/k8s"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/usage"
log "github.com/sirupsen/logrus"
)

// This file will not be regenerated automatically.
Expand Down Expand Up @@ -51,8 +53,12 @@ func NewConfig(mongodbOperator mongodb.MongoOperator) generated.Config {
analyticsOperator := dbSchemaAnalytics.NewAnalyticsOperator(mongodbOperator)
imageRegistryOperator := dbOperationsImageRegistry.NewImageRegistryOperator(mongodbOperator)

kubeCluster, err := k8s.NewKubeCluster()
if err != nil {
log.Fatalf("Error in getting k8s cluster, err: %v", err)
}
// service
clusterService := cluster.NewService(clusterOperator, chaosWorkflowOperator)
clusterService := cluster.NewService(clusterOperator, chaosWorkflowOperator, kubeCluster)
chaosHubService := chaoshub.NewService(chaosHubOperator)
analyticsService := service.NewService(analyticsOperator, chaosWorkflowOperator, clusterService)
usageService := usage.NewService(clusterOperator)
Expand Down
8 changes: 4 additions & 4 deletions litmus-portal/graphql-server/pkg/cluster/cluster_jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/utils"
)

// ClusterCreateJWT generates jwt used in cluster registration
func ClusterCreateJWT(id string) (string, error) {
// CreateClusterJWT generates jwt used in cluster registration
func CreateClusterJWT(id string) (string, error) {
claims := jwt.MapClaims{}
claims["cluster_id"] = id
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
Expand All @@ -22,8 +22,8 @@ func ClusterCreateJWT(id string) (string, error) {
return tokenString, nil
}

// ClusterValidateJWT validates the cluster jwt
func ClusterValidateJWT(token string) (string, error) {
// ValidateClusterJWT validates the cluster jwt
func ValidateClusterJWT(token string) (string, error) {
tkn, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
Expand Down
71 changes: 71 additions & 0 deletions litmus-portal/graphql-server/pkg/cluster/cluster_jwt_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package cluster_test

import (
"testing"

"github.com/google/uuid"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/pkg/cluster"
"github.com/litmuschaos/litmus/litmus-portal/graphql-server/utils"
"github.com/stretchr/testify/assert"
)

// TestCreateClusterJWT tests the CreateClusterJWT function
func TestCreateClusterJWT(t *testing.T) {
// given
utils.Config.JwtSecret = uuid.NewString()
// when
_, err := cluster.CreateClusterJWT(uuid.NewString())
// then
assert.NoError(t, err)
}

// TestValidateClusterJWT tests the ValidateClusterJWT function
func TestValidateClusterJWT(t *testing.T) {
// given
testcases := []struct {
name string
wantError bool
given func() string
}{
{
name: "success",
wantError: false,
given: func() string {
utils.Config.JwtSecret = uuid.NewString()
token, _ := cluster.CreateClusterJWT(uuid.NewString())
return token
},
},
{
name: "failure: invalid token",
wantError: true,
given: func() string {
return uuid.NewString()
},
},
{
name: "failure: valid token but secret changed",
wantError: true,
given: func() string {
utils.Config.JwtSecret = uuid.NewString()
token, _ := cluster.CreateClusterJWT(uuid.NewString())
utils.Config.JwtSecret = uuid.NewString()
return token
},
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
// given
token := tc.given()
// when
_, err := cluster.ValidateClusterJWT(token)
// then
if tc.wantError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}
61 changes: 44 additions & 17 deletions litmus-portal/graphql-server/pkg/cluster/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
"go.mongodb.org/mongo-driver/bson"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)

type Service interface {
Expand All @@ -35,24 +36,28 @@ type Service interface {
VerifyCluster(identity model.ClusterIdentity) (*dbSchemaCluster.Cluster, error)
GetManifest(token string) ([]byte, int, error)
GetCluster(clusterID string) (dbSchemaCluster.Cluster, error)
GetEndpoint(agentType utils.AgentType) (string, error)
GetClusterResource(manifest string, namespace string) (*unstructured.Unstructured, error)
}

type clusterService struct {
clusterOperator *dbSchemaCluster.Operator
chaosWorkflowOperator *dbOperationsWorkflow.Operator
kubeClients *k8s.KubeClients
}

// NewService returns a new instance of Service
func NewService(clusterOperator *dbSchemaCluster.Operator, chaosWorkflowOperator *dbOperationsWorkflow.Operator) Service {
func NewService(clusterOperator *dbSchemaCluster.Operator, chaosWorkflowOperator *dbOperationsWorkflow.Operator, kubeClients *k8s.KubeClients) Service {
return &clusterService{
clusterOperator: clusterOperator,
chaosWorkflowOperator: chaosWorkflowOperator,
kubeClients: kubeClients,
}
}

// RegisterCluster creates an entry for a new cluster in DB and generates the url used to apply manifest
func (c *clusterService) RegisterCluster(request model.RegisterClusterRequest) (*model.RegisterClusterResponse, error) {
endpoint, err := GetEndpoint(request.ClusterType)
endpoint, err := c.GetEndpoint(utils.AgentType(request.ClusterType))
if err != nil {
return nil, err
}
Expand All @@ -62,7 +67,7 @@ func (c *clusterService) RegisterCluster(request model.RegisterClusterRequest) (
}

clusterID := uuid.New().String()
token, err := ClusterCreateJWT(clusterID)
token, err := CreateClusterJWT(clusterID)
if err != nil {
return &model.RegisterClusterResponse{}, err
}
Expand Down Expand Up @@ -204,7 +209,7 @@ func (c *clusterService) DeleteClusters(ctx context.Context, projectID string, c
}
clusters, err := c.clusterOperator.ListClusters(ctx, query)
if err != nil {
return "", nil
return "", err
}

for _, cluster := range clusters {
Expand Down Expand Up @@ -253,7 +258,7 @@ func (c *clusterService) ListClusters(projectID string, clusterType *string) ([]
if err != nil {
return nil, err
}
newClusters := []*model.Cluster{}
var newClusters []*model.Cluster

for _, cluster := range clusters {
var totalNoOfSchedules int
Expand Down Expand Up @@ -312,30 +317,30 @@ func (c *clusterService) GetManifestWithClusterID(clusterID string, accessKey st
}

var config subscriberConfigurations
config.ServerEndpoint, err = GetEndpoint(reqCluster.ClusterType)
config.ServerEndpoint, err = c.GetEndpoint(utils.AgentType(reqCluster.ClusterType))
if err != nil {
return nil, fmt.Errorf("failed to retrieve the server endpoint %v", err)
}

var scope = utils.Config.ChaosCenterScope
if scope == clusterScope && utils.Config.TlsSecretName != "" {
config.TLSCert, err = k8s.GetTLSCert(utils.Config.TlsSecretName)
if scope == string(utils.AgentScopeCluster) && utils.Config.TlsSecretName != "" {
config.TLSCert, err = c.kubeClients.GetTLSCert(utils.Config.TlsSecretName)
if err != nil {
return nil, fmt.Errorf("failed to retrieve the tls cert %v", err)
}
}

if scope == namespaceScope {
if scope == string(utils.AgentScopeNamespace) {
config.TLSCert = utils.Config.TlsCertB64
}

var respData []byte
if reqCluster.AgentScope == clusterScope {
if reqCluster.AgentScope == string(utils.AgentScopeCluster) {
respData, err = manifestParser(reqCluster, "manifests/cluster", &config)
} else if reqCluster.AgentScope == namespaceScope {
} else if reqCluster.AgentScope == string(utils.AgentScopeNamespace) {
respData, err = manifestParser(reqCluster, "manifests/namespace", &config)
} else {
log.Error("env AGENT_SCOPE is empty")
return nil, fmt.Errorf("env AGENT_SCOPE is empty")
}

if err != nil {
Expand Down Expand Up @@ -390,7 +395,7 @@ func (c *clusterService) VerifyCluster(identity model.ClusterIdentity) (*dbSchem

// GetManifest returns manifest for a given cluster
func (c *clusterService) GetManifest(token string) ([]byte, int, error) {
clusterID, err := ClusterValidateJWT(token)
clusterID, err := ValidateClusterJWT(token)
if err != nil {
return nil, http.StatusNotFound, err
}
Expand All @@ -401,20 +406,20 @@ func (c *clusterService) GetManifest(token string) ([]byte, int, error) {
}

var config subscriberConfigurations
config.ServerEndpoint, err = GetEndpoint(reqCluster.ClusterType)
config.ServerEndpoint, err = c.GetEndpoint(utils.AgentType(reqCluster.ClusterType))
if err != nil {
return nil, http.StatusInternalServerError, err
}

var scope = utils.Config.ChaosCenterScope
if scope == clusterScope && utils.Config.TlsSecretName != "" {
config.TLSCert, err = k8s.GetTLSCert(utils.Config.TlsSecretName)
if scope == string(utils.AgentScopeCluster) && utils.Config.TlsSecretName != "" {
config.TLSCert, err = c.kubeClients.GetTLSCert(utils.Config.TlsSecretName)
if err != nil {
return nil, http.StatusInternalServerError, err
}
}

if scope == namespaceScope {
if scope == string(utils.AgentScopeNamespace) {
config.TLSCert = utils.Config.TlsCertB64
}

Expand All @@ -441,3 +446,25 @@ func (c *clusterService) GetManifest(token string) ([]byte, int, error) {
func (c *clusterService) GetCluster(clusterID string) (dbSchemaCluster.Cluster, error) {
return c.clusterOperator.GetCluster(clusterID)
}

// GetEndpoint returns the endpoint for the subscriber
func (c *clusterService) GetEndpoint(agentType utils.AgentType) (string, error) {
// returns endpoint from env, if provided by user
if utils.Config.ChaosCenterUiEndpoint != "" {
return utils.Config.ChaosCenterUiEndpoint + "/ws/query", nil
}

// generating endpoint based on ChaosCenter Scope & AgentType (Self or External)
agentEndpoint, err := c.kubeClients.GetServerEndpoint(utils.AgentScope(utils.Config.ChaosCenterScope), agentType)

if agentEndpoint == "" || err != nil {
return "", fmt.Errorf("failed to retrieve the server endpoint %v", err)
}

return agentEndpoint, err
}

// GetClusterResource returns the cluster resource for a given manifest
func (c *clusterService) GetClusterResource(manifest string, namespace string) (*unstructured.Unstructured, error) {
return c.kubeClients.ClusterResource(manifest, namespace)
}
Loading

0 comments on commit fbd7961

Please sign in to comment.