diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000000..592ed30b07e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,21 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "chaoscenter/authentication" + schedule: + interval: "daily" + + - package-ecosystem: "gomod" + directory: "chaoscenter/event-tracker" + schedule: + interval: "daily" + + - package-ecosystem: "gomod" + directory: "chaoscenter/subscriber" + schedule: + interval: "daily" + + - package-ecosystem: "gomod" + directory: "chaoscenter/graphql" + schedule: + interval: "daily" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97aaa2566c8..29039acdafd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -82,22 +82,39 @@ jobs: cd chaoscenter make frontend-services-checks - # backend-unit-tests: - # runs-on: ubuntu-latest - # needs: - # - changes - # - backend-checks - # steps: - # - name: Checkout repository - # uses: actions/checkout@v2 - # - uses: actions/setup-go@v2 - # with: - # go-version: "1.20" # By default, the go version is v1.15 in runner. - # - name: Backend unit tests - # shell: bash - # run: | - # cd chaoscenter - # make unit-tests + backend-unit-tests: + runs-on: ubuntu-latest + needs: + - changes + - backend-checks + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: "1.20" # By default, the go version is v1.15 in runner. + - name: Backend unit tests + shell: bash + run: | + cd chaoscenter + make backend-unit-tests + + web-unit-tests: + runs-on: ubuntu-latest + needs: + - changes + - frontend-checks + steps: + - name: Checkout repository + uses: actions/checkout@v2 + - uses: actions/setup-node@v3 + with: + node-version: 16 + - name: Chaoscenter web unit tests + shell: bash + run: | + cd chaoscenter + make web-unit-tests docker-build-graphql-server: runs-on: ubuntu-latest diff --git a/chaoscenter/Makefile b/chaoscenter/Makefile index 9730df177fc..267ff860bf2 100644 --- a/chaoscenter/Makefile +++ b/chaoscenter/Makefile @@ -97,15 +97,21 @@ backend-services-checks: # && exit 1; \ # fi -unit-tests: +backend-unit-tests: @echo "------------------" - @echo "--> Running unit tests" + @echo "--> Running backend unit tests" @echo "------------------" - @cd graphql-server && go test -cover ./... -# @cd authentication && go test -v ./... -# @cd cluster-agents/subscriber && go test -v ./... + @cd graphql/server && go test -cover ./... + @cd authentication && go test -v ./... + @#cd cluster-agents/subscriber && go test -v ./... # @cd cluster-agents/event-tracker && go test -v ./... +web-unit-tests: + @echo "------------------" + @echo "--> Running frontend unit tests" + @echo "------------------" + @cd web && yarn -s && yarn test --coverage + .PHONY: docker.buildx docker.buildx: @echo "------------------------------" diff --git a/chaoscenter/authentication/api/handlers/grpc/grpc_handler_test.go b/chaoscenter/authentication/api/handlers/grpc/grpc_handler_test.go new file mode 100644 index 00000000000..2da2782d00d --- /dev/null +++ b/chaoscenter/authentication/api/handlers/grpc/grpc_handler_test.go @@ -0,0 +1,168 @@ +package grpc_test + +import ( + "context" + "errors" + "testing" + + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/handlers/grpc" + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/mocks" + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter/protos" + "github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/entities" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" +) + +func TestGetProjectById(t *testing.T) { + testCases := []struct { + name string + projectID string + mockGetProjectResponse *entities.Project + mockGetProjectError error + mockFindUsersResponse *[]entities.User + mockFindUsersError error + expectedResponse *protos.GetProjectByIdResponse + expectedError bool + }{ + { + name: "PositiveTestProjectExists", + projectID: "project-id", + mockGetProjectResponse: &entities.Project{ + ID: "project-id", + Name: "test-project", + Members: []*entities.Member{ + { + UserID: "user-1", + Invitation: entities.PendingInvitation, + JoinedAt: 1234567890, + }, + }, + }, + mockGetProjectError: nil, + mockFindUsersResponse: &[]entities.User{ + { + ID: "user-1", + Email: "user1@email.com", + Username: "user1", + }, + }, + mockFindUsersError: nil, + expectedResponse: &protos.GetProjectByIdResponse{ + Id: "project-id", + Name: "test-project", + }, + expectedError: false, + }, + { + name: "NegativeTestProjectDoesNotExist", + projectID: "non-existing-project-id", + mockGetProjectResponse: nil, + mockGetProjectError: errors.New("project not found"), + mockFindUsersResponse: nil, + mockFindUsersError: nil, + expectedResponse: nil, + expectedError: true, + }, + } + + s := &grpc.ServerGrpc{ + ApplicationService: &mocks.MockedApplicationService{}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx := context.Background() + + mockService := s.ApplicationService.(*mocks.MockedApplicationService) + mockService.On("GetProjectByProjectID", tc.projectID).Return(tc.mockGetProjectResponse, tc.mockGetProjectError) + if tc.mockFindUsersResponse != nil { + mockService.On("FindUsersByUID", mock.Anything).Return(tc.mockFindUsersResponse, tc.mockFindUsersError) + } + + req := &protos.GetProjectByIdRequest{ + ProjectID: tc.projectID, + } + + resp, err := s.GetProjectById(ctx, req) + + if tc.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, tc.expectedResponse.Name, resp.Name) + } + mockService.AssertExpectations(t) + }) + } +} + +func TestGetUserById(t *testing.T) { + testcases := []struct { + name string + userID string + mockServiceResponse *entities.User + mockServiceError error + expectedResponse *protos.GetUserByIdResponse + expectedError bool + }{ + { + name: "PositiveTestUserExists", + userID: "user-id", + mockServiceResponse: &entities.User{ + ID: "user-id", + Name: "test-user", + Username: "username", + DeactivatedAt: nil, + Role: "admin", + Email: "user@email.com", + }, + mockServiceError: nil, + expectedResponse: &protos.GetUserByIdResponse{ + Id: "user-id", + Name: "test-user", + Email: "user@email.com", + DeactivatedAt: "nil", + }, + expectedError: false, + }, + { + name: "NegativeTestUserDoesNotExist", + userID: "non-existing-user-id", + mockServiceResponse: nil, + mockServiceError: errors.New("user not found"), + expectedResponse: nil, + expectedError: true, + }, + } + + s := &grpc.ServerGrpc{ + ApplicationService: &mocks.MockedApplicationService{}, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + ctx := context.Background() + + mockService := s.ApplicationService.(*mocks.MockedApplicationService) + mockService.On("GetUser", tc.userID).Return(tc.mockServiceResponse, tc.mockServiceError) + + req := &protos.GetUserByIdRequest{ + UserID: tc.userID, + } + + resp, err := s.GetUserById(ctx, req) + + if tc.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.NotNil(t, resp) + assert.Equal(t, tc.expectedResponse.Name, resp.Name) + assert.Equal(t, tc.expectedResponse.Email, resp.Email) + } + + mockService.AssertExpectations(t) + }) + } +} diff --git a/chaoscenter/authentication/api/mocks/grpc_mocks.go b/chaoscenter/authentication/api/mocks/grpc_mocks.go new file mode 100644 index 00000000000..2f678c446c7 --- /dev/null +++ b/chaoscenter/authentication/api/mocks/grpc_mocks.go @@ -0,0 +1,38 @@ +package mocks + +import ( + "context" + + "github.com/litmuschaos/litmus/chaoscenter/authentication/api/presenter/protos" + "github.com/stretchr/testify/mock" + "google.golang.org/grpc" +) + +// ServerGrpc is a mock type for the ServerGrpc type +type MockAuthRpcServiceClient struct { + mock.Mock +} + +func (m *MockAuthRpcServiceClient) ValidateRequest(ctx context.Context, in *protos.ValidationRequest, opts ...grpc.CallOption) (*protos.ValidationResponse, error) { + args := m.Called(ctx, in, opts) + if vr, ok := args.Get(0).(*protos.ValidationResponse); ok { + return vr, args.Error(1) + } + return nil, args.Error(1) +} + +func (m *MockAuthRpcServiceClient) GetProjectById(ctx context.Context, in *protos.GetProjectByIdRequest, opts ...grpc.CallOption) (*protos.GetProjectByIdResponse, error) { + args := m.Called(ctx, in, opts) + if gpir, ok := args.Get(0).(*protos.GetProjectByIdResponse); ok { + return gpir, args.Error(1) + } + return nil, args.Error(1) +} + +func (m *MockAuthRpcServiceClient) GetUserById(ctx context.Context, in *protos.GetUserByIdRequest, opts ...grpc.CallOption) (*protos.GetUserByIdResponse, error) { + args := m.Called(ctx, in, opts) + if guir, ok := args.Get(0).(*protos.GetUserByIdResponse); ok { + return guir, args.Error(1) + } + return nil, args.Error(1) +} diff --git a/chaoscenter/authentication/api/mocks/rest_mocks.go b/chaoscenter/authentication/api/mocks/rest_mocks.go new file mode 100644 index 00000000000..674ed47a109 --- /dev/null +++ b/chaoscenter/authentication/api/mocks/rest_mocks.go @@ -0,0 +1,201 @@ +package mocks + +import ( + "context" + + "github.com/golang-jwt/jwt" + "github.com/litmuschaos/litmus/chaoscenter/authentication/pkg/entities" + "github.com/stretchr/testify/mock" + "go.mongodb.org/mongo-driver/bson" + "go.mongodb.org/mongo-driver/mongo" + "go.mongodb.org/mongo-driver/mongo/options" +) + +type MockedApplicationService struct { + mock.Mock +} + +func (m *MockedApplicationService) IsAdministrator(user *entities.User) error { + args := m.Called(user) + return args.Error(0) +} + +func (m *MockedApplicationService) UpdatePassword(userPassword *entities.UserPassword, isAdminBeingReset bool) error { + args := m.Called(userPassword, isAdminBeingReset) + return args.Error(0) +} + +func (m *MockedApplicationService) AddMember(projectID string, member *entities.Member) error { + args := m.Called(projectID, member) + return args.Error(0) +} + +func (m *MockedApplicationService) LoginUser(user *entities.User) (*entities.User, error) { + args := m.Called(user) + return args.Get(0).(*entities.User), args.Error(1) +} + +func (m *MockedApplicationService) GetUser(uid string) (*entities.User, error) { + args := m.Called(uid) + return args.Get(0).(*entities.User), args.Error(1) +} + +func (m *MockedApplicationService) GetUsers() (*[]entities.User, error) { + args := m.Called() + return args.Get(0).(*[]entities.User), args.Error(1) +} + +func (m *MockedApplicationService) FindUsersByUID(uid []string) (*[]entities.User, error) { + args := m.Called(uid) + return args.Get(0).(*[]entities.User), args.Error(1) +} + +func (m *MockedApplicationService) FindUserByUsername(username string) (*entities.User, error) { + args := m.Called(username) + return args.Get(0).(*entities.User), args.Error(1) +} + +func (m *MockedApplicationService) CheckPasswordHash(hash, password string) error { + args := m.Called(hash, password) + return args.Error(0) +} + +func (m *MockedApplicationService) CreateUser(user *entities.User) (*entities.User, error) { + args := m.Called(user) + return args.Get(0).(*entities.User), args.Error(1) +} + +func (m *MockedApplicationService) UpdateUser(user *entities.UserDetails) error { + args := m.Called(user) + return args.Error(0) +} + +func (m *MockedApplicationService) UpdateUserState(username string, isDeactivate bool, deactivateTime int64) error { + args := m.Called(username, isDeactivate, deactivateTime) + return args.Error(0) +} + +func (m *MockedApplicationService) InviteUsers(invitedUsers []string) (*[]entities.User, error) { + args := m.Called(invitedUsers) + return args.Get(0).(*[]entities.User), args.Error(1) +} + +func (m *MockedApplicationService) GetProjectByProjectID(projectID string) (*entities.Project, error) { + args := m.Called(projectID) + return args.Get(0).(*entities.Project), args.Error(1) +} + +func (m *MockedApplicationService) GetProjects(query bson.D) ([]*entities.Project, error) { + args := m.Called(query) + return args.Get(0).([]*entities.Project), args.Error(1) +} + +func (m *MockedApplicationService) GetProjectsByUserID(uid string, isOwner bool) ([]*entities.Project, error) { + args := m.Called(uid, isOwner) + return args.Get(0).([]*entities.Project), args.Error(1) +} + +func (m *MockedApplicationService) GetProjectStats() ([]*entities.ProjectStats, error) { + args := m.Called() + return args.Get(0).([]*entities.ProjectStats), args.Error(1) +} + +func (m *MockedApplicationService) CreateProject(project *entities.Project) error { + args := m.Called(project) + return args.Error(0) +} + +func (m *MockedApplicationService) RemoveInvitation(projectID, userID string, invitation entities.Invitation) error { + args := m.Called(projectID, userID, invitation) + return args.Error(0) +} + +func (m *MockedApplicationService) UpdateInvite(projectID, userID string, invitation entities.Invitation, role *entities.MemberRole) error { + args := m.Called(projectID, userID, invitation, role) + return args.Error(0) +} + +func (m *MockedApplicationService) UpdateProjectName(projectID, projectName string) error { + args := m.Called(projectID, projectName) + return args.Error(0) +} + +func (m *MockedApplicationService) GetAggregateProjects(pipeline mongo.Pipeline, opts *options.AggregateOptions) (*mongo.Cursor, error) { + args := m.Called(pipeline, opts) + return args.Get(0).(*mongo.Cursor), args.Error(1) +} + +func (m *MockedApplicationService) UpdateProjectState(userID string, deactivateTime int64, isDeactivate bool) error { + args := m.Called(userID, deactivateTime, isDeactivate) + return args.Error(0) +} + +func (m *MockedApplicationService) GetOwnerProjectIDs(ctx context.Context, userID string) ([]*entities.Project, error) { + args := m.Called(ctx, userID) + return args.Get(0).([]*entities.Project), args.Error(1) +} + +func (m *MockedApplicationService) GetProjectRole(projectID, userID string) (*entities.MemberRole, error) { + args := m.Called(projectID, userID) + return args.Get(0).(*entities.MemberRole), args.Error(1) +} + +func (m *MockedApplicationService) GetProjectMembers(projectID, state string) ([]*entities.Member, error) { + args := m.Called(projectID, state) + return args.Get(0).([]*entities.Member), args.Error(1) +} + +func (m *MockedApplicationService) ListInvitations(userID string, invitationState entities.Invitation) ([]*entities.Project, error) { + args := m.Called(userID, invitationState) + return args.Get(0).([]*entities.Project), args.Error(1) +} + +func (m *MockedApplicationService) RevokeToken(tokenString string) error { + args := m.Called(tokenString) + return args.Error(0) +} + +func (m *MockedApplicationService) ValidateToken(encodedToken string) (*jwt.Token, error) { + args := m.Called(encodedToken) + return args.Get(0).(*jwt.Token), args.Error(1) +} + +func (m *MockedApplicationService) GetSignedJWT(user *entities.User) (string, error) { + args := m.Called(user) + return args.String(0), args.Error(1) +} + +func (m *MockedApplicationService) CreateApiToken(user *entities.User, request entities.ApiTokenInput) (string, error) { + args := m.Called(user, request) + return args.String(0), args.Error(1) +} + +func (m *MockedApplicationService) GetApiTokensByUserID(userID string) ([]entities.ApiToken, error) { + args := m.Called(userID) + return args.Get(0).([]entities.ApiToken), args.Error(1) +} + +func (m *MockedApplicationService) DeleteApiToken(token string) error { + args := m.Called(token) + return args.Error(0) +} + +func (m *MockedApplicationService) ListCollection() ([]string, error) { + args := m.Called() + return args.Get(0).([]string), args.Error(1) +} + +func (m *MockedApplicationService) ListDataBase() ([]string, error) { + args := m.Called() + return args.Get(0).([]string), args.Error(1) +} + +func (m *MockedApplicationService) UpdateStateTransaction(userRequest entities.UpdateUserState) error { + args := m.Called(userRequest) + return args.Error(0) +} + +func (m *MockedApplicationService) RbacValidator(userID, resourceID string, rules []string, invitationStatus string) error { + args := m.Called(userID, resourceID, rules, invitationStatus) + return args.Error(0) +} diff --git a/chaoscenter/authentication/go.mod b/chaoscenter/authentication/go.mod index fe2118f70e8..1af9a9e82af 100644 --- a/chaoscenter/authentication/go.mod +++ b/chaoscenter/authentication/go.mod @@ -8,9 +8,10 @@ require ( github.com/gin-gonic/gin v1.7.7 github.com/golang-jwt/jwt v3.2.1+incompatible github.com/golang/protobuf v1.5.2 - github.com/google/uuid v1.2.0 + github.com/google/uuid v1.3.0 github.com/kelseyhightower/envconfig v1.4.0 - github.com/sirupsen/logrus v1.4.2 + github.com/sirupsen/logrus v1.9.2 + github.com/stretchr/testify v1.7.0 go.mongodb.org/mongo-driver v1.5.3 golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f @@ -20,33 +21,37 @@ require ( require ( github.com/aws/aws-sdk-go v1.34.28 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.13.0 // indirect github.com/go-playground/universal-translator v0.17.0 // indirect github.com/go-playground/validator/v10 v10.4.1 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/golang/snappy v0.0.1 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/json-iterator/go v1.1.9 // indirect github.com/klauspost/compress v1.9.5 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/leodido/go-urn v1.2.0 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 // indirect github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/stretchr/objx v0.1.1 // indirect github.com/ugorji/go/codec v1.1.7 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 // indirect - golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 // indirect - golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect - golang.org/x/text v0.3.6 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.6 // indirect google.golang.org/genproto v0.0.0-20200825200019-8632dd797987 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.2.8 // indirect + gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect ) diff --git a/chaoscenter/authentication/go.sum b/chaoscenter/authentication/go.sum index 696ae3167b6..9f645d42bfe 100644 --- a/chaoscenter/authentication/go.sum +++ b/chaoscenter/authentication/go.sum @@ -138,8 +138,9 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -151,8 +152,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -177,7 +178,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.9.5 h1:U+CaK85mrNNb4k8BNOfgJtJ/gr6kswUCFj6miSzVC6M= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -210,18 +210,21 @@ github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFR github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.2 h1:oxx1eChJGI6Uks2ZC4W1zpLlVgqB8ner4EuQwV4Ik1Y= +github.com/sirupsen/logrus v1.9.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= @@ -312,8 +315,8 @@ golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -329,8 +332,9 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -363,16 +367,17 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -423,7 +428,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= diff --git a/chaoscenter/graphql/definitions/shared/chaos_experiment.graphqls b/chaoscenter/graphql/definitions/shared/chaos_experiment.graphqls index 246d190ff78..fb78559ffcb 100644 --- a/chaoscenter/graphql/definitions/shared/chaos_experiment.graphqls +++ b/chaoscenter/graphql/definitions/shared/chaos_experiment.graphqls @@ -768,4 +768,12 @@ extend type Mutation { experimentRunID: String projectID: ID! ): Boolean! + + """ + Enable/Disable cron experiment state + """ + updateCronExperimentState(experimentID: String! + disable: Boolean! + projectID: ID! + ): Boolean! @authorized } diff --git a/chaoscenter/graphql/server/go.mod b/chaoscenter/graphql/server/go.mod index 6982e0d8918..f56ac6f2470 100644 --- a/chaoscenter/graphql/server/go.mod +++ b/chaoscenter/graphql/server/go.mod @@ -30,6 +30,7 @@ require ( k8s.io/api v0.26.0 k8s.io/apimachinery v0.26.0 k8s.io/client-go v12.0.0+incompatible + sigs.k8s.io/yaml v1.3.0 ) @@ -42,7 +43,6 @@ require ( github.com/agnivade/levenshtein v1.0.3 // indirect github.com/bytedance/sonic v1.8.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/emicklei/go-restful v2.15.0+incompatible // indirect github.com/emirpasic/gods v1.12.0 // indirect @@ -82,21 +82,19 @@ require ( github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/sergi/go-diff v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.0 // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.9 // indirect - github.com/urfave/cli/v2 v2.1.1 // indirect github.com/xanzy/ssh-agent v0.3.0 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.1 // indirect github.com/xdg-go/stringprep v1.0.3 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect golang.org/x/net v0.7.0 // indirect golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect @@ -104,7 +102,6 @@ require ( golang.org/x/term v0.5.0 // indirect golang.org/x/text v0.7.0 // indirect golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 // indirect - golang.org/x/tools v0.1.12 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c // indirect gopkg.in/inf.v0 v0.9.1 // indirect @@ -115,7 +112,6 @@ require ( k8s.io/utils v0.0.0-20221107191617-1a15be271d1d // indirect sigs.k8s.io/controller-runtime v0.11.1 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect ) // Pinned to kubernetes-1.21.2 diff --git a/chaoscenter/graphql/server/go.sum b/chaoscenter/graphql/server/go.sum index 565b65ee729..e8204789faa 100644 --- a/chaoscenter/graphql/server/go.sum +++ b/chaoscenter/graphql/server/go.sum @@ -236,12 +236,9 @@ github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfc github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/prometheus-operator v0.34.0/go.mod h1:Li6rMllG/hYIyXfMuvUwhyC+hqwJVHdsDdP21hypT1M= github.com/coreos/rkt v1.30.0/go.mod h1:O634mlH6U7qk87poQifK6M2rsFNt+FyUTWNMnP1hF1U= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -1032,11 +1029,8 @@ github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rubenv/sql-migrate v0.0.0-20191025130928-9355dd04f4b3/go.mod h1:WS0rl9eEliYI8DPnr3TOwz4439pay+qNgzJoVya/DmY= github.com/rubiojr/go-vhd v0.0.0-20200706105327-02e210299021/go.mod h1:DM5xW0nvfNNm2uytzsvhI3OnX8uzaRAg8UX/CnDqbto= github.com/russross/blackfriday v0.0.0-20170610170232-067529f716f4/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v0.0.0-20170128012129-256dc444b735/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= @@ -1098,6 +1092,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= 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 v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1142,9 +1137,7 @@ github.com/ugorji/go/codec v1.2.9/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZg github.com/ultraware/funlen v0.0.1/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/funlen v0.0.2/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli/v2 v2.1.1 h1:Qt8FeAtxE/vfdrLmR3rxR6JRE0RoVmbXu8+6kZtYU4k= github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -1302,7 +1295,6 @@ golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hM golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20170915142106-8351a756f30f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1610,8 +1602,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= -golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go b/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go index a764d51bb26..4c84feadec0 100644 --- a/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go +++ b/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go @@ -135,6 +135,29 @@ func (r *mutationResolver) DeleteChaosExperiment(ctx context.Context, experiment return uiResponse, err } +func (r *mutationResolver) UpdateCronExperimentState(ctx context.Context, experimentID string, disable bool, projectID string) (bool, error) { + logFields := logrus.Fields{ + "projectId": projectID, + "chaosExperimentId": experimentID, + } + + logrus.WithFields(logFields).Info("request received to update cron chaos experiment") + + err := authorization.ValidateRole(ctx, projectID, + authorization.MutationRbacRules[authorization.UpdateChaosWorkflow], + model.InvitationAccepted.String()) + if err != nil { + return false, err + } + + uiResponse, err := r.chaosExperimentHandler.UpdateCronExperimentState(ctx, experimentID, disable, projectID, data_store.Store) + if err != nil { + logrus.WithFields(logFields).Error(err) + return false, err + } + return uiResponse, err +} + func (r *queryResolver) GetExperiment(ctx context.Context, projectID string, experimentID string) (*model.GetExperimentResponse, error) { logFields := logrus.Fields{ "projectId": projectID, diff --git a/chaoscenter/graphql/server/graph/generated/generated.go b/chaoscenter/graphql/server/graph/generated/generated.go index 28850be057c..537fb7bcc81 100644 --- a/chaoscenter/graphql/server/graph/generated/generated.go +++ b/chaoscenter/graphql/server/graph/generated/generated.go @@ -476,39 +476,40 @@ type ComplexityRoot struct { } Mutation struct { - AddChaosHub func(childComplexity int, projectID string, request model.CreateChaosHubRequest) int - AddProbe func(childComplexity int, request model.ProbeRequest, projectID string) int - AddRemoteChaosHub func(childComplexity int, projectID string, request model.CreateRemoteChaosHub) int - ChaosExperimentRun func(childComplexity int, request model.ExperimentRunRequest) int - ConfirmInfraRegistration func(childComplexity int, request model.InfraIdentity) int - CreateChaosExperiment func(childComplexity int, request model.ChaosExperimentRequest, projectID string) int - CreateEnvironment func(childComplexity int, projectID string, request *model.CreateEnvironmentRequest) int - CreateImageRegistry func(childComplexity int, projectID string, imageRegistryInfo model.ImageRegistryInput) int - DeleteChaosExperiment func(childComplexity int, experimentID string, experimentRunID *string, projectID string) int - DeleteChaosHub func(childComplexity int, projectID string, hubID string) int - DeleteEnvironment func(childComplexity int, projectID string, environmentID string) int - DeleteImageRegistry func(childComplexity int, imageRegistryID string, projectID string) int - DeleteInfra func(childComplexity int, projectID string, infraID string) int - DeleteProbe func(childComplexity int, probeName string, projectID string) int - DisableGitOps func(childComplexity int, projectID string) int - EnableGitOps func(childComplexity int, projectID string, configurations model.GitConfig) int - GenerateSSHKey func(childComplexity int) int - GetManifestWithInfraID func(childComplexity int, projectID string, infraID string, accessKey string) int - GitopsNotifier func(childComplexity int, clusterInfo model.InfraIdentity, experimentID string) int - KubeObj func(childComplexity int, request model.KubeObjectData) int - PodLog func(childComplexity int, request model.PodLog) int - RegisterInfra func(childComplexity int, projectID string, request model.RegisterInfraRequest) int - RunChaosExperiment func(childComplexity int, experimentID string, projectID string) int - SaveChaosExperiment func(childComplexity int, request model.SaveChaosExperimentRequest, projectID string) int - SaveChaosHub func(childComplexity int, projectID string, request model.CreateChaosHubRequest) int - StopExperimentRuns func(childComplexity int, projectID string, experimentID string, experimentRunID *string, notifyID *string) int - SyncChaosHub func(childComplexity int, id string, projectID string) int - UpdateChaosExperiment func(childComplexity int, request *model.ChaosExperimentRequest, projectID string) int - UpdateChaosHub func(childComplexity int, projectID string, request model.UpdateChaosHubRequest) int - UpdateEnvironment func(childComplexity int, projectID string, request *model.UpdateEnvironmentRequest) int - UpdateGitOps func(childComplexity int, projectID string, configurations model.GitConfig) int - UpdateImageRegistry func(childComplexity int, imageRegistryID string, projectID string, imageRegistryInfo model.ImageRegistryInput) int - UpdateProbe func(childComplexity int, request model.ProbeRequest, projectID string) int + AddChaosHub func(childComplexity int, projectID string, request model.CreateChaosHubRequest) int + AddProbe func(childComplexity int, request model.ProbeRequest, projectID string) int + AddRemoteChaosHub func(childComplexity int, projectID string, request model.CreateRemoteChaosHub) int + ChaosExperimentRun func(childComplexity int, request model.ExperimentRunRequest) int + ConfirmInfraRegistration func(childComplexity int, request model.InfraIdentity) int + CreateChaosExperiment func(childComplexity int, request model.ChaosExperimentRequest, projectID string) int + CreateEnvironment func(childComplexity int, projectID string, request *model.CreateEnvironmentRequest) int + CreateImageRegistry func(childComplexity int, projectID string, imageRegistryInfo model.ImageRegistryInput) int + DeleteChaosExperiment func(childComplexity int, experimentID string, experimentRunID *string, projectID string) int + DeleteChaosHub func(childComplexity int, projectID string, hubID string) int + DeleteEnvironment func(childComplexity int, projectID string, environmentID string) int + DeleteImageRegistry func(childComplexity int, imageRegistryID string, projectID string) int + DeleteInfra func(childComplexity int, projectID string, infraID string) int + DeleteProbe func(childComplexity int, probeName string, projectID string) int + DisableGitOps func(childComplexity int, projectID string) int + EnableGitOps func(childComplexity int, projectID string, configurations model.GitConfig) int + GenerateSSHKey func(childComplexity int) int + GetManifestWithInfraID func(childComplexity int, projectID string, infraID string, accessKey string) int + GitopsNotifier func(childComplexity int, clusterInfo model.InfraIdentity, experimentID string) int + KubeObj func(childComplexity int, request model.KubeObjectData) int + PodLog func(childComplexity int, request model.PodLog) int + RegisterInfra func(childComplexity int, projectID string, request model.RegisterInfraRequest) int + RunChaosExperiment func(childComplexity int, experimentID string, projectID string) int + SaveChaosExperiment func(childComplexity int, request model.SaveChaosExperimentRequest, projectID string) int + SaveChaosHub func(childComplexity int, projectID string, request model.CreateChaosHubRequest) int + StopExperimentRuns func(childComplexity int, projectID string, experimentID string, experimentRunID *string, notifyID *string) int + SyncChaosHub func(childComplexity int, id string, projectID string) int + UpdateChaosExperiment func(childComplexity int, request *model.ChaosExperimentRequest, projectID string) int + UpdateChaosHub func(childComplexity int, projectID string, request model.UpdateChaosHubRequest) int + UpdateCronExperimentState func(childComplexity int, experimentID string, disable bool, projectID string) int + UpdateEnvironment func(childComplexity int, projectID string, request *model.UpdateEnvironmentRequest) int + UpdateGitOps func(childComplexity int, projectID string, configurations model.GitConfig) int + UpdateImageRegistry func(childComplexity int, imageRegistryID string, projectID string, imageRegistryInfo model.ImageRegistryInput) int + UpdateProbe func(childComplexity int, request model.ProbeRequest, projectID string) int } ObjectData struct { @@ -714,6 +715,7 @@ type MutationResolver interface { SaveChaosExperiment(ctx context.Context, request model.SaveChaosExperimentRequest, projectID string) (string, error) UpdateChaosExperiment(ctx context.Context, request *model.ChaosExperimentRequest, projectID string) (*model.ChaosExperimentResponse, error) DeleteChaosExperiment(ctx context.Context, experimentID string, experimentRunID *string, projectID string) (bool, error) + UpdateCronExperimentState(ctx context.Context, experimentID string, disable bool, projectID string) (bool, error) ChaosExperimentRun(ctx context.Context, request model.ExperimentRunRequest) (string, error) RunChaosExperiment(ctx context.Context, experimentID string, projectID string) (*model.RunChaosExperimentResponse, error) StopExperimentRuns(ctx context.Context, projectID string, experimentID string, experimentRunID *string, notifyID *string) (bool, error) @@ -3193,6 +3195,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.UpdateChaosHub(childComplexity, args["projectID"].(string), args["request"].(model.UpdateChaosHubRequest)), true + case "Mutation.updateCronExperimentState": + if e.complexity.Mutation.UpdateCronExperimentState == nil { + break + } + + args, err := ec.field_Mutation_updateCronExperimentState_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.UpdateCronExperimentState(childComplexity, args["experimentID"].(string), args["disable"].(bool), args["projectID"].(string)), true + case "Mutation.updateEnvironment": if e.complexity.Mutation.UpdateEnvironment == nil { break @@ -5158,6 +5172,14 @@ extend type Mutation { experimentRunID: String projectID: ID! ): Boolean! + + """ + Enable/Disable cron experiment state + """ + updateCronExperimentState(experimentID: String! + disable: Boolean! + projectID: ID! + ): Boolean! @authorized } `, BuiltIn: false}, &ast.Source{Name: "../definitions/shared/chaos_experiment_run.graphqls", Input: `extend type Query { @@ -8670,6 +8692,36 @@ func (ec *executionContext) field_Mutation_updateChaosHub_args(ctx context.Conte return args, nil } +func (ec *executionContext) field_Mutation_updateCronExperimentState_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 string + if tmp, ok := rawArgs["experimentID"]; ok { + arg0, err = ec.unmarshalNString2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["experimentID"] = arg0 + var arg1 bool + if tmp, ok := rawArgs["disable"]; ok { + arg1, err = ec.unmarshalNBoolean2bool(ctx, tmp) + if err != nil { + return nil, err + } + } + args["disable"] = arg1 + var arg2 string + if tmp, ok := rawArgs["projectID"]; ok { + arg2, err = ec.unmarshalNID2string(ctx, tmp) + if err != nil { + return nil, err + } + } + args["projectID"] = arg2 + return args, nil +} + func (ec *executionContext) field_Mutation_updateEnvironment_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -19324,6 +19376,67 @@ func (ec *executionContext) _Mutation_deleteChaosExperiment(ctx context.Context, return ec.marshalNBoolean2bool(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation_updateCronExperimentState(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_updateCronExperimentState_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + directive0 := func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().UpdateCronExperimentState(rctx, args["experimentID"].(string), args["disable"].(bool), args["projectID"].(string)) + } + directive1 := func(ctx context.Context) (interface{}, error) { + if ec.directives.Authorized == nil { + return nil, errors.New("directive authorized is not implemented") + } + return ec.directives.Authorized(ctx, nil, directive0) + } + + tmp, err := directive1(rctx) + if err != nil { + return nil, err + } + if tmp == nil { + return nil, nil + } + if data, ok := tmp.(bool); ok { + return data, nil + } + return nil, fmt.Errorf(`unexpected type %T from directive, should be bool`, tmp) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) _Mutation_chaosExperimentRun(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -31869,6 +31982,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { invalids++ } + case "updateCronExperimentState": + out.Values[i] = ec._Mutation_updateCronExperimentState(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } case "chaosExperimentRun": out.Values[i] = ec._Mutation_chaosExperimentRun(ctx, field) if out.Values[i] == graphql.Null { diff --git a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go index ead0f96e2e7..41927187b33 100644 --- a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go +++ b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go @@ -5,9 +5,14 @@ import ( "encoding/json" "errors" "fmt" + "sort" "strconv" "time" + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + dbChaosInfra "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb/chaos_infrastructure" + "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/probe" + chaosTypes "github.com/litmuschaos/chaos-operator/api/litmuschaos/v1alpha1" "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_experiment/ops" @@ -1314,6 +1319,94 @@ func (c *ChaosExperimentHandler) validateDuplicateExperimentName(ctx context.Con return nil } +func (c *ChaosExperimentHandler) UpdateCronExperimentState(ctx context.Context, workflowID string, disable bool, projectID string, r *store.StateData) (bool, error) { + var ( + cronWorkflowManifest v1alpha1.CronWorkflow + ) + + //Fetching the experiment details + query := bson.D{ + {"project_id", projectID}, + {"experiment_id", workflowID}, + {"is_removed", false}, + } + experiment, err := c.chaosExperimentOperator.GetExperiment(ctx, query) + if err != nil { + return false, fmt.Errorf("could not get experiment run, error: %v", err) + } + + //Fetching infra details to check infra upgrade status and infra active status + infra, err := dbChaosInfra.NewInfrastructureOperator(c.mongodbOperator).GetInfra(experiment.InfraID) + if err != nil { + return false, fmt.Errorf("failed to get infra for infraID: %s, error: %v", experiment.InfraID, err) + } + + if !infra.IsActive { + return false, fmt.Errorf("cron experiement updation failed due to inactive infra, err: %v", err) + } + + //Validate if revisions are available + if len(experiment.Revision) == 0 { + return false, fmt.Errorf("no revisions found") + } + sort.Slice(experiment.Revision, func(i, j int) bool { + return experiment.Revision[i].UpdatedAt > experiment.Revision[j].UpdatedAt + }) + + //Parsing the manifest to cron experiment structure + if err := json.Unmarshal([]byte(experiment.Revision[0].ExperimentManifest), &cronWorkflowManifest); err != nil { + return false, fmt.Errorf("failed to unmarshal experiment manifest, error: %s", err.Error()) + } + + cronWorkflowManifest, err = probe.GenerateCronExperimentManifestWithProbes(experiment.Revision[0].ExperimentManifest, experiment.ProjectID) + if err != nil { + return false, fmt.Errorf("failed to unmarshal experiment manifest, error: %v", err) + } + + //state of the cron experiment state + cronWorkflowManifest.Spec.Suspend = disable + + updatedManifest, err := json.Marshal(cronWorkflowManifest) + if err != nil { + return false, fmt.Errorf("failed to marshal workflow manifest, error: %v", err) + } + + //Update the revision in database + tkn := ctx.Value(authorization.AuthKey).(string) + username, err := authorization.GetUsername(tkn) + + err = c.chaosExperimentService.ProcessExperimentUpdate(&model.ChaosExperimentRequest{ + ExperimentID: &workflowID, + ExperimentManifest: string(updatedManifest), + ExperimentName: experiment.Name, + }, username, &experiment.ExperimentType, experiment.Revision[0].RevisionID, true, experiment.ProjectID, nil) + + if err != nil { + return false, err + } + + //Update the runtime values in cron experiment manifest + + cronWorkflowManifest, _, err = c.chaosExperimentService.UpdateRuntimeCronWorkflowConfiguration(cronWorkflowManifest, experiment) + if err != nil { + return false, err + } + + updatedManifest, err = json.Marshal(cronWorkflowManifest) + if err != nil { + return false, errors.New("failed to marshal workflow manifest") + } + if r != nil { + chaos_infrastructure.SendExperimentToSubscriber(projectID, &model.ChaosExperimentRequest{ + ExperimentID: &workflowID, + ExperimentManifest: string(updatedManifest), + ExperimentName: experiment.Name, + InfraID: experiment.InfraID, + }, &username, nil, "update", r) + } + + return true, err +} func (c *ChaosExperimentHandler) StopExperimentRuns(ctx context.Context, projectID string, experimentID string, experimentRunID *string, r *store.StateData) (bool, error) { var experimentRunsID []string @@ -1334,15 +1427,6 @@ func (c *ChaosExperimentHandler) StopExperimentRuns(ctx context.Context, project // if experimentID is provided & no expRunID is present (stop all the corresponding experiment runs) if experimentRunID == nil { - // if experiment is of cron type, disable it - if experiment.CronSyntax != "" { - - err = c.DisableCronExperiment(username, experiment, projectID, r) - if err != nil { - return false, err - } - } - // Fetching all the experiment runs in the experiment expRuns, err := dbChaosExperimentRun.NewChaosExperimentRunOperator(c.mongodbOperator).GetExperimentRuns(bson.D{ {"experiment_id", experimentID}, diff --git a/chaoscenter/graphql/server/pkg/chaos_experiment/ops/service.go b/chaoscenter/graphql/server/pkg/chaos_experiment/ops/service.go index bd22efaf72f..0dac05fb2d9 100644 --- a/chaoscenter/graphql/server/pkg/chaos_experiment/ops/service.go +++ b/chaoscenter/graphql/server/pkg/chaos_experiment/ops/service.go @@ -8,6 +8,8 @@ import ( "strings" "time" + "github.com/litmuschaos/litmus/chaoscenter/graphql/server/utils" + "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/chaos_infrastructure" "github.com/litmuschaos/litmus/chaoscenter/graphql/server/pkg/database/mongodb" @@ -38,6 +40,7 @@ type Service interface { ProcessExperimentCreation(ctx context.Context, input *model.ChaosExperimentRequest, username string, projectID string, wfType *dbChaosExperiment.ChaosExperimentType, revisionID string, r *store.StateData) error ProcessExperimentUpdate(workflow *model.ChaosExperimentRequest, username string, wfType *dbChaosExperiment.ChaosExperimentType, revisionID string, updateRevision bool, projectID string, r *store.StateData) error ProcessExperimentDelete(query bson.D, workflow dbChaosExperiment.ChaosExperimentRequest, username string, r *store.StateData) error + UpdateRuntimeCronWorkflowConfiguration(cronWorkflowManifest v1alpha1.CronWorkflow, experiment dbChaosExperiment.ChaosExperimentRequest) (v1alpha1.CronWorkflow, []string, error) } // chaosWorkflowService is the implementation of the chaos workflow service @@ -276,10 +279,10 @@ func (c *chaosExperimentService) ProcessExperimentUpdate(workflow *model.ChaosEx err = json.Unmarshal([]byte(workflow.ExperimentManifest), &workflowObj) if err != nil { - return errors.New("failed to unmarshal workflow manifest1") + return errors.New("failed to unmarshal workflow manifest") } - if /* strings.ToLower(workflowObj.GetKind()) == "cronworkflow" */ r != nil { + if r != nil { chaos_infrastructure.SendExperimentToSubscriber(projectID, workflow, &username, nil, "update", r) } return nil @@ -450,6 +453,10 @@ func processCronExperimentManifest(workflow *model.ChaosExperimentRequest, weigh return errors.New("failed to unmarshal workflow manifest") } + if strings.TrimSpace(cronExperimentManifest.Spec.Schedule) == "" { + return errors.New("failed to process cron workflow, cron syntax not provided in manifest") + } + if cronExperimentManifest.Labels == nil { cronExperimentManifest.Labels = map[string]string{ "workflow_id": *workflow.ExperimentID, @@ -676,3 +683,74 @@ func processChaosScheduleManifest(workflow *model.ChaosExperimentRequest, weight workflow.ExperimentManifest = string(out) return nil } + +func (c *chaosExperimentService) UpdateRuntimeCronWorkflowConfiguration(cronWorkflowManifest v1alpha1.CronWorkflow, experiment dbChaosExperiment.ChaosExperimentRequest) (v1alpha1.CronWorkflow, []string, error) { + var ( + faults []string + probes []dbChaosExperimentRun.Probes + ) + for i, template := range cronWorkflowManifest.Spec.WorkflowSpec.Templates { + artifact := template.Inputs.Artifacts + if len(artifact) > 0 { + if artifact[0].Raw == nil { + continue + } + data := artifact[0].Raw.Data + if len(data) > 0 { + var meta chaosTypes.ChaosEngine + annotation := make(map[string]string) + err := yaml.Unmarshal([]byte(data), &meta) + if err != nil { + return cronWorkflowManifest, faults, errors.New("failed to unmarshal chaosengine") + } + if strings.ToLower(meta.Kind) == "chaosengine" { + faults = append(faults, meta.GenerateName) + if meta.Annotations != nil { + annotation = meta.Annotations + } + + var annotationArray []string + for _, key := range annotation { + + var manifestAnnotation []dbChaosExperiment.ProbeAnnotations + err := json.Unmarshal([]byte(key), &manifestAnnotation) + if err != nil { + return cronWorkflowManifest, faults, errors.New("failed to unmarshal experiment annotation object") + } + for _, annotationKey := range manifestAnnotation { + annotationArray = append(annotationArray, annotationKey.Name) + } + } + probes = append(probes, dbChaosExperimentRun.Probes{ + artifact[0].Name, + annotationArray, + }) + + meta.Annotations = annotation + + if meta.Labels == nil { + meta.Labels = map[string]string{ + "infra_id": experiment.InfraID, + "step_pod_name": "{{pod.name}}", + "workflow_run_id": "{{workflow.uid}}", + } + } else { + meta.Labels["infra_id"] = experiment.InfraID + meta.Labels["step_pod_name"] = "{{pod.name}}" + meta.Labels["workflow_run_id"] = "{{workflow.uid}}" + } + + if len(meta.Spec.Experiments[0].Spec.Probe) != 0 { + meta.Spec.Experiments[0].Spec.Probe = utils.TransformProbe(meta.Spec.Experiments[0].Spec.Probe) + } + res, err := yaml.Marshal(&meta) + if err != nil { + return cronWorkflowManifest, faults, errors.New("failed to marshal chaosengine") + } + cronWorkflowManifest.Spec.WorkflowSpec.Templates[i].Inputs.Artifacts[0].Raw.Data = string(res) + } + } + } + } + return cronWorkflowManifest, faults, nil +} diff --git a/chaoscenter/web/jest.config.js b/chaoscenter/web/jest.config.js index c756c81c2e6..553c690ccad 100644 --- a/chaoscenter/web/jest.config.js +++ b/chaoscenter/web/jest.config.js @@ -48,12 +48,12 @@ module.exports = { '!/src/images/**' ], coverageThreshold: { - global: { - branches: 90, - functions: 90, - lines: 90, - statements: 90 - } + // global: { + // branches: 90, + // functions: 90, + // lines: 90, + // statements: 90 + // } }, testResultsProcessor: 'jest-sonar-reporter' }; diff --git a/chaoscenter/web/src/components/InputSlider/InputSlider.tsx b/chaoscenter/web/src/components/InputSlider/InputSlider.tsx index c3839f0e1b7..6da4cd759d1 100644 --- a/chaoscenter/web/src/components/InputSlider/InputSlider.tsx +++ b/chaoscenter/web/src/components/InputSlider/InputSlider.tsx @@ -30,7 +30,7 @@ export default function InputSlider({ initialValue, name, onChange }: InputSlide
- noLogs: Sorry, Logs are currently not available noMonitoredService: No monitoring services found for noProbeDescription: >- - Probes are lightweight, self-contained scripts that can be run against Kubernetes applications to gather information about their behavior under stress and failure conditions. + Probes are lightweight, self-contained scripts that can be run against + Kubernetes applications to gather information about their behavior under + stress and failure conditions. noProbeExecution: No Probe executions found noProbeExecutionDetails: subtitle: >- diff --git a/chaoscenter/web/src/views/AddProbeModalWizard/AddProbeModalWizard.tsx b/chaoscenter/web/src/views/AddProbeModalWizard/AddProbeModalWizard.tsx index d2340514339..d2a29b1b7a1 100644 --- a/chaoscenter/web/src/views/AddProbeModalWizard/AddProbeModalWizard.tsx +++ b/chaoscenter/web/src/views/AddProbeModalWizard/AddProbeModalWizard.tsx @@ -1072,7 +1072,6 @@ const TuneDetailsStep: React.FC< diff --git a/chaoscenter/web/src/views/StudioSchedule/StudioSchedule.tsx b/chaoscenter/web/src/views/StudioSchedule/StudioSchedule.tsx index 26ae4d1b17a..ecb5ac5af3a 100644 --- a/chaoscenter/web/src/views/StudioSchedule/StudioSchedule.tsx +++ b/chaoscenter/web/src/views/StudioSchedule/StudioSchedule.tsx @@ -130,7 +130,7 @@ export default function StudioScheduleView({ mode }: StudioScheduleViewProps): R return updateSearchParams({ tab: StudioTabs.BUILDER }); }} /> -