diff --git a/pkg/cli/commands/organizations/common.go b/pkg/cli/commands/organizations/common.go new file mode 100644 index 0000000000..afc7b17895 --- /dev/null +++ b/pkg/cli/commands/organizations/common.go @@ -0,0 +1,26 @@ +package organizations + +import ( + "fmt" + "io" + "time" + + "github.com/superplanehq/superplane/pkg/openapi_client" +) + +func renderOrganization(stdout io.Writer, org openapi_client.OrganizationsOrganization) error { + metadata := org.GetMetadata() + + _, _ = fmt.Fprintf(stdout, "ID: %s\n", metadata.GetId()) + _, _ = fmt.Fprintf(stdout, "Name: %s\n", metadata.GetName()) + _, _ = fmt.Fprintf(stdout, "Description: %s\n", metadata.GetDescription()) + _, _ = fmt.Fprintf(stdout, "Versioning Enabled: %t\n", metadata.GetVersioningEnabled()) + if metadata.HasCreatedAt() { + _, _ = fmt.Fprintf(stdout, "Created At: %s\n", metadata.GetCreatedAt().Format(time.RFC3339)) + } + if metadata.HasUpdatedAt() { + _, _ = fmt.Fprintf(stdout, "Updated At: %s\n", metadata.GetUpdatedAt().Format(time.RFC3339)) + } + + return nil +} diff --git a/pkg/cli/commands/organizations/get.go b/pkg/cli/commands/organizations/get.go new file mode 100644 index 0000000000..93e5042dd5 --- /dev/null +++ b/pkg/cli/commands/organizations/get.go @@ -0,0 +1,32 @@ +package organizations + +import ( + "io" + + "github.com/superplanehq/superplane/pkg/cli/core" +) + +type getCommand struct{} + +func (c *getCommand) Execute(ctx core.CommandContext) error { + organizationID, err := core.ResolveOrganizationID(ctx) + if err != nil { + return err + } + + response, _, err := ctx.API.OrganizationAPI. + OrganizationsDescribeOrganization(ctx.Context, organizationID). + Execute() + if err != nil { + return err + } + + if !ctx.Renderer.IsText() { + return ctx.Renderer.Render(response) + } + + org := response.GetOrganization() + return ctx.Renderer.RenderText(func(stdout io.Writer) error { + return renderOrganization(stdout, org) + }) +} diff --git a/pkg/cli/commands/organizations/root.go b/pkg/cli/commands/organizations/root.go new file mode 100644 index 0000000000..5e5c7424c5 --- /dev/null +++ b/pkg/cli/commands/organizations/root.go @@ -0,0 +1,43 @@ +package organizations + +import ( + "github.com/spf13/cobra" + "github.com/superplanehq/superplane/pkg/cli/core" +) + +func NewCommand(options core.BindOptions) *cobra.Command { + root := &cobra.Command{ + Use: "organizations", + Short: "Manage organizations", + Aliases: []string{"org", "orgs"}, + } + + getCmd := &cobra.Command{ + Use: "get", + Short: "Get details for the current organization", + Args: cobra.NoArgs, + } + core.Bind(getCmd, &getCommand{}, options) + + var updateName string + var updateDescription string + var updateVersioningEnabled bool + updateCmd := &cobra.Command{ + Use: "update", + Short: "Update the current organization", + Args: cobra.NoArgs, + } + updateCmd.Flags().StringVar(&updateName, "name", "", "organization name") + updateCmd.Flags().StringVar(&updateDescription, "description", "", "organization description") + updateCmd.Flags().BoolVar(&updateVersioningEnabled, "versioning-enabled", false, "enable or disable global versioning") + core.Bind(updateCmd, &updateCommand{ + name: &updateName, + description: &updateDescription, + versioningEnabled: &updateVersioningEnabled, + }, options) + + root.AddCommand(getCmd) + root.AddCommand(updateCmd) + + return root +} diff --git a/pkg/cli/commands/organizations/update.go b/pkg/cli/commands/organizations/update.go new file mode 100644 index 0000000000..ce6a53ebb3 --- /dev/null +++ b/pkg/cli/commands/organizations/update.go @@ -0,0 +1,62 @@ +package organizations + +import ( + "fmt" + "io" + + "github.com/superplanehq/superplane/pkg/cli/core" + "github.com/superplanehq/superplane/pkg/openapi_client" +) + +type updateCommand struct { + name *string + description *string + versioningEnabled *bool +} + +func (c *updateCommand) Execute(ctx core.CommandContext) error { + if !ctx.Cmd.Flags().Changed("name") && + !ctx.Cmd.Flags().Changed("description") && + !ctx.Cmd.Flags().Changed("versioning-enabled") { + return fmt.Errorf("at least one flag must be provided: --name, --description, or --versioning-enabled") + } + + organizationID, err := core.ResolveOrganizationID(ctx) + if err != nil { + return err + } + + metadata := openapi_client.OrganizationsOrganizationMetadata{} + if ctx.Cmd.Flags().Changed("name") { + metadata.SetName(*c.name) + } + if ctx.Cmd.Flags().Changed("description") { + metadata.SetDescription(*c.description) + } + if ctx.Cmd.Flags().Changed("versioning-enabled") { + metadata.SetVersioningEnabled(*c.versioningEnabled) + } + + org := openapi_client.OrganizationsOrganization{} + org.SetMetadata(metadata) + + body := openapi_client.OrganizationsUpdateOrganizationBody{} + body.SetOrganization(org) + + response, _, err := ctx.API.OrganizationAPI. + OrganizationsUpdateOrganization(ctx.Context, organizationID). + Body(body). + Execute() + if err != nil { + return err + } + + if !ctx.Renderer.IsText() { + return ctx.Renderer.Render(response) + } + + updated := response.GetOrganization() + return ctx.Renderer.RenderText(func(stdout io.Writer) error { + return renderOrganization(stdout, updated) + }) +} diff --git a/pkg/cli/commands/secrets/common.go b/pkg/cli/commands/secrets/common.go index d39015a5a0..6f67d7141c 100644 --- a/pkg/cli/commands/secrets/common.go +++ b/pkg/cli/commands/secrets/common.go @@ -5,7 +5,6 @@ import ( "io" "os" "sort" - "strings" "text/tabwriter" "time" @@ -25,19 +24,6 @@ type secretResource struct { Spec *openapi_client.SecretsSecretSpec `json:"spec,omitempty"` } -func resolveOrganizationID(ctx core.CommandContext) (string, error) { - me, _, err := ctx.API.MeAPI.MeMe(ctx.Context).Execute() - if err != nil { - return "", err - } - - if !me.HasOrganizationId() || strings.TrimSpace(me.GetOrganizationId()) == "" { - return "", fmt.Errorf("organization id not found for authenticated user") - } - - return me.GetOrganizationId(), nil -} - func organizationDomainType() openapi_client.AuthorizationDomainType { return openapi_client.AUTHORIZATIONDOMAINTYPE_DOMAIN_TYPE_ORGANIZATION } diff --git a/pkg/cli/commands/secrets/create.go b/pkg/cli/commands/secrets/create.go index efe9cdab04..1f457cf6e1 100644 --- a/pkg/cli/commands/secrets/create.go +++ b/pkg/cli/commands/secrets/create.go @@ -21,7 +21,7 @@ func (c *createCommand) Execute(ctx core.CommandContext) error { return fmt.Errorf("--file is required") } - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } diff --git a/pkg/cli/commands/secrets/delete.go b/pkg/cli/commands/secrets/delete.go index 6fcb9d478b..f7e17b3189 100644 --- a/pkg/cli/commands/secrets/delete.go +++ b/pkg/cli/commands/secrets/delete.go @@ -10,7 +10,7 @@ import ( type deleteCommand struct{} func (c *deleteCommand) Execute(ctx core.CommandContext) error { - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } diff --git a/pkg/cli/commands/secrets/get.go b/pkg/cli/commands/secrets/get.go index 7d8ff8aa72..6dd359df1a 100644 --- a/pkg/cli/commands/secrets/get.go +++ b/pkg/cli/commands/secrets/get.go @@ -9,7 +9,7 @@ import ( type getCommand struct{} func (c *getCommand) Execute(ctx core.CommandContext) error { - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } diff --git a/pkg/cli/commands/secrets/list.go b/pkg/cli/commands/secrets/list.go index 3f5f24c432..e1a81a2da7 100644 --- a/pkg/cli/commands/secrets/list.go +++ b/pkg/cli/commands/secrets/list.go @@ -9,7 +9,7 @@ import ( type listCommand struct{} func (c *listCommand) Execute(ctx core.CommandContext) error { - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } diff --git a/pkg/cli/commands/secrets/update.go b/pkg/cli/commands/secrets/update.go index db41c15b86..52042b4d69 100644 --- a/pkg/cli/commands/secrets/update.go +++ b/pkg/cli/commands/secrets/update.go @@ -24,7 +24,7 @@ func (c *updateCommand) Execute(ctx core.CommandContext) error { return fmt.Errorf("update does not accept positional arguments") } - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } diff --git a/pkg/cli/commands/usage/get.go b/pkg/cli/commands/usage/get.go index b1e82d37c2..c8cdb3a163 100644 --- a/pkg/cli/commands/usage/get.go +++ b/pkg/cli/commands/usage/get.go @@ -18,7 +18,7 @@ const unlimitedValue = "-1" type getCommand struct{} func (c *getCommand) Execute(ctx core.CommandContext) error { - organizationID, err := resolveOrganizationID(ctx) + organizationID, err := core.ResolveOrganizationID(ctx) if err != nil { return err } @@ -39,19 +39,6 @@ func (c *getCommand) Execute(ctx core.CommandContext) error { }) } -func resolveOrganizationID(ctx core.CommandContext) (string, error) { - me, _, err := ctx.API.MeAPI.MeMe(ctx.Context).Execute() - if err != nil { - return "", err - } - - if !me.HasOrganizationId() || strings.TrimSpace(me.GetOrganizationId()) == "" { - return "", fmt.Errorf("organization id not found for authenticated user") - } - - return me.GetOrganizationId(), nil -} - func renderUsageText(stdout io.Writer, response *openapi_client.OrganizationsDescribeUsageResponse) error { if response == nil { return fmt.Errorf("usage response was empty") diff --git a/pkg/cli/core/common.go b/pkg/cli/core/common.go index acaa168c30..f10a1e62fb 100644 --- a/pkg/cli/core/common.go +++ b/pkg/cli/core/common.go @@ -57,6 +57,19 @@ func FindIntegrationDefinition(ctx CommandContext, name string) (openapi_client. return openapi_client.IntegrationsIntegrationDefinition{}, fmt.Errorf("integration %q not found", name) } +func ResolveOrganizationID(ctx CommandContext) (string, error) { + me, _, err := ctx.API.MeAPI.MeMe(ctx.Context).Execute() + if err != nil { + return "", err + } + + if !me.HasOrganizationId() || strings.TrimSpace(me.GetOrganizationId()) == "" { + return "", fmt.Errorf("organization id not found for authenticated user") + } + + return me.GetOrganizationId(), nil +} + func ResolveCanvasID(ctx CommandContext, canvasID string) (string, error) { canvasID = strings.TrimSpace(canvasID) if canvasID != "" { diff --git a/pkg/cli/root.go b/pkg/cli/root.go index ee79425eab..fc47df7c63 100644 --- a/pkg/cli/root.go +++ b/pkg/cli/root.go @@ -15,6 +15,7 @@ import ( executions "github.com/superplanehq/superplane/pkg/cli/commands/executions" index "github.com/superplanehq/superplane/pkg/cli/commands/index" integrations "github.com/superplanehq/superplane/pkg/cli/commands/integrations" + organizations "github.com/superplanehq/superplane/pkg/cli/commands/organizations" queue "github.com/superplanehq/superplane/pkg/cli/commands/queue" secrets "github.com/superplanehq/superplane/pkg/cli/commands/secrets" usage "github.com/superplanehq/superplane/pkg/cli/commands/usage" @@ -57,6 +58,7 @@ func init() { RootCmd.AddCommand(events.NewCommand(options)) RootCmd.AddCommand(index.NewCommand(options)) RootCmd.AddCommand(integrations.NewCommand(options)) + RootCmd.AddCommand(organizations.NewCommand(options)) RootCmd.AddCommand(queue.NewCommand(options)) RootCmd.AddCommand(secrets.NewCommand(options)) RootCmd.AddCommand(usage.NewCommand(options))