diff --git a/api/external/infra_proxy/migrations/migrations.pb.client_mock.go b/api/external/infra_proxy/migrations/migrations.pb.client_mock.go new file mode 100644 index 00000000000..6a910db8efe --- /dev/null +++ b/api/external/infra_proxy/migrations/migrations.pb.client_mock.go @@ -0,0 +1,95 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: infra_proxy/migrations/migrations.pb.go + +// Package migrations is a generated GoMock package. +package migrations + +import ( + context "context" + request "github.com/chef/automate/api/external/infra_proxy/migrations/request" + response "github.com/chef/automate/api/external/infra_proxy/migrations/response" + gomock "github.com/golang/mock/gomock" + grpc "google.golang.org/grpc" + reflect "reflect" +) + +// MockInfraProxyMigrationClient is a mock of InfraProxyMigrationClient interface +type MockInfraProxyMigrationClient struct { + ctrl *gomock.Controller + recorder *MockInfraProxyMigrationClientMockRecorder +} + +// MockInfraProxyMigrationClientMockRecorder is the mock recorder for MockInfraProxyMigrationClient +type MockInfraProxyMigrationClientMockRecorder struct { + mock *MockInfraProxyMigrationClient +} + +// NewMockInfraProxyMigrationClient creates a new mock instance +func NewMockInfraProxyMigrationClient(ctrl *gomock.Controller) *MockInfraProxyMigrationClient { + mock := &MockInfraProxyMigrationClient{ctrl: ctrl} + mock.recorder = &MockInfraProxyMigrationClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockInfraProxyMigrationClient) EXPECT() *MockInfraProxyMigrationClientMockRecorder { + return m.recorder +} + +// GetMigrationStatus mocks base method +func (m *MockInfraProxyMigrationClient) GetMigrationStatus(ctx context.Context, in *request.GetMigrationStatus, opts ...grpc.CallOption) (*response.GetMigrationStatus, error) { + m.ctrl.T.Helper() + varargs := []interface{}{ctx, in} + for _, a := range opts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetMigrationStatus", varargs...) + ret0, _ := ret[0].(*response.GetMigrationStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMigrationStatus indicates an expected call of GetMigrationStatus +func (mr *MockInfraProxyMigrationClientMockRecorder) GetMigrationStatus(ctx, in interface{}, opts ...interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]interface{}{ctx, in}, opts...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrationStatus", reflect.TypeOf((*MockInfraProxyMigrationClient)(nil).GetMigrationStatus), varargs...) +} + +// MockInfraProxyMigrationServer is a mock of InfraProxyMigrationServer interface +type MockInfraProxyMigrationServer struct { + ctrl *gomock.Controller + recorder *MockInfraProxyMigrationServerMockRecorder +} + +// MockInfraProxyMigrationServerMockRecorder is the mock recorder for MockInfraProxyMigrationServer +type MockInfraProxyMigrationServerMockRecorder struct { + mock *MockInfraProxyMigrationServer +} + +// NewMockInfraProxyMigrationServer creates a new mock instance +func NewMockInfraProxyMigrationServer(ctrl *gomock.Controller) *MockInfraProxyMigrationServer { + mock := &MockInfraProxyMigrationServer{ctrl: ctrl} + mock.recorder = &MockInfraProxyMigrationServerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockInfraProxyMigrationServer) EXPECT() *MockInfraProxyMigrationServerMockRecorder { + return m.recorder +} + +// GetMigrationStatus mocks base method +func (m *MockInfraProxyMigrationServer) GetMigrationStatus(arg0 context.Context, arg1 *request.GetMigrationStatus) (*response.GetMigrationStatus, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMigrationStatus", arg0, arg1) + ret0, _ := ret[0].(*response.GetMigrationStatus) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMigrationStatus indicates an expected call of GetMigrationStatus +func (mr *MockInfraProxyMigrationServerMockRecorder) GetMigrationStatus(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrationStatus", reflect.TypeOf((*MockInfraProxyMigrationServer)(nil).GetMigrationStatus), arg0, arg1) +} diff --git a/components/infra-proxy-service/server/migrations/migrations.go b/components/infra-proxy-service/migrations/migrations.go similarity index 100% rename from components/infra-proxy-service/server/migrations/migrations.go rename to components/infra-proxy-service/migrations/migrations.go diff --git a/components/infra-proxy-service/server/migrations/migrations_test.go b/components/infra-proxy-service/migrations/migrations_test.go similarity index 100% rename from components/infra-proxy-service/server/migrations/migrations_test.go rename to components/infra-proxy-service/migrations/migrations_test.go diff --git a/components/infra-proxy-service/pipeline/models.go b/components/infra-proxy-service/migrations/pipeline/models.go similarity index 96% rename from components/infra-proxy-service/pipeline/models.go rename to components/infra-proxy-service/migrations/pipeline/models.go index c76d3f5f9c6..77dd3774a67 100644 --- a/components/infra-proxy-service/pipeline/models.go +++ b/components/infra-proxy-service/migrations/pipeline/models.go @@ -27,6 +27,12 @@ type Meta struct { // UnzipFolder for unzipped folder's location UnzipFolder string `json:"unzip_folder"` + + // Chef Infra Server ID + ServerID string `json:"server_id"` + + // Migration ID + MigrationID string `json:"migration_id"` } type StageResult struct { diff --git a/components/infra-proxy-service/migrations/pipeline/utility.go b/components/infra-proxy-service/migrations/pipeline/utility.go new file mode 100644 index 00000000000..a80b731ecc0 --- /dev/null +++ b/components/infra-proxy-service/migrations/pipeline/utility.go @@ -0,0 +1,64 @@ +package pipeline + +import ( + "context" + + "github.com/chef/automate/components/infra-proxy-service/storage" + log "github.com/sirupsen/logrus" +) + +// StoreOrgs reads the Result struct and populate the orgs table +func StoreOrgs(ctx context.Context, st storage.Storage, mst storage.MigrationStorage, res Result) (Result, error) { + var err error + var msg string + var totalSucceeded, totalSkipped, totalFailed int64 + _, err = mst.StartOrgMigration(ctx, res.Meta.MigrationID, res.Meta.ServerID) + if err != nil { + return res, err + } + log.Info("Starting the organisation migration phase for migration id: ", res.Meta.MigrationID) + for _, org := range res.ParsedResult.Orgs { + err, _ = StoreOrg(ctx, st, org, res.Meta.ServerID) + if err != nil { + totalFailed++ + msg = err.Error() + continue + } + if org.ActionOps == Skip { + totalSkipped++ + continue + } + totalSucceeded++ + } + if len(res.ParsedResult.Orgs) == int(totalFailed) { + log.Errorf("Failed to migrate orgs for migration id %s : %s", res.Meta.MigrationID, err.Error()) + _, _ = mst.FailedOrgMigration(ctx, res.Meta.MigrationID, res.Meta.ServerID, msg, totalSucceeded, totalSkipped, totalFailed) + return res, err + } + _, err = mst.CompleteOrgMigration(ctx, res.Meta.MigrationID, res.Meta.ServerID, totalSucceeded, totalSkipped, totalFailed) + if err != nil { + log.Errorf("Failed to update the status for migration id %s : %s", res.Meta.MigrationID, err.Error()) + return res, err + } + log.Info("Successfully completed the organisation migration phase for migration id: ", res.Meta.MigrationID) + return res, err +} + +// StoreOrg stores a single Org into DB +func StoreOrg(ctx context.Context, st storage.Storage, org Org, serverID string) (error, ActionOps) { + var actionTaken ActionOps + var err error + switch org.ActionOps { + case Insert: + _, err = st.StoreOrg(ctx, org.Name, org.FullName, "", "", serverID, nil) + actionTaken = Insert + case Delete: + _, err = st.DeleteOrg(ctx, org.Name, serverID) + actionTaken = Delete + case Update: + _, err = st.EditOrg(ctx, org.Name, org.FullName, "", serverID, nil) + actionTaken = Update + default: + } + return err, actionTaken +} diff --git a/components/infra-proxy-service/migrations/pipeline/utility_test.go b/components/infra-proxy-service/migrations/pipeline/utility_test.go new file mode 100644 index 00000000000..2458650f4f0 --- /dev/null +++ b/components/infra-proxy-service/migrations/pipeline/utility_test.go @@ -0,0 +1,40 @@ +package pipeline + +import ( + "context" + "github.com/chef/automate/components/infra-proxy-service/storage" + "github.com/chef/automate/components/infra-proxy-service/storage/testDB" + "reflect" + "testing" +) + +func TestStoreOrg(t *testing.T) { + type args struct { + ctx context.Context + st storage.Storage + org Org + serverID string + } + tests := []struct { + name string + args args + want error + want1 ActionOps + }{ + // TODO: Add test cases. + {name: "Test Delete Org", args: args{ctx: context.Background(), st: &testDB.TestDB{}, org: Org{Name: "org1", FullName: "Org 1", ActionOps: Delete}, serverID: "server1"}, want: nil, want1: Delete}, + {name: "Test Store Org", args: args{ctx: context.Background(), st: &testDB.TestDB{}, org: Org{Name: "org1", FullName: "Org 1", ActionOps: Insert}, serverID: "server1"}, want: nil, want1: Insert}, + {name: "Test Edit Org", args: args{ctx: context.Background(), st: &testDB.TestDB{}, org: Org{Name: "org1", FullName: "Org 1", ActionOps: Update}, serverID: "server1"}, want: nil, want1: Update}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1 := StoreOrg(tt.args.ctx, tt.args.st, tt.args.org, tt.args.serverID) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("StoreOrg() got = %v, want %v", got, tt.want) + } + if got1 != tt.want1 { + t.Errorf("StoreOrg() got1 = %v, want %v", got1, tt.want1) + } + }) + } +} diff --git a/components/infra-proxy-service/server/migrations/server.go b/components/infra-proxy-service/migrations/server.go similarity index 100% rename from components/infra-proxy-service/server/migrations/server.go rename to components/infra-proxy-service/migrations/server.go diff --git a/components/infra-proxy-service/server/server.go b/components/infra-proxy-service/server/server.go index 332f1e5e4c3..463e224ff63 100644 --- a/components/infra-proxy-service/server/server.go +++ b/components/infra-proxy-service/server/server.go @@ -4,6 +4,7 @@ import ( "context" "crypto/tls" "fmt" + "github.com/chef/automate/components/infra-proxy-service/migrations" "net" "net/http" @@ -17,8 +18,6 @@ import ( grpc_s "github.com/chef/automate/api/interservice/infra_proxy/service" grpc_migration "github.com/chef/automate/api/interservice/infra_proxy/migrations/service" - migrations "github.com/chef/automate/components/infra-proxy-service/server/migrations" - "github.com/chef/automate/components/infra-proxy-service/service" "github.com/chef/automate/lib/grpc/health" "github.com/chef/automate/lib/tracing" diff --git a/components/infra-proxy-service/storage/testDB/testDB.go b/components/infra-proxy-service/storage/testDB/testDB.go new file mode 100644 index 00000000000..4424eb2db0d --- /dev/null +++ b/components/infra-proxy-service/storage/testDB/testDB.go @@ -0,0 +1,104 @@ +package testDB + +import ( + "context" + "errors" + "github.com/chef/automate/components/infra-proxy-service/storage" +) + +type TestDB struct { + Orgs map[string]storage.Org + Servers map[string]storage.Server + Users map[string]storage.User + NeedError bool +} + +func (t *TestDB) GetServer(_ context.Context, id string) (storage.Server, error) { + if t.NeedError { + return storage.Server{}, errors.New("failed to fetch Server") + } + if _, ok := t.Servers[id]; !ok { + return storage.Server{}, errors.New("No such server found") + } + return t.Servers[id], nil +} + +func (t *TestDB) GetServers(ctx context.Context) ([]storage.Server, error) { + if t.NeedError { + return []storage.Server{}, errors.New("failed to fetch Server") + } + var x []storage.Server + for _, v := range t.Servers { + x = append(x, v) + } + return x, nil +} + +func (t *TestDB) StoreServer(ctx context.Context, id string, name string, fqdn string, ipAddress string, credentialId string) (storage.Server, error) { + panic("implement me") +} + +func (t *TestDB) DeleteServer(ctx context.Context, id string) (storage.Server, error) { + panic("implement me") +} + +func (t *TestDB) EditServer(ctx context.Context, id string, name string, fqdn string, ipAddress string) (storage.Server, error) { + panic("implement me") +} + +func (t *TestDB) EditServerWebuiKey(ctx context.Context, id, credentialId string) (storage.Server, error) { + panic("implement me") +} + +func (t *TestDB) GetOrg(ctx context.Context, orgID string, serverID string) (storage.Org, error) { + panic("implement me") +} + +func (t *TestDB) GetOrgs(ctx context.Context, serverID string) ([]storage.Org, error) { + panic("implement me") +} + +func (t *TestDB) StoreOrg(ctx context.Context, id string, name string, adminUser string, adminKey string, serverID string, projects []string) (storage.Org, error) { + if t.NeedError { + return storage.Org{}, errors.New("failed to store org") + } + return storage.Org{ID: id, Name: name, AdminUser: adminUser, CredentialID: adminKey, ServerID: serverID, Projects: projects}, nil +} + +func (t *TestDB) DeleteOrg(ctx context.Context, orgID string, serverID string) (storage.Org, error) { + if t.NeedError { + return storage.Org{}, errors.New("failed to delete org") + } + return storage.Org{ID: orgID}, nil +} + +func (t *TestDB) EditOrg(ctx context.Context, id string, name string, adminUser string, serverID string, projects []string) (storage.Org, error) { + if t.NeedError { + return storage.Org{}, errors.New("failed to edit org") + } + return storage.Org{ID: id, Name: name, AdminUser: adminUser, ServerID: serverID, Projects: projects}, nil +} + +func (t *TestDB) TouchOrg(ctx context.Context, id string, serverID string) (storage.Org, error) { + panic("implement me") +} + +func (t *TestDB) InsertUser(ctx context.Context, id, serverID, infraServerUsername, credentialID, Connector, automateUserID string, IsServerAdmin bool) (storage.User, error) { + panic("implement me") +} + +func (t *TestDB) GetUser(ctx context.Context, id string) (storage.User, error) { + panic("implement me") +} + +func (t *TestDB) EditUser(ctx context.Context, id, serverID, infraServerUsername, credentialID, Connector, automateUserID string, IsServerAdmin bool) (storage.User, error) { + panic("implement me") +} + +func (t *TestDB) DeleteUser(ctx context.Context, id string) (storage.User, error) { + panic("implement me") +} + +func (t *TestDB) GetAutomateInfraServerUsers(ctx context.Context, serverId string) ([]storage.User, error) { + panic("implement me") +} diff --git a/components/infra-proxy-service/storage/testDB/testMigrationsDB.go b/components/infra-proxy-service/storage/testDB/testMigrationsDB.go new file mode 100644 index 00000000000..3b72d5414bc --- /dev/null +++ b/components/infra-proxy-service/storage/testDB/testMigrationsDB.go @@ -0,0 +1,183 @@ +package testDB + +import ( + "context" + "github.com/chef/automate/components/infra-proxy-service/storage" +) + +type MigrationDB struct { + MigrationStatus []storage.Migration + NeedError bool +} + +func (m MigrationDB) StartMigration(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartFileUpload(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteFileUpload(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedFileUpload(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartUnzip(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteUnzip(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedUnzip(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartOrgParsing(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteOrgParsing(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedOrgParsing(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartUsersParsing(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteUsersParsing(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedUsersParsing(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartUserAssociationParsing(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteUserAssociationParsing(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedUserAssociationParsing(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartPermissionParsing(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompletePermissionParsing(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedPermissionParsing(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartCreatePreview(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteCreatePreview(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedCreatePreview(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartOrgMigration(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteOrgMigration(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedOrgMigration(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartUserMigration(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteUserMigration(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedUserMigration(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartAssociation(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteAssociation(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedAssociation(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StartPermissionMigration(ctx context.Context, migrationId, serverId string) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompletePermissionMigration(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedPermissionMigration(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CompleteMigration(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedMigration(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) CancelMigration(ctx context.Context, migrationId, serverId string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) FailedCancelMigration(ctx context.Context, migrationId, serverId, message string, totalSucceeded, totalSkipped, totalFailed int64) (storage.Migration, error) { + panic("implement me") +} + +func (m MigrationDB) StoreMigrationStage(ctx context.Context, migrationId string, parsedData interface{}) (storage.MigrationStage, error) { + panic("implement me") +} + +func (m MigrationDB) GetMigrationStage(ctx context.Context, migrationId string) (storage.MigrationStage, error) { + panic("implement me") +} + +func (m MigrationDB) DeleteMigrationStage(ctx context.Context, migrationId string) (storage.MigrationStage, error) { + panic("implement me") +} + +func (m MigrationDB) GetActiveMigration(ctx context.Context, serverId string) (storage.MigrationStatus, error) { + panic("implement me") +} + +func (m MigrationDB) GetMigrationStatus(ctx context.Context, migrationId string) (storage.MigrationStatus, error) { + panic("implement me") +}