diff --git a/cmd/api-server/main.go b/cmd/api-server/main.go index ad57c53c70..a323a22e12 100644 --- a/cmd/api-server/main.go +++ b/cmd/api-server/main.go @@ -235,8 +235,10 @@ func main() { testsourcesClient := testsourcesclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) testExecutionsClient := testexecutionsclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) testsuiteExecutionsClient := testsuiteexecutionsclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) - testWorkflowsClient := testworkflowsclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) - testWorkflowTemplatesClient := testworkflowsclientv1.NewTestWorkflowTemplatesClient(kubeClient, cfg.TestkubeNamespace) + var testWorkflowsClient testworkflowsclientv1.Interface + testWorkflowsClient = testworkflowsclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) + var testWorkflowTemplatesClient testworkflowsclientv1.TestWorkflowTemplatesInterface + testWorkflowTemplatesClient = testworkflowsclientv1.NewTestWorkflowTemplatesClient(kubeClient, cfg.TestkubeNamespace) testWorkflowExecutionsClient := testworkflowsclientv1.NewTestWorkflowExecutionsClient(kubeClient, cfg.TestkubeNamespace) templatesClient := templatesclientv1.NewClient(kubeClient, cfg.TestkubeNamespace) @@ -274,6 +276,10 @@ func main() { resultsRepository = cloudresult.NewCloudResultRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) testResultsRepository = cloudtestresult.NewCloudRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) configRepository = cloudconfig.NewCloudResultRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) + + //TODO add some flag + testWorkflowsClient = cloudtestworkflow.NewCloudTestWorkflowRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) + testWorkflowTemplatesClient = cloudtestworkflow.NewCloudTestWorkflowTemplateRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) // Pro edition only (tcl protected code) testWorkflowResultsRepository = cloudtestworkflow.NewCloudRepository(grpcClient, grpcConn, cfg.TestkubeProAPIKey) var opts []cloudtestworkflow.Option diff --git a/internal/app/api/v1/server.go b/internal/app/api/v1/server.go index 688a6a0ab7..9f52d2b064 100644 --- a/internal/app/api/v1/server.go +++ b/internal/app/api/v1/server.go @@ -82,8 +82,8 @@ func NewTestkubeAPI( clientset kubernetes.Interface, testkubeClientset testkubeclientset.Interface, testsourcesClient *testsourcesclientv1.TestSourcesClient, - testWorkflowsClient *testworkflowsv1.TestWorkflowsClient, - testWorkflowTemplatesClient *testworkflowsv1.TestWorkflowTemplatesClient, + testWorkflowsClient testworkflowsv1.Interface, + testWorkflowTemplatesClient testworkflowsv1.TestWorkflowTemplatesInterface, configMap repoConfig.Repository, clusterId string, eventsEmitter *event.Emitter, diff --git a/pkg/cloud/data/testworkflow/commands.go b/pkg/cloud/data/testworkflow/commands.go index 611e7dcf75..7667138687 100644 --- a/pkg/cloud/data/testworkflow/commands.go +++ b/pkg/cloud/data/testworkflow/commands.go @@ -29,6 +29,10 @@ const ( CmdTestWorkflowOutputHasLog executor.Command = "workflow_output_has_log" CmdTestWorkflowOutputDeleteByTestWorkflow executor.Command = "workflow_output_delete_by_test_workflow" CmdTestworkflowOutputDeleteForTestWorkflows executor.Command = "workflow_output_delete_for_test_workflows" + + CmdTestWorkflowList executor.Command = "workflow_list" + CmdTestWorkflowGet executor.Command = "workflow_get" + CmdTestWorkflowTemplateGet executor.Command = "workflow_template_get" ) func command(v interface{}) executor.Command { @@ -82,6 +86,13 @@ func command(v interface{}) executor.Command { return CmdTestWorkflowOutputDeleteByTestWorkflow case ExecutionDeleteOutputForTestWorkflowsRequest: return CmdTestworkflowOutputDeleteForTestWorkflows + + case TestWorkflowGetRequest: + return CmdTestWorkflowGet + case TestWorkflowListRequest: + return CmdTestWorkflowList + case TestWorkflowTemplateGetRequest: + return CmdTestWorkflowTemplateGet } panic("unknown test workflows Cloud request") } diff --git a/pkg/cloud/data/testworkflow/execution.go b/pkg/cloud/data/testworkflow/execution.go index 46b0c17c6d..7ce4120de7 100644 --- a/pkg/cloud/data/testworkflow/execution.go +++ b/pkg/cloud/data/testworkflow/execution.go @@ -7,6 +7,7 @@ import ( "google.golang.org/grpc" + testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" testworkflow2 "github.com/kubeshop/testkube/pkg/repository/testworkflow" "github.com/kubeshop/testkube/pkg/api/v1/testkube" @@ -177,3 +178,20 @@ func (r *CloudRepository) GetExecutionTags(ctx context.Context, testWorkflowName } return pass(r.executor, ctx, req, process) } + +func (r *CloudRepository) List(selector string) (*testworkflowsv1.TestWorkflowList, error) { + req := TestWorkflowListRequest{Selector: selector} + response, err := r.executor.Execute(context.Background(), CmdTestWorkflowList, req) + if err != nil { + return nil, err + } + var commandResponse TestWorkflowListResponse + if err := json.Unmarshal(response, &commandResponse); err != nil { + return nil, err + } + var list testworkflowsv1.TestWorkflowList + for _, tw := range commandResponse.TestWorkflows { + _ = tw + } + return &list, nil +} diff --git a/pkg/cloud/data/testworkflow/execution_models.go b/pkg/cloud/data/testworkflow/execution_models.go index 38f0432303..58f170465d 100644 --- a/pkg/cloud/data/testworkflow/execution_models.go +++ b/pkg/cloud/data/testworkflow/execution_models.go @@ -186,3 +186,27 @@ type ExecutionGetExecutionTagsRequest struct { type ExecutionGetExecutionTagsResponse struct { Tags map[string][]string `json:"tags"` } + +type TestWorkflowListRequest struct { + Selector string `json:"selector"` +} + +type TestWorkflowListResponse struct { + TestWorkflows []testkube.TestWorkflow `json:"testWorkflows"` +} + +type TestWorkflowGetRequest struct { + Name string `json:"name"` +} + +type TestWorkflowGetResponse struct { + TestWorkflow testkube.TestWorkflow `json:"testWorkflow"` +} + +type TestWorkflowTemplateGetRequest struct { + Name string `json:"name"` +} + +type TestWorkflowTemplateGetResponse struct { + TestWorkflowTemplate testkube.TestWorkflowTemplate `json:"testWorkflowTemplate"` +} diff --git a/pkg/cloud/data/testworkflow/templates.go b/pkg/cloud/data/testworkflow/templates.go new file mode 100644 index 0000000000..cfdae086d4 --- /dev/null +++ b/pkg/cloud/data/testworkflow/templates.go @@ -0,0 +1,77 @@ +package testworkflow + +import ( + "context" + "encoding/json" + + testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" + testworkflowsclientv1 "github.com/kubeshop/testkube-operator/pkg/client/testworkflows/v1" + "github.com/kubeshop/testkube/pkg/cloud" + "github.com/kubeshop/testkube/pkg/cloud/data/executor" + testworkflowmappers "github.com/kubeshop/testkube/pkg/mapper/testworkflows" + + "github.com/pkg/errors" + "google.golang.org/grpc" +) + +var _ testworkflowsclientv1.TestWorkflowTemplatesInterface = (*CloudTestWorkflowTemplateRepository)(nil) + +type CloudTestWorkflowTemplateRepository struct { + executor executor.Executor +} + +func NewCloudTestWorkflowTemplateRepository(client cloud.TestKubeCloudAPIClient, grpcConn *grpc.ClientConn, apiKey string) *CloudTestWorkflowTemplateRepository { + return &CloudTestWorkflowTemplateRepository{executor: executor.NewCloudGRPCExecutor(client, grpcConn, apiKey)} +} + +func (r *CloudTestWorkflowTemplateRepository) List(selector string) (*testworkflowsv1.TestWorkflowTemplateList, error) { + return nil, errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) ListLabels() (map[string][]string, error) { + return make(map[string][]string), nil +} + +func (r *CloudTestWorkflowTemplateRepository) Get(name string) (*testworkflowsv1.TestWorkflowTemplate, error) { + req := TestWorkflowTemplateGetRequest{Name: name} + response, err := r.executor.Execute(context.Background(), CmdTestWorkflowTemplateGet, req) + if err != nil { + return nil, err + } + var commandResponse TestWorkflowTemplateGetResponse + if err := json.Unmarshal(response, &commandResponse); err != nil { + return nil, err + } + return testworkflowmappers.MapTemplateAPIToKube(&commandResponse.TestWorkflowTemplate), nil +} + +// Create creates new TestWorkflow +func (r *CloudTestWorkflowTemplateRepository) Create(workflow *testworkflowsv1.TestWorkflowTemplate) (*testworkflowsv1.TestWorkflowTemplate, error) { + return nil, errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) Update(workflow *testworkflowsv1.TestWorkflowTemplate) (*testworkflowsv1.TestWorkflowTemplate, error) { + return nil, errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) Apply(workflow *testworkflowsv1.TestWorkflowTemplate) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) Delete(name string) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) DeleteAll() error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) DeleteByLabels(selector string) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowTemplateRepository) UpdateStatus(workflow *testworkflowsv1.TestWorkflowTemplate) error { + // This is the actual implementation, as update status + // should update k8s crd's status field, but we don't have it when stored in mongo + return nil +} diff --git a/pkg/cloud/data/testworkflow/workflows.go b/pkg/cloud/data/testworkflow/workflows.go new file mode 100644 index 0000000000..109eedff86 --- /dev/null +++ b/pkg/cloud/data/testworkflow/workflows.go @@ -0,0 +1,87 @@ +package testworkflow + +import ( + "context" + "encoding/json" + + testworkflowsv1 "github.com/kubeshop/testkube-operator/api/testworkflows/v1" + testworkflowsclientv1 "github.com/kubeshop/testkube-operator/pkg/client/testworkflows/v1" + "github.com/kubeshop/testkube/pkg/cloud" + "github.com/kubeshop/testkube/pkg/cloud/data/executor" + testworkflowmappers "github.com/kubeshop/testkube/pkg/mapper/testworkflows" + + "github.com/pkg/errors" + "google.golang.org/grpc" +) + +var _ testworkflowsclientv1.Interface = (*CloudTestWorkflowRepository)(nil) + +type CloudTestWorkflowRepository struct { + executor executor.Executor +} + +func NewCloudTestWorkflowRepository(client cloud.TestKubeCloudAPIClient, grpcConn *grpc.ClientConn, apiKey string) *CloudTestWorkflowRepository { + return &CloudTestWorkflowRepository{executor: executor.NewCloudGRPCExecutor(client, grpcConn, apiKey)} +} + +func (r *CloudTestWorkflowRepository) List(selector string) (*testworkflowsv1.TestWorkflowList, error) { + req := TestWorkflowListRequest{Selector: selector} + response, err := r.executor.Execute(context.Background(), CmdTestWorkflowList, req) + if err != nil { + return nil, err + } + var commandResponse TestWorkflowListResponse + if err := json.Unmarshal(response, &commandResponse); err != nil { + return nil, err + } + list := testworkflowmappers.MapListAPIToKube(commandResponse.TestWorkflows) + return &list, nil +} + +func (r *CloudTestWorkflowRepository) ListLabels() (map[string][]string, error) { + return make(map[string][]string), errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) Get(name string) (*testworkflowsv1.TestWorkflow, error) { + req := TestWorkflowGetRequest{Name: name} + response, err := r.executor.Execute(context.Background(), CmdTestWorkflowGet, req) + if err != nil { + return nil, err + } + var commandResponse TestWorkflowGetResponse + if err := json.Unmarshal(response, &commandResponse); err != nil { + return nil, err + } + return testworkflowmappers.MapAPIToKube(&commandResponse.TestWorkflow), nil +} + +// Create creates new TestWorkflow +func (r *CloudTestWorkflowRepository) Create(workflow *testworkflowsv1.TestWorkflow) (*testworkflowsv1.TestWorkflow, error) { + return nil, errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) Update(workflow *testworkflowsv1.TestWorkflow) (*testworkflowsv1.TestWorkflow, error) { + return nil, errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) Apply(workflow *testworkflowsv1.TestWorkflow) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) Delete(name string) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) DeleteAll() error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) DeleteByLabels(selector string) error { + return errors.New("unimplemented") +} + +func (r *CloudTestWorkflowRepository) UpdateStatus(workflow *testworkflowsv1.TestWorkflow) error { + // This is the actual implementation, as update status + // should update k8s crd's status field, but we don't have it when stored in mongo + return nil +}