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

[ChaosCenter]: Add unit tests to k8s and cluster package in GraphQL server #3971

Merged
merged 7 commits into from
May 22, 2023
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 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)
}
})
}
}
62 changes: 45 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 @@ -437,6 +442,29 @@ func (c *clusterService) GetManifest(token string) ([]byte, int, error) {
}
}

// GetCluster returns cluster details for a given clusterID
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