Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion cmd/ctrlc/root/api/get/deployment/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func NewDeploymentCmd() *cobra.Command {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}
resp, err := client.GetDeploymentByName(cmd.Context(), workspaceID.String(), name)
if err != nil {
return fmt.Errorf("failed to get deployment: %w", err)
Expand Down
5 changes: 4 additions & 1 deletion cmd/ctrlc/root/api/get/release/release.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ func NewReleaseCmd() *cobra.Command {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}
resp, err := client.GetRelease(cmd.Context(), workspaceID.String(), releaseID)
if err != nil {
return fmt.Errorf("failed to get release: %w", err)
Expand Down
5 changes: 4 additions & 1 deletion cmd/ctrlc/root/api/get/releasetargets/releasetargets.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ func NewReleaseTargetsCmd() *cobra.Command {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

params := &api.PreviewReleaseTargetsForResourceParams{}
if limit > 0 {
Expand Down
5 changes: 4 additions & 1 deletion cmd/ctrlc/root/api/get/resources/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ func NewResourcesCmd() *cobra.Command {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

params := &api.GetAllResourcesParams{}
if limit > 0 {
Expand Down
5 changes: 4 additions & 1 deletion cmd/ctrlc/root/api/plan/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,10 @@ func NewPlanVersionCmd() *cobra.Command {
metadata["ctrlplane/links"] = string(linksJSON)
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

config := cliutil.ConvertConfigArrayToNestedMap(configArray)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,10 @@ func NewUpsertDeploymentVersionCmd() *cobra.Command {
stat = &s
}

workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

config := cliutil.ConvertConfigArrayToNestedMap(configArray)

Expand Down
7 changes: 3 additions & 4 deletions cmd/ctrlc/root/apply/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"github.com/ctrlplanedev/cli/internal/api/providers"
"github.com/ctrlplanedev/cli/internal/api/resolver"
"github.com/fatih/color"
"github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -76,9 +75,9 @@ func runApply(ctx context.Context, filePatterns []string, selectorRaw string) er
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(ctx, workspace)
if workspaceID == uuid.Nil {
return fmt.Errorf("workspace not found: %s", workspace)
workspaceID, err := client.GetWorkspaceID(ctx, workspace)
if err != nil {
return err
}

resolver := resolver.NewAPIResolver(client, workspaceID)
Expand Down
2 changes: 2 additions & 0 deletions cmd/ctrlc/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/sync"
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/ui"
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/version"
"github.com/ctrlplanedev/cli/cmd/ctrlc/root/workflow"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)
Expand Down Expand Up @@ -63,6 +64,7 @@ func NewRootCmd() *cobra.Command {
cmd.AddCommand(run.NewRunCmd())
cmd.AddCommand(ui.NewUICmd())
cmd.AddCommand(version.NewVersionCmd())
cmd.AddCommand(workflow.NewWorkflowCmd())

return cmd
}
6 changes: 5 additions & 1 deletion cmd/ctrlc/root/sync/pipe/pipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,11 @@ func NewSyncPipeCmd() *cobra.Command {
return fmt.Errorf("failed to upsert resources: %w", err)
}

workspaceID := ctrlplaneClient.GetWorkspaceID(ctx, workspace).String()
workspaceUUID, err := ctrlplaneClient.GetWorkspaceID(ctx, workspace)
if err != nil {
return err
}
workspaceID := workspaceUUID.String()
if err := syncResourceVariables(ctx, ctrlplaneClient, workspaceID, resourceInputs); err != nil {
return err
}
Expand Down
6 changes: 3 additions & 3 deletions cmd/ctrlc/root/ui/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ func NewUICmd() *cobra.Command {
}

// Resolve workspace slug to UUID
workspaceID := client.GetWorkspaceID(cmd.Context(), workspace)
if workspaceID.String() == "00000000-0000-0000-0000-000000000000" {
return fmt.Errorf("failed to resolve workspace: %s", workspace)
workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

// Load last-viewed resource type (default: resources)
Expand Down
63 changes: 63 additions & 0 deletions cmd/ctrlc/root/workflow/list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package workflow

import (
"fmt"

"github.com/ctrlplanedev/cli/internal/api"
"github.com/ctrlplanedev/cli/internal/cliutil"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func NewListCmd() *cobra.Command {
var limit int
var offset int

cmd := &cobra.Command{
Use: "list",
Short: "List workflows",
Long: `List all workflows in the workspace.`,
RunE: func(cmd *cobra.Command, args []string) error {
apiURL := viper.GetString("url")
apiKey := viper.GetString("api-key")
workspace := viper.GetString("workspace")

client, err := api.NewAPIKeyClientWithResponses(apiURL, apiKey)
if err != nil {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

if limit < 0 {
return fmt.Errorf("invalid --limit %d, must be non-negative", limit)
}
if offset < 0 {
return fmt.Errorf("invalid --offset %d, must be non-negative", offset)
}

params := &api.ListWorkflowsParams{}
if limit > 0 {
params.Limit = &limit
}
if offset > 0 {
params.Offset = &offset
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

resp, err := client.ListWorkflows(cmd.Context(), workspaceID.String(), params)
if err != nil {
return fmt.Errorf("failed to list workflows: %w", err)
}

return cliutil.HandleResponseOutput(cmd, resp)
},
}

cmd.Flags().IntVarP(&limit, "limit", "l", 50, "Limit the number of results")
cmd.Flags().IntVarP(&offset, "offset", "o", 0, "Offset the results")

return cmd
}
66 changes: 66 additions & 0 deletions cmd/ctrlc/root/workflow/trigger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package workflow

import (
"fmt"
"strings"

"github.com/ctrlplanedev/cli/internal/api"
"github.com/ctrlplanedev/cli/internal/cliutil"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func NewTriggerCmd() *cobra.Command {
var inputFlags []string

cmd := &cobra.Command{
Use: "trigger <workflow-id>",
Short: "Trigger a workflow run",
Long: `Trigger a workflow run with the given inputs.`,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
workflowID := args[0]

apiURL := viper.GetString("url")
apiKey := viper.GetString("api-key")
workspace := viper.GetString("workspace")

client, err := api.NewAPIKeyClientWithResponses(apiURL, apiKey)
if err != nil {
return fmt.Errorf("failed to create API client: %w", err)
}

workspaceID, err := client.GetWorkspaceID(cmd.Context(), workspace)
if err != nil {
return err
}

inputs := make(map[string]interface{})
for _, input := range inputFlags {
key, value, found := strings.Cut(input, "=")
if !found {
return fmt.Errorf("invalid input format %q, expected key=value", input)
}
if key == "" {
return fmt.Errorf("invalid input format %q, empty key, expected key=value", input)
}
inputs[key] = value
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.

body := api.CreateWorkflowRunJSONRequestBody{
Inputs: inputs,
}

resp, err := client.CreateWorkflowRun(cmd.Context(), workspaceID.String(), workflowID, body)
if err != nil {
return fmt.Errorf("failed to trigger workflow: %w", err)
}

return cliutil.HandleResponseOutput(cmd, resp)
},
}

cmd.Flags().StringArrayVarP(&inputFlags, "input", "i", nil, "Input key=value pair (can be specified multiple times)")

return cmd
}
21 changes: 21 additions & 0 deletions cmd/ctrlc/root/workflow/workflow.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package workflow

import (
"github.com/spf13/cobra"
)

func NewWorkflowCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "workflow <subcommand>",
Short: "Manage workflows",
Long: `Commands for listing and triggering workflows.`,
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}

cmd.AddCommand(NewListCmd())
cmd.AddCommand(NewTriggerCmd())

return cmd
}
23 changes: 21 additions & 2 deletions internal/api/client.gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 6 additions & 7 deletions internal/api/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,19 @@ func NewAPIKeyClientWithResponses(server string, apiKey string) (*ClientWithResp
)
}

func (c *ClientWithResponses) GetWorkspaceID(ctx context.Context, workspace string) uuid.UUID {
id, err := uuid.Parse(workspace)
if err == nil {
return id
func (c *ClientWithResponses) GetWorkspaceID(ctx context.Context, workspace string) (uuid.UUID, error) {
if id, err := uuid.Parse(workspace); err == nil {
return id, nil
}

resp, err := c.GetWorkspaceBySlugWithResponse(ctx, workspace)
if err != nil {
return uuid.Nil
return uuid.Nil, fmt.Errorf("failed to look up workspace %q: %w", workspace, err)
}

if resp.JSON200 == nil {
return uuid.Nil
return uuid.Nil, fmt.Errorf("workspace %q not found", workspace)
}

return resp.JSON200.Id
return resp.JSON200.Id, nil
}
6 changes: 3 additions & 3 deletions internal/api/resolver/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ func NewAPIResolver(client *api.ClientWithResponses, workspaceID uuid.UUID) *API
}

func NewAPIResolverFromWorkspace(ctx context.Context, client *api.ClientWithResponses, workspace string) (*APIResolver, error) {
workspaceID := client.GetWorkspaceID(ctx, workspace)
if workspaceID == uuid.Nil {
return nil, fmt.Errorf("workspace not found: %s", workspace)
workspaceID, err := client.GetWorkspaceID(ctx, workspace)
if err != nil {
return nil, err
}
return NewAPIResolver(client, workspaceID), nil
}
Expand Down
5 changes: 4 additions & 1 deletion internal/resources/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ func NewAPIResourceService(ctx context.Context, apiURL, apiKey, workspace string
return nil, fmt.Errorf("failed to create API client: %w", err)
}

workspaceID := client.GetWorkspaceID(ctx, workspace)
workspaceID, err := client.GetWorkspaceID(ctx, workspace)
if err != nil {
return nil, err
}
log.Debug("resolved workspace", "input", workspace, "workspaceID", workspaceID.String())

return &APIResourceService{
Expand Down
6 changes: 5 additions & 1 deletion pkg/resourceprovider/resourceprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,11 @@ import (

func New(client *api.ClientWithResponses, workspace string, name string) (*ResourceProvider, error) {
ctx := context.Background()
workspaceId := client.GetWorkspaceID(ctx, workspace).String()
workspaceUUID, err := client.GetWorkspaceID(ctx, workspace)
if err != nil {
return nil, err
}
workspaceId := workspaceUUID.String()

log.Debug("Upserting resource provider", "workspaceId", workspaceId, "name", name)

Expand Down
Loading