diff --git a/README.md b/README.md
index 83b5e7f..fab15c9 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,7 @@
- [Examples](#examples)
- [Git VCS scan and bulk import](#git-vcs-scan-and-bulk-import)
- [Interactive mode](#interactive-mode)
+- [Go CLI](#go-cli)
---
@@ -496,3 +497,17 @@ On launch you will be prompted for your **org** and **workflow group**, which ar
Navigation: arrow keys to move, Enter to select, Ctrl+C or `q` to go back / exit.
+
+---
+
+## Go CLI
+
+The `go/` directory contains a Go implementation of `sg-cli` built on
+[`sg-sdk-go`](https://github.com/StackGuardian/sg-sdk-go). It covers every
+API operation exposed by the SDK (organizations, users, roles, API accesses,
+secrets, policies, connectors, connector groups, runner groups, state backends,
+workflow groups, workflows and runs, stacks and stack runs, templates and
+revisions, chats, billing, audit logs and more) with the same `--org`,
+`--patch-payload`, `--preview` and `--dry-run` conventions as the shell
+script. See [go/README.md](go/README.md) for the build steps, the command
+groups and examples.
diff --git a/go/README.md b/go/README.md
new file mode 100644
index 0000000..6aca993
--- /dev/null
+++ b/go/README.md
@@ -0,0 +1,171 @@
+# sg-cli (Go)
+
+A command-line client for the StackGuardian platform built on
+[`sg-sdk-go`](https://github.com/StackGuardian/sg-sdk-go). Every SDK operation
+(226 API endpoints) is reachable from one of the 30 command groups below.
+
+## Contents
+
+- [Build](#build)
+- [Configuration](#configuration)
+- [Conventions](#conventions)
+- [Command groups](#command-groups)
+- [Examples](#examples)
+- [Payload notes](#payload-notes)
+- [Tests](#tests)
+
+## Build
+
+Requires Go 1.22.4 or newer.
+
+```bash
+cd go
+go build -o sg-cli .
+./sg-cli --help
+```
+
+## Configuration
+
+| Variable | Required | Default | Description |
+|---|---|---|---|
+| `SG_API_TOKEN` | Yes | — | API token. Both `sgu_` (personal) and `sgo_` (organization) tokens work; the `apikey ` prefix is added automatically. |
+| `SG_BASE_URL` | No | `https://api.app.stackguardian.io` | API base URL. |
+
+## Conventions
+
+- **Organization.** Every group takes `--org ` as a persistent flag.
+ Groups that work inside a workflow group also take `--workflow-group`, and
+ workflow-scoped groups take `--workflow-id`. Nested workflow groups are
+ addressed as `parent/child`.
+- **Identifiers are flags.** Resources are named with flags such as
+ `--stack-id`, `--secret-id`, `--connector-id`, `--template-id`, `--run-id`
+ or `--chat-id`. Template revisions use `--revision-id NAME:REVISION`.
+- **Payloads.** Commands that send a body take a JSON file as the single
+ positional argument after `--`. Pass `-` to read the payload from stdin.
+ - `--patch-payload ''` merges keys into the file before sending.
+ - `--preview` prints the final payload and continues.
+ - `--dry-run` prints the final payload and stops without sending.
+- **Output.** Read and list commands print the API response as indented JSON
+ on stdout, so they can be piped into `jq`. Write commands print a short
+ confirmation; add `--output-json` to print the response as well. List
+ endpoints that the API answers with `204 No Content` print `null`.
+- **Errors.** API errors are printed as `Error: : ` and the
+ command exits with status 1.
+
+## Command groups
+
+| Group | Commands |
+|---|---|
+| `organization` | read, update, create, delete, list, workflows, count-workflows, bulk-action |
+| `user` | list, read, create, update, delete |
+| `role` | list, read, create, update, delete |
+| `role-binding` | read |
+| `api-access` | list, read, create, update, delete, regenerate-key |
+| `api-token` | create, delete |
+| `audit-log` | list |
+| `benchmark-report` | read |
+| `billing` | details, balance, invoices, dashboard-url, change-plan, `profile setup/update`, `payment-methods list/setup-intent/set-default/detach` |
+| `secret` | list, read-bulk, create, update, delete |
+| `policy` | list, read, create, update, delete |
+| `connector` | list, read, create, update, delete, authenticate, repos, github-repos, list-accounts |
+| `connector-group` | list, read, create, update, delete, authenticate, discovery-scan, `connectors list/read/update/delete/authenticate` |
+| `runner-group` | list, read, create, update, delete, register, deregister-runner, update-runner-state, storage-backend-auth |
+| `state-backend` | list, read, create, update, delete, list-statefiles |
+| `resource` | search, move, tags |
+| `chat` | list, read, create, update, delete, commit-bundle, create-pr, pr-status, pr-sync-status, `artifacts list/get-url/upload-url`, `messages list/read/create/cancel/retry` |
+| `workflow-group` | list, read, create, update, delete, create-child, list-children, list-resources |
+| `workflow` | list, read, create, update, delete, apply, destroy, outputs, compare, vcs-triggers, file-upload-url, tfstate-upload-url |
+| `workflow-run` | list, read, create, update, delete, cancel, approve, logs, read-by-ksuid, update-by-ksuid, `facts read/create/update` |
+| `artifacts` | list, read, create, delete, get-url, versions, rollback, lock, unlock |
+| `stack` | list, read, create, update, delete, apply, destroy, outputs, compare |
+| `stack-run` | list, read, create |
+| `stack-workflow` | list, read, create, update, delete, outputs, compare, vcs-triggers, file-upload-url, tfstate-upload-url, `artifacts list/read/create/delete/get-url/lock/unlock` |
+| `stack-workflow-run` | list, read, create, update, delete, approve, logs, `facts read/create/update` |
+| `template` | list, list-by-owner, read, create, update, delete, group-iac, input-schema, vcs-triggers, `artifacts list/upload-url/download-url/delete`, `subscriptions read/create/update`, `public list/list-all/read` |
+| `workflow-template` | read, create, update, delete, `revisions read/create/update/delete` |
+| `workflow-step-template` | read, create, update, delete, `revisions read/create/update/delete` |
+| `stack-template` | read, create, update, delete, `revisions read/create/update/delete` |
+
+`sg-cli --help` and `sg-cli --help` list the flags of
+each command. Commands that need a Cognito user token rather than an API key
+(organization create/list, public templates, template input schemas) say so in
+their help text.
+
+## Examples
+
+```bash
+export SG_API_TOKEN=sgu_xxx
+
+# Read commands print JSON
+./sg-cli organization read --org demo-org
+./sg-cli workflow-group list --org demo-org | jq '.msg[].ResourceName'
+./sg-cli workflow read --org demo-org --workflow-group demo-grp --workflow-id my-wf
+./sg-cli workflow-run logs --org demo-org --workflow-group demo-grp --workflow-id my-wf --run-id abc123
+./sg-cli secret read-bulk --org demo-org --names db_password,api_key
+./sg-cli template list --org demo-org --template-type IAC
+./sg-cli audit-log list --org demo-org --limit 20
+
+# Write commands take a payload after --
+./sg-cli secret create --org demo-org -- secret.json
+./sg-cli role update --org demo-org --role-id viewer --patch-payload '{"Description":"read only"}' -- role.json
+./sg-cli workflow-group create-child --org demo-org --parent platform -- child.json
+./sg-cli workflow-group read --org demo-org --workflow-group platform/child
+
+# Preview the merged payload without sending it
+./sg-cli connector create --org demo-org --dry-run --patch-payload '{"ResourceName":"aws-prod"}' -- connector.json
+
+# Print the API response of a write command
+./sg-cli workflow-template create --org demo-org --output-json -- template.json
+
+# Templates are addressed by NAME, revisions by NAME:REVISION
+./sg-cli workflow-template revisions read --org demo-org --revision-id my-template:2
+./sg-cli template artifacts list --org demo-org --template-type IAC --template-id my-template:2
+
+# Trigger and approve runs
+./sg-cli workflow-run create --org demo-org --workflow-group demo-grp --workflow-id my-wf
+./sg-cli workflow-run approve --org demo-org --workflow-group demo-grp --workflow-id my-wf --run-id abc123
+```
+
+The `workflow` and `stack` groups keep the original behaviour: `create`
+supports `--run`, `--wait`, `--bulk` and state-file upload, as documented in
+the [repository README](../README.md).
+
+## Payload notes
+
+These rules come from running each command against a live organization; the
+API rejects the request otherwise.
+
+- `policy update` needs `PolicyType` in the payload (`GENERAL` or
+ `FILTER.INSIGHT`) even for partial updates.
+- `secret update` needs `ResourceName`; the CLI fills it from `--secret-id`.
+- Template creates (`workflow-template`, `stack-template`,
+ `workflow-step-template`, `template create`) need `TemplateName`,
+ `OwnerOrg` in the form `/orgs/` and `SourceConfigKind` (`TERRAFORM`,
+ `OPENTOFU`, ... for IaC templates; `MIXED` for stack templates;
+ `DOCKER_IMAGE` for step templates). `revisions create` needs the same
+ `OwnerOrg` and `SourceConfigKind`.
+- A template with revisions cannot be deleted directly; delete its revisions
+ first. Deleting the last revision removes the parent.
+- `state-backend create` needs `Statefiles` (an empty list is fine) and
+ `StateBackendConfig.type` (`aws_s3` or `azure_blob_storage`) with
+ `auth.integrationId` pointing at a connector.
+- `connector-group create` needs `Settings.awsDefaultRegion` for AWS kinds.
+- `api-access create` needs `Roles`.
+- `resource search` needs `ResourceTypes` (`--resource-types WORKFLOW,STACK`).
+- Runner groups must be enabled for the organization; otherwise the API
+ answers `409`.
+
+## Tests
+
+Offline unit tests mock the HTTP transport and check the request each command
+sends (method, path, query and body) and what it prints:
+
+```bash
+cd go
+go test ./tests/ -run 'TestCommandTree|TestMatrix|TestCreateWorkflow|TestReadWorkflow|TestListWorkflow|TestDeleteWorkflow|TestApplyWorkflow|TestDestroyWorkflow|TestUpdateWorkflow|TestCreateStack|TestDeleteStack|TestApplyStack|TestDestroyStack|TestStackOutputs|TestListArtifacts'
+```
+
+`tests/tree_test.go` pins the full command tree, so adding or renaming a
+command requires updating `expectedLeaves`. The remaining tests in `tests/`
+are end-to-end tests that run a built `../sg-cli` binary against a live
+organization and need `SG_API_TOKEN`.
diff --git a/go/cmd/apiaccess/apiaccess.go b/go/cmd/apiaccess/apiaccess.go
new file mode 100644
index 0000000..13d0c21
--- /dev/null
+++ b/go/cmd/apiaccess/apiaccess.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewApiAccessCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "api-access",
+ Short: "Manage API accesses (API keys and OIDC identities)",
+ Long: `Manage API accesses (API keys and OIDC identities)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create an API access
+ read Get an API access
+ update Update an API access
+ delete Delete an API access
+ regenerate-key Regenerate the key of an API access
+ list List API accesses`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newRegenerateKeyCmd(c),
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/apiaccess/create.go b/go/cmd/apiaccess/create.go
new file mode 100644
index 0000000..60050c1
--- /dev/null
+++ b/go/cmd/apiaccess/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create an API access",
+ Long: `Create an API access`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.ApiAccess
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.AccessManagement.CreateApiAccess(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API access created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/apiaccess/delete.go b/go/cmd/apiaccess/delete.go
new file mode 100644
index 0000000..ac5031f
--- /dev/null
+++ b/go/cmd/apiaccess/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete an API access",
+ Long: `Delete an API access`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ accessId := common.String(cmd, "access-id")
+ response, err := c.AccessManagement.DeleteApiAccess(ctx, accessId, org)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API access deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("access-id", "", "The API access ID.")
+ _ = cmd.MarkFlagRequired("access-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/apiaccess/list.go b/go/cmd/apiaccess/list.go
new file mode 100644
index 0000000..36b069c
--- /dev/null
+++ b/go/cmd/apiaccess/list.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "fmt"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List API accesses",
+ Long: `List API accesses`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var accessType *sggosdk.ListAllApiAccessesRequestAccessType
+ if v := common.OptString(cmd, "access-type"); v != nil {
+ if *v != "APIKEY" && *v != "OIDC" {
+ return fmt.Errorf("--access-type must be APIKEY or OIDC, got %q", *v)
+ }
+ t := sggosdk.ListAllApiAccessesRequestAccessType(*v)
+ accessType = &t
+ }
+ response, err := c.AccessManagement.ListAllApiAccesses(ctx, org, &sggosdk.ListAllApiAccessesRequest{Limit: common.OptInt(cmd, "limit"), LastEvaluatedKey: common.OptString(cmd, "last-evaluated-key"), ResourceName: common.OptString(cmd, "resource-name"), Roles: common.OptString(cmd, "roles"), Status: common.OptString(cmd, "status"), AccessType: accessType})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("access-type", "", "Filter by access type (APIKEY, OIDC).")
+ cmd.Flags().String("resource-name", "", "Filter by resource name.")
+ cmd.Flags().String("roles", "", "Filter by roles (comma-separated).")
+ cmd.Flags().String("status", "", "Filter by status (active, expired).")
+ return cmd
+}
diff --git a/go/cmd/apiaccess/read.go b/go/cmd/apiaccess/read.go
new file mode 100644
index 0000000..6d559ea
--- /dev/null
+++ b/go/cmd/apiaccess/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get an API access",
+ Long: `Get an API access`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ accessId := common.String(cmd, "access-id")
+ response, err := c.AccessManagement.ReadApiAccess(ctx, accessId, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("access-id", "", "The API access ID.")
+ _ = cmd.MarkFlagRequired("access-id")
+ return cmd
+}
diff --git a/go/cmd/apiaccess/regenerate_key.go b/go/cmd/apiaccess/regenerate_key.go
new file mode 100644
index 0000000..7d4142c
--- /dev/null
+++ b/go/cmd/apiaccess/regenerate_key.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRegenerateKeyCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "regenerate-key",
+ Short: "Regenerate the key of an API access",
+ Long: `Regenerate the key of an API access`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ accessId := common.String(cmd, "access-id")
+ noExpiration := common.Bool(cmd, "no-expiration")
+ var body sggosdk.ApiAccessRegenerate
+ if v := common.OptInt(cmd, "expires-at"); v != nil {
+ body.ExpiresAt = sggosdk.Optional(*v)
+ }
+ if noExpiration {
+ body.ExpiresAt = sggosdk.Null[int]()
+ }
+ response, err := c.AccessManagement.RegenerateApiKey(ctx, accessId, org, &body)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API key regenerated.")
+ return nil
+ },
+ }
+ cmd.Flags().String("access-id", "", "The API access ID.")
+ _ = cmd.MarkFlagRequired("access-id")
+ cmd.Flags().Int("expires-at", 0, "New expiration as a Unix timestamp in milliseconds.")
+ cmd.Flags().Bool("no-expiration", false, "Remove the expiration.")
+ common.AddOutputJSONFlag(cmd)
+ cmd.MarkFlagsMutuallyExclusive("expires-at", "no-expiration")
+ return cmd
+}
diff --git a/go/cmd/apiaccess/update.go b/go/cmd/apiaccess/update.go
new file mode 100644
index 0000000..01c1fcb
--- /dev/null
+++ b/go/cmd/apiaccess/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apiaccess
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update an API access",
+ Long: `Update an API access`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ accessId := common.String(cmd, "access-id")
+ var req sggosdk.PatchedApiAccessPatch
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.AccessManagement.UpdateApiAccess(ctx, accessId, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API access updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("access-id", "", "The API access ID.")
+ _ = cmd.MarkFlagRequired("access-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/apitoken/apitoken.go b/go/cmd/apitoken/apitoken.go
new file mode 100644
index 0000000..537f236
--- /dev/null
+++ b/go/cmd/apitoken/apitoken.go
@@ -0,0 +1,28 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apitoken
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewApiTokenCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "api-token",
+ Short: "Manage legacy user API keys",
+ Long: `Manage legacy user API keys`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create or retrieve the caller's API key, or look up a runner group's key
+ delete Revoke the API key of a principal`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newDeleteCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/apitoken/create.go b/go/cmd/apitoken/create.go
new file mode 100644
index 0000000..ab9b339
--- /dev/null
+++ b/go/cmd/apitoken/create.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apitoken
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/accessmanagement"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create",
+ Short: "Create or retrieve the caller's API key, or look up a runner group's key",
+ Long: `Create or retrieve the caller's API key, or look up a runner group's key`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.CreateApiToken(ctx, org, &accessmanagement.ApiTokenRequest{Regenerate: common.OptBool(cmd, "regenerate"), RunnerGroupId: common.OptString(cmd, "runner-group-id")})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API token request completed.")
+ return nil
+ },
+ }
+ cmd.Flags().Bool("regenerate", false, "Replace the existing key with a new one.")
+ cmd.Flags().String("runner-group-id", "", "Look up the key of this runner group (/runnergroups/).")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/apitoken/delete.go b/go/cmd/apitoken/delete.go
new file mode 100644
index 0000000..e2d9ba1
--- /dev/null
+++ b/go/cmd/apitoken/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package apitoken
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Revoke the API key of a principal",
+ Long: `Revoke the API key of a principal`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ principalId := common.String(cmd, "principal-id")
+ response, err := c.AccessManagement.DeleteApiToken(ctx, org, principalId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "API token revoked.")
+ return nil
+ },
+ }
+ cmd.Flags().String("principal-id", "", "Principal id in the form //.")
+ _ = cmd.MarkFlagRequired("principal-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/artifacts.go b/go/cmd/artifacts/artifacts.go
index 47604aa..da12728 100644
--- a/go/cmd/artifacts/artifacts.go
+++ b/go/cmd/artifacts/artifacts.go
@@ -3,6 +3,7 @@ package artifacts
import (
"fmt"
+ artifactsextra "github.com/StackGuardian/sg-cli/cmd/artifacts/extra"
"github.com/StackGuardian/sg-cli/cmd/artifacts/list"
"github.com/StackGuardian/sg-sdk-go/client"
"github.com/spf13/cobra"
@@ -31,5 +32,7 @@ func NewArtifactsCmd(c *client.Client) *cobra.Command {
artifactsCmd.AddCommand(list.NewListCmd(c))
+ artifactsextra.AddCommands(artifactsCmd, c)
+
return artifactsCmd
}
diff --git a/go/cmd/artifacts/extra/create.go b/go/cmd/artifacts/extra/create.go
new file mode 100644
index 0000000..a261fc6
--- /dev/null
+++ b/go/cmd/artifacts/extra/create.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create or replace an artifact with the JSON payload as its content",
+ Long: `Create or replace an artifact with the JSON payload as its content`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ var req interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Workflows.CreateArtifact(ctx, org, workflowId, workflowGroup, artifactId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/delete.go b/go/cmd/artifacts/extra/delete.go
new file mode 100644
index 0000000..4344431
--- /dev/null
+++ b/go/cmd/artifacts/extra/delete.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete an artifact",
+ Long: `Delete an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.Workflows.DeleteArtifact(ctx, org, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/extra.go b/go/cmd/artifacts/extra/extra.go
new file mode 100644
index 0000000..19e0a56
--- /dev/null
+++ b/go/cmd/artifacts/extra/extra.go
@@ -0,0 +1,22 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+// AddCommands attaches the generated sub-commands to an existing command group.
+func AddCommands(cmd *cobra.Command, c *client.Client) {
+ cmd.AddCommand(
+ newGetUrlCmd(c),
+ newReadCmd(c),
+ newCreateCmd(c),
+ newDeleteCmd(c),
+ newVersionsCmd(c),
+ newRollbackCmd(c),
+ newLockCmd(c),
+ newUnlockCmd(c),
+ )
+}
diff --git a/go/cmd/artifacts/extra/get_url.go b/go/cmd/artifacts/extra/get_url.go
new file mode 100644
index 0000000..672eb17
--- /dev/null
+++ b/go/cmd/artifacts/extra/get_url.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newGetUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "get-url",
+ Short: "Get a signed download URL for an artifact",
+ Long: `Get a signed download URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactPath := common.String(cmd, "artifact-path")
+ response, err := c.Workflows.GetWorkflowArtifactUrl(ctx, org, workflowId, workflowGroup, &workflows.GetWorkflowArtifactRequest{ArtifactPath: artifactPath, VersionId: common.OptString(cmd, "version-id")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-path", "", "Path of the artifact.")
+ _ = cmd.MarkFlagRequired("artifact-path")
+ cmd.Flags().String("version-id", "", "Specific version of the artifact.")
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/lock.go b/go/cmd/artifacts/extra/lock.go
new file mode 100644
index 0000000..73c862e
--- /dev/null
+++ b/go/cmd/artifacts/extra/lock.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newLockCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "lock",
+ Short: "Lock the workflow on an artifact",
+ Long: `Lock the workflow on an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.Workflows.LockArtifact(ctx, org, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact locked.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/read.go b/go/cmd/artifacts/extra/read.go
new file mode 100644
index 0000000..12e26d8
--- /dev/null
+++ b/go/cmd/artifacts/extra/read.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Read an artifact's content (or a signed URL on private runners)",
+ Long: `Read an artifact's content (or a signed URL on private runners)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.Workflows.ReadArtifact(ctx, org, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/rollback.go b/go/cmd/artifacts/extra/rollback.go
new file mode 100644
index 0000000..0f2e18a
--- /dev/null
+++ b/go/cmd/artifacts/extra/rollback.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newRollbackCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "rollback",
+ Short: "Roll an artifact back to a previous version",
+ Long: `Roll an artifact back to a previous version`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ versionId := common.String(cmd, "version-id")
+ response, err := c.Workflows.RollbackArtifactVersion(ctx, org, workflowId, workflowGroup, artifactId, &workflows.RollbackArtifactVersionRequest{VersionId: versionId})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact rolled back.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ cmd.Flags().String("version-id", "", "Version to roll back to.")
+ _ = cmd.MarkFlagRequired("version-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/unlock.go b/go/cmd/artifacts/extra/unlock.go
new file mode 100644
index 0000000..8c9dd2c
--- /dev/null
+++ b/go/cmd/artifacts/extra/unlock.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUnlockCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "unlock",
+ Short: "Release the workflow's lock on an artifact",
+ Long: `Release the workflow's lock on an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.Workflows.UnlockArtifact(ctx, org, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact unlocked.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/artifacts/extra/versions.go b/go/cmd/artifacts/extra/versions.go
new file mode 100644
index 0000000..5c337d7
--- /dev/null
+++ b/go/cmd/artifacts/extra/versions.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newVersionsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "versions",
+ Short: "List the versions of an artifact",
+ Long: `List the versions of an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.Workflows.ListArtifactVersions(ctx, org, workflowId, workflowGroup, artifactId, &workflows.ListArtifactVersionsRequest{Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ return cmd
+}
diff --git a/go/cmd/artifacts/list/artifacts_list.go b/go/cmd/artifacts/list/artifacts_list.go
index d8d4016..4c74a3b 100644
--- a/go/cmd/artifacts/list/artifacts_list.go
+++ b/go/cmd/artifacts/list/artifacts_list.go
@@ -2,6 +2,7 @@ package list
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"strings"
@@ -38,10 +39,10 @@ func NewListCmd(c *client.Client) *cobra.Command {
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
},
}
listCmd.Flags().BoolVar(&opts.OutputJson, "output-json", false, "Output execution response as json to STDIN.")
diff --git a/go/cmd/auditlog/auditlog.go b/go/cmd/auditlog/auditlog.go
new file mode 100644
index 0000000..41e098b
--- /dev/null
+++ b/go/cmd/auditlog/auditlog.go
@@ -0,0 +1,26 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package auditlog
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewAuditLogCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "audit-log",
+ Short: "Read organization audit logs",
+ Long: `Read organization audit logs`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List audit log entries`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/auditlog/list.go b/go/cmd/auditlog/list.go
new file mode 100644
index 0000000..28b2f88
--- /dev/null
+++ b/go/cmd/auditlog/list.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package auditlog
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List audit log entries",
+ Long: `List audit log entries`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.ReadAuditLogs(ctx, org, &sggosdk.ReadAuditLogsRequest{Effect: common.OptString(cmd, "effect"), EndTime: common.OptInt(cmd, "end-time"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), PrincipalEmail: common.OptString(cmd, "principal-email"), RequestMethod: common.OptString(cmd, "request-method"), Resource: common.OptString(cmd, "resource"), SourceIp: common.OptString(cmd, "source-ip"), StartTime: common.OptInt(cmd, "start-time")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("effect", "", "Filter by effect (Allow, Deny).")
+ cmd.Flags().Int("start-time", 0, "Start time as a Unix timestamp in milliseconds.")
+ cmd.Flags().Int("end-time", 0, "End time as a Unix timestamp in milliseconds.")
+ cmd.Flags().String("principal-email", "", "Filter by principal email.")
+ cmd.Flags().String("request-method", "", "Filter by HTTP method.")
+ cmd.Flags().String("resource", "", "Filter by resource name.")
+ cmd.Flags().String("source-ip", "", "Filter by source IP address.")
+ return cmd
+}
diff --git a/go/cmd/benchmarkreport/benchmarkreport.go b/go/cmd/benchmarkreport/benchmarkreport.go
new file mode 100644
index 0000000..4a28e3a
--- /dev/null
+++ b/go/cmd/benchmarkreport/benchmarkreport.go
@@ -0,0 +1,26 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package benchmarkreport
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewBenchmarkReportCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "benchmark-report",
+ Short: "Read compliance benchmark reports",
+ Long: `Read compliance benchmark reports`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get the benchmark report`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/benchmarkreport/read.go b/go/cmd/benchmarkreport/read.go
new file mode 100644
index 0000000..56515a1
--- /dev/null
+++ b/go/cmd/benchmarkreport/read.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package benchmarkreport
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get the benchmark report",
+ Long: `Get the benchmark report`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.BenchmarkReports.GetBenchmarkReports(ctx, org, &sggosdk.GetBenchmarkReportsRequest{Date: common.OptString(cmd, "date"), Detailed: common.OptBool(cmd, "detailed"), FilterCsp: common.OptString(cmd, "filter-csp"), FilterAccountId: common.OptString(cmd, "filter-account-id"), FilterBenchmark: common.OptString(cmd, "filter-benchmark"), FilterControlId: common.OptString(cmd, "filter-control-id"), FilterControlTitle: common.OptString(cmd, "filter-control-title"), FilterRegion: common.OptString(cmd, "filter-region"), FilterSeverity: common.OptString(cmd, "filter-severity"), FilterStatus: common.OptString(cmd, "filter-status"), GroupBy: common.OptString(cmd, "group-by"), Limit: common.OptInt(cmd, "limit"), Page: common.OptInt(cmd, "page"), RequiredColumns: common.OptString(cmd, "required-columns")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("date", "", "Report date in DD_MM_YYYY format (defaults to today).")
+ cmd.Flags().Bool("detailed", false, "Return detailed results instead of grouped data.")
+ cmd.Flags().String("filter-csp", "", "Filter by cloud provider (AWS, AZURE, GCP).")
+ cmd.Flags().String("filter-account-id", "", "Filter by account id.")
+ cmd.Flags().String("filter-benchmark", "", "Filter by benchmark, e.g. cis_v200.")
+ cmd.Flags().String("filter-control-id", "", "Filter by control id.")
+ cmd.Flags().String("filter-control-title", "", "Filter by control title.")
+ cmd.Flags().String("filter-region", "", "Filter by region.")
+ cmd.Flags().String("filter-severity", "", "Filter by severity.")
+ cmd.Flags().String("filter-status", "", "Filter by status (fails, passes, info, skips, error).")
+ cmd.Flags().String("group-by", "", "Column(s) to group by (required when not --detailed).")
+ cmd.Flags().Int("limit", 0, "Maximum number of records.")
+ cmd.Flags().Int("page", 0, "Page number (requires --limit).")
+ cmd.Flags().String("required-columns", "", "Columns to include in a detailed report (comma-separated).")
+ return cmd
+}
diff --git a/go/cmd/billing/balance.go b/go/cmd/billing/balance.go
new file mode 100644
index 0000000..431dce4
--- /dev/null
+++ b/go/cmd/billing/balance.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newBalanceCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "balance",
+ Short: "Show the credit balances",
+ Long: `Show the credit balances`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.ListBalance(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/billing/billing.go b/go/cmd/billing/billing.go
new file mode 100644
index 0000000..beec92f
--- /dev/null
+++ b/go/cmd/billing/billing.go
@@ -0,0 +1,76 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewBillingCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "billing",
+ Short: "Inspect and manage the organization's billing",
+ Long: `Inspect and manage the organization's billing`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ balance Show the credit balances
+ dashboard-url Get the URL of the embeddable billing dashboard
+ invoices List invoices
+ details Show the current package and billing information
+ change-plan Move the organization to another billing package
+ profile Manage the Stripe billing profile
+ payment-methods Manage the cards on the billing profile`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newBalanceCmd(c),
+ newDashboardUrlCmd(c),
+ newInvoicesCmd(c),
+ newDetailsCmd(c),
+ newChangePlanCmd(c),
+ newProfileCmd(c),
+ newPaymentMethodsCmd(c),
+ )
+ return cmd
+}
+func newProfileCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "profile",
+ Short: "Manage the Stripe billing profile",
+ Long: `Manage the Stripe billing profile`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ setup Create the billing profile (once per organization)
+ update Update the billing profile's email, name or address`)
+ },
+ }
+ cmd.AddCommand(
+ newProfileSetupCmd(c),
+ newProfileUpdateCmd(c),
+ )
+ return cmd
+}
+func newPaymentMethodsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "payment-methods",
+ Short: "Manage the cards on the billing profile",
+ Long: `Manage the cards on the billing profile`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List payment methods
+ setup-intent Create a Stripe SetupIntent for adding a card
+ set-default Make a card the default payment method
+ detach Remove a card`)
+ },
+ }
+ cmd.AddCommand(
+ newPaymentMethodsListCmd(c),
+ newPaymentMethodsSetupIntentCmd(c),
+ newPaymentMethodsSetDefaultCmd(c),
+ newPaymentMethodsDetachCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/billing/change_plan.go b/go/cmd/billing/change_plan.go
new file mode 100644
index 0000000..e45a394
--- /dev/null
+++ b/go/cmd/billing/change_plan.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newChangePlanCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "change-plan",
+ Short: "Move the organization to another billing package",
+ Long: `Move the organization to another billing package`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.ChangePlan(ctx, org, &billing.ChangePlanRequest{TargetPackageId: common.OptString(cmd, "target-package-id"), TargetPackage: common.OptString(cmd, "target-package")})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Plan change submitted.")
+ return nil
+ },
+ }
+ cmd.Flags().String("target-package-id", "", "Id of the target package.")
+ cmd.Flags().String("target-package", "", "Name of the target package, e.g. \"SG | Standard\".")
+ common.AddOutputJSONFlag(cmd)
+ cmd.MarkFlagsOneRequired("target-package-id", "target-package")
+ cmd.MarkFlagsMutuallyExclusive("target-package-id", "target-package")
+ return cmd
+}
diff --git a/go/cmd/billing/dashboard_url.go b/go/cmd/billing/dashboard_url.go
new file mode 100644
index 0000000..5fbba49
--- /dev/null
+++ b/go/cmd/billing/dashboard_url.go
@@ -0,0 +1,32 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDashboardUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "dashboard-url",
+ Short: "Get the URL of the embeddable billing dashboard",
+ Long: `Get the URL of the embeddable billing dashboard`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.GetDashboardUrl(ctx, org, &billing.DashboardRequest{Type: common.OptString(cmd, "type")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("type", "", "Dashboard type (invoices, usage).")
+ return cmd
+}
diff --git a/go/cmd/billing/details.go b/go/cmd/billing/details.go
new file mode 100644
index 0000000..44e2c24
--- /dev/null
+++ b/go/cmd/billing/details.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDetailsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "details",
+ Short: "Show the current package and billing information",
+ Long: `Show the current package and billing information`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.GetBillingDetails(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/billing/invoices.go b/go/cmd/billing/invoices.go
new file mode 100644
index 0000000..c653dad
--- /dev/null
+++ b/go/cmd/billing/invoices.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newInvoicesCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "invoices",
+ Short: "List invoices",
+ Long: `List invoices`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.ListInvoices(ctx, org, &billing.ListInvoicesRequest{Limit: common.OptInt(cmd, "limit"), NextPage: common.OptString(cmd, "next-page")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Page size (1-100).")
+ cmd.Flags().String("next-page", "", "Cursor from the previous response.")
+ return cmd
+}
diff --git a/go/cmd/billing/payment_methods_detach.go b/go/cmd/billing/payment_methods_detach.go
new file mode 100644
index 0000000..374ad3d
--- /dev/null
+++ b/go/cmd/billing/payment_methods_detach.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPaymentMethodsDetachCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "detach",
+ Short: "Remove a card",
+ Long: `Remove a card`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ paymentMethodId := common.String(cmd, "payment-method-id")
+ response, err := c.Billing.DetachCard(ctx, org, &billing.PaymentMethodRequest{PaymentMethodId: paymentMethodId})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Card detached.")
+ return nil
+ },
+ }
+ cmd.Flags().String("payment-method-id", "", "Stripe payment method id.")
+ _ = cmd.MarkFlagRequired("payment-method-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/billing/payment_methods_list.go b/go/cmd/billing/payment_methods_list.go
new file mode 100644
index 0000000..77fb25a
--- /dev/null
+++ b/go/cmd/billing/payment_methods_list.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPaymentMethodsListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List payment methods",
+ Long: `List payment methods`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.ListPaymentMethods(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/billing/payment_methods_set_default.go b/go/cmd/billing/payment_methods_set_default.go
new file mode 100644
index 0000000..3e7fdde
--- /dev/null
+++ b/go/cmd/billing/payment_methods_set_default.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPaymentMethodsSetDefaultCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "set-default",
+ Short: "Make a card the default payment method",
+ Long: `Make a card the default payment method`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ paymentMethodId := common.String(cmd, "payment-method-id")
+ response, err := c.Billing.SetDefaultPaymentMethod(ctx, org, &billing.PaymentMethodRequest{PaymentMethodId: paymentMethodId})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Default payment method set.")
+ return nil
+ },
+ }
+ cmd.Flags().String("payment-method-id", "", "Stripe payment method id.")
+ _ = cmd.MarkFlagRequired("payment-method-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/billing/payment_methods_setup_intent.go b/go/cmd/billing/payment_methods_setup_intent.go
new file mode 100644
index 0000000..8cc52a6
--- /dev/null
+++ b/go/cmd/billing/payment_methods_setup_intent.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPaymentMethodsSetupIntentCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "setup-intent",
+ Short: "Create a Stripe SetupIntent for adding a card",
+ Long: `Create a Stripe SetupIntent for adding a card`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Billing.CreatePaymentSetupIntent(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/billing/profile_setup.go b/go/cmd/billing/profile_setup.go
new file mode 100644
index 0000000..9bbbff3
--- /dev/null
+++ b/go/cmd/billing/profile_setup.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newProfileSetupCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "setup -- payload.json",
+ Short: "Create the billing profile (once per organization)",
+ Long: `Create the billing profile (once per organization)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req billing.BillingProfileRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ response, err := c.Billing.SetupBillingProfile(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Billing profile created.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/billing/profile_update.go b/go/cmd/billing/profile_update.go
new file mode 100644
index 0000000..c15a1ac
--- /dev/null
+++ b/go/cmd/billing/profile_update.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package billing
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/billing"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newProfileUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update the billing profile's email, name or address",
+ Long: `Update the billing profile's email, name or address`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req billing.BillingProfileRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Billing.UpdateBillingProfile(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Billing profile updated.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/artifacts_get_url.go b/go/cmd/chat/artifacts_get_url.go
new file mode 100644
index 0000000..73517d1
--- /dev/null
+++ b/go/cmd/chat/artifacts_get_url.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsGetUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "get-url",
+ Short: "Get a presigned download URL for an artifact",
+ Long: `Get a presigned download URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ artifactPath := common.String(cmd, "artifact-path")
+ response, err := c.Chats.GetChatArtifact(ctx, org, chatId, &chats.GetChatArtifactRequest{ArtifactPath: artifactPath})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-path", "", "Artifact path relative to the chat's artifact store.")
+ _ = cmd.MarkFlagRequired("artifact-path")
+ return cmd
+}
diff --git a/go/cmd/chat/artifacts_list.go b/go/cmd/chat/artifacts_list.go
new file mode 100644
index 0000000..3f0b607
--- /dev/null
+++ b/go/cmd/chat/artifacts_list.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "Get a presigned URL that lists the artifacts",
+ Long: `Get a presigned URL that lists the artifacts`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.ListAllChatArtifacts(ctx, org, chatId, &chats.ListAllChatArtifactsRequest{Prefix: common.OptString(cmd, "prefix"), MaxKeys: common.OptInt(cmd, "max-keys"), StartAfterKey: common.OptString(cmd, "start-after-key")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("prefix", "", "Only list artifacts under this prefix.")
+ cmd.Flags().Int("max-keys", 0, "Maximum number of keys.")
+ cmd.Flags().String("start-after-key", "", "Full S3 key to start after.")
+ return cmd
+}
diff --git a/go/cmd/chat/artifacts_upload_url.go b/go/cmd/chat/artifacts_upload_url.go
new file mode 100644
index 0000000..854a135
--- /dev/null
+++ b/go/cmd/chat/artifacts_upload_url.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "upload-url",
+ Short: "Get a presigned upload URL for an artifact",
+ Long: `Get a presigned upload URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ artifactPath := common.String(cmd, "artifact-path")
+ response, err := c.Chats.SaveChatArtifact(ctx, org, chatId, &chats.SaveChatArtifactRequest{ArtifactPath: artifactPath, ContentType: common.OptString(cmd, "content-type")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-path", "", "Artifact path relative to the chat's artifact store.")
+ _ = cmd.MarkFlagRequired("artifact-path")
+ cmd.Flags().String("content-type", "", "Content type the upload must use (default application/octet-stream).")
+ return cmd
+}
diff --git a/go/cmd/chat/chat.go b/go/cmd/chat/chat.go
new file mode 100644
index 0000000..7d4d51a
--- /dev/null
+++ b/go/cmd/chat/chat.go
@@ -0,0 +1,92 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewChatCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "chat",
+ Short: "Manage AI assistant chats (infra2code and kyro) and their messages",
+ Long: `Manage AI assistant chats (infra2code and kyro) and their messages`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a chat
+ list List chats
+ read Get a chat
+ update Update a chat
+ delete Archive a chat
+ commit-bundle Commit an uploaded git bundle
+ create-pr Push the generated code and open a pull request
+ pr-status Show the status of the chat's pull request
+ pr-sync-status Compare the local bundle with the pull request
+ artifacts Work with a chat's artifacts through presigned URLs
+ messages Send and read the messages of a kyro chat`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newListCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newCommitBundleCmd(c),
+ newCreatePrCmd(c),
+ newPrStatusCmd(c),
+ newPrSyncStatusCmd(c),
+ newArtifactsCmd(c),
+ newMessagesCmd(c),
+ )
+ return cmd
+}
+func newArtifactsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "artifacts",
+ Short: "Work with a chat's artifacts through presigned URLs",
+ Long: `Work with a chat's artifacts through presigned URLs`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list Get a presigned URL that lists the artifacts
+ get-url Get a presigned download URL for an artifact
+ upload-url Get a presigned upload URL for an artifact`)
+ },
+ }
+ cmd.PersistentFlags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkPersistentFlagRequired("chat-id")
+ cmd.AddCommand(
+ newArtifactsListCmd(c),
+ newArtifactsGetUrlCmd(c),
+ newArtifactsUploadUrlCmd(c),
+ )
+ return cmd
+}
+func newMessagesCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "messages",
+ Short: "Send and read the messages of a kyro chat",
+ Long: `Send and read the messages of a kyro chat`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Send a message (use --text or a payload)
+ list List the messages of a chat, oldest first
+ read Get a message
+ cancel Stop a pending or streaming assistant message
+ retry Retry an errored or stopped assistant message`)
+ },
+ }
+ cmd.PersistentFlags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkPersistentFlagRequired("chat-id")
+ cmd.AddCommand(
+ newMessagesCreateCmd(c),
+ newMessagesListCmd(c),
+ newMessagesReadCmd(c),
+ newMessagesCancelCmd(c),
+ newMessagesRetryCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/chat/commit_bundle.go b/go/cmd/chat/commit_bundle.go
new file mode 100644
index 0000000..3568a87
--- /dev/null
+++ b/go/cmd/chat/commit_bundle.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCommitBundleCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "commit-bundle",
+ Short: "Commit an uploaded git bundle",
+ Long: `Commit an uploaded git bundle`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ expectedVersion, _ := cmd.Flags().GetInt("expected-version")
+ response, err := c.Chats.CommitChatBundle(ctx, org, chatId, &chats.CommitChatBundleRequest{ExpectedVersion: expectedVersion})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Bundle committed.")
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ cmd.Flags().Int("expected-version", 0, "The BundleVersion last seen by the caller.")
+ _ = cmd.MarkFlagRequired("expected-version")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/create.go b/go/cmd/chat/create.go
new file mode 100644
index 0000000..ef91784
--- /dev/null
+++ b/go/cmd/chat/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a chat",
+ Long: `Create a chat`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req chats.Chat
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Chats.CreateChat(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Chat created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/create_pr.go b/go/cmd/chat/create_pr.go
new file mode 100644
index 0000000..b4c3f7d
--- /dev/null
+++ b/go/cmd/chat/create_pr.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreatePrCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create-pr -- payload.json",
+ Short: "Push the generated code and open a pull request",
+ Long: `Push the generated code and open a pull request`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ var req chats.CreateChatPrRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Chats.CreateChatPr(ctx, org, chatId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Pull request request completed.")
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/delete.go b/go/cmd/chat/delete.go
new file mode 100644
index 0000000..c7982a7
--- /dev/null
+++ b/go/cmd/chat/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Archive a chat",
+ Long: `Archive a chat`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.DeleteChat(ctx, org, chatId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Chat archived successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/list.go b/go/cmd/chat/list.go
new file mode 100644
index 0000000..74f2834
--- /dev/null
+++ b/go/cmd/chat/list.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List chats",
+ Long: `List chats`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Chats.ListAllChats(ctx, org, &chats.ListAllChatsRequest{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), SearchQuery: common.OptString(cmd, "search-query"), RefreshPrStatus: common.OptBool(cmd, "refresh-pr-status"), ChatType: common.OptString(cmd, "chat-type")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("search-query", "", "Comma-separated terms matched against name, description and tags.")
+ cmd.Flags().Bool("refresh-pr-status", false, "Refresh pull request statuses from the VCS provider.")
+ cmd.Flags().String("chat-type", "", "Filter by chat type (infra2code, kyro).")
+ return cmd
+}
diff --git a/go/cmd/chat/messages_cancel.go b/go/cmd/chat/messages_cancel.go
new file mode 100644
index 0000000..fb94ba9
--- /dev/null
+++ b/go/cmd/chat/messages_cancel.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newMessagesCancelCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "cancel",
+ Short: "Stop a pending or streaming assistant message",
+ Long: `Stop a pending or streaming assistant message`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ messageId := common.String(cmd, "message-id")
+ response, err := c.Chats.CancelMessage(ctx, org, chatId, messageId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Message cancelled.")
+ return nil
+ },
+ }
+ cmd.Flags().String("message-id", "", "The message ID.")
+ _ = cmd.MarkFlagRequired("message-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/messages_create.go b/go/cmd/chat/messages_create.go
new file mode 100644
index 0000000..b4ef1f9
--- /dev/null
+++ b/go/cmd/chat/messages_create.go
@@ -0,0 +1,56 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newMessagesCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Send a message (use --text or a payload)",
+ Long: `Send a message (use --text or a payload)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ text := common.String(cmd, "text")
+ var req chats.Message
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if text != "" {
+ req.Content = []*chats.ContentBlock{{Type: "text", Text: &text}}
+ }
+ if v := common.OptString(cmd, "client-request-id"); v != nil {
+ req.ClientRequestId = v
+ }
+ if len(req.Content) == 0 {
+ return errors.New("provide --text or a payload with content blocks")
+ }
+ response, err := c.Chats.CreateMessage(ctx, org, chatId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Message sent.")
+ return nil
+ },
+ }
+ cmd.Flags().String("text", "", "Text of the message (shortcut for a single text content block).")
+ cmd.Flags().String("client-request-id", "", "Idempotency key.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/messages_list.go b/go/cmd/chat/messages_list.go
new file mode 100644
index 0000000..e54a4de
--- /dev/null
+++ b/go/cmd/chat/messages_list.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newMessagesListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the messages of a chat, oldest first",
+ Long: `List the messages of a chat, oldest first`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.ListAllMessages(ctx, org, chatId, &chats.ListAllMessagesRequest{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ return cmd
+}
diff --git a/go/cmd/chat/messages_read.go b/go/cmd/chat/messages_read.go
new file mode 100644
index 0000000..0808d21
--- /dev/null
+++ b/go/cmd/chat/messages_read.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newMessagesReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a message",
+ Long: `Get a message`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ messageId := common.String(cmd, "message-id")
+ response, err := c.Chats.ReadMessage(ctx, org, chatId, messageId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("message-id", "", "The message ID.")
+ _ = cmd.MarkFlagRequired("message-id")
+ return cmd
+}
diff --git a/go/cmd/chat/messages_retry.go b/go/cmd/chat/messages_retry.go
new file mode 100644
index 0000000..4240e83
--- /dev/null
+++ b/go/cmd/chat/messages_retry.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newMessagesRetryCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "retry",
+ Short: "Retry an errored or stopped assistant message",
+ Long: `Retry an errored or stopped assistant message`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ messageId := common.String(cmd, "message-id")
+ response, err := c.Chats.RetryMessage(ctx, org, chatId, messageId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Message retried.")
+ return nil
+ },
+ }
+ cmd.Flags().String("message-id", "", "The message ID.")
+ _ = cmd.MarkFlagRequired("message-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/chat/pr_status.go b/go/cmd/chat/pr_status.go
new file mode 100644
index 0000000..b8338de
--- /dev/null
+++ b/go/cmd/chat/pr_status.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPrStatusCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "pr-status",
+ Short: "Show the status of the chat's pull request",
+ Long: `Show the status of the chat's pull request`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.GetChatPrStatus(ctx, org, chatId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ return cmd
+}
diff --git a/go/cmd/chat/pr_sync_status.go b/go/cmd/chat/pr_sync_status.go
new file mode 100644
index 0000000..052e247
--- /dev/null
+++ b/go/cmd/chat/pr_sync_status.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPrSyncStatusCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "pr-sync-status",
+ Short: "Compare the local bundle with the pull request",
+ Long: `Compare the local bundle with the pull request`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.GetChatPrSyncStatus(ctx, org, chatId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ return cmd
+}
diff --git a/go/cmd/chat/read.go b/go/cmd/chat/read.go
new file mode 100644
index 0000000..477c741
--- /dev/null
+++ b/go/cmd/chat/read.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a chat",
+ Long: `Get a chat`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ response, err := c.Chats.ReadChat(ctx, org, chatId, &chats.ReadChatRequest{RefreshPrStatus: common.OptBool(cmd, "refresh-pr-status")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ cmd.Flags().Bool("refresh-pr-status", false, "Refresh the pull request status from the VCS provider.")
+ return cmd
+}
diff --git a/go/cmd/chat/update.go b/go/cmd/chat/update.go
new file mode 100644
index 0000000..89cc8ae
--- /dev/null
+++ b/go/cmd/chat/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package chat
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/chats"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a chat",
+ Long: `Update a chat`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ chatId := common.String(cmd, "chat-id")
+ var req chats.PatchedChat
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Chats.UpdateChat(ctx, org, chatId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Chat updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("chat-id", "", "The chat ID.")
+ _ = cmd.MarkFlagRequired("chat-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/common/common.go b/go/cmd/common/common.go
new file mode 100644
index 0000000..27f29b9
--- /dev/null
+++ b/go/cmd/common/common.go
@@ -0,0 +1,232 @@
+// Package common holds the helpers shared by every sg-cli command: client
+// construction, JSON output, flag access and payload handling.
+package common
+
+import (
+ "bytes"
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "net/http"
+ "os"
+ "strings"
+ "sync"
+
+ "github.com/StackGuardian/sg-cli/utilities"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/option"
+ "github.com/spf13/cobra"
+)
+
+const (
+ DefaultBaseURL = "https://api.app.stackguardian.io"
+ DashboardURL = "https://app.stackguardian.io/orchestrator"
+)
+
+// capture records the most recent response body so commands can print the
+// API's JSON verbatim: re-encoding the SDK's typed structs would drop any
+// field the SDK does not declare.
+type capture struct {
+ next http.RoundTripper
+ mu sync.Mutex
+ body []byte
+}
+
+func (c *capture) RoundTrip(req *http.Request) (*http.Response, error) {
+ resp, err := c.next.RoundTrip(req)
+ if err != nil {
+ return nil, err
+ }
+ body, err := io.ReadAll(resp.Body)
+ resp.Body.Close()
+ if err != nil {
+ return nil, err
+ }
+ resp.Body = io.NopCloser(bytes.NewReader(body))
+ c.mu.Lock()
+ c.body = body
+ c.mu.Unlock()
+ return resp, nil
+}
+
+var lastResponse = &capture{next: http.DefaultTransport}
+
+// NewClient builds the SDK client from SG_API_TOKEN and SG_BASE_URL with the
+// response capture installed. Both sgu_ (personal) and sgo_ (org) tokens work.
+func NewClient() *client.Client {
+ apiKey := strings.TrimSpace(os.Getenv("SG_API_TOKEN"))
+ if !strings.HasPrefix(strings.ToLower(apiKey), "apikey ") {
+ apiKey = "apikey " + apiKey
+ }
+ baseURL := os.Getenv("SG_BASE_URL")
+ if baseURL == "" {
+ baseURL = DefaultBaseURL
+ }
+ return client.NewClient(
+ option.WithApiKey(apiKey),
+ option.WithBaseURL(strings.TrimRight(baseURL, "/")),
+ option.WithHTTPClient(&http.Client{Transport: lastResponse}),
+ )
+}
+
+// PrintJSON writes the API response as indented JSON: the captured raw body
+// when the client was built by NewClient, otherwise the encoded value.
+func PrintJSON(cmd *cobra.Command, response interface{}) {
+ lastResponse.mu.Lock()
+ body := lastResponse.body
+ lastResponse.mu.Unlock()
+ var out bytes.Buffer
+ if len(bytes.TrimSpace(body)) > 0 && json.Indent(&out, body, "", " ") == nil {
+ cmd.Println(out.String())
+ return
+ }
+ encoded, err := json.MarshalIndent(response, "", " ")
+ if err != nil {
+ cmd.Println(response)
+ return
+ }
+ cmd.Println(string(encoded))
+}
+
+// Org returns the value of the --org flag, searching parent commands.
+func Org(cmd *cobra.Command) string {
+ return String(cmd, "org")
+}
+
+// String returns a string flag defined on cmd or inherited from a parent.
+func String(cmd *cobra.Command, name string) string {
+ if f := cmd.Flag(name); f != nil {
+ return f.Value.String()
+ }
+ return ""
+}
+
+// Bool returns a bool flag defined on cmd or inherited from a parent.
+func Bool(cmd *cobra.Command, name string) bool {
+ if f := cmd.Flag(name); f != nil {
+ return f.Value.String() == "true"
+ }
+ return false
+}
+
+// Optional flag helpers: they return nil when the flag was not set, so a
+// default never overrides the API's own default.
+
+func OptString(cmd *cobra.Command, name string) *string {
+ if f := cmd.Flags().Lookup(name); f == nil || !f.Changed {
+ return nil
+ }
+ v, _ := cmd.Flags().GetString(name)
+ return &v
+}
+
+func OptInt(cmd *cobra.Command, name string) *int {
+ if f := cmd.Flags().Lookup(name); f == nil || !f.Changed {
+ return nil
+ }
+ v, _ := cmd.Flags().GetInt(name)
+ return &v
+}
+
+func OptBool(cmd *cobra.Command, name string) *bool {
+ if f := cmd.Flags().Lookup(name); f == nil || !f.Changed {
+ return nil
+ }
+ v, _ := cmd.Flags().GetBool(name)
+ return &v
+}
+
+func OptStringSlice(cmd *cobra.Command, name string) []string {
+ if f := cmd.Flags().Lookup(name); f == nil || !f.Changed {
+ return nil
+ }
+ v, _ := cmd.Flags().GetStringSlice(name)
+ return v
+}
+
+// AddOrgFlag registers the required --org persistent flag on a command group.
+func AddOrgFlag(cmd *cobra.Command) {
+ cmd.PersistentFlags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkPersistentFlagRequired("org")
+}
+
+// AddPayloadFlags registers the flags that accompany a JSON payload file.
+func AddPayloadFlags(cmd *cobra.Command) {
+ cmd.Flags().String("patch-payload", "", "Patch original payload.json input. Add or replace values. Requires valid JSON input.")
+ cmd.Flags().Bool("preview", false, "Preview payload content before sending. Execution will not pause.")
+ cmd.Flags().Bool("dry-run", false, "Similar to --preview. But execution will stop, nothing will be sent.")
+}
+
+// AddOutputJSONFlag registers --output-json on commands that print a message by default.
+func AddOutputJSONFlag(cmd *cobra.Command) {
+ cmd.Flags().Bool("output-json", false, "Output execution response as json to STDOUT.")
+}
+
+// ErrDryRun is returned by ReadPayload after printing the payload for --dry-run.
+var ErrDryRun = errors.New("dry run: nothing was sent")
+
+// ReadPayload reads the JSON payload file given as the positional argument
+// (use "-" for stdin), applies --patch-payload, honours --preview/--dry-run
+// and decodes the result into dst.
+func ReadPayload(cmd *cobra.Command, args []string, dst interface{}) error {
+ if len(args) != 1 {
+ return errors.New("a JSON payload file is required after --")
+ }
+ var payload []byte
+ var err error
+ if args[0] == "-" {
+ payload, err = io.ReadAll(cmd.InOrStdin())
+ } else {
+ payload, err = os.ReadFile(args[0])
+ }
+ if err != nil {
+ return fmt.Errorf("read payload: %w", err)
+ }
+ if patch := String(cmd, "patch-payload"); patch != "" {
+ payload = []byte(utilities.PatchJSON(string(payload), patch))
+ }
+ if Bool(cmd, "preview") || Bool(cmd, "dry-run") {
+ var pretty bytes.Buffer
+ if json.Indent(&pretty, payload, "", " ") == nil {
+ cmd.Println(pretty.String())
+ } else {
+ cmd.Println(string(payload))
+ }
+ if Bool(cmd, "dry-run") {
+ return ErrDryRun
+ }
+ }
+ if err := json.Unmarshal(payload, dst); err != nil {
+ return fmt.Errorf("invalid JSON payload: %w", err)
+ }
+ return nil
+}
+
+// Done prints the response when --output-json is set, then the message.
+func Done(cmd *cobra.Command, response interface{}, message string) {
+ if Bool(cmd, "output-json") {
+ PrintJSON(cmd, response)
+ }
+ cmd.Println(message)
+}
+
+// Require returns an error naming the first of the given flags that is empty.
+func Require(cmd *cobra.Command, names ...string) error {
+ for _, n := range names {
+ if String(cmd, n) == "" {
+ return fmt.Errorf("required flag \"%s\" not set", n)
+ }
+ }
+ return nil
+}
+
+// CheckEnum validates that value is one of allowed.
+func CheckEnum(flag, value string, allowed ...string) error {
+ for _, a := range allowed {
+ if value == a {
+ return nil
+ }
+ }
+ return fmt.Errorf("invalid value %q for --%s: must be one of %s", value, flag, strings.Join(allowed, ", "))
+}
diff --git a/go/cmd/connector/authenticate.go b/go/cmd/connector/authenticate.go
new file mode 100644
index 0000000..b4cca8e
--- /dev/null
+++ b/go/cmd/connector/authenticate.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newAuthenticateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "authenticate",
+ Short: "Verify that a connector can authenticate against its provider",
+ Long: `Verify that a connector can authenticate against its provider`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.Connectors.AuthenticateConnector(ctx, connectorId, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ return cmd
+}
diff --git a/go/cmd/connector/connector.go b/go/cmd/connector/connector.go
new file mode 100644
index 0000000..d9ac3ab
--- /dev/null
+++ b/go/cmd/connector/connector.go
@@ -0,0 +1,42 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewConnectorCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "connector",
+ Short: "Manage connectors (cloud and VCS integrations)",
+ Long: `Manage connectors (cloud and VCS integrations)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new connector
+ read Get details of a connector
+ update Update a connector
+ delete Delete a connector
+ list List connectors
+ authenticate Verify that a connector can authenticate against its provider
+ list-accounts List the cloud accounts or subscriptions reachable with a connector's credentials
+ github-repos List the repositories accessible to a GITHUB_COM connector
+ repos List the repositories reachable through a VCS connector`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ newAuthenticateCmd(c),
+ newListAccountsCmd(c),
+ newGithubReposCmd(c),
+ newReposCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/connector/create.go b/go/cmd/connector/create.go
new file mode 100644
index 0000000..d00ad24
--- /dev/null
+++ b/go/cmd/connector/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new connector",
+ Long: `Create a new connector`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.Integration
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Connectors.CreateConnector(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connector/delete.go b/go/cmd/connector/delete.go
new file mode 100644
index 0000000..99be3e3
--- /dev/null
+++ b/go/cmd/connector/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a connector",
+ Long: `Delete a connector`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.Connectors.DeleteConnector(ctx, connectorId, org)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connector/github_repos.go b/go/cmd/connector/github_repos.go
new file mode 100644
index 0000000..dc3534c
--- /dev/null
+++ b/go/cmd/connector/github_repos.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newGithubReposCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "github-repos",
+ Short: "List the repositories accessible to a GITHUB_COM connector",
+ Long: `List the repositories accessible to a GITHUB_COM connector`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.Connectors.GetGithubComRepos(ctx, connectorId, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ return cmd
+}
diff --git a/go/cmd/connector/list.go b/go/cmd/connector/list.go
new file mode 100644
index 0000000..2b93d50
--- /dev/null
+++ b/go/cmd/connector/list.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List connectors",
+ Long: `List connectors`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Connectors.ListAllConnectors(ctx, org, &sggosdk.ListAllConnectorsRequest{ResourceNames: common.OptString(cmd, "resource-names"), Kind: common.OptString(cmd, "kind"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("resource-names", "", "Filter by resource name.")
+ cmd.Flags().String("kind", "", "Filter by kind (comma-separated), e.g. AWS_RBAC,AZURE_OIDC.")
+ return cmd
+}
diff --git a/go/cmd/connector/list_accounts.go b/go/cmd/connector/list_accounts.go
new file mode 100644
index 0000000..e7dadb9
--- /dev/null
+++ b/go/cmd/connector/list_accounts.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/connectors"
+ "github.com/spf13/cobra"
+)
+
+func newListAccountsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-accounts -- payload.json",
+ Short: "List the cloud accounts or subscriptions reachable with a connector's credentials",
+ Long: `List the cloud accounts or subscriptions reachable with a connector's credentials`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req connectors.ListAccountsRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Connectors.ListAccounts(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ return cmd
+}
diff --git a/go/cmd/connector/read.go b/go/cmd/connector/read.go
new file mode 100644
index 0000000..80078af
--- /dev/null
+++ b/go/cmd/connector/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a connector",
+ Long: `Get details of a connector`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.Connectors.ReadConnector(ctx, connectorId, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ return cmd
+}
diff --git a/go/cmd/connector/repos.go b/go/cmd/connector/repos.go
new file mode 100644
index 0000000..b69036c
--- /dev/null
+++ b/go/cmd/connector/repos.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/connectors"
+ "github.com/spf13/cobra"
+)
+
+func newReposCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "repos",
+ Short: "List the repositories reachable through a VCS connector",
+ Long: `List the repositories reachable through a VCS connector`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.Connectors.ListRepositories(ctx, connectorId, org, &connectors.ListRepositoriesRequest{Login: common.OptString(cmd, "login"), InstallationId: common.OptString(cmd, "installation-id"), Page: common.OptString(cmd, "page"), Limit: common.OptInt(cmd, "limit"), SearchQuery: common.OptString(cmd, "search-query")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ cmd.Flags().String("login", "", "GitHub account or organization login (GITHUB_COM).")
+ cmd.Flags().String("installation-id", "", "GitHub App installation id (GITHUB_COM).")
+ cmd.Flags().String("page", "", "Page number or provider cursor.")
+ cmd.Flags().Int("limit", 0, "Page size.")
+ cmd.Flags().String("search-query", "", "Filter by name or namespace.")
+ return cmd
+}
diff --git a/go/cmd/connector/update.go b/go/cmd/connector/update.go
new file mode 100644
index 0000000..98bc838
--- /dev/null
+++ b/go/cmd/connector/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connector
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a connector",
+ Long: `Update a connector`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorId := common.String(cmd, "connector-id")
+ var req sggosdk.PatchedIntegration
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Connectors.UpdateConnector(ctx, connectorId, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/authenticate.go b/go/cmd/connectorgroup/authenticate.go
new file mode 100644
index 0000000..f901902
--- /dev/null
+++ b/go/cmd/connectorgroup/authenticate.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newAuthenticateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "authenticate",
+ Short: "Authenticate a connector group",
+ Long: `Authenticate a connector group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ response, err := c.ConnectorGroups.AuthenticateConnectorGroup(ctx, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkFlagRequired("connector-group")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectorgroup.go b/go/cmd/connectorgroup/connectorgroup.go
new file mode 100644
index 0000000..dea5191
--- /dev/null
+++ b/go/cmd/connectorgroup/connectorgroup.go
@@ -0,0 +1,65 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewConnectorGroupCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "connector-group",
+ Short: "Manage connector groups (cloud integration groups)",
+ Long: `Manage connector groups (cloud integration groups)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new connector group
+ read Get details of a connector group
+ update Update a connector group
+ delete Delete a connector group
+ authenticate Authenticate a connector group
+ list List connector groups
+ discovery-scan Trigger discovery scans across the group's child connectors
+ connectors Manage the connectors inside a connector group`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newAuthenticateCmd(c),
+ newListCmd(c),
+ newDiscoveryScanCmd(c),
+ newConnectorsCmd(c),
+ )
+ return cmd
+}
+func newConnectorsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "connectors",
+ Short: "Manage the connectors inside a connector group",
+ Long: `Manage the connectors inside a connector group`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a connector in the group
+ update Update a connector in the group
+ delete Delete a connector from the group
+ list List the connectors in the group
+ authenticate Verify that a connector in the group can authenticate`)
+ },
+ }
+ cmd.PersistentFlags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkPersistentFlagRequired("connector-group")
+ cmd.AddCommand(
+ newConnectorsReadCmd(c),
+ newConnectorsUpdateCmd(c),
+ newConnectorsDeleteCmd(c),
+ newConnectorsListCmd(c),
+ newConnectorsAuthenticateCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectors_authenticate.go b/go/cmd/connectorgroup/connectors_authenticate.go
new file mode 100644
index 0000000..91be9c4
--- /dev/null
+++ b/go/cmd/connectorgroup/connectors_authenticate.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newConnectorsAuthenticateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "authenticate",
+ Short: "Verify that a connector in the group can authenticate",
+ Long: `Verify that a connector in the group can authenticate`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.ConnectorGroups.AuthenticateChildInACloudConnectorGroup(ctx, connectorId, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectors_delete.go b/go/cmd/connectorgroup/connectors_delete.go
new file mode 100644
index 0000000..577b85a
--- /dev/null
+++ b/go/cmd/connectorgroup/connectors_delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newConnectorsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a connector from the group",
+ Long: `Delete a connector from the group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.ConnectorGroups.DeleteChildInACloudConnectorGroup(ctx, connectorId, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectors_list.go b/go/cmd/connectorgroup/connectors_list.go
new file mode 100644
index 0000000..0027899
--- /dev/null
+++ b/go/cmd/connectorgroup/connectors_list.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newConnectorsListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the connectors in the group",
+ Long: `List the connectors in the group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ response, err := c.ConnectorGroups.ListAllConnectorsInAGroup(ctx, connectorGroup, org, &sggosdk.ListAllConnectorsInAGroupRequest{ResourceNames: common.OptString(cmd, "resource-names"), Kind: common.OptString(cmd, "kind"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), Scope: common.OptString(cmd, "scope")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("resource-names", "", "Filter by resource name.")
+ cmd.Flags().String("kind", "", "Filter by kind.")
+ cmd.Flags().String("scope", "", "Filter by scope.")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectors_read.go b/go/cmd/connectorgroup/connectors_read.go
new file mode 100644
index 0000000..5f7f26e
--- /dev/null
+++ b/go/cmd/connectorgroup/connectors_read.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newConnectorsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a connector in the group",
+ Long: `Get a connector in the group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ connectorId := common.String(cmd, "connector-id")
+ response, err := c.ConnectorGroups.ReadChildInACloudConnectorGroup(ctx, connectorId, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/connectors_update.go b/go/cmd/connectorgroup/connectors_update.go
new file mode 100644
index 0000000..c48c4dd
--- /dev/null
+++ b/go/cmd/connectorgroup/connectors_update.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newConnectorsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a connector in the group",
+ Long: `Update a connector in the group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ connectorId := common.String(cmd, "connector-id")
+ var req sggosdk.PatchedIntegration
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.ConnectorGroups.UpdateChildInACloudConnectorGroup(ctx, connectorId, connectorGroup, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-id", "", "The connector ID.")
+ _ = cmd.MarkFlagRequired("connector-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/create.go b/go/cmd/connectorgroup/create.go
new file mode 100644
index 0000000..49b0327
--- /dev/null
+++ b/go/cmd/connectorgroup/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new connector group",
+ Long: `Create a new connector group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.IntegrationGroups
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.ConnectorGroups.CreateConnectorGroup(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector group created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/delete.go b/go/cmd/connectorgroup/delete.go
new file mode 100644
index 0000000..7ecd0da
--- /dev/null
+++ b/go/cmd/connectorgroup/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a connector group",
+ Long: `Delete a connector group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ response, err := c.ConnectorGroups.DeleteConnectorGroup(ctx, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector group deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkFlagRequired("connector-group")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/discovery_scan.go b/go/cmd/connectorgroup/discovery_scan.go
new file mode 100644
index 0000000..a481a95
--- /dev/null
+++ b/go/cmd/connectorgroup/discovery_scan.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/connectorgroups"
+ "github.com/spf13/cobra"
+)
+
+func newDiscoveryScanCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "discovery-scan",
+ Short: "Trigger discovery scans across the group's child connectors",
+ Long: `Trigger discovery scans across the group's child connectors`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ response, err := c.ConnectorGroups.TriggerDiscoveryScan(ctx, connectorGroup, org, &connectorgroups.DiscoveryScanRequest{Benchmark: common.OptString(cmd, "benchmark")})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Discovery scan triggered.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkFlagRequired("connector-group")
+ cmd.Flags().String("benchmark", "", "Benchmarks to scan (comma-separated, default inventory).")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/list.go b/go/cmd/connectorgroup/list.go
new file mode 100644
index 0000000..13045e0
--- /dev/null
+++ b/go/cmd/connectorgroup/list.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List connector groups",
+ Long: `List connector groups`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.ConnectorGroups.ListAllConnectorGroups(ctx, org, &sggosdk.ListAllConnectorGroupsRequest{ResourceNames: common.OptString(cmd, "resource-names"), Kind: common.OptString(cmd, "kind"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), Scope: common.OptString(cmd, "scope")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("resource-names", "", "Filter by resource name.")
+ cmd.Flags().String("kind", "", "Filter by kind.")
+ cmd.Flags().String("scope", "", "Filter by scope.")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/read.go b/go/cmd/connectorgroup/read.go
new file mode 100644
index 0000000..b9c3fa1
--- /dev/null
+++ b/go/cmd/connectorgroup/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a connector group",
+ Long: `Get details of a connector group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ response, err := c.ConnectorGroups.ReadConnectorGroup(ctx, connectorGroup, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkFlagRequired("connector-group")
+ return cmd
+}
diff --git a/go/cmd/connectorgroup/update.go b/go/cmd/connectorgroup/update.go
new file mode 100644
index 0000000..bd095bb
--- /dev/null
+++ b/go/cmd/connectorgroup/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package connectorgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a connector group",
+ Long: `Update a connector group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ connectorGroup := common.String(cmd, "connector-group")
+ var req sggosdk.PatchedIntegrationGroups
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.ConnectorGroups.UpdateConnectorGroup(ctx, connectorGroup, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Connector group updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("connector-group", "", "The connector group name.")
+ _ = cmd.MarkFlagRequired("connector-group")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/organization/bulk_action.go b/go/cmd/organization/bulk_action.go
new file mode 100644
index 0000000..b6f9959
--- /dev/null
+++ b/go/cmd/organization/bulk_action.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "fmt"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/organizations"
+ "github.com/spf13/cobra"
+)
+
+func newBulkActionCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "bulk-action",
+ Short: "Activate or deactivate workflows and stacks in bulk",
+ Long: `Activate or deactivate workflows and stacks in bulk`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ action := common.String(cmd, "action")
+ resourceIds := common.OptStringSlice(cmd, "resource-ids")
+ if action != "activate" && action != "deactivate" {
+ return fmt.Errorf("--action must be activate or deactivate, got %q", action)
+ }
+ response, err := c.Organizations.BulkActionWorkflows(ctx, org, &organizations.WorkflowsBulkActionRequest{Action: action, ResourceIds: resourceIds})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Bulk action submitted.")
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ cmd.Flags().String("action", "", "activate or deactivate.")
+ _ = cmd.MarkFlagRequired("action")
+ cmd.Flags().StringSlice("resource-ids", nil, "Resource paths relative to the organization, e.g. /wfgrps/g/wfs/w (comma-separated).")
+ _ = cmd.MarkFlagRequired("resource-ids")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/organization/count_workflows.go b/go/cmd/organization/count_workflows.go
new file mode 100644
index 0000000..dd22102
--- /dev/null
+++ b/go/cmd/organization/count_workflows.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/organizations"
+ "github.com/spf13/cobra"
+)
+
+func newCountWorkflowsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "count-workflows",
+ Short: "Count workflows across every workflow group of an organization",
+ Long: `Count workflows across every workflow group of an organization`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Organizations.CountWorkflows(ctx, org, &organizations.ListAllOrganizationWorkflowsRequest{
+ ResourceNames: common.OptString(cmd, "resource-names"), Description: common.OptString(cmd, "description"), Tags: common.OptString(cmd, "tags"), IsActive: common.OptString(cmd, "is-active"),
+ })
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ cmd.Flags().String("resource-names", "", "Filter by resource names (comma-separated).")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("tags", "", "Filter by tags (comma-separated).")
+ cmd.Flags().String("is-active", "", "Filter by active state (0 or 1).")
+ return cmd
+}
diff --git a/go/cmd/organization/create.go b/go/cmd/organization/create.go
new file mode 100644
index 0000000..596137a
--- /dev/null
+++ b/go/cmd/organization/create.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/organizations"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new organization (requires a user token, not an API key)",
+ Long: `Create a new organization (requires a user token, not an API key)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ var req organizations.CreateOrganizationRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Organizations.CreateOrganization(ctx, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Organization created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/organization/delete.go b/go/cmd/organization/delete.go
new file mode 100644
index 0000000..590643c
--- /dev/null
+++ b/go/cmd/organization/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Archive an organization and all of its resources",
+ Long: `Archive an organization and all of its resources`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Organizations.DeleteOrganization(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Organization archived successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/organization/list.go b/go/cmd/organization/list.go
new file mode 100644
index 0000000..e829023
--- /dev/null
+++ b/go/cmd/organization/list.go
@@ -0,0 +1,29 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the organizations the caller belongs to (requires a user token)",
+ Long: `List the organizations the caller belongs to (requires a user token)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ response, err := c.Organizations.ListAllOrganizations(ctx)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/organization/organization.go b/go/cmd/organization/organization.go
new file mode 100644
index 0000000..02e23e5
--- /dev/null
+++ b/go/cmd/organization/organization.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewOrganizationCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "organization",
+ Short: "Manage organizations",
+ Long: `Manage organizations`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get details of an organization
+ create Create a new organization (requires a user token, not an API key)
+ list List the organizations the caller belongs to (requires a user token)
+ update Update the settings of an organization
+ delete Archive an organization and all of its resources
+ workflows List workflows across every workflow group of an organization
+ count-workflows Count workflows across every workflow group of an organization
+ bulk-action Activate or deactivate workflows and stacks in bulk`)
+ },
+ }
+ cmd.AddCommand(
+ newReadCmd(c),
+ newCreateCmd(c),
+ newListCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newWorkflowsCmd(c),
+ newCountWorkflowsCmd(c),
+ newBulkActionCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/organization/read.go b/go/cmd/organization/read.go
new file mode 100644
index 0000000..727f87b
--- /dev/null
+++ b/go/cmd/organization/read.go
@@ -0,0 +1,32 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of an organization",
+ Long: `Get details of an organization`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Organizations.ReadOrganization(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ return cmd
+}
diff --git a/go/cmd/organization/update.go b/go/cmd/organization/update.go
new file mode 100644
index 0000000..22fe033
--- /dev/null
+++ b/go/cmd/organization/update.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/organizations"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update the settings of an organization",
+ Long: `Update the settings of an organization`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req organizations.PatchedOrganization
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Organizations.UpdateOrganization(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Organization updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/organization/workflows.go b/go/cmd/organization/workflows.go
new file mode 100644
index 0000000..1dded23
--- /dev/null
+++ b/go/cmd/organization/workflows.go
@@ -0,0 +1,56 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package organization
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/organizations"
+ "github.com/spf13/cobra"
+)
+
+func newWorkflowsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "workflows",
+ Short: "List workflows across every workflow group of an organization",
+ Long: `List workflows across every workflow group of an organization`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Organizations.ListAllWorkflows(ctx, org, &organizations.ListAllOrganizationWorkflowsRequest{
+ Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), FetchSgOwnedWfs: common.OptBool(cmd, "fetch-sg-owned-wfs"),
+ LatestWfRunStatuses: common.OptString(cmd, "latest-wf-run-statuses"), LatestDriftRunStatuses: common.OptString(cmd, "latest-drift-run-statuses"),
+ RepoId: common.OptString(cmd, "repo-id"), UseMarketplaceTemplate: common.OptString(cmd, "use-marketplace-template"), IacTemplateId: common.OptString(cmd, "iac-template-id"),
+ ParentIacTemplateId: common.OptString(cmd, "parent-iac-template-id"), TerraformConfigTerraformVersion: common.OptString(cmd, "terraform-version"),
+ RunnerNames: common.OptString(cmd, "runner-names"), TerraformConfigDriftCheck: common.OptString(cmd, "drift-check"), ResourceNames: common.OptString(cmd, "resource-names"),
+ Description: common.OptString(cmd, "description"), Tags: common.OptString(cmd, "tags"), IsActive: common.OptString(cmd, "is-active"),
+ })
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("org", "", "The organization name on Stackguardian platform.")
+ _ = cmd.MarkFlagRequired("org")
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().Bool("fetch-sg-owned-wfs", true, "Include workflows owned by StackGuardian.")
+ cmd.Flags().String("latest-wf-run-statuses", "", "Filter by latest run status (comma-separated).")
+ cmd.Flags().String("latest-drift-run-statuses", "", "Filter by latest drift run status (comma-separated).")
+ cmd.Flags().String("repo-id", "", "Filter by VCS repository.")
+ cmd.Flags().String("use-marketplace-template", "", "Filter by marketplace template usage (true/false).")
+ cmd.Flags().String("iac-template-id", "", "Filter by IaC template id.")
+ cmd.Flags().String("parent-iac-template-id", "", "Filter by parent IaC template id.")
+ cmd.Flags().String("terraform-version", "", "Filter by Terraform version.")
+ cmd.Flags().String("runner-names", "", "Filter by runner names (comma-separated).")
+ cmd.Flags().String("drift-check", "", "Any value restricts to workflows with drift information.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names (comma-separated).")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("tags", "", "Filter by tags (comma-separated).")
+ cmd.Flags().String("is-active", "", "Filter by active state (0 or 1).")
+ return cmd
+}
diff --git a/go/cmd/policy/create.go b/go/cmd/policy/create.go
new file mode 100644
index 0000000..4f24e4a
--- /dev/null
+++ b/go/cmd/policy/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new policy (payload must include PolicyType: GENERAL or FILTER.INSIGHT)",
+ Long: `Create a new policy (payload must include PolicyType: GENERAL or FILTER.INSIGHT)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.PolymorphicPolicy
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Policies.CreatePolicy(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Policy created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/policy/delete.go b/go/cmd/policy/delete.go
new file mode 100644
index 0000000..a32c234
--- /dev/null
+++ b/go/cmd/policy/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a policy",
+ Long: `Delete a policy`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ policyId := common.String(cmd, "policy-id")
+ if err := c.Policies.DeletePolicy(ctx, org, policyId); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Policy deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("policy-id", "", "The policy ID.")
+ _ = cmd.MarkFlagRequired("policy-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/policy/list.go b/go/cmd/policy/list.go
new file mode 100644
index 0000000..0b7bdcd
--- /dev/null
+++ b/go/cmd/policy/list.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List policies",
+ Long: `List policies`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Policies.ListAllPolicies(ctx, org, &sggosdk.ListAllPoliciesRequest{Description: common.OptString(cmd, "description"), PolicyTypes: common.OptString(cmd, "policy-types"), ResourceNames: common.OptString(cmd, "resource-names"), Tags: common.OptString(cmd, "tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), SearchQuery: common.OptString(cmd, "search-query")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("policy-types", "", "Filter by policy types (default GENERAL).")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ cmd.Flags().String("tags", "", "Filter by tags.")
+ cmd.Flags().String("search-query", "", "Search by resource name, tags or description.")
+ return cmd
+}
diff --git a/go/cmd/policy/policy.go b/go/cmd/policy/policy.go
new file mode 100644
index 0000000..2aa3568
--- /dev/null
+++ b/go/cmd/policy/policy.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewPolicyCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "policy",
+ Short: "Manage policies",
+ Long: `Manage policies`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new policy (payload must include PolicyType: GENERAL or FILTER.INSIGHT)
+ read Get details of a policy
+ update Update a policy (payload must include PolicyType)
+ delete Delete a policy
+ list List policies`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/policy/read.go b/go/cmd/policy/read.go
new file mode 100644
index 0000000..4587e6f
--- /dev/null
+++ b/go/cmd/policy/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a policy",
+ Long: `Get details of a policy`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ policyId := common.String(cmd, "policy-id")
+ response, err := c.Policies.ReadPolicy(ctx, org, policyId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("policy-id", "", "The policy ID.")
+ _ = cmd.MarkFlagRequired("policy-id")
+ return cmd
+}
diff --git a/go/cmd/policy/update.go b/go/cmd/policy/update.go
new file mode 100644
index 0000000..3ac7f02
--- /dev/null
+++ b/go/cmd/policy/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package policy
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a policy (payload must include PolicyType)",
+ Long: `Update a policy (payload must include PolicyType)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ policyId := common.String(cmd, "policy-id")
+ var req sggosdk.PatchedPolymorphicPolicy
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Policies.UpdatePolicy(ctx, org, policyId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Policy updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("policy-id", "", "The policy ID.")
+ _ = cmd.MarkFlagRequired("policy-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/resource/move.go b/go/cmd/resource/move.go
new file mode 100644
index 0000000..7b0a08b
--- /dev/null
+++ b/go/cmd/resource/move.go
@@ -0,0 +1,54 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package resource
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/resources"
+ "github.com/spf13/cobra"
+)
+
+func newMoveCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "move -- payload.json",
+ Short: "Move workflows, stacks or workflow groups to another parent",
+ Long: `Move workflows, stacks or workflow groups to another parent`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req resources.MoveResourcesRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if v := common.OptStringSlice(cmd, "source-ids"); v != nil {
+ req.SourceResourceIds = v
+ }
+ if v := common.OptString(cmd, "destination"); v != nil {
+ req.DestinationParentId = *v
+ }
+ if len(req.SourceResourceIds) == 0 || req.DestinationParentId == "" {
+ return errors.New("provide --source-ids and --destination, or a payload with SourceResourceIds and DestinationParentId")
+ }
+ response, err := c.Resources.MoveResources(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Resources moved.")
+ return nil
+ },
+ }
+ cmd.Flags().StringSlice("source-ids", nil, "Resource ids to move (comma-separated).")
+ cmd.Flags().String("destination", "", "Id of the destination parent.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/resource/resource.go b/go/cmd/resource/resource.go
new file mode 100644
index 0000000..fd6c6fe
--- /dev/null
+++ b/go/cmd/resource/resource.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package resource
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewResourceCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "resource",
+ Short: "Move and search resources across the organization",
+ Long: `Move and search resources across the organization`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ move Move workflows, stacks or workflow groups to another parent
+ search Search resources (payload and flags are merged; ResourceTypes is required by the API)
+ tags List the distinct tags used on resources`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newMoveCmd(c),
+ newSearchCmd(c),
+ newTagsCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/resource/search.go b/go/cmd/resource/search.go
new file mode 100644
index 0000000..138e114
--- /dev/null
+++ b/go/cmd/resource/search.go
@@ -0,0 +1,58 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package resource
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/resources"
+ "github.com/spf13/cobra"
+)
+
+func newSearchCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "search -- payload.json",
+ Short: "Search resources (payload and flags are merged; ResourceTypes is required by the API)",
+ Long: `Search resources (payload and flags are merged; ResourceTypes is required by the API)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req resources.SearchResourcesRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if v := common.OptString(cmd, "search-query"); v != nil {
+ req.SearchQuery = v
+ }
+ if v := common.OptStringSlice(cmd, "resource-types"); v != nil {
+ req.ResourceTypes = v
+ }
+ if v := common.OptInt(cmd, "limit"); v != nil {
+ req.Limit = v
+ }
+ if v := common.OptString(cmd, "last-evaluated-key"); v != nil {
+ req.LastEvaluatedKey = v
+ }
+ response, err := c.Resources.SearchResources(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("search-query", "", "Free-text search query.")
+ cmd.Flags().StringSlice("resource-types", nil, "Resource types to search, e.g. WORKFLOW,STACK (comma-separated).")
+ cmd.Flags().Int("limit", 0, "Maximum number of results.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ common.AddPayloadFlags(cmd)
+ return cmd
+}
diff --git a/go/cmd/resource/tags.go b/go/cmd/resource/tags.go
new file mode 100644
index 0000000..ef4cc41
--- /dev/null
+++ b/go/cmd/resource/tags.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package resource
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/resources"
+ "github.com/spf13/cobra"
+)
+
+func newTagsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "tags",
+ Short: "List the distinct tags used on resources",
+ Long: `List the distinct tags used on resources`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Resources.ListResourceTags(ctx, org, &resources.ListResourceTagsRequest{ContextTagKey: common.OptString(cmd, "context-tag-key"), Limit: common.OptInt(cmd, "limit"), Query: common.OptString(cmd, "query"), ResourceType: common.OptString(cmd, "resource-type"), TagKind: common.OptString(cmd, "tag-kind")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("context-tag-key", "", "Context tag key to list values for.")
+ cmd.Flags().Int("limit", 0, "Maximum number of tags.")
+ cmd.Flags().String("query", "", "Filter tags by prefix or substring.")
+ cmd.Flags().String("resource-type", "", "Restrict to a resource type.")
+ cmd.Flags().String("tag-kind", "", "Tag kind to list.")
+ return cmd
+}
diff --git a/go/cmd/role/create.go b/go/cmd/role/create.go
new file mode 100644
index 0000000..f1adea9
--- /dev/null
+++ b/go/cmd/role/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new role",
+ Long: `Create a new role`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.Role
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.AccessManagement.CreateRole(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Role created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/role/delete.go b/go/cmd/role/delete.go
new file mode 100644
index 0000000..663f0bf
--- /dev/null
+++ b/go/cmd/role/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a role",
+ Long: `Delete a role`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ roleId := common.String(cmd, "role-id")
+ if err := c.AccessManagement.DeleteRole(ctx, org, roleId); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Role deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("role-id", "", "The role ID.")
+ _ = cmd.MarkFlagRequired("role-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/role/list.go b/go/cmd/role/list.go
new file mode 100644
index 0000000..be5fd38
--- /dev/null
+++ b/go/cmd/role/list.go
@@ -0,0 +1,32 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List roles",
+ Long: `List roles`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.ListAllRoles(ctx, org, &sggosdk.ListAllRolesRequest{IncludePredefinedRoles: common.OptBool(cmd, "include-predefined-roles")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Bool("include-predefined-roles", false, "Include predefined system roles.")
+ return cmd
+}
diff --git a/go/cmd/role/read.go b/go/cmd/role/read.go
new file mode 100644
index 0000000..b32bf7b
--- /dev/null
+++ b/go/cmd/role/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a role",
+ Long: `Get details of a role`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ roleId := common.String(cmd, "role-id")
+ response, err := c.AccessManagement.ReadRole(ctx, org, roleId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("role-id", "", "The role ID.")
+ _ = cmd.MarkFlagRequired("role-id")
+ return cmd
+}
diff --git a/go/cmd/role/role.go b/go/cmd/role/role.go
new file mode 100644
index 0000000..8ec3c34
--- /dev/null
+++ b/go/cmd/role/role.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewRoleCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "role",
+ Short: "Manage roles",
+ Long: `Manage roles`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new role
+ read Get details of a role
+ update Update a role
+ delete Delete a role
+ list List roles`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/role/update.go b/go/cmd/role/update.go
new file mode 100644
index 0000000..fa9abee
--- /dev/null
+++ b/go/cmd/role/update.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package role
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a role",
+ Long: `Update a role`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ roleId := common.String(cmd, "role-id")
+ var req sggosdk.PatchedRole
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if req.ResourceName == nil {
+ req.ResourceName = sggosdk.Optional(roleId) // the API requires it on updates
+ }
+ response, err := c.AccessManagement.UpdateRole(ctx, org, roleId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Role updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("role-id", "", "The role ID.")
+ _ = cmd.MarkFlagRequired("role-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/rolebinding/read.go b/go/cmd/rolebinding/read.go
new file mode 100644
index 0000000..fde3854
--- /dev/null
+++ b/go/cmd/rolebinding/read.go
@@ -0,0 +1,32 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package rolebinding
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a role binding",
+ Long: `Get a role binding`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ roleBinding := common.String(cmd, "role-binding")
+ response, err := c.AccessManagement.ReadRoleBinding(ctx, org, roleBinding)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("role-binding", "default", "The role binding name.")
+ return cmd
+}
diff --git a/go/cmd/rolebinding/rolebinding.go b/go/cmd/rolebinding/rolebinding.go
new file mode 100644
index 0000000..5b28bf8
--- /dev/null
+++ b/go/cmd/rolebinding/rolebinding.go
@@ -0,0 +1,26 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package rolebinding
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewRoleBindingCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "role-binding",
+ Short: "Inspect role bindings",
+ Long: `Inspect role bindings`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a role binding`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/root.go b/go/cmd/root.go
index 370a890..8ca8980 100644
--- a/go/cmd/root.go
+++ b/go/cmd/root.go
@@ -3,18 +3,43 @@ package cmd
import (
"os"
+ "github.com/StackGuardian/sg-cli/cmd/apiaccess"
+ "github.com/StackGuardian/sg-cli/cmd/apitoken"
"github.com/StackGuardian/sg-cli/cmd/artifacts"
+ "github.com/StackGuardian/sg-cli/cmd/auditlog"
+ "github.com/StackGuardian/sg-cli/cmd/benchmarkreport"
+ "github.com/StackGuardian/sg-cli/cmd/billing"
+ "github.com/StackGuardian/sg-cli/cmd/chat"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-cli/cmd/connector"
+ "github.com/StackGuardian/sg-cli/cmd/connectorgroup"
+ "github.com/StackGuardian/sg-cli/cmd/organization"
+ "github.com/StackGuardian/sg-cli/cmd/policy"
+ "github.com/StackGuardian/sg-cli/cmd/resource"
+ "github.com/StackGuardian/sg-cli/cmd/role"
+ "github.com/StackGuardian/sg-cli/cmd/rolebinding"
+ "github.com/StackGuardian/sg-cli/cmd/runnergroup"
+ "github.com/StackGuardian/sg-cli/cmd/secret"
"github.com/StackGuardian/sg-cli/cmd/stack"
+ "github.com/StackGuardian/sg-cli/cmd/stackrun"
+ "github.com/StackGuardian/sg-cli/cmd/stacktemplate"
+ "github.com/StackGuardian/sg-cli/cmd/stackworkflow"
+ "github.com/StackGuardian/sg-cli/cmd/stackworkflowrun"
+ "github.com/StackGuardian/sg-cli/cmd/statebackend"
+ "github.com/StackGuardian/sg-cli/cmd/template"
+ "github.com/StackGuardian/sg-cli/cmd/user"
workflow "github.com/StackGuardian/sg-cli/cmd/workflow"
- "github.com/StackGuardian/sg-sdk-go/client"
- "github.com/StackGuardian/sg-sdk-go/option"
+ "github.com/StackGuardian/sg-cli/cmd/workflowgroup"
+ "github.com/StackGuardian/sg-cli/cmd/workflowrun"
+ "github.com/StackGuardian/sg-cli/cmd/workflowsteptemplate"
+ "github.com/StackGuardian/sg-cli/cmd/workflowtemplate"
"github.com/spf13/cobra"
)
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "sg-cli",
- Version: "2.1.0",
+ Version: "2.2.0",
Short: "sg-cli is CLI command for managing resources on Stackguardian platform.",
Long: `sg-cli is CLI command for managing resources on Stackguardian platform.
More information available at: https://docs.qa.stackguardian.io/docs/`,
@@ -29,17 +54,42 @@ func Execute() {
}
func init() {
-
- API_KEY := "apikey " + os.Getenv("SG_API_TOKEN")
- SG_BASE_URL := os.Getenv("SG_BASE_URL")
- if SG_BASE_URL == "" {
- SG_BASE_URL = "https://api.app.stackguardian.io"
- }
- c := client.NewClient(
- option.WithApiKey(API_KEY),
- option.WithBaseURL(SG_BASE_URL),
- )
+ // cmd.Println writes to stderr unless an output is set; responses and
+ // --output-json belong on stdout so they can be piped.
+ rootCmd.SetOut(os.Stdout)
+ c := common.NewClient()
rootCmd.AddCommand(workflow.NewWorkflowCmd(c))
rootCmd.AddCommand(stack.NewStackCmd(c))
rootCmd.AddCommand(artifacts.NewArtifactsCmd(c))
+ rootCmd.AddCommand(apiaccess.NewApiAccessCmd(c))
+ rootCmd.AddCommand(apitoken.NewApiTokenCmd(c))
+ rootCmd.AddCommand(auditlog.NewAuditLogCmd(c))
+ rootCmd.AddCommand(benchmarkreport.NewBenchmarkReportCmd(c))
+ rootCmd.AddCommand(billing.NewBillingCmd(c))
+ rootCmd.AddCommand(chat.NewChatCmd(c))
+ rootCmd.AddCommand(connector.NewConnectorCmd(c))
+ rootCmd.AddCommand(connectorgroup.NewConnectorGroupCmd(c))
+ rootCmd.AddCommand(organization.NewOrganizationCmd(c))
+ rootCmd.AddCommand(policy.NewPolicyCmd(c))
+ rootCmd.AddCommand(resource.NewResourceCmd(c))
+ rootCmd.AddCommand(role.NewRoleCmd(c))
+ rootCmd.AddCommand(rolebinding.NewRoleBindingCmd(c))
+ rootCmd.AddCommand(runnergroup.NewRunnerGroupCmd(c))
+ rootCmd.AddCommand(secret.NewSecretCmd(c))
+ rootCmd.AddCommand(stackrun.NewStackRunCmd(c))
+ rootCmd.AddCommand(stacktemplate.NewStackTemplateCmd(c))
+ rootCmd.AddCommand(stackworkflow.NewStackWorkflowCmd(c))
+ rootCmd.AddCommand(stackworkflowrun.NewStackWorkflowRunCmd(c))
+ rootCmd.AddCommand(statebackend.NewStateBackendCmd(c))
+ rootCmd.AddCommand(template.NewTemplateCmd(c))
+ rootCmd.AddCommand(user.NewUserCmd(c))
+ rootCmd.AddCommand(workflowgroup.NewWorkflowGroupCmd(c))
+ rootCmd.AddCommand(workflowrun.NewWorkflowRunCmd(c))
+ rootCmd.AddCommand(workflowsteptemplate.NewWorkflowStepTemplateCmd(c))
+ rootCmd.AddCommand(workflowtemplate.NewWorkflowTemplateCmd(c))
+}
+
+// RootCommand returns the root command with every sub-command attached (used by tests).
+func RootCommand() *cobra.Command {
+ return rootCmd
}
diff --git a/go/cmd/runnergroup/create.go b/go/cmd/runnergroup/create.go
new file mode 100644
index 0000000..1367b9c
--- /dev/null
+++ b/go/cmd/runnergroup/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new runner group",
+ Long: `Create a new runner group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.RunnerGroup
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.RunnerGroups.CreateNewRunnerGroup(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Runner group created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/runnergroup/delete.go b/go/cmd/runnergroup/delete.go
new file mode 100644
index 0000000..b40c68c
--- /dev/null
+++ b/go/cmd/runnergroup/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a runner group",
+ Long: `Delete a runner group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ response, err := c.RunnerGroups.DeleteRunnerGroup(ctx, org, runnerGroup)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Runner group deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/runnergroup/deregister_runner.go b/go/cmd/runnergroup/deregister_runner.go
new file mode 100644
index 0000000..eee6976
--- /dev/null
+++ b/go/cmd/runnergroup/deregister_runner.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeregisterRunnerCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "deregister-runner",
+ Short: "Deregister a runner from a runner group",
+ Long: `Deregister a runner from a runner group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ var body sggosdk.RunnerDeregister
+ if v := common.OptString(cmd, "runner-id"); v != nil {
+ body.RunnerId = sggosdk.Optional(*v)
+ }
+ if v := common.OptStringSlice(cmd, "container-instance-ids"); v != nil {
+ body.ContainerInstanceIds = sggosdk.Optional(v)
+ }
+ if v := common.OptBool(cmd, "force"); v != nil {
+ body.ForceDeregister = sggosdk.Optional(*v)
+ }
+ if err := c.RunnerGroups.DeregisterRunner(ctx, org, runnerGroup, &body); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Runner deregistered.")
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ cmd.Flags().String("runner-id", "", "Runner id.")
+ cmd.Flags().StringSlice("container-instance-ids", nil, "Container instance ids (comma-separated).")
+ cmd.Flags().Bool("force", false, "Force deregistration.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/runnergroup/list.go b/go/cmd/runnergroup/list.go
new file mode 100644
index 0000000..850d1b6
--- /dev/null
+++ b/go/cmd/runnergroup/list.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/runnergroups"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List runner groups",
+ Long: `List runner groups`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.RunnerGroups.ListAllRunnerGroups(ctx, org, &runnergroups.ListAllRunnerGroupsRequest{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), FilterResourceNames: common.OptString(cmd, "resource-names")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ return cmd
+}
diff --git a/go/cmd/runnergroup/read.go b/go/cmd/runnergroup/read.go
new file mode 100644
index 0000000..b9136e2
--- /dev/null
+++ b/go/cmd/runnergroup/read.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a runner group",
+ Long: `Get details of a runner group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ response, err := c.RunnerGroups.ReadRunnerGroup(ctx, org, runnerGroup, &sggosdk.ReadRunnerGroupRequest{GetActiveWorkflows: common.OptBool(cmd, "get-active-workflows"), GetActiveWorkflowsDetails: common.OptBool(cmd, "get-active-workflows-details")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ cmd.Flags().Bool("get-active-workflows", false, "Include the active workflows.")
+ cmd.Flags().Bool("get-active-workflows-details", false, "Include details of the active workflows.")
+ return cmd
+}
diff --git a/go/cmd/runnergroup/register.go b/go/cmd/runnergroup/register.go
new file mode 100644
index 0000000..fab4d41
--- /dev/null
+++ b/go/cmd/runnergroup/register.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRegisterCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "register",
+ Short: "Register a runner node (use the runner group's own token as the API key)",
+ Long: `Register a runner node (use the runner group's own token as the API key)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ response, err := c.RunnerGroups.RegisterRunner(ctx, org, runnerGroup)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Runner registered.")
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/runnergroup/runnergroup.go b/go/cmd/runnergroup/runnergroup.go
new file mode 100644
index 0000000..2444eef
--- /dev/null
+++ b/go/cmd/runnergroup/runnergroup.go
@@ -0,0 +1,42 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewRunnerGroupCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "runner-group",
+ Short: "Manage private runner groups",
+ Long: `Manage private runner groups`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new runner group
+ read Get details of a runner group
+ update Update a runner group
+ delete Delete a runner group
+ list List runner groups
+ register Register a runner node (use the runner group's own token as the API key)
+ storage-backend-auth Generate short-lived credentials for the runner group's storage backend
+ deregister-runner Deregister a runner from a runner group
+ update-runner-state Update the state of a runner (ACTIVE or DRAINING)`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ newRegisterCmd(c),
+ newStorageBackendAuthCmd(c),
+ newDeregisterRunnerCmd(c),
+ newUpdateRunnerStateCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/runnergroup/storage_backend_auth.go b/go/cmd/runnergroup/storage_backend_auth.go
new file mode 100644
index 0000000..4ab59f8
--- /dev/null
+++ b/go/cmd/runnergroup/storage_backend_auth.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newStorageBackendAuthCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "storage-backend-auth",
+ Short: "Generate short-lived credentials for the runner group's storage backend",
+ Long: `Generate short-lived credentials for the runner group's storage backend`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ response, err := c.RunnerGroups.GenerateStorageBackendAuth(ctx, org, runnerGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ return cmd
+}
diff --git a/go/cmd/runnergroup/update.go b/go/cmd/runnergroup/update.go
new file mode 100644
index 0000000..1e64bed
--- /dev/null
+++ b/go/cmd/runnergroup/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a runner group",
+ Long: `Update a runner group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ var req sggosdk.PatchedRunnerGroup
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.RunnerGroups.UpdateRunnerGroup(ctx, org, runnerGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Runner group updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/runnergroup/update_runner_state.go b/go/cmd/runnergroup/update_runner_state.go
new file mode 100644
index 0000000..302f678
--- /dev/null
+++ b/go/cmd/runnergroup/update_runner_state.go
@@ -0,0 +1,50 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package runnergroup
+
+import (
+ "context"
+ "fmt"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateRunnerStateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update-runner-state",
+ Short: "Update the state of a runner (ACTIVE or DRAINING)",
+ Long: `Update the state of a runner (ACTIVE or DRAINING)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ runnerGroup := common.String(cmd, "runner-group")
+ status := common.String(cmd, "status")
+ if status != "ACTIVE" && status != "DRAINING" {
+ return fmt.Errorf("--status must be ACTIVE or DRAINING, got %q", status)
+ }
+ body := sggosdk.RunnerStatus{Status: sggosdk.StatusEnum(status)}
+ if v := common.OptString(cmd, "runner-id"); v != nil {
+ body.RunnerId = sggosdk.Optional(*v)
+ }
+ if v := common.OptStringSlice(cmd, "container-instance-ids"); v != nil {
+ body.ContainerInstanceIds = sggosdk.Optional(v)
+ }
+ if err := c.RunnerGroups.UpdateRunnerState(ctx, org, runnerGroup, &body); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Runner state updated.")
+ return nil
+ },
+ }
+ cmd.Flags().String("runner-group", "", "The runner group name.")
+ _ = cmd.MarkFlagRequired("runner-group")
+ cmd.Flags().String("status", "", "New runner status (ACTIVE, DRAINING).")
+ _ = cmd.MarkFlagRequired("status")
+ cmd.Flags().String("runner-id", "", "Runner id.")
+ cmd.Flags().StringSlice("container-instance-ids", nil, "Container instance ids (comma-separated).")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/secret/create.go b/go/cmd/secret/create.go
new file mode 100644
index 0000000..0044e11
--- /dev/null
+++ b/go/cmd/secret/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new secret",
+ Long: `Create a new secret`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.Secret
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Secrets.CreateSecret(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Secret created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/secret/delete.go b/go/cmd/secret/delete.go
new file mode 100644
index 0000000..f2abd78
--- /dev/null
+++ b/go/cmd/secret/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a secret",
+ Long: `Delete a secret`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ secretId := common.String(cmd, "secret-id")
+ response, err := c.Secrets.DeleteSecret(ctx, org, secretId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Secret deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("secret-id", "", "The secret name.")
+ _ = cmd.MarkFlagRequired("secret-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/secret/list.go b/go/cmd/secret/list.go
new file mode 100644
index 0000000..c7ccfcb
--- /dev/null
+++ b/go/cmd/secret/list.go
@@ -0,0 +1,30 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List secrets",
+ Long: `List secrets`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.Secrets.ListAllSecrets(ctx, org)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/secret/read_bulk.go b/go/cmd/secret/read_bulk.go
new file mode 100644
index 0000000..3573b43
--- /dev/null
+++ b/go/cmd/secret/read_bulk.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/secrets"
+ "github.com/spf13/cobra"
+)
+
+func newReadBulkCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read-bulk",
+ Short: "Read several secrets by name",
+ Long: `Read several secrets by name`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ names := common.OptStringSlice(cmd, "names")
+ response, err := c.Secrets.ReadSecretsInBulk(ctx, org, &secrets.ReadSecretsInBulkRequest{ResourceNames: names})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().StringSlice("names", nil, "Secret names (comma-separated).")
+ _ = cmd.MarkFlagRequired("names")
+ return cmd
+}
diff --git a/go/cmd/secret/secret.go b/go/cmd/secret/secret.go
new file mode 100644
index 0000000..67e444f
--- /dev/null
+++ b/go/cmd/secret/secret.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewSecretCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "secret",
+ Short: "Manage secrets",
+ Long: `Manage secrets`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new secret
+ update Update a secret
+ delete Delete a secret
+ list List secrets
+ read-bulk Read several secrets by name`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ newReadBulkCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/secret/update.go b/go/cmd/secret/update.go
new file mode 100644
index 0000000..7d0cc69
--- /dev/null
+++ b/go/cmd/secret/update.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package secret
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a secret",
+ Long: `Update a secret`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ secretId := common.String(cmd, "secret-id")
+ var req sggosdk.PatchedSecret
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if req.ResourceName == nil {
+ req.ResourceName = sggosdk.Optional(secretId) // the API requires it on updates
+ }
+ response, err := c.Secrets.UpdateSecret(ctx, org, secretId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Secret updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("secret-id", "", "The secret name.")
+ _ = cmd.MarkFlagRequired("secret-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stack/apply/stack_apply.go b/go/cmd/stack/apply/stack_apply.go
index cde4e4e..17423fa 100644
--- a/go/cmd/stack/apply/stack_apply.go
+++ b/go/cmd/stack/apply/stack_apply.go
@@ -2,6 +2,7 @@ package apply
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
sggosdk "github.com/StackGuardian/sg-sdk-go"
@@ -42,7 +43,7 @@ func NewApplyCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
workflowRunPath := DASHBOARD_URL +
"/orgs/" +
diff --git a/go/cmd/stack/create/stack_create.go b/go/cmd/stack/create/stack_create.go
index 64b015d..e6b512c 100644
--- a/go/cmd/stack/create/stack_create.go
+++ b/go/cmd/stack/create/stack_create.go
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"strings"
@@ -91,7 +92,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Stack created successfully.")
diff --git a/go/cmd/stack/delete/stack_delete.go b/go/cmd/stack/delete/stack_delete.go
index f78e680..4317881 100644
--- a/go/cmd/stack/delete/stack_delete.go
+++ b/go/cmd/stack/delete/stack_delete.go
@@ -3,6 +3,7 @@ package delete
import (
"context"
"fmt"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"strings"
@@ -37,7 +38,7 @@ func NewDeleteCmd(c *client.Client) *cobra.Command {
}
if opts.OutputJson && response != nil {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Stack deleted successfully.")
},
diff --git a/go/cmd/stack/destroy/stack_destroy.go b/go/cmd/stack/destroy/stack_destroy.go
index c81d5c5..972e9a9 100644
--- a/go/cmd/stack/destroy/stack_destroy.go
+++ b/go/cmd/stack/destroy/stack_destroy.go
@@ -2,6 +2,7 @@ package destroy
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
sggosdk "github.com/StackGuardian/sg-sdk-go"
@@ -42,7 +43,7 @@ func NewDestroyCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
workflowRunPath := DASHBOARD_URL +
"/orgs/" +
diff --git a/go/cmd/stack/extra/compare.go b/go/cmd/stack/extra/compare.go
new file mode 100644
index 0000000..975c352
--- /dev/null
+++ b/go/cmd/stack/extra/compare.go
@@ -0,0 +1,57 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stacks"
+ "github.com/spf13/cobra"
+)
+
+func newCompareCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "compare -- payload.json",
+ Short: "Compare a stack against a stack template without applying changes",
+ Long: `Compare a stack against a stack template without applying changes`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ var req stacks.CompareStackRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if v := common.OptString(cmd, "target-template-group-id"); v != nil {
+ req.TargetTemplateGroupId = *v
+ }
+ if v := common.OptString(cmd, "upgrade-mode"); v != nil {
+ req.UpgradeMode = v
+ }
+ if req.TargetTemplateGroupId == "" {
+ return errors.New("provide --target-template-group-id or a payload with targetTemplateGroupId")
+ }
+ response, err := c.Stacks.CompareStack(ctx, org, stackId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkFlagRequired("stack-id")
+ cmd.Flags().String("target-template-group-id", "", "Stack template to compare against.")
+ cmd.Flags().String("upgrade-mode", "", "Upgrade mode to simulate.")
+ common.AddPayloadFlags(cmd)
+ return cmd
+}
diff --git a/go/cmd/stack/extra/extra.go b/go/cmd/stack/extra/extra.go
new file mode 100644
index 0000000..b986485
--- /dev/null
+++ b/go/cmd/stack/extra/extra.go
@@ -0,0 +1,18 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+// AddCommands attaches the generated sub-commands to an existing command group.
+func AddCommands(cmd *cobra.Command, c *client.Client) {
+ cmd.AddCommand(
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newListCmd(c),
+ newCompareCmd(c),
+ )
+}
diff --git a/go/cmd/stack/extra/list.go b/go/cmd/stack/extra/list.go
new file mode 100644
index 0000000..5e79bf8
--- /dev/null
+++ b/go/cmd/stack/extra/list.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the stacks in a workflow group",
+ Long: `List the stacks in a workflow group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ response, err := c.Stacks.ListAllStacks(ctx, org, workflowGroup, &sggosdk.ListAllStacksRequest{Description: common.OptString(cmd, "description"), ResourceNames: common.OptString(cmd, "resource-names"), Tags: common.OptString(cmd, "tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ cmd.Flags().String("tags", "", "Filter by tags.")
+ return cmd
+}
diff --git a/go/cmd/stack/extra/read.go b/go/cmd/stack/extra/read.go
new file mode 100644
index 0000000..56a4337
--- /dev/null
+++ b/go/cmd/stack/extra/read.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a stack",
+ Long: `Get details of a stack`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ response, err := c.Stacks.ReadStack(ctx, org, stackId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkFlagRequired("stack-id")
+ return cmd
+}
diff --git a/go/cmd/stack/extra/update.go b/go/cmd/stack/extra/update.go
new file mode 100644
index 0000000..a039df7
--- /dev/null
+++ b/go/cmd/stack/extra/update.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a stack",
+ Long: `Update a stack`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ var req sggosdk.PatchedStack
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Stacks.UpdateStack(ctx, org, stackId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkFlagRequired("stack-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stack/outputs/stack_outputs.go b/go/cmd/stack/outputs/stack_outputs.go
index caf80c6..f8d8b64 100644
--- a/go/cmd/stack/outputs/stack_outputs.go
+++ b/go/cmd/stack/outputs/stack_outputs.go
@@ -2,6 +2,7 @@ package outputs
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"github.com/StackGuardian/sg-sdk-go/client"
@@ -25,7 +26,7 @@ func NewOutputsCmd(c *client.Client) *cobra.Command {
cmd.Println(err)
os.Exit(-1)
}
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
},
}
diff --git a/go/cmd/stack/stack.go b/go/cmd/stack/stack.go
index dfaa630..12c0d99 100644
--- a/go/cmd/stack/stack.go
+++ b/go/cmd/stack/stack.go
@@ -7,6 +7,7 @@ import (
"github.com/StackGuardian/sg-cli/cmd/stack/create"
"github.com/StackGuardian/sg-cli/cmd/stack/delete"
"github.com/StackGuardian/sg-cli/cmd/stack/destroy"
+ stackextra "github.com/StackGuardian/sg-cli/cmd/stack/extra"
"github.com/StackGuardian/sg-cli/cmd/stack/outputs"
"github.com/StackGuardian/sg-sdk-go/client"
"github.com/spf13/cobra"
@@ -40,5 +41,7 @@ func NewStackCmd(c *client.Client) *cobra.Command {
stackCmd.AddCommand(delete.NewDeleteCmd(c))
stackCmd.AddCommand(apply.NewApplyCmd(c))
+ stackextra.AddCommands(stackCmd, c)
+
return stackCmd
}
diff --git a/go/cmd/stackrun/create.go b/go/cmd/stackrun/create.go
new file mode 100644
index 0000000..16f2c3d
--- /dev/null
+++ b/go/cmd/stackrun/create.go
@@ -0,0 +1,53 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Trigger a stack run (use --action-type or a payload)",
+ Long: `Trigger a stack run (use --action-type or a payload)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ actionType := common.String(cmd, "action-type")
+ var req sggosdk.StackAction
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if actionType != "" {
+ req.ActionType = actionType
+ }
+ if req.ActionType == "" {
+ return errors.New("provide --action-type or a payload with ActionType")
+ }
+ response, err := c.StackRuns.CreateStackRun(ctx, org, stackId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack run created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("action-type", "", "Action to run, e.g. APPLY or DESTROY.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackrun/list.go b/go/cmd/stackrun/list.go
new file mode 100644
index 0000000..742e7da
--- /dev/null
+++ b/go/cmd/stackrun/list.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the runs of a stack",
+ Long: `List the runs of a stack`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ response, err := c.StackRuns.ListAllStackRuns(ctx, org, stackId, workflowGroup, &sggosdk.ListAllStackRunsRequest{Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ return cmd
+}
diff --git a/go/cmd/stackrun/read.go b/go/cmd/stackrun/read.go
new file mode 100644
index 0000000..27adfa5
--- /dev/null
+++ b/go/cmd/stackrun/read.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a stack run",
+ Long: `Get a stack run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ runId := common.String(cmd, "run-id")
+ response, err := c.StackRuns.ReadStackRun(ctx, org, stackId, runId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The stack run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ return cmd
+}
diff --git a/go/cmd/stackrun/stackrun.go b/go/cmd/stackrun/stackrun.go
new file mode 100644
index 0000000..e99200e
--- /dev/null
+++ b/go/cmd/stackrun/stackrun.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackrun
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewStackRunCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "stack-run",
+ Short: "Trigger and inspect stack runs",
+ Long: `Trigger and inspect stack runs`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Trigger a stack run (use --action-type or a payload)
+ read Get a stack run
+ list List the runs of a stack`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.PersistentFlags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkPersistentFlagRequired("workflow-group")
+ cmd.PersistentFlags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkPersistentFlagRequired("stack-id")
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/create.go b/go/cmd/stacktemplate/create.go
new file mode 100644
index 0000000..c246ccd
--- /dev/null
+++ b/go/cmd/stacktemplate/create.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stacktemplates"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a stack template",
+ Long: `Create a stack template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ createFirstRevision := common.Bool(cmd, "create-first-revision")
+ var req stacktemplates.CreateStackTemplateRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackTemplates.CreateStackTemplate(ctx, org, createFirstRevision, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack template created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().Bool("create-first-revision", true, "Also create the first revision of the template.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/delete.go b/go/cmd/stacktemplate/delete.go
new file mode 100644
index 0000000..0db09cb
--- /dev/null
+++ b/go/cmd/stacktemplate/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a stack template",
+ Long: `Delete a stack template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ if err := c.StackTemplates.DeleteStackTemplate(ctx, org, templateId); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Stack template deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/read.go b/go/cmd/stacktemplate/read.go
new file mode 100644
index 0000000..8c78321
--- /dev/null
+++ b/go/cmd/stacktemplate/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a stack template",
+ Long: `Get a stack template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ response, err := c.StackTemplates.ReadStackTemplate(ctx, org, templateId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/revisions_create.go b/go/cmd/stacktemplate/revisions_create.go
new file mode 100644
index 0000000..0dabfbd
--- /dev/null
+++ b/go/cmd/stacktemplate/revisions_create.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stacktemplaterevisions"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new revision of a stack template",
+ Long: `Create a new revision of a stack template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req stacktemplaterevisions.CreateStackTemplateRevisionRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackTemplateRevisions.CreateStackTemplateRevision(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/revisions_delete.go b/go/cmd/stacktemplate/revisions_delete.go
new file mode 100644
index 0000000..0ed7ed6
--- /dev/null
+++ b/go/cmd/stacktemplate/revisions_delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a stack template revision",
+ Long: `Delete a stack template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ keepParentTemplate := common.Bool(cmd, "keep-parent-template")
+ if err := c.StackTemplateRevisions.DeleteStackTemplateRevision(ctx, org, revisionId, keepParentTemplate); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Revision deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ cmd.Flags().Bool("keep-parent-template", false, "Keep the parent template when deleting its last revision.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/revisions_read.go b/go/cmd/stacktemplate/revisions_read.go
new file mode 100644
index 0000000..62091e5
--- /dev/null
+++ b/go/cmd/stacktemplate/revisions_read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a stack template revision",
+ Long: `Get a stack template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ response, err := c.StackTemplateRevisions.ReadStackTemplateRevision(ctx, org, revisionId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/revisions_update.go b/go/cmd/stacktemplate/revisions_update.go
new file mode 100644
index 0000000..32eb6fb
--- /dev/null
+++ b/go/cmd/stacktemplate/revisions_update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stacktemplaterevisions"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a stack template revision",
+ Long: `Update a stack template revision`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ var req stacktemplaterevisions.UpdateStackTemplateRevisionRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackTemplateRevisions.UpdateStackTemplateRevision(ctx, org, revisionId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/stacktemplate.go b/go/cmd/stacktemplate/stacktemplate.go
new file mode 100644
index 0000000..149ff52
--- /dev/null
+++ b/go/cmd/stacktemplate/stacktemplate.go
@@ -0,0 +1,55 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewStackTemplateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "stack-template",
+ Short: "Manage stack (IaC group) templates",
+ Long: `Manage stack (IaC group) templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a stack template
+ create Create a stack template
+ update Update a stack template
+ delete Delete a stack template
+ revisions Manage revisions of stack (IaC group) templates`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ newCreateCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newRevisionsCmd(c),
+ )
+ return cmd
+}
+func newRevisionsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "revisions",
+ Short: "Manage revisions of stack (IaC group) templates",
+ Long: `Manage revisions of stack (IaC group) templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new revision of a stack template
+ read Get a stack template revision
+ update Update a stack template revision
+ delete Delete a stack template revision`)
+ },
+ }
+ cmd.AddCommand(
+ newRevisionsCreateCmd(c),
+ newRevisionsReadCmd(c),
+ newRevisionsUpdateCmd(c),
+ newRevisionsDeleteCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/stacktemplate/update.go b/go/cmd/stacktemplate/update.go
new file mode 100644
index 0000000..ec41c6b
--- /dev/null
+++ b/go/cmd/stacktemplate/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stacktemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stacktemplates"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a stack template",
+ Long: `Update a stack template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req stacktemplates.UpdateStackTemplateRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackTemplates.UpdateStackTemplate(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack template updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_create.go b/go/cmd/stackworkflow/artifacts_create.go
new file mode 100644
index 0000000..2cc25dc
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_create.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create or replace an artifact with the JSON payload as its content",
+ Long: `Create or replace an artifact with the JSON payload as its content`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ var req interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflows.CreateStackWorkflowArtifact(ctx, org, stackId, workflowId, workflowGroup, artifactId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_delete.go b/go/cmd/stackworkflow/artifacts_delete.go
new file mode 100644
index 0000000..35a823a
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_delete.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete an artifact",
+ Long: `Delete an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.StackWorkflows.DeleteStackWorkflowArtifact(ctx, org, stackId, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_get_url.go b/go/cmd/stackworkflow/artifacts_get_url.go
new file mode 100644
index 0000000..e98f9e5
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_get_url.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsGetUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "get-url",
+ Short: "Get a signed download URL for an artifact",
+ Long: `Get a signed download URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactPath := common.String(cmd, "artifact-path")
+ response, err := c.StackWorkflows.GetStackWorkflowArtifactUrl(ctx, org, stackId, workflowId, workflowGroup, &workflows.GetWorkflowArtifactRequest{ArtifactPath: artifactPath})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-path", "", "Path of the artifact.")
+ _ = cmd.MarkFlagRequired("artifact-path")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_list.go b/go/cmd/stackworkflow/artifacts_list.go
new file mode 100644
index 0000000..3965f1c
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_list.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the artifacts of a stack workflow",
+ Long: `List the artifacts of a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.StackWorkflows.ListAllStackWorkflowsArtifacts(ctx, org, stackId, workflowId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_lock.go b/go/cmd/stackworkflow/artifacts_lock.go
new file mode 100644
index 0000000..9515a63
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_lock.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsLockCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "lock",
+ Short: "Lock the stack workflow on an artifact",
+ Long: `Lock the stack workflow on an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.StackWorkflows.LockStackWorkflowArtifact(ctx, org, stackId, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact locked.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_read.go b/go/cmd/stackworkflow/artifacts_read.go
new file mode 100644
index 0000000..14c0e4e
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_read.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Read an artifact's content (or a signed URL on private runners)",
+ Long: `Read an artifact's content (or a signed URL on private runners)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.StackWorkflows.ReadStackWorkflowArtifact(ctx, org, stackId, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/artifacts_unlock.go b/go/cmd/stackworkflow/artifacts_unlock.go
new file mode 100644
index 0000000..474d93f
--- /dev/null
+++ b/go/cmd/stackworkflow/artifacts_unlock.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsUnlockCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "unlock",
+ Short: "Release the stack workflow's lock on an artifact",
+ Long: `Release the stack workflow's lock on an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ artifactId := common.String(cmd, "artifact-id")
+ response, err := c.StackWorkflows.UnlockStackWorkflowArtifact(ctx, org, stackId, workflowId, workflowGroup, artifactId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact unlocked.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID (path).")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/compare.go b/go/cmd/stackworkflow/compare.go
new file mode 100644
index 0000000..246252b
--- /dev/null
+++ b/go/cmd/stackworkflow/compare.go
@@ -0,0 +1,58 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newCompareCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "compare -- payload.json",
+ Short: "Compare a stack workflow against a template without applying changes",
+ Long: `Compare a stack workflow against a template without applying changes`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ var req workflows.CompareWorkflowRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if v := common.OptString(cmd, "target-template-id"); v != nil {
+ req.TargetTemplateId = *v
+ }
+ if v := common.OptString(cmd, "upgrade-mode"); v != nil {
+ req.UpgradeMode = v
+ }
+ if req.TargetTemplateId == "" {
+ return errors.New("provide --target-template-id or a payload with targetTemplateId")
+ }
+ response, err := c.StackWorkflows.CompareStackWorkflow(ctx, org, stackId, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("target-template-id", "", "Template to compare against.")
+ cmd.Flags().String("upgrade-mode", "", "Upgrade mode to simulate.")
+ common.AddPayloadFlags(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/create.go b/go/cmd/stackworkflow/create.go
new file mode 100644
index 0000000..314dafe
--- /dev/null
+++ b/go/cmd/stackworkflow/create.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a workflow inside a stack",
+ Long: `Create a workflow inside a stack`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ var req workflows.Workflow
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflows.CreateStackWorkflow(ctx, org, stackId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/delete.go b/go/cmd/stackworkflow/delete.go
new file mode 100644
index 0000000..efacebf
--- /dev/null
+++ b/go/cmd/stackworkflow/delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a stack workflow",
+ Long: `Delete a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ if err := c.StackWorkflows.DeleteStackWorkflow(ctx, org, stackId, workflowId, workflowGroup); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Stack workflow deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/file_upload_url.go b/go/cmd/stackworkflow/file_upload_url.go
new file mode 100644
index 0000000..7561093
--- /dev/null
+++ b/go/cmd/stackworkflow/file_upload_url.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newFileUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "file-upload-url",
+ Short: "Get a signed URL to upload a file to a stack workflow",
+ Long: `Get a signed URL to upload a file to a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ filename := common.String(cmd, "filename")
+ response, err := c.StackWorkflows.GetFileUploadUrlForStackWorkflow(ctx, org, stackId, workflowId, workflowGroup, &workflows.GetFileUploadUrlRequest{Filename: filename, Folder: common.OptString(cmd, "folder")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("filename", "", "Name of the file to upload.")
+ _ = cmd.MarkFlagRequired("filename")
+ cmd.Flags().String("folder", "", "Folder to upload the file into.")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/list.go b/go/cmd/stackworkflow/list.go
new file mode 100644
index 0000000..82e2220
--- /dev/null
+++ b/go/cmd/stackworkflow/list.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the workflows of a stack",
+ Long: `List the workflows of a stack`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ response, err := c.StackWorkflows.ListAllStackWorkflows(ctx, org, stackId, workflowGroup, &sggosdk.ListAllStackWorkflowsRequest{Description: common.OptString(cmd, "description"), IacTemplateId: common.OptString(cmd, "iac-template-id"), LatestWfRunStatuses: common.OptInt(cmd, "latest-wf-run-statuses"), ResourceNames: common.OptString(cmd, "resource-names"), RunnerNames: common.OptString(cmd, "runner-names"), Tags: common.OptString(cmd, "tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("iac-template-id", "", "Filter by IaC template id.")
+ cmd.Flags().Int("latest-wf-run-statuses", 0, "Filter by latest workflow run status.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ cmd.Flags().String("runner-names", "", "Filter by runner names.")
+ cmd.Flags().String("tags", "", "Filter by tags.")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/outputs.go b/go/cmd/stackworkflow/outputs.go
new file mode 100644
index 0000000..94e7bc1
--- /dev/null
+++ b/go/cmd/stackworkflow/outputs.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newOutputsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "outputs",
+ Short: "Get the outputs of a stack workflow",
+ Long: `Get the outputs of a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.StackWorkflows.StackWorkflowOutputs(ctx, org, stackId, workflowId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/read.go b/go/cmd/stackworkflow/read.go
new file mode 100644
index 0000000..485d1d6
--- /dev/null
+++ b/go/cmd/stackworkflow/read.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a stack workflow",
+ Long: `Get a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.StackWorkflows.ReadStackWorkflow(ctx, org, stackId, workflowId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/stackworkflow.go b/go/cmd/stackworkflow/stackworkflow.go
new file mode 100644
index 0000000..859afff
--- /dev/null
+++ b/go/cmd/stackworkflow/stackworkflow.go
@@ -0,0 +1,79 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewStackWorkflowCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "stack-workflow",
+ Short: "Manage the workflows that belong to a stack",
+ Long: `Manage the workflows that belong to a stack`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a workflow inside a stack
+ read Get a stack workflow
+ update Update a stack workflow
+ delete Delete a stack workflow
+ list List the workflows of a stack
+ outputs Get the outputs of a stack workflow
+ tfstate-upload-url Get a signed URL to upload a Terraform state file
+ file-upload-url Get a signed URL to upload a file to a stack workflow
+ compare Compare a stack workflow against a template without applying changes
+ vcs-triggers Create VCS webhook triggers for a stack workflow
+ artifacts Manage the artifacts of a stack workflow`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.PersistentFlags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkPersistentFlagRequired("workflow-group")
+ cmd.PersistentFlags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkPersistentFlagRequired("stack-id")
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ newOutputsCmd(c),
+ newTfstateUploadUrlCmd(c),
+ newFileUploadUrlCmd(c),
+ newCompareCmd(c),
+ newVcsTriggersCmd(c),
+ newArtifactsCmd(c),
+ )
+ return cmd
+}
+func newArtifactsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "artifacts",
+ Short: "Manage the artifacts of a stack workflow",
+ Long: `Manage the artifacts of a stack workflow`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List the artifacts of a stack workflow
+ get-url Get a signed download URL for an artifact
+ read Read an artifact's content (or a signed URL on private runners)
+ create Create or replace an artifact with the JSON payload as its content
+ delete Delete an artifact
+ lock Lock the stack workflow on an artifact
+ unlock Release the stack workflow's lock on an artifact`)
+ },
+ }
+ cmd.PersistentFlags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkPersistentFlagRequired("workflow-id")
+ cmd.AddCommand(
+ newArtifactsListCmd(c),
+ newArtifactsGetUrlCmd(c),
+ newArtifactsReadCmd(c),
+ newArtifactsCreateCmd(c),
+ newArtifactsDeleteCmd(c),
+ newArtifactsLockCmd(c),
+ newArtifactsUnlockCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/tfstate_upload_url.go b/go/cmd/stackworkflow/tfstate_upload_url.go
new file mode 100644
index 0000000..b8df44c
--- /dev/null
+++ b/go/cmd/stackworkflow/tfstate_upload_url.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newTfstateUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "tfstate-upload-url",
+ Short: "Get a signed URL to upload a Terraform state file",
+ Long: `Get a signed URL to upload a Terraform state file`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.StackWorkflows.GetSignedUrlToUploadTfstateFileForStackWorkflow(ctx, org, stackId, workflowId, workflowGroup, &sggosdk.GetSignedUrlToUploadTfstateFileForStackWorkflowRequest{Filename: common.OptString(cmd, "filename")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("filename", "", "Name of the file to upload (default tfstate.json).")
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/update.go b/go/cmd/stackworkflow/update.go
new file mode 100644
index 0000000..4c295c3
--- /dev/null
+++ b/go/cmd/stackworkflow/update.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a stack workflow",
+ Long: `Update a stack workflow`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ var req sggosdk.PatchedWorkflow
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflows.UpdateStackWorkflow(ctx, org, stackId, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflow/vcs_triggers.go b/go/cmd/stackworkflow/vcs_triggers.go
new file mode 100644
index 0000000..27d53a4
--- /dev/null
+++ b/go/cmd/stackworkflow/vcs_triggers.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflow
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newVcsTriggersCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "vcs-triggers -- payload.json",
+ Short: "Create VCS webhook triggers for a stack workflow",
+ Long: `Create VCS webhook triggers for a stack workflow`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ var req workflows.CreateVcsTriggersRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflows.CreateVcsTriggersForStackWorkflow(ctx, org, stackId, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "VCS triggers created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/approve.go b/go/cmd/stackworkflowrun/approve.go
new file mode 100644
index 0000000..705ca2d
--- /dev/null
+++ b/go/cmd/stackworkflowrun/approve.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newApproveCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "approve",
+ Short: "Approve (or, with --reject, reject) a stack workflow run waiting for approval",
+ Long: `Approve (or, with --reject, reject) a stack workflow run waiting for approval`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ reject := common.Bool(cmd, "reject")
+ approve := !reject
+ body := sggosdk.WorkflowRunApproval{Approve: &approve, Message: common.OptString(cmd, "message"), ApprovalStep: common.OptString(cmd, "approval-step"), ReasonForApprovalRequired: common.OptString(cmd, "reason")}
+ if err := c.StackWorkflowRuns.ApproveStackWorkflowRun(ctx, org, stackId, workflowId, workflowGroup, runId, &body); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Approval decision submitted.")
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ cmd.Flags().Bool("reject", false, "Reject instead of approve.")
+ cmd.Flags().String("message", "", "Message to attach to the decision.")
+ cmd.Flags().String("approval-step", "", "Name of the approval step.")
+ cmd.Flags().String("reason", "", "Reason the approval was required.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/create.go b/go/cmd/stackworkflowrun/create.go
new file mode 100644
index 0000000..07a89db
--- /dev/null
+++ b/go/cmd/stackworkflowrun/create.go
@@ -0,0 +1,46 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Trigger a run of a stack workflow (payload optional)",
+ Long: `Trigger a run of a stack workflow (payload optional)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ var req sggosdk.WorkflowRun
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ response, err := c.StackWorkflowRuns.CreateStackWorkflowRun(ctx, org, stackId, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow run created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/delete.go b/go/cmd/stackworkflowrun/delete.go
new file mode 100644
index 0000000..7aa4092
--- /dev/null
+++ b/go/cmd/stackworkflowrun/delete.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Cancel a stack workflow run through the DELETE endpoint",
+ Long: `Cancel a stack workflow run through the DELETE endpoint`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ response, err := c.StackWorkflowRuns.DeleteStackWorkflowRun(ctx, org, stackId, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow run cancelled.")
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/facts_create.go b/go/cmd/stackworkflowrun/facts_create.go
new file mode 100644
index 0000000..724750d
--- /dev/null
+++ b/go/cmd/stackworkflowrun/facts_create.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create or replace the facts of a stack workflow run",
+ Long: `Create or replace the facts of a stack workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ var req map[string]interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflowRunFacts.CreateStackWorkflowRunFacts(ctx, org, stackId, workflowId, workflowGroup, runId, factsId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow run facts created.")
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/facts_read.go b/go/cmd/stackworkflowrun/facts_read.go
new file mode 100644
index 0000000..f276c72
--- /dev/null
+++ b/go/cmd/stackworkflowrun/facts_read.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get the facts of a stack workflow run",
+ Long: `Get the facts of a stack workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ response, err := c.StackWorkflowRunFacts.GetStackWorkflowRunFacts(ctx, org, stackId, workflowId, workflowGroup, runId, factsId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/facts_update.go b/go/cmd/stackworkflowrun/facts_update.go
new file mode 100644
index 0000000..81cc7d9
--- /dev/null
+++ b/go/cmd/stackworkflowrun/facts_update.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update the facts of a stack workflow run",
+ Long: `Update the facts of a stack workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ var req map[string]interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflowRunFacts.UpdateStackWorkflowRunFacts(ctx, org, stackId, workflowId, workflowGroup, runId, factsId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow run facts updated.")
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/list.go b/go/cmd/stackworkflowrun/list.go
new file mode 100644
index 0000000..797bd1c
--- /dev/null
+++ b/go/cmd/stackworkflowrun/list.go
@@ -0,0 +1,54 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/stackworkflowruns"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the runs of a stack workflow",
+ Long: `List the runs of a stack workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.StackWorkflowRuns.ListAllStackWorkflowRuns(ctx, org, stackId, workflowId, workflowGroup, &stackworkflowruns.ListAllStackWorkflowRunsRequest{
+ Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), CreatedAfter: common.OptString(cmd, "created-after"), ParentKSUID: common.OptString(cmd, "parent-ksuid"),
+ ResourceNames: common.OptString(cmd, "resource-names"), TemplateId: common.OptString(cmd, "template-id"), UseMarketplaceTemplate: common.OptString(cmd, "use-marketplace-template"), Author: common.OptString(cmd, "author"),
+ Approver: common.OptString(cmd, "approver"), LatestStatus: common.OptString(cmd, "latest-status"), RepoId: common.OptString(cmd, "repo-id"), Ref: common.OptString(cmd, "ref"), TerraformAction: common.OptString(cmd, "terraform-action"),
+ RunnerType: common.OptString(cmd, "runner-type"), ContextTags: common.OptString(cmd, "context-tags"),
+ })
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("created-after", "", "Only runs created after this Unix timestamp in milliseconds.")
+ cmd.Flags().String("parent-ksuid", "", "KSUID of the parent workflow.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names (comma-separated).")
+ cmd.Flags().String("template-id", "", "Filter by IaC template id.")
+ cmd.Flags().String("use-marketplace-template", "", "Filter by marketplace template usage (true/false).")
+ cmd.Flags().String("author", "", "Filter by authors (comma-separated).")
+ cmd.Flags().String("approver", "", "Filter by approvers (comma-separated).")
+ cmd.Flags().String("latest-status", "", "Filter by latest status (comma-separated).")
+ cmd.Flags().String("repo-id", "", "Filter by VCS repository.")
+ cmd.Flags().String("ref", "", "Filter by VCS ref.")
+ cmd.Flags().String("terraform-action", "", "Filter by Terraform action (comma-separated).")
+ cmd.Flags().String("runner-type", "", "Filter by runner type.")
+ cmd.Flags().String("context-tags", "", "Filter by context tags as key or key:value (comma-separated).")
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/logs.go b/go/cmd/stackworkflowrun/logs.go
new file mode 100644
index 0000000..6aae008
--- /dev/null
+++ b/go/cmd/stackworkflowrun/logs.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newLogsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "logs",
+ Short: "Get the logs of a stack workflow run",
+ Long: `Get the logs of a stack workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ response, err := c.StackWorkflowRuns.ReadStackWorkflowRunLogs(ctx, org, stackId, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/read.go b/go/cmd/stackworkflowrun/read.go
new file mode 100644
index 0000000..e54b827
--- /dev/null
+++ b/go/cmd/stackworkflowrun/read.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a stack workflow run",
+ Long: `Get a stack workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ response, err := c.StackWorkflowRuns.ReadStackWorkflowRun(ctx, org, stackId, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/stackworkflowrun.go b/go/cmd/stackworkflowrun/stackworkflowrun.go
new file mode 100644
index 0000000..9118dda
--- /dev/null
+++ b/go/cmd/stackworkflowrun/stackworkflowrun.go
@@ -0,0 +1,67 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewStackWorkflowRunCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "stack-workflow-run",
+ Short: "Trigger, inspect and approve runs of a stack workflow",
+ Long: `Trigger, inspect and approve runs of a stack workflow`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Trigger a run of a stack workflow (payload optional)
+ read Get a stack workflow run
+ update Update a stack workflow run
+ delete Cancel a stack workflow run through the DELETE endpoint
+ logs Get the logs of a stack workflow run
+ approve Approve (or, with --reject, reject) a stack workflow run waiting for approval
+ list List the runs of a stack workflow
+ facts Read and write the facts of a stack workflow run`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.PersistentFlags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkPersistentFlagRequired("workflow-group")
+ cmd.PersistentFlags().String("stack-id", "", "The stack ID.")
+ _ = cmd.MarkPersistentFlagRequired("stack-id")
+ cmd.PersistentFlags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkPersistentFlagRequired("workflow-id")
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newLogsCmd(c),
+ newApproveCmd(c),
+ newListCmd(c),
+ newFactsCmd(c),
+ )
+ return cmd
+}
+func newFactsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "facts",
+ Short: "Read and write the facts of a stack workflow run",
+ Long: `Read and write the facts of a stack workflow run`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get the facts of a stack workflow run
+ create Create or replace the facts of a stack workflow run
+ update Update the facts of a stack workflow run`)
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ cmd.AddCommand(
+ newFactsReadCmd(c),
+ newFactsCreateCmd(c),
+ newFactsUpdateCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/stackworkflowrun/update.go b/go/cmd/stackworkflowrun/update.go
new file mode 100644
index 0000000..f0b3231
--- /dev/null
+++ b/go/cmd/stackworkflowrun/update.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package stackworkflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a stack workflow run",
+ Long: `Update a stack workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ stackId := common.String(cmd, "stack-id")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ var req sggosdk.PatchedWorkflowRun
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StackWorkflowRuns.UpdateStackWorkflowRun(ctx, org, stackId, workflowId, workflowGroup, runId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Stack workflow run updated successfully.")
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/statebackend/create.go b/go/cmd/statebackend/create.go
new file mode 100644
index 0000000..55a50dd
--- /dev/null
+++ b/go/cmd/statebackend/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/statebackends"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new state backend",
+ Long: `Create a new state backend`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req statebackends.StateBackend
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StateBackends.CreateStateBackend(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "State backend created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/statebackend/delete.go b/go/cmd/statebackend/delete.go
new file mode 100644
index 0000000..3dee392
--- /dev/null
+++ b/go/cmd/statebackend/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a state backend",
+ Long: `Delete a state backend`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ stateBackend := common.String(cmd, "state-backend")
+ response, err := c.StateBackends.DeleteStateBackend(ctx, org, stateBackend)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "State backend deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("state-backend", "", "The state backend name.")
+ _ = cmd.MarkFlagRequired("state-backend")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/statebackend/list.go b/go/cmd/statebackend/list.go
new file mode 100644
index 0000000..4bc8aa8
--- /dev/null
+++ b/go/cmd/statebackend/list.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/statebackends"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List state backends",
+ Long: `List state backends`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.StateBackends.ListAllStateBackends(ctx, org, &statebackends.ListAllStateBackendsRequest{Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), SearchQuery: common.OptString(cmd, "search-query")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("search-query", "", "Search by resource name, tags or description.")
+ return cmd
+}
diff --git a/go/cmd/statebackend/list_statefiles.go b/go/cmd/statebackend/list_statefiles.go
new file mode 100644
index 0000000..0fb135a
--- /dev/null
+++ b/go/cmd/statebackend/list_statefiles.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/statebackends"
+ "github.com/spf13/cobra"
+)
+
+func newListStatefilesCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-statefiles",
+ Short: "List the state files in a storage backend",
+ Long: `List the state files in a storage backend`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ config := common.String(cmd, "config")
+ response, err := c.StateBackends.ListStatefiles(ctx, org, &statebackends.ListStatefilesRequest{Config: config})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("config", "", "Base64-encoded JSON StateBackendConfig.")
+ _ = cmd.MarkFlagRequired("config")
+ return cmd
+}
diff --git a/go/cmd/statebackend/read.go b/go/cmd/statebackend/read.go
new file mode 100644
index 0000000..b3d25a3
--- /dev/null
+++ b/go/cmd/statebackend/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a state backend",
+ Long: `Get details of a state backend`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ stateBackend := common.String(cmd, "state-backend")
+ response, err := c.StateBackends.ReadStateBackend(ctx, org, stateBackend)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("state-backend", "", "The state backend name.")
+ _ = cmd.MarkFlagRequired("state-backend")
+ return cmd
+}
diff --git a/go/cmd/statebackend/statebackend.go b/go/cmd/statebackend/statebackend.go
new file mode 100644
index 0000000..1f724f6
--- /dev/null
+++ b/go/cmd/statebackend/statebackend.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewStateBackendCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "state-backend",
+ Short: "Manage state backends (S3 or Azure Blob storage for state files)",
+ Long: `Manage state backends (S3 or Azure Blob storage for state files)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new state backend
+ read Get details of a state backend
+ update Update a state backend
+ delete Delete a state backend
+ list List state backends
+ list-statefiles List the state files in a storage backend`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newListCmd(c),
+ newListStatefilesCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/statebackend/update.go b/go/cmd/statebackend/update.go
new file mode 100644
index 0000000..3296d8a
--- /dev/null
+++ b/go/cmd/statebackend/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package statebackend
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/statebackends"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a state backend",
+ Long: `Update a state backend`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ stateBackend := common.String(cmd, "state-backend")
+ var req statebackends.PatchedStateBackend
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.StateBackends.UpdateStateBackend(ctx, org, stateBackend, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "State backend updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("state-backend", "", "The state backend name.")
+ _ = cmd.MarkFlagRequired("state-backend")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/artifacts_delete.go b/go/cmd/template/artifacts_delete.go
new file mode 100644
index 0000000..9ecfc41
--- /dev/null
+++ b/go/cmd/template/artifacts_delete.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete an artifact",
+ Long: `Delete an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ artifactId := common.String(cmd, "artifact-id")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.DeleteTemplateArtifact(ctx, ownerOrg, templateType, templateId, artifactId, &templates.TemplateArtifactRequest{SgOrgid: org})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Artifact deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID.")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/artifacts_download_url.go b/go/cmd/template/artifacts_download_url.go
new file mode 100644
index 0000000..30dac6a
--- /dev/null
+++ b/go/cmd/template/artifacts_download_url.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsDownloadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "download-url",
+ Short: "Get a presigned download URL for an artifact",
+ Long: `Get a presigned download URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ artifactId := common.String(cmd, "artifact-id")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.GetTemplateArtifactDownloadUrl(ctx, ownerOrg, templateType, templateId, artifactId, &templates.TemplateArtifactRequest{SgOrgid: org})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID.")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ return cmd
+}
diff --git a/go/cmd/template/artifacts_list.go b/go/cmd/template/artifacts_list.go
new file mode 100644
index 0000000..73e307c
--- /dev/null
+++ b/go/cmd/template/artifacts_list.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the artifacts of a template",
+ Long: `List the artifacts of a template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.ListAllTemplateArtifacts(ctx, ownerOrg, templateType, templateId, &templates.ListAllTemplateArtifactsRequest{SgOrgid: org, ArtifactPrefix: common.OptString(cmd, "prefix"), MaxKeys: common.OptInt(cmd, "max-keys"), StartAfterKey: common.OptString(cmd, "start-after-key")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("prefix", "", "Only list artifacts under this prefix.")
+ cmd.Flags().Int("max-keys", 0, "Maximum number of keys.")
+ cmd.Flags().String("start-after-key", "", "Pagination: start after this key.")
+ return cmd
+}
diff --git a/go/cmd/template/artifacts_upload_url.go b/go/cmd/template/artifacts_upload_url.go
new file mode 100644
index 0000000..91b8430
--- /dev/null
+++ b/go/cmd/template/artifacts_upload_url.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newArtifactsUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "upload-url",
+ Short: "Get a presigned upload URL for an artifact",
+ Long: `Get a presigned upload URL for an artifact`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ artifactId := common.String(cmd, "artifact-id")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.GetTemplateArtifactUploadUrl(ctx, ownerOrg, templateType, templateId, artifactId, &templates.TemplateArtifactRequest{SgOrgid: org})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("artifact-id", "", "The artifact ID.")
+ _ = cmd.MarkFlagRequired("artifact-id")
+ return cmd
+}
diff --git a/go/cmd/template/create.go b/go/cmd/template/create.go
new file mode 100644
index 0000000..dbdee92
--- /dev/null
+++ b/go/cmd/template/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a template or a new revision of it (payload must include TemplateType: IAC, IAC_GROUP or IAC_POLICY)",
+ Long: `Create a template or a new revision of it (payload must include TemplateType: IAC, IAC_GROUP or IAC_POLICY)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.CreateTemplateRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Templates.CreateTemplateRevision(ctx, &sggosdk.CreateTemplateRevisionRequest{SgOrgid: org, Body: &req})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Template created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/delete.go b/go/cmd/template/delete.go
new file mode 100644
index 0000000..d2a5b34
--- /dev/null
+++ b/go/cmd/template/delete.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a template or one of its revisions",
+ Long: `Delete a template or one of its revisions`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ if err := c.Templates.DeleteTemplateRevision(ctx, ownerOrg, templateId, templateType, &sggosdk.DeleteTemplateRevisionRequest{SgOrgid: org}); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Template deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/group_iac.go b/go/cmd/template/group_iac.go
new file mode 100644
index 0000000..e12b177
--- /dev/null
+++ b/go/cmd/template/group_iac.go
@@ -0,0 +1,42 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newGroupIacCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "group-iac",
+ Short: "Get an IaC template that belongs to an IaC group template",
+ Long: `Get an IaC template that belongs to an IaC group template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ iacTemplateId := common.String(cmd, "iac-template-id")
+ ownerOrg := common.String(cmd, "owner-org")
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.ReadIacGroupsIacTemplate(ctx, ownerOrg, iacTemplateId, templateId, &sggosdk.ReadIacGroupsIacTemplateRequest{SgOrgid: org})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The IaC group template.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("iac-template-id", "", "The IaC template inside the group.")
+ _ = cmd.MarkFlagRequired("iac-template-id")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ return cmd
+}
diff --git a/go/cmd/template/input_schema.go b/go/cmd/template/input_schema.go
new file mode 100644
index 0000000..442bed7
--- /dev/null
+++ b/go/cmd/template/input_schema.go
@@ -0,0 +1,48 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newInputSchemaCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "input-schema",
+ Short: "Decode one of a template's input schemas (requires a user token)",
+ Long: `Decode one of a template's input schemas (requires a user token)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ schemaType := common.String(cmd, "schema-type")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.GetTemplateInputSchema(ctx, ownerOrg, templateType, templateId, &templates.GetTemplateInputSchemaRequest{SchemaType: schemaType})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ cmd.Flags().String("schema-type", "", "Schema to decode (FORM_JSONSCHEMA, RAW_JSON, NO_CODE_JSON, TIRITH_JSON).")
+ _ = cmd.MarkFlagRequired("schema-type")
+ return cmd
+}
diff --git a/go/cmd/template/list.go b/go/cmd/template/list.go
new file mode 100644
index 0000000..40df712
--- /dev/null
+++ b/go/cmd/template/list.go
@@ -0,0 +1,42 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List templates of a type",
+ Long: `List templates of a type`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateType := common.String(cmd, "template-type")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ response, err := c.Templates.ListAllTemplates(ctx, sggosdk.ListAllTemplatesRequestTemplateType(templateType), &sggosdk.ListAllTemplatesRequest{SgOrgid: org, IsPublic: common.OptString(cmd, "is-public"), OwnerOrgs: common.OptString(cmd, "owner-orgs"), SearchQuery: common.OptString(cmd, "search-query"), TemplateId: common.OptString(cmd, "template-id"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("is-public", "", "0 for private, 1 for public templates.")
+ cmd.Flags().String("owner-orgs", "", "Organizations that own the templates (comma-separated).")
+ cmd.Flags().String("search-query", "", "Search by name, tags or description.")
+ cmd.Flags().String("template-id", "", "Parent template id to list its revisions.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ return cmd
+}
diff --git a/go/cmd/template/list_by_owner.go b/go/cmd/template/list_by_owner.go
new file mode 100644
index 0000000..06634b0
--- /dev/null
+++ b/go/cmd/template/list_by_owner.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListByOwnerCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-by-owner",
+ Short: "List templates owned by an organization",
+ Long: `List templates owned by an organization`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ ownerOrg := common.String(cmd, "owner-org")
+ response, err := c.Templates.ListAllTemplatesBasedOnOwnerOrg(ctx, ownerOrg, &sggosdk.ListAllTemplatesBasedOnOwnerOrgRequest{SgOrgid: org, IsPublic: common.OptString(cmd, "is-public"), SearchQuery: common.OptString(cmd, "search-query"), IsSharedTemplate: common.OptBool(cmd, "shared"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("owner-org", "", "Organization that owns the templates.")
+ _ = cmd.MarkFlagRequired("owner-org")
+ cmd.Flags().String("is-public", "", "0 for private, 1 for public templates.")
+ cmd.Flags().String("search-query", "", "Search by name, tags or description.")
+ cmd.Flags().Bool("shared", false, "List shared templates.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ return cmd
+}
diff --git a/go/cmd/template/public_list.go b/go/cmd/template/public_list.go
new file mode 100644
index 0000000..5e34893
--- /dev/null
+++ b/go/cmd/template/public_list.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newPublicListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List public templates of a type",
+ Long: `List public templates of a type`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ templateType := common.String(cmd, "template-type")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ response, err := c.Templates.ListAllPublicTemplates(ctx, templateType, &templates.ListAllPublicTemplatesRequest{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), TemplateId: common.OptString(cmd, "template-id"), OwnerOrgs: common.OptString(cmd, "owner-orgs"), SearchQuery: common.OptString(cmd, "search-query"), ContextTags: common.OptString(cmd, "context-tags"), SourceConfigKinds: common.OptString(cmd, "source-config-kinds")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkPersistentFlagRequired("template-type")
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("template-id", "", "Parent template id (with owner org) to list its revisions.")
+ cmd.Flags().String("owner-orgs", "", "Owner organizations (comma-separated).")
+ cmd.Flags().String("search-query", "", "Search by name, description or tags.")
+ cmd.Flags().String("context-tags", "", "Filter by context tags as key or key:value (comma-separated).")
+ cmd.Flags().String("source-config-kinds", "", "Filter by source config kind (comma-separated).")
+ return cmd
+}
diff --git a/go/cmd/template/public_list_all.go b/go/cmd/template/public_list_all.go
new file mode 100644
index 0000000..d6a950b
--- /dev/null
+++ b/go/cmd/template/public_list_all.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newPublicListAllCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-all",
+ Short: "List public templates across all types",
+ Long: `List public templates across all types`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ response, err := c.Templates.ListAllPublicTemplatesV2(ctx, &templates.ListAllPublicTemplatesV2Request{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), IsActive: common.OptString(cmd, "is-active"), TemplateName: common.OptString(cmd, "template-name"), GitHubComRepoID: common.OptString(cmd, "github-repo-id"), SearchQuery: common.OptString(cmd, "search-query"), Tags: common.OptString(cmd, "tags"), TemplateTypes: common.OptString(cmd, "template-types"), SourceConfigKinds: common.OptString(cmd, "source-config-kinds"), ContextTags: common.OptString(cmd, "context-tags"), OwnerOrgs: common.OptString(cmd, "owner-orgs")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("is-active", "", "Filter by active state (0 or 1).")
+ cmd.Flags().String("template-name", "", "Filter by template name.")
+ cmd.Flags().String("github-repo-id", "", "Filter by GitHub repository id.")
+ cmd.Flags().String("search-query", "", "Search by name, description, tags or id.")
+ cmd.Flags().String("tags", "", "Filter by tags (comma-separated).")
+ cmd.Flags().String("template-types", "", "Filter by template types (comma-separated).")
+ cmd.Flags().String("source-config-kinds", "", "Filter by source config kind (comma-separated).")
+ cmd.Flags().String("context-tags", "", "Filter by context tags as key or key:value (comma-separated).")
+ cmd.Flags().String("owner-orgs", "", "Owner organizations (comma-separated).")
+ return cmd
+}
diff --git a/go/cmd/template/public_read.go b/go/cmd/template/public_read.go
new file mode 100644
index 0000000..c4ab7cf
--- /dev/null
+++ b/go/cmd/template/public_read.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newPublicReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a public template",
+ Long: `Get a public template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ response, err := c.Templates.ReadPublicTemplate(ctx, ownerOrg, templateType, templateId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.PersistentFlags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkPersistentFlagRequired("template-id")
+ cmd.PersistentFlags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkPersistentFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template.")
+ _ = cmd.MarkFlagRequired("owner-org")
+ return cmd
+}
diff --git a/go/cmd/template/read.go b/go/cmd/template/read.go
new file mode 100644
index 0000000..844a20f
--- /dev/null
+++ b/go/cmd/template/read.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a template or one of its revisions",
+ Long: `Get a template or one of its revisions`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.ReadTemplateRevision(ctx, ownerOrg, templateId, sggosdk.ReadTemplateRevisionRequestTemplateType(templateType), &sggosdk.ReadTemplateRevisionRequest{SgOrgid: org})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ return cmd
+}
diff --git a/go/cmd/template/subscriptions_create.go b/go/cmd/template/subscriptions_create.go
new file mode 100644
index 0000000..37ab8b6
--- /dev/null
+++ b/go/cmd/template/subscriptions_create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newSubscriptionsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a subscription set (all four subscription maps are required)",
+ Long: `Create a subscription set (all four subscription maps are required)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req templates.CreateSubscriptionRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Templates.CreateSubscription(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Subscription created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/subscriptions_read.go b/go/cmd/template/subscriptions_read.go
new file mode 100644
index 0000000..f3671aa
--- /dev/null
+++ b/go/cmd/template/subscriptions_read.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newSubscriptionsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get the subscriptions of a type",
+ Long: `Get the subscriptions of a type`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ subscriptionType := common.String(cmd, "subscription-type")
+ if err := common.CheckEnum("subscription-type", subscriptionType, "IACGroupSubscriptions", "IACSubscriptions", "PolicySubscriptions", "WfStepSubscriptions"); err != nil {
+ return err
+ }
+ response, err := c.Templates.ReadSubscription(ctx, org, &sggosdk.ReadSubscriptionRequest{SubscriptionType: sggosdk.ReadSubscriptionRequestSubscriptionType(subscriptionType)})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("subscription-type", "", "Subscription type (IACGroupSubscriptions, IACSubscriptions, PolicySubscriptions, WfStepSubscriptions).")
+ _ = cmd.MarkFlagRequired("subscription-type")
+ return cmd
+}
diff --git a/go/cmd/template/subscriptions_update.go b/go/cmd/template/subscriptions_update.go
new file mode 100644
index 0000000..41ccc6a
--- /dev/null
+++ b/go/cmd/template/subscriptions_update.go
@@ -0,0 +1,49 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/templates"
+ "github.com/spf13/cobra"
+)
+
+func newSubscriptionsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Subscribe to or unsubscribe from templates",
+ Long: `Subscribe to or unsubscribe from templates`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ subscription := common.String(cmd, "subscription")
+ action := common.String(cmd, "action")
+ var req templates.UpdateSubscriptionRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.CheckEnum("action", action, "subscribe", "unsubscribe"); err != nil {
+ return err
+ }
+ response, err := c.Templates.UpdateSubscription(ctx, org, subscription, action, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Subscription updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("subscription", "default", "The subscription name.")
+ cmd.Flags().String("action", "", "subscribe or unsubscribe.")
+ _ = cmd.MarkFlagRequired("action")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/template.go b/go/cmd/template/template.go
new file mode 100644
index 0000000..da5bbf6
--- /dev/null
+++ b/go/cmd/template/template.go
@@ -0,0 +1,114 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewTemplateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "template",
+ Short: "Manage templates and template revisions across all template types",
+ Long: `Manage templates and template revisions across all template types.
+
+A template revision is addressed as NAME or NAME:REVISION (for example my-template:5). Without a revision the base template is used.`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List templates of a type
+ list-by-owner List templates owned by an organization
+ create Create a template or a new revision of it (payload must include TemplateType: IAC, IAC_GROUP or IAC_POLICY)
+ read Get a template or one of its revisions
+ update Update a template or one of its revisions
+ delete Delete a template or one of its revisions
+ group-iac Get an IaC template that belongs to an IaC group template
+ input-schema Decode one of a template's input schemas (requires a user token)
+ vcs-triggers Create VCS webhook triggers for a template
+ subscriptions Manage the organization's template subscriptions
+ artifacts Work with template artifacts through presigned URLs
+ public Browse public marketplace templates (requires a user token)`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newListCmd(c),
+ newListByOwnerCmd(c),
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newGroupIacCmd(c),
+ newInputSchemaCmd(c),
+ newVcsTriggersCmd(c),
+ newSubscriptionsCmd(c),
+ newArtifactsCmd(c),
+ newPublicCmd(c),
+ )
+ return cmd
+}
+func newSubscriptionsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "subscriptions",
+ Short: "Manage the organization's template subscriptions",
+ Long: `Manage the organization's template subscriptions`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get the subscriptions of a type
+ create Create a subscription set (all four subscription maps are required)
+ update Subscribe to or unsubscribe from templates`)
+ },
+ }
+ cmd.AddCommand(
+ newSubscriptionsReadCmd(c),
+ newSubscriptionsCreateCmd(c),
+ newSubscriptionsUpdateCmd(c),
+ )
+ return cmd
+}
+func newArtifactsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "artifacts",
+ Short: "Work with template artifacts through presigned URLs",
+ Long: `Work with template artifacts through presigned URLs`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List the artifacts of a template
+ download-url Get a presigned download URL for an artifact
+ upload-url Get a presigned upload URL for an artifact
+ delete Delete an artifact`)
+ },
+ }
+ cmd.PersistentFlags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkPersistentFlagRequired("template-id")
+ cmd.PersistentFlags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkPersistentFlagRequired("template-type")
+ cmd.PersistentFlags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ cmd.AddCommand(
+ newArtifactsListCmd(c),
+ newArtifactsDownloadUrlCmd(c),
+ newArtifactsUploadUrlCmd(c),
+ newArtifactsDeleteCmd(c),
+ )
+ return cmd
+}
+func newPublicCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "public",
+ Short: "Browse public marketplace templates (requires a user token)",
+ Long: `Browse public marketplace templates (requires a user token)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ list List public templates of a type
+ list-all List public templates across all types
+ read Get a public template`)
+ },
+ }
+ cmd.AddCommand(
+ newPublicListCmd(c),
+ newPublicListAllCmd(c),
+ newPublicReadCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/template/update.go b/go/cmd/template/update.go
new file mode 100644
index 0000000..a759e91
--- /dev/null
+++ b/go/cmd/template/update.go
@@ -0,0 +1,56 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a template or one of its revisions",
+ Long: `Update a template or one of its revisions`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ var req sggosdk.PatchedTemplateUpdate
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ req.SgOrgid = org
+ response, err := c.Templates.UpdateTemplateRevision(ctx, ownerOrg, templateId, templateType, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Template updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/template/vcs_triggers.go b/go/cmd/template/vcs_triggers.go
new file mode 100644
index 0000000..a173166
--- /dev/null
+++ b/go/cmd/template/vcs_triggers.go
@@ -0,0 +1,55 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package template
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newVcsTriggersCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "vcs-triggers -- payload.json",
+ Short: "Create VCS webhook triggers for a template",
+ Long: `Create VCS webhook triggers for a template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ templateType := common.String(cmd, "template-type")
+ ownerOrg := common.String(cmd, "owner-org")
+ var req workflows.CreateVcsTriggersRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.CheckEnum("template-type", templateType, "IAC", "IAC_GROUP", "IAC_POLICY", "WORKFLOW_STEP"); err != nil {
+ return err
+ }
+ if ownerOrg == "" {
+ ownerOrg = org
+ }
+ response, err := c.Templates.CreateTemplateVcsTriggers(ctx, ownerOrg, templateType, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "VCS triggers created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "Template name, optionally with revision as NAME:REVISION.")
+ _ = cmd.MarkFlagRequired("template-id")
+ cmd.Flags().String("template-type", "", "Template type (IAC, IAC_GROUP, IAC_POLICY, WORKFLOW_STEP).")
+ _ = cmd.MarkFlagRequired("template-type")
+ cmd.Flags().String("owner-org", "", "Organization that owns the template (defaults to --org).")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/user/create.go b/go/cmd/user/create.go
new file mode 100644
index 0000000..aa2a9cd
--- /dev/null
+++ b/go/cmd/user/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Invite a user or SSO group to the organization",
+ Long: `Invite a user or SSO group to the organization`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.AddUserToOrganization
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.AccessManagement.CreateUser(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "User invited successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/user/delete.go b/go/cmd/user/delete.go
new file mode 100644
index 0000000..6477b04
--- /dev/null
+++ b/go/cmd/user/delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Remove a user or SSO group from the organization",
+ Long: `Remove a user or SSO group from the organization`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.DeleteUser(ctx, org, &sggosdk.GetorRemoveUserFromOrganization{UserId: common.OptString(cmd, "user-id"), Alias: common.OptString(cmd, "alias")})
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "User removed successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("user-id", "", "User id (email) or SSO group id.")
+ cmd.Flags().String("alias", "", "Alias of an SSO group.")
+ common.AddOutputJSONFlag(cmd)
+ cmd.MarkFlagsOneRequired("user-id", "alias")
+ return cmd
+}
diff --git a/go/cmd/user/list.go b/go/cmd/user/list.go
new file mode 100644
index 0000000..4d9ad43
--- /dev/null
+++ b/go/cmd/user/list.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List users and SSO groups",
+ Long: `List users and SSO groups`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.ListAllUsers(ctx, org, &sggosdk.ListAllUsersRequest{Alias: common.OptString(cmd, "alias"), EntityType: common.OptString(cmd, "entity-type"), LoginMethod: common.OptString(cmd, "login-method"), Roles: common.OptString(cmd, "roles"), UserId: common.OptString(cmd, "user-id")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("alias", "", "Filter by alias.")
+ cmd.Flags().String("entity-type", "", "Filter by entity type (EMAIL, GROUP).")
+ cmd.Flags().String("login-method", "", "Filter by login method.")
+ cmd.Flags().String("roles", "", "Filter by roles (comma-separated).")
+ cmd.Flags().String("user-id", "", "Filter by user id.")
+ return cmd
+}
diff --git a/go/cmd/user/read.go b/go/cmd/user/read.go
new file mode 100644
index 0000000..ee8fa01
--- /dev/null
+++ b/go/cmd/user/read.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a user or SSO group",
+ Long: `Get a user or SSO group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.AccessManagement.ReadUser(ctx, org, &sggosdk.GetorRemoveUserFromOrganization{UserId: common.OptString(cmd, "user-id"), Alias: common.OptString(cmd, "alias")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("user-id", "", "User id (email) or SSO group id.")
+ cmd.Flags().String("alias", "", "Alias of an SSO group.")
+ cmd.MarkFlagsOneRequired("user-id", "alias")
+ return cmd
+}
diff --git a/go/cmd/user/update.go b/go/cmd/user/update.go
new file mode 100644
index 0000000..06bbef5
--- /dev/null
+++ b/go/cmd/user/update.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a user or SSO group",
+ Long: `Update a user or SSO group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.AddUserToOrganization
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.AccessManagement.UpdateUser(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "User updated successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/user/user.go b/go/cmd/user/user.go
new file mode 100644
index 0000000..ef395f5
--- /dev/null
+++ b/go/cmd/user/user.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package user
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewUserCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "user",
+ Short: "Manage users and SSO groups",
+ Long: `Manage users and SSO groups`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a user or SSO group
+ create Invite a user or SSO group to the organization
+ delete Remove a user or SSO group from the organization
+ update Update a user or SSO group
+ list List users and SSO groups`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ newCreateCmd(c),
+ newDeleteCmd(c),
+ newUpdateCmd(c),
+ newListCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/workflow/apply/workflow_apply.go b/go/cmd/workflow/apply/workflow_apply.go
index f134116..e3a3891 100644
--- a/go/cmd/workflow/apply/workflow_apply.go
+++ b/go/cmd/workflow/apply/workflow_apply.go
@@ -2,6 +2,7 @@ package apply
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
sggosdk "github.com/StackGuardian/sg-sdk-go"
@@ -44,7 +45,7 @@ func NewApplyCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow apply run successfully.")
workflowRunPath := DASHBOARD_URL +
diff --git a/go/cmd/workflow/create/workflow_create.go b/go/cmd/workflow/create/workflow_create.go
index c22ed19..4c15f7f 100644
--- a/go/cmd/workflow/create/workflow_create.go
+++ b/go/cmd/workflow/create/workflow_create.go
@@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"io"
"net/http"
"os"
@@ -13,12 +14,13 @@ import (
"github.com/StackGuardian/sg-cli/utilities"
sggosdk "github.com/StackGuardian/sg-sdk-go"
"github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
"github.com/spf13/cobra"
)
// Extend the Workflow struct from the sdk to add the new field for bulk
type BulkWorkflow struct {
- sggosdk.Workflow
+ workflows.Workflow
CLIConfiguration
}
@@ -102,7 +104,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
// Iterate over the slice of BulkWorkflow objects
for idx, bulkWorkflow := range createBulkWorkflowRequest {
- var individualWorkflow *sggosdk.Workflow
+ var individualWorkflow *workflows.Workflow
// delete the CLIConfiguration field from the tempMap
delete(tempMap[idx], "CLIConfiguration")
// Convert map to []byte and then unmarshal to workflow object
@@ -116,7 +118,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
cmd.PrintErrln(err)
continue
}
- cmd.Println(">> Processing workflow: " + individualWorkflow.ResourceName.Value)
+ cmd.Println(">> Processing workflow: " + *individualWorkflow.ResourceName)
err = performPreExecutionFlagChecks(cmd, individualWorkflow, opts)
if err != nil {
cmd.PrintErrln(err)
@@ -136,14 +138,14 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
)
if err != nil {
if !strings.Contains(err.Error(), "Workflow name not unique") {
- cmd.PrintErrln(">> [ERROR] Processing workflow failed for resource name: " + individualWorkflow.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Processing workflow failed for resource name: " + *individualWorkflow.ResourceName + "\n")
cmd.PrintErrln(err)
continue
} else {
cmd.Println("Workflow already exists, updating instead...")
// convert to update workflow request
- var updateIndividualWorkflow *sggosdk.PatchedWorkflow
- err = json.Unmarshal(jsonBody, &individualWorkflow)
+ var updateIndividualWorkflow *workflows.PatchedWorkflow
+ err = json.Unmarshal(jsonBody, &updateIndividualWorkflow)
if err != nil {
cmd.PrintErrln(err)
continue
@@ -151,45 +153,47 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
response, err := c.Workflows.UpdateWorkflow(
context.Background(),
opts.Org,
- individualWorkflow.ResourceName.Value,
+ *individualWorkflow.ResourceName,
opts.WfgGrp,
+ nil,
updateIndividualWorkflow,
)
if err != nil {
- cmd.PrintErrln(">> [ERROR] Updating workflow failed for resource name: " + *updateIndividualWorkflow.ResourceName + "\n")
+ cmd.PrintErrln(">> [ERROR] Updating workflow failed for resource name: " + *individualWorkflow.ResourceName + "\n")
cmd.PrintErrln(err)
continue
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow updated successfully.")
if bulkWorkflow.CLIConfiguration.CLIConfiguration.TfStateFilePath == "" {
- cmd.Println("TfStateFilePath is not provided for workflow: " + bulkWorkflow.ResourceName.Value)
- cmd.Println(">> Skipping update of state file..\n")
+ cmd.Println("TfStateFilePath is not provided for workflow: " + *bulkWorkflow.ResourceName)
+ cmd.Println(">> Skipping update of state file..")
+ cmd.Println()
} else {
cmd.Println(">> Attempting to upload state file..")
err = uploadTfState(cmd, &bulkWorkflow, opts)
if err != nil {
- cmd.PrintErrln("Failed to upload state file for workflow: " + individualWorkflow.ResourceName.Value + "\n")
+ cmd.PrintErrln("Failed to upload state file for workflow: " + *individualWorkflow.ResourceName + "\n")
continue
}
}
}
} else {
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow created successfully.")
if bulkWorkflow.CLIConfiguration.CLIConfiguration.TfStateFilePath == "" {
- cmd.PrintErrln("[ERROR] TfStateFilePath is not provided for workflow: " + bulkWorkflow.ResourceName.Value)
+ cmd.PrintErrln("[ERROR] TfStateFilePath is not provided for workflow: " + *bulkWorkflow.ResourceName)
cmd.PrintErrln(">> Skipping update of state file..")
} else {
cmd.Println(">> Attempting to upload state file..")
err = uploadTfState(cmd, &bulkWorkflow, opts)
if err != nil {
- cmd.PrintErrln("Failed to upload state file for workflow: " + individualWorkflow.ResourceName.Value + "\n")
+ cmd.PrintErrln("Failed to upload state file for workflow: " + *individualWorkflow.ResourceName + "\n")
}
}
// Run on create
@@ -203,7 +207,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
response, err := c.WorkflowRuns.CreateWorkflowRun(
context.Background(),
opts.Org,
- bulkWorkflow.ResourceName.Value,
+ *bulkWorkflow.ResourceName,
opts.WfgGrp,
createWorkflowRunRequest,
)
@@ -213,7 +217,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
continue
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow run created successfully.")
workflowRunPath := DASHBOARD_URL +
@@ -222,7 +226,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
"/wfgrps/" +
opts.WfgGrp +
"/wfs/" +
- bulkWorkflow.ResourceName.Value +
+ *bulkWorkflow.ResourceName +
"?tab=runs"
cmd.Println("To view the workflow run, please visit the following URL:")
cmd.Println(workflowRunPath)
@@ -232,7 +236,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
}
}
} else {
- var createWorkflowRequest *sggosdk.Workflow
+ var createWorkflowRequest *workflows.Workflow
var createWorkflowRunRequest *sggosdk.WorkflowRun
if opts.PatchPayload != "" && !opts.Bulk {
patchedJson := utilities.PatchJSON(string(payload), opts.PatchPayload)
@@ -286,7 +290,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
response, err := c.WorkflowRuns.CreateWorkflowRun(
context.Background(),
opts.Org,
- createWorkflowRequest.ResourceName.Value,
+ *createWorkflowRequest.ResourceName,
opts.WfgGrp,
createWorkflowRunRequest,
)
@@ -296,7 +300,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow run created successfully.")
workflowRunPath := DASHBOARD_URL +
@@ -305,7 +309,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
"/wfgrps/" +
opts.WfgGrp +
"/wfs/" +
- createWorkflowRequest.ResourceName.Value +
+ *createWorkflowRequest.ResourceName +
"?tab=runs"
cmd.Println("To view the workflow run, please visit the following URL:")
cmd.Println(workflowRunPath)
@@ -322,7 +326,7 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow created successfully.")
}
@@ -349,9 +353,9 @@ func NewCreateCmd(c *client.Client) *cobra.Command {
}
// performPreExecutionFlagChecks performs pre-execution flag checks and returns the payload
-func performPreExecutionFlagChecks(cmd *cobra.Command, payload *sggosdk.Workflow, opts *RunOptions) error {
+func performPreExecutionFlagChecks(cmd *cobra.Command, payload *workflows.Workflow, opts *RunOptions) error {
- if payload.ResourceName == nil || payload.ResourceName.Value == "" {
+ if payload.ResourceName == nil || *payload.ResourceName == "" {
return errors.New(">> [ERROR] Workflow ResourceName is required in object payload, skipping")
}
@@ -385,11 +389,11 @@ func uploadTfState(cmd *cobra.Command, payload *BulkWorkflow, opts *RunOptions)
"/wfgrps/" +
opts.WfgGrp +
"/wfs/" +
- payload.ResourceName.Value +
+ *payload.ResourceName +
"/tfstate_upload_url"
req, err := http.NewRequest("GET", url, nil)
if err != nil {
- cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln(err)
return err
}
@@ -398,25 +402,25 @@ func uploadTfState(cmd *cobra.Command, payload *BulkWorkflow, opts *RunOptions)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
- cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln(err)
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
- cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln("Expected status code 200, got " + resp.Status)
return err
}
body, err := io.ReadAll(resp.Body)
if err != nil {
- cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln(err)
return err
}
var response tfStateUploadUrlResponse
if err := json.Unmarshal(body, &response); err != nil {
- cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to get tfstate upload url for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln(err)
return err
}
@@ -427,7 +431,7 @@ func uploadTfState(cmd *cobra.Command, payload *BulkWorkflow, opts *RunOptions)
// Create a temporary directory to store the state file
tmpDir, err := os.MkdirTemp("", opts.Org+"-"+opts.WfgGrp)
if err != nil {
- cmd.PrintErrln(">> [ERROR] Failed to create temp directory for state file upload: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to create temp directory for state file upload: " + *payload.ResourceName + "\n")
cmd.PrintErrln(err)
return err
}
@@ -459,7 +463,7 @@ func uploadTfState(cmd *cobra.Command, payload *BulkWorkflow, opts *RunOptions)
if strings.Contains(string(output), "HTTP/1.1 200 OK") {
cmd.Println(">> State file uploaded successfully.")
} else {
- cmd.PrintErrln(">> [ERROR] Failed to upload state file for workflow: " + payload.ResourceName.Value + "\n")
+ cmd.PrintErrln(">> [ERROR] Failed to upload state file for workflow: " + *payload.ResourceName + "\n")
cmd.PrintErrln(string(output))
}
diff --git a/go/cmd/workflow/delete/workflow_delete.go b/go/cmd/workflow/delete/workflow_delete.go
index 41c2da5..d2b2164 100644
--- a/go/cmd/workflow/delete/workflow_delete.go
+++ b/go/cmd/workflow/delete/workflow_delete.go
@@ -2,6 +2,7 @@ package delete
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"github.com/StackGuardian/sg-sdk-go/client"
@@ -38,7 +39,7 @@ func NewDeleteCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow deleted successfully.")
},
diff --git a/go/cmd/workflow/destroy/workflow_destroy.go b/go/cmd/workflow/destroy/workflow_destroy.go
index c128cb9..897f735 100644
--- a/go/cmd/workflow/destroy/workflow_destroy.go
+++ b/go/cmd/workflow/destroy/workflow_destroy.go
@@ -2,6 +2,7 @@ package destroy
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
sggosdk "github.com/StackGuardian/sg-sdk-go"
@@ -45,7 +46,7 @@ func NewDestroyCmd(c *client.Client) *cobra.Command {
os.Exit(-1)
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
cmd.Println("Workflow destroy run successfully.")
workflowRunPath := DASHBOARD_URL +
diff --git a/go/cmd/workflow/extra/compare.go b/go/cmd/workflow/extra/compare.go
new file mode 100644
index 0000000..1bf52aa
--- /dev/null
+++ b/go/cmd/workflow/extra/compare.go
@@ -0,0 +1,57 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newCompareCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "compare -- payload.json",
+ Short: "Compare a workflow against a template without applying changes",
+ Long: `Compare a workflow against a template without applying changes`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ var req workflows.CompareWorkflowRequest
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if v := common.OptString(cmd, "target-template-id"); v != nil {
+ req.TargetTemplateId = *v
+ }
+ if v := common.OptString(cmd, "upgrade-mode"); v != nil {
+ req.UpgradeMode = v
+ }
+ if req.TargetTemplateId == "" {
+ return errors.New("provide --target-template-id or a payload with targetTemplateId")
+ }
+ response, err := c.Workflows.CompareWorkflow(ctx, org, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("target-template-id", "", "Template to compare against.")
+ cmd.Flags().String("upgrade-mode", "", "Upgrade mode to simulate.")
+ common.AddPayloadFlags(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflow/extra/extra.go b/go/cmd/workflow/extra/extra.go
new file mode 100644
index 0000000..7de9848
--- /dev/null
+++ b/go/cmd/workflow/extra/extra.go
@@ -0,0 +1,20 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+// AddCommands attaches the generated sub-commands to an existing command group.
+func AddCommands(cmd *cobra.Command, c *client.Client) {
+ cmd.AddCommand(
+ newUpdateCmd(c),
+ newOutputsCmd(c),
+ newCompareCmd(c),
+ newFileUploadUrlCmd(c),
+ newTfstateUploadUrlCmd(c),
+ newVcsTriggersCmd(c),
+ )
+}
diff --git a/go/cmd/workflow/extra/file_upload_url.go b/go/cmd/workflow/extra/file_upload_url.go
new file mode 100644
index 0000000..d3158cd
--- /dev/null
+++ b/go/cmd/workflow/extra/file_upload_url.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newFileUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "file-upload-url",
+ Short: "Get a signed URL to upload a file to a workflow",
+ Long: `Get a signed URL to upload a file to a workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ filename := common.String(cmd, "filename")
+ response, err := c.Workflows.GetFileUploadUrl(ctx, org, workflowId, workflowGroup, &workflows.GetFileUploadUrlRequest{Filename: filename, Folder: common.OptString(cmd, "folder")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("filename", "", "Name of the file to upload.")
+ _ = cmd.MarkFlagRequired("filename")
+ cmd.Flags().String("folder", "", "Folder to upload the file into.")
+ return cmd
+}
diff --git a/go/cmd/workflow/extra/outputs.go b/go/cmd/workflow/extra/outputs.go
new file mode 100644
index 0000000..a3a16f9
--- /dev/null
+++ b/go/cmd/workflow/extra/outputs.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newOutputsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "outputs",
+ Short: "Get the outputs of a workflow",
+ Long: `Get the outputs of a workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.Workflows.Outputs(ctx, org, workflowId, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ return cmd
+}
diff --git a/go/cmd/workflow/extra/tfstate_upload_url.go b/go/cmd/workflow/extra/tfstate_upload_url.go
new file mode 100644
index 0000000..dcf0898
--- /dev/null
+++ b/go/cmd/workflow/extra/tfstate_upload_url.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newTfstateUploadUrlCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "tfstate-upload-url",
+ Short: "Get a signed URL to upload a Terraform state file",
+ Long: `Get a signed URL to upload a Terraform state file`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ response, err := c.Workflows.GetSignedUrlToUploadTfstateFile(ctx, org, workflowId, workflowGroup, &sggosdk.GetSignedUrlToUploadTfstateFileRequest{Filename: common.OptString(cmd, "filename")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("filename", "", "Name of the file to upload (default tfstate.json).")
+ return cmd
+}
diff --git a/go/cmd/workflow/extra/update.go b/go/cmd/workflow/extra/update.go
new file mode 100644
index 0000000..011a875
--- /dev/null
+++ b/go/cmd/workflow/extra/update.go
@@ -0,0 +1,54 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update an existing workflow",
+ Long: `Update an existing workflow`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ var req workflows.PatchedWorkflow
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ var mode *workflows.UpgradeModeEnum
+ if v := common.OptString(cmd, "upgrade-mode"); v != nil {
+ if err := common.CheckEnum("upgrade-mode", *v, "PRESERVE_SETTINGS", "RESET_TO_TEMPLATE", "MANUAL"); err != nil {
+ return err
+ }
+ m := workflows.UpgradeModeEnum(*v)
+ mode = &m
+ }
+ response, err := c.Workflows.UpdateWorkflow(ctx, org, workflowId, workflowGroup, mode, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ cmd.Flags().String("upgrade-mode", "", "Template upgrade mode (PRESERVE_SETTINGS, RESET_TO_TEMPLATE, MANUAL).")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflow/extra/vcs_triggers.go b/go/cmd/workflow/extra/vcs_triggers.go
new file mode 100644
index 0000000..871fadb
--- /dev/null
+++ b/go/cmd/workflow/extra/vcs_triggers.go
@@ -0,0 +1,45 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package extra
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflows"
+ "github.com/spf13/cobra"
+)
+
+func newVcsTriggersCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "vcs-triggers -- payload.json",
+ Short: "Create VCS webhook triggers for a workflow",
+ Long: `Create VCS webhook triggers for a workflow`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ var req workflows.CreateVcsTriggersRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.Workflows.CreateVcsTriggers(ctx, org, workflowGroup, workflowId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "VCS triggers created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-id", "", "The workflow ID.")
+ _ = cmd.MarkFlagRequired("workflow-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflow/list/workflow_list.go b/go/cmd/workflow/list/workflow_list.go
index 1d3e0ae..0861a0b 100644
--- a/go/cmd/workflow/list/workflow_list.go
+++ b/go/cmd/workflow/list/workflow_list.go
@@ -2,6 +2,7 @@ package list
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
sggosdk "github.com/StackGuardian/sg-sdk-go"
@@ -33,7 +34,7 @@ func NewListCmd(c *client.Client) *cobra.Command {
}
if opts.OutputJson {
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
}
for _, workflow := range response.Msg {
diff --git a/go/cmd/workflow/read/workflow_read.go b/go/cmd/workflow/read/workflow_read.go
index de69a79..c138243 100644
--- a/go/cmd/workflow/read/workflow_read.go
+++ b/go/cmd/workflow/read/workflow_read.go
@@ -2,6 +2,7 @@ package read
import (
"context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
"os"
"github.com/StackGuardian/sg-sdk-go/client"
@@ -25,7 +26,7 @@ func NewReadCmd(c *client.Client) *cobra.Command {
cmd.Println(err)
os.Exit(-1)
}
- cmd.Println(response)
+ common.PrintJSON(cmd, response)
},
}
diff --git a/go/cmd/workflow/workflow.go b/go/cmd/workflow/workflow.go
index 0ad39b3..c14272e 100644
--- a/go/cmd/workflow/workflow.go
+++ b/go/cmd/workflow/workflow.go
@@ -7,6 +7,7 @@ import (
"github.com/StackGuardian/sg-cli/cmd/workflow/create"
"github.com/StackGuardian/sg-cli/cmd/workflow/delete"
"github.com/StackGuardian/sg-cli/cmd/workflow/destroy"
+ workflowextra "github.com/StackGuardian/sg-cli/cmd/workflow/extra"
"github.com/StackGuardian/sg-cli/cmd/workflow/list"
"github.com/StackGuardian/sg-cli/cmd/workflow/read"
"github.com/StackGuardian/sg-sdk-go/client"
@@ -43,5 +44,7 @@ func NewWorkflowCmd(c *client.Client) *cobra.Command {
workflowCmd.AddCommand(list.NewListCmd(c))
workflowCmd.AddCommand(destroy.NewDestroyCmd(c))
+ workflowextra.AddCommands(workflowCmd, c)
+
return workflowCmd
}
diff --git a/go/cmd/workflowgroup/create.go b/go/cmd/workflowgroup/create.go
new file mode 100644
index 0000000..59c42d9
--- /dev/null
+++ b/go/cmd/workflowgroup/create.go
@@ -0,0 +1,41 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new workflow group",
+ Long: `Create a new workflow group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ var req sggosdk.WorkflowGroup
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowGroups.CreateWorkflowGroup(ctx, org, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow group created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/create_child.go b/go/cmd/workflowgroup/create_child.go
new file mode 100644
index 0000000..8dffb37
--- /dev/null
+++ b/go/cmd/workflowgroup/create_child.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateChildCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create-child -- payload.json",
+ Short: "Create a child workflow group inside a parent group",
+ Long: `Create a child workflow group inside a parent group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ parent := common.String(cmd, "parent")
+ var req sggosdk.WorkflowGroup
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowGroups.CreateChildWorkflowGroup(ctx, org, parent, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Child workflow group created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("parent", "", "The parent workflow group.")
+ _ = cmd.MarkFlagRequired("parent")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/delete.go b/go/cmd/workflowgroup/delete.go
new file mode 100644
index 0000000..3715047
--- /dev/null
+++ b/go/cmd/workflowgroup/delete.go
@@ -0,0 +1,34 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a workflow group",
+ Long: `Delete a workflow group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ response, err := c.WorkflowGroups.DeleteWorkflowGroup(ctx, org, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow group deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkFlagRequired("workflow-group")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/list.go b/go/cmd/workflowgroup/list.go
new file mode 100644
index 0000000..b353f35
--- /dev/null
+++ b/go/cmd/workflowgroup/list.go
@@ -0,0 +1,37 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List workflow groups",
+ Long: `List workflow groups`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ response, err := c.WorkflowGroups.ListAllWorkflowGroups(ctx, org, &sggosdk.ListAllWorkflowGroupsRequest{Description: common.OptString(cmd, "description"), ResourceNames: common.OptString(cmd, "resource-names"), Tags: common.OptString(cmd, "tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit"), SearchQuery: common.OptString(cmd, "search-query")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ cmd.Flags().String("tags", "", "Filter by tags.")
+ cmd.Flags().String("search-query", "", "Search by resource name, tags or description.")
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/list_children.go b/go/cmd/workflowgroup/list_children.go
new file mode 100644
index 0000000..f8855bb
--- /dev/null
+++ b/go/cmd/workflowgroup/list_children.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListChildrenCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-children",
+ Short: "List the child workflow groups of a parent group",
+ Long: `List the child workflow groups of a parent group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ parent := common.String(cmd, "parent")
+ response, err := c.WorkflowGroups.ListAllChildWorkflowGroups(ctx, org, parent, &sggosdk.ListAllChildWorkflowGroupsRequest{Description: common.OptString(cmd, "description"), ResourceNames: common.OptString(cmd, "resource-names"), Tags: common.OptString(cmd, "tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("parent", "", "The parent workflow group.")
+ _ = cmd.MarkFlagRequired("parent")
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names.")
+ cmd.Flags().String("tags", "", "Filter by tags.")
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/list_resources.go b/go/cmd/workflowgroup/list_resources.go
new file mode 100644
index 0000000..561aed3
--- /dev/null
+++ b/go/cmd/workflowgroup/list_resources.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowgroups"
+ "github.com/spf13/cobra"
+)
+
+func newListResourcesCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list-resources",
+ Short: "List the workflows, stacks and child groups inside a workflow group",
+ Long: `List the workflows, stacks and child groups inside a workflow group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ response, err := c.WorkflowGroups.ListAllResourcesInWorkflowGroup(ctx, org, workflowGroup, &workflowgroups.ListAllResourcesRequest{Limit: common.OptInt(cmd, "limit"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), ResourceNames: common.OptString(cmd, "resource-names"), Description: common.OptString(cmd, "description"), Tags: common.OptString(cmd, "tags"), SearchQuery: common.OptString(cmd, "search-query"), LatestStatuses: common.OptString(cmd, "latest-statuses"), ResourceTypes: common.OptString(cmd, "resource-types"), ContextTags: common.OptString(cmd, "context-tags"), IsActive: common.OptString(cmd, "is-active")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkFlagRequired("workflow-group")
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("resource-names", "", "Filter by resource names (comma-separated).")
+ cmd.Flags().String("description", "", "Filter by description.")
+ cmd.Flags().String("tags", "", "Filter by tags (comma-separated).")
+ cmd.Flags().String("search-query", "", "Search by resource name, description or tags.")
+ cmd.Flags().String("latest-statuses", "", "Filter by latest status (comma-separated).")
+ cmd.Flags().String("resource-types", "", "Filter by resource type: WORKFLOW, STACK, WORKFLOW_GROUP (comma-separated).")
+ cmd.Flags().String("context-tags", "", "Filter by context tags as key or key:value (comma-separated).")
+ cmd.Flags().String("is-active", "", "Filter by active state (0 or 1).")
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/read.go b/go/cmd/workflowgroup/read.go
new file mode 100644
index 0000000..262bcfe
--- /dev/null
+++ b/go/cmd/workflowgroup/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get details of a workflow group",
+ Long: `Get details of a workflow group`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ response, err := c.WorkflowGroups.ReadWorkflowGroup(ctx, org, workflowGroup)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkFlagRequired("workflow-group")
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/update.go b/go/cmd/workflowgroup/update.go
new file mode 100644
index 0000000..9bedfa0
--- /dev/null
+++ b/go/cmd/workflowgroup/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow group",
+ Long: `Update a workflow group`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ var req sggosdk.PatchedWorkflowGroup
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowGroups.UpdateWorkflowGroup(ctx, org, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow group updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("workflow-group", "", "The workflow group under the organization.")
+ _ = cmd.MarkFlagRequired("workflow-group")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowgroup/workflowgroup.go b/go/cmd/workflowgroup/workflowgroup.go
new file mode 100644
index 0000000..1aa0a2f
--- /dev/null
+++ b/go/cmd/workflowgroup/workflowgroup.go
@@ -0,0 +1,40 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowgroup
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewWorkflowGroupCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "workflow-group",
+ Short: "Manage workflow groups (nested groups are addressed as parent/child)",
+ Long: `Manage workflow groups (nested groups are addressed as parent/child)`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new workflow group
+ read Get details of a workflow group
+ update Update a workflow group
+ delete Delete a workflow group
+ create-child Create a child workflow group inside a parent group
+ list-children List the child workflow groups of a parent group
+ list List workflow groups
+ list-resources List the workflows, stacks and child groups inside a workflow group`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newCreateChildCmd(c),
+ newListChildrenCmd(c),
+ newListCmd(c),
+ newListResourcesCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/workflowrun/approve.go b/go/cmd/workflowrun/approve.go
new file mode 100644
index 0000000..2b6a2f9
--- /dev/null
+++ b/go/cmd/workflowrun/approve.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newApproveCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "approve",
+ Short: "Approve (or, with --reject, reject) a workflow run waiting for approval",
+ Long: `Approve (or, with --reject, reject) a workflow run waiting for approval`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ reject := common.Bool(cmd, "reject")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ approve := !reject
+ body := sggosdk.WorkflowRunApproval{Approve: &approve, Message: common.OptString(cmd, "message"), ApprovalStep: common.OptString(cmd, "approval-step"), ReasonForApprovalRequired: common.OptString(cmd, "reason")}
+ response, err := c.WorkflowRuns.ApproveWorkflowRun(ctx, org, workflowId, workflowGroup, runId, &body)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Approval decision submitted.")
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ cmd.Flags().Bool("reject", false, "Reject instead of approve.")
+ cmd.Flags().String("message", "", "Message to attach to the decision.")
+ cmd.Flags().String("approval-step", "", "Name of the approval step.")
+ cmd.Flags().String("reason", "", "Reason the approval was required.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/cancel.go b/go/cmd/workflowrun/cancel.go
new file mode 100644
index 0000000..496100b
--- /dev/null
+++ b/go/cmd/workflowrun/cancel.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCancelCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "cancel",
+ Short: "Cancel a workflow run",
+ Long: `Cancel a workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.CancelWorkflowRun(ctx, org, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run cancelled.")
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/create.go b/go/cmd/workflowrun/create.go
new file mode 100644
index 0000000..b938ec1
--- /dev/null
+++ b/go/cmd/workflowrun/create.go
@@ -0,0 +1,48 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Trigger a workflow run (payload optional)",
+ Long: `Trigger a workflow run (payload optional)`,
+ Args: cobra.MaximumNArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ var req sggosdk.WorkflowRun
+ if len(args) > 0 {
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ }
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.CreateWorkflowRun(ctx, org, workflowId, workflowGroup, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run created successfully.")
+ return nil
+ },
+ }
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/delete.go b/go/cmd/workflowrun/delete.go
new file mode 100644
index 0000000..275ba89
--- /dev/null
+++ b/go/cmd/workflowrun/delete.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Cancel a workflow run through the DELETE endpoint",
+ Long: `Cancel a workflow run through the DELETE endpoint`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.DeleteWorkflowRun(ctx, org, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run cancelled.")
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/facts_create.go b/go/cmd/workflowrun/facts_create.go
new file mode 100644
index 0000000..579ba07
--- /dev/null
+++ b/go/cmd/workflowrun/facts_create.go
@@ -0,0 +1,49 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create or replace the facts of a workflow run",
+ Long: `Create or replace the facts of a workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ var req map[string]interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRunFacts.CreateWorkflowRunFacts(ctx, org, workflowId, workflowGroup, runId, factsId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run facts created.")
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/facts_read.go b/go/cmd/workflowrun/facts_read.go
new file mode 100644
index 0000000..81b1b5a
--- /dev/null
+++ b/go/cmd/workflowrun/facts_read.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get the facts of a workflow run",
+ Long: `Get the facts of a workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRunFacts.ReadWorkflowRunFacts(ctx, org, workflowId, workflowGroup, runId, factsId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ return cmd
+}
diff --git a/go/cmd/workflowrun/facts_update.go b/go/cmd/workflowrun/facts_update.go
new file mode 100644
index 0000000..3838ac9
--- /dev/null
+++ b/go/cmd/workflowrun/facts_update.go
@@ -0,0 +1,49 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newFactsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update the facts of a workflow run",
+ Long: `Update the facts of a workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ factsId := common.String(cmd, "facts-id")
+ var req map[string]interface{}
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRunFacts.UpdateWorkflowRunFacts(ctx, org, workflowId, workflowGroup, runId, factsId, req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run facts updated.")
+ return nil
+ },
+ }
+ cmd.Flags().String("facts-id", "", "The workflow run facts ID.")
+ _ = cmd.MarkFlagRequired("facts-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/list.go b/go/cmd/workflowrun/list.go
new file mode 100644
index 0000000..3b9839a
--- /dev/null
+++ b/go/cmd/workflowrun/list.go
@@ -0,0 +1,39 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newListCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "list",
+ Short: "List the runs of a workflow",
+ Long: `List the runs of a workflow`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.ListAllWorkflowRuns(ctx, org, workflowId, workflowGroup, &sggosdk.ListAllWorkflowRunsRequest{ContextTags: common.OptString(cmd, "context-tags"), Lastevaluatedkey: common.OptString(cmd, "last-evaluated-key"), Limit: common.OptInt(cmd, "limit")})
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().Int("limit", 0, "Limit the number of results returned.")
+ cmd.Flags().String("last-evaluated-key", "", "Pagination token from a previous response.")
+ cmd.Flags().String("context-tags", "", "Filter by context tags.")
+ return cmd
+}
diff --git a/go/cmd/workflowrun/logs.go b/go/cmd/workflowrun/logs.go
new file mode 100644
index 0000000..2f2ec25
--- /dev/null
+++ b/go/cmd/workflowrun/logs.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newLogsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "logs",
+ Short: "Get the logs of a workflow run",
+ Long: `Get the logs of a workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.ReadWorkflowRunLogs(ctx, org, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ return cmd
+}
diff --git a/go/cmd/workflowrun/read.go b/go/cmd/workflowrun/read.go
new file mode 100644
index 0000000..aeb30f0
--- /dev/null
+++ b/go/cmd/workflowrun/read.go
@@ -0,0 +1,38 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a workflow run",
+ Long: `Get a workflow run`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.ReadWorkflowRun(ctx, org, workflowId, workflowGroup, runId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ return cmd
+}
diff --git a/go/cmd/workflowrun/read_by_ksuid.go b/go/cmd/workflowrun/read_by_ksuid.go
new file mode 100644
index 0000000..a1d84e3
--- /dev/null
+++ b/go/cmd/workflowrun/read_by_ksuid.go
@@ -0,0 +1,36 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadByKsuidCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read-by-ksuid",
+ Short: "Get a workflow run by KSUIDs (runner and machine tokens only)",
+ Long: `Get a workflow run by KSUIDs (runner and machine tokens only)`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ parentKsuid := common.String(cmd, "parent-ksuid")
+ resourceKsuid := common.String(cmd, "resource-ksuid")
+ response, err := c.WorkflowRuns.ReadWorkflowRunByKsuid(ctx, org, parentKsuid, resourceKsuid)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("parent-ksuid", "", "KSUID of the parent workflow.")
+ _ = cmd.MarkFlagRequired("parent-ksuid")
+ cmd.Flags().String("resource-ksuid", "", "KSUID of the workflow run.")
+ _ = cmd.MarkFlagRequired("resource-ksuid")
+ return cmd
+}
diff --git a/go/cmd/workflowrun/update.go b/go/cmd/workflowrun/update.go
new file mode 100644
index 0000000..57656fa
--- /dev/null
+++ b/go/cmd/workflowrun/update.go
@@ -0,0 +1,49 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow run",
+ Long: `Update a workflow run`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ workflowGroup := common.String(cmd, "workflow-group")
+ workflowId := common.String(cmd, "workflow-id")
+ runId := common.String(cmd, "run-id")
+ var req sggosdk.PatchedWorkflowRun
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ if err := common.Require(cmd, "workflow-group", "workflow-id"); err != nil {
+ return err
+ }
+ response, err := c.WorkflowRuns.UpdateWorkflowRun(ctx, org, workflowId, workflowGroup, runId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkFlagRequired("run-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/update_by_ksuid.go b/go/cmd/workflowrun/update_by_ksuid.go
new file mode 100644
index 0000000..0cc235d
--- /dev/null
+++ b/go/cmd/workflowrun/update_by_ksuid.go
@@ -0,0 +1,47 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ sggosdk "github.com/StackGuardian/sg-sdk-go"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateByKsuidCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update-by-ksuid -- payload.json",
+ Short: "Update a workflow run by KSUIDs (runner and machine tokens only)",
+ Long: `Update a workflow run by KSUIDs (runner and machine tokens only)`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ parentKsuid := common.String(cmd, "parent-ksuid")
+ resourceKsuid := common.String(cmd, "resource-ksuid")
+ var req sggosdk.PatchedWorkflowRun
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowRuns.UpdateWorkflowRunByKsuid(ctx, org, parentKsuid, resourceKsuid, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow run updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("parent-ksuid", "", "KSUID of the parent workflow.")
+ _ = cmd.MarkFlagRequired("parent-ksuid")
+ cmd.Flags().String("resource-ksuid", "", "KSUID of the workflow run.")
+ _ = cmd.MarkFlagRequired("resource-ksuid")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowrun/workflowrun.go b/go/cmd/workflowrun/workflowrun.go
new file mode 100644
index 0000000..1db1b12
--- /dev/null
+++ b/go/cmd/workflowrun/workflowrun.go
@@ -0,0 +1,69 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowrun
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewWorkflowRunCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "workflow-run",
+ Short: "Trigger, inspect, cancel and approve workflow runs",
+ Long: `Trigger, inspect, cancel and approve workflow runs`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Trigger a workflow run (payload optional)
+ read Get a workflow run
+ update Update a workflow run
+ cancel Cancel a workflow run
+ delete Cancel a workflow run through the DELETE endpoint
+ logs Get the logs of a workflow run
+ approve Approve (or, with --reject, reject) a workflow run waiting for approval
+ list List the runs of a workflow
+ read-by-ksuid Get a workflow run by KSUIDs (runner and machine tokens only)
+ update-by-ksuid Update a workflow run by KSUIDs (runner and machine tokens only)
+ facts Read and write the facts of a workflow run`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.PersistentFlags().String("workflow-group", "", "The workflow group under the organization.")
+ cmd.PersistentFlags().String("workflow-id", "", "The workflow ID.")
+ cmd.AddCommand(
+ newCreateCmd(c),
+ newReadCmd(c),
+ newUpdateCmd(c),
+ newCancelCmd(c),
+ newDeleteCmd(c),
+ newLogsCmd(c),
+ newApproveCmd(c),
+ newListCmd(c),
+ newReadByKsuidCmd(c),
+ newUpdateByKsuidCmd(c),
+ newFactsCmd(c),
+ )
+ return cmd
+}
+func newFactsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "facts",
+ Short: "Read and write the facts of a workflow run",
+ Long: `Read and write the facts of a workflow run`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get the facts of a workflow run
+ create Create or replace the facts of a workflow run
+ update Update the facts of a workflow run`)
+ },
+ }
+ cmd.PersistentFlags().String("run-id", "", "The workflow run ID.")
+ _ = cmd.MarkPersistentFlagRequired("run-id")
+ cmd.AddCommand(
+ newFactsReadCmd(c),
+ newFactsCreateCmd(c),
+ newFactsUpdateCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/create.go b/go/cmd/workflowsteptemplate/create.go
new file mode 100644
index 0000000..9fe12b7
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/create.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowsteptemplate"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a workflow step template",
+ Long: `Create a workflow step template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ createFirstRevision := common.Bool(cmd, "create-first-revision")
+ var req workflowsteptemplate.CreateWorkflowStepTemplate
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowStepTemplate.CreateWorkflowStepTemplate(ctx, org, createFirstRevision, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow step template created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().Bool("create-first-revision", true, "Also create the first revision of the template.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/delete.go b/go/cmd/workflowsteptemplate/delete.go
new file mode 100644
index 0000000..4dee215
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a workflow step template",
+ Long: `Delete a workflow step template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ if err := c.WorkflowStepTemplate.DeleteWorkflowStepTemplate(ctx, org, templateId); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Workflow step template deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/read.go b/go/cmd/workflowsteptemplate/read.go
new file mode 100644
index 0000000..6e199b3
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a workflow step template",
+ Long: `Get a workflow step template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ response, err := c.WorkflowStepTemplate.ReadWorkflowStepTemplate(ctx, org, templateId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/revisions_create.go b/go/cmd/workflowsteptemplate/revisions_create.go
new file mode 100644
index 0000000..56a27d2
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/revisions_create.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowsteptemplaterevision"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new revision of a workflow step template",
+ Long: `Create a new revision of a workflow step template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req workflowsteptemplaterevision.CreateWorkflowStepTemplateRevisionModel
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowStepTemplateRevision.CreateWorkflowStepTemplateRevision(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/revisions_delete.go b/go/cmd/workflowsteptemplate/revisions_delete.go
new file mode 100644
index 0000000..14715e6
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/revisions_delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a workflow step template revision",
+ Long: `Delete a workflow step template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ keepParentTemplate := common.Bool(cmd, "keep-parent-template")
+ if err := c.WorkflowStepTemplateRevision.DeleteWorkflowStepTemplateRevision(ctx, org, revisionId, keepParentTemplate); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Revision deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ cmd.Flags().Bool("keep-parent-template", false, "Keep the parent template when deleting its last revision.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/revisions_read.go b/go/cmd/workflowsteptemplate/revisions_read.go
new file mode 100644
index 0000000..bace6db
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/revisions_read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a workflow step template revision",
+ Long: `Get a workflow step template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ response, err := c.WorkflowStepTemplateRevision.ReadWorkflowStepTemplateRevision(ctx, org, revisionId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/revisions_update.go b/go/cmd/workflowsteptemplate/revisions_update.go
new file mode 100644
index 0000000..fc96bcd
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/revisions_update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowsteptemplaterevision"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow step template revision",
+ Long: `Update a workflow step template revision`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ var req workflowsteptemplaterevision.UpdateWorkflowStepTemplateRevisionModel
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowStepTemplateRevision.UpdateWorkflowStepTemplateRevision(ctx, org, revisionId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/update.go b/go/cmd/workflowsteptemplate/update.go
new file mode 100644
index 0000000..f81fd92
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowsteptemplate"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow step template",
+ Long: `Update a workflow step template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req workflowsteptemplate.UpdateWorkflowStepTemplateRequestModel
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowStepTemplate.UpdateWorkflowStepTemplate(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow step template updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowsteptemplate/workflowsteptemplate.go b/go/cmd/workflowsteptemplate/workflowsteptemplate.go
new file mode 100644
index 0000000..bf2bfa5
--- /dev/null
+++ b/go/cmd/workflowsteptemplate/workflowsteptemplate.go
@@ -0,0 +1,55 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowsteptemplate
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewWorkflowStepTemplateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "workflow-step-template",
+ Short: "Manage workflow step templates",
+ Long: `Manage workflow step templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a workflow step template
+ create Create a workflow step template
+ update Update a workflow step template
+ delete Delete a workflow step template
+ revisions Manage revisions of workflow step templates`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ newCreateCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newRevisionsCmd(c),
+ )
+ return cmd
+}
+func newRevisionsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "revisions",
+ Short: "Manage revisions of workflow step templates",
+ Long: `Manage revisions of workflow step templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new revision of a workflow step template
+ read Get a workflow step template revision
+ update Update a workflow step template revision
+ delete Delete a workflow step template revision`)
+ },
+ }
+ cmd.AddCommand(
+ newRevisionsCreateCmd(c),
+ newRevisionsReadCmd(c),
+ newRevisionsUpdateCmd(c),
+ newRevisionsDeleteCmd(c),
+ )
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/create.go b/go/cmd/workflowtemplate/create.go
new file mode 100644
index 0000000..0521f69
--- /dev/null
+++ b/go/cmd/workflowtemplate/create.go
@@ -0,0 +1,43 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowtemplates"
+ "github.com/spf13/cobra"
+)
+
+func newCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a workflow template",
+ Long: `Create a workflow template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ createFirstRevision := common.Bool(cmd, "create-first-revision")
+ var req workflowtemplates.CreateWorkflowTemplateRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowTemplates.CreateWorkflowTemplate(ctx, org, createFirstRevision, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow template created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().Bool("create-first-revision", true, "Also create the first revision of the template.")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/delete.go b/go/cmd/workflowtemplate/delete.go
new file mode 100644
index 0000000..89878a0
--- /dev/null
+++ b/go/cmd/workflowtemplate/delete.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a workflow template",
+ Long: `Delete a workflow template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ if err := c.WorkflowTemplates.DeleteWorkflowTemplate(ctx, org, templateId); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Workflow template deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/read.go b/go/cmd/workflowtemplate/read.go
new file mode 100644
index 0000000..61edcf9
--- /dev/null
+++ b/go/cmd/workflowtemplate/read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a workflow template",
+ Long: `Get a workflow template`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ response, err := c.WorkflowTemplates.ReadWorkflowTemplate(ctx, org, templateId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/revisions_create.go b/go/cmd/workflowtemplate/revisions_create.go
new file mode 100644
index 0000000..c88c783
--- /dev/null
+++ b/go/cmd/workflowtemplate/revisions_create.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowtemplaterevisions"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsCreateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "create -- payload.json",
+ Short: "Create a new revision of a workflow template",
+ Long: `Create a new revision of a workflow template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req workflowtemplaterevisions.CreateWorkflowTemplateRevisionsRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowTemplatesRevisions.CreateWorkflowTemplateRevision(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision created successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/revisions_delete.go b/go/cmd/workflowtemplate/revisions_delete.go
new file mode 100644
index 0000000..f6b59cc
--- /dev/null
+++ b/go/cmd/workflowtemplate/revisions_delete.go
@@ -0,0 +1,35 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsDeleteCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "delete",
+ Short: "Delete a workflow template revision",
+ Long: `Delete a workflow template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ keepParentTemplate := common.Bool(cmd, "keep-parent-template")
+ if err := c.WorkflowTemplatesRevisions.DeleteWorkflowTemplateRevision(ctx, org, revisionId, keepParentTemplate); err != nil {
+ return err
+ }
+ common.Done(cmd, nil, "Revision deleted successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ cmd.Flags().Bool("keep-parent-template", false, "Keep the parent template when deleting its last revision.")
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/revisions_read.go b/go/cmd/workflowtemplate/revisions_read.go
new file mode 100644
index 0000000..a72162f
--- /dev/null
+++ b/go/cmd/workflowtemplate/revisions_read.go
@@ -0,0 +1,33 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsReadCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "read",
+ Short: "Get a workflow template revision",
+ Long: `Get a workflow template revision`,
+ Args: cobra.NoArgs,
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ response, err := c.WorkflowTemplatesRevisions.ReadWorkflowTemplateRevision(ctx, org, revisionId)
+ if err != nil {
+ return err
+ }
+ common.PrintJSON(cmd, response)
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/revisions_update.go b/go/cmd/workflowtemplate/revisions_update.go
new file mode 100644
index 0000000..e90ef5b
--- /dev/null
+++ b/go/cmd/workflowtemplate/revisions_update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowtemplaterevisions"
+ "github.com/spf13/cobra"
+)
+
+func newRevisionsUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow template revision",
+ Long: `Update a workflow template revision`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ revisionId := common.String(cmd, "revision-id")
+ var req workflowtemplaterevisions.UpdateWorkflowTemplateRevisionRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowTemplatesRevisions.UpdateWorkflowTemplateRevision(ctx, org, revisionId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Revision updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("revision-id", "", "The revision ID (NAME:REVISION).")
+ _ = cmd.MarkFlagRequired("revision-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/update.go b/go/cmd/workflowtemplate/update.go
new file mode 100644
index 0000000..41777c2
--- /dev/null
+++ b/go/cmd/workflowtemplate/update.go
@@ -0,0 +1,44 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "context"
+ "errors"
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/workflowtemplates"
+ "github.com/spf13/cobra"
+)
+
+func newUpdateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "update -- payload.json",
+ Short: "Update a workflow template",
+ Long: `Update a workflow template`,
+ Args: cobra.ExactArgs(1),
+ RunE: func(cmd *cobra.Command, args []string) error {
+ ctx := context.Background()
+ org := common.Org(cmd)
+ templateId := common.String(cmd, "template-id")
+ var req workflowtemplates.UpdateWorkflowTemplateRequest
+ if err := common.ReadPayload(cmd, args, &req); err != nil {
+ if errors.Is(err, common.ErrDryRun) {
+ return nil
+ }
+ return err
+ }
+ response, err := c.WorkflowTemplates.UpdateWorkflowTemplate(ctx, org, templateId, &req)
+ if err != nil {
+ return err
+ }
+ common.Done(cmd, response, "Workflow template updated successfully.")
+ return nil
+ },
+ }
+ cmd.Flags().String("template-id", "", "The template ID.")
+ _ = cmd.MarkFlagRequired("template-id")
+ common.AddPayloadFlags(cmd)
+ common.AddOutputJSONFlag(cmd)
+ return cmd
+}
diff --git a/go/cmd/workflowtemplate/workflowtemplate.go b/go/cmd/workflowtemplate/workflowtemplate.go
new file mode 100644
index 0000000..e19eecf
--- /dev/null
+++ b/go/cmd/workflowtemplate/workflowtemplate.go
@@ -0,0 +1,55 @@
+// Code generated for sg-cli; edit the generator spec or this file directly.
+
+package workflowtemplate
+
+import (
+ "github.com/StackGuardian/sg-cli/cmd/common"
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/spf13/cobra"
+)
+
+func NewWorkflowTemplateCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "workflow-template",
+ Short: "Manage workflow (IaC) templates",
+ Long: `Manage workflow (IaC) templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ read Get a workflow template
+ create Create a workflow template
+ update Update a workflow template
+ delete Delete a workflow template
+ revisions Manage revisions of workflow (IaC) templates`)
+ },
+ }
+ common.AddOrgFlag(cmd)
+ cmd.AddCommand(
+ newReadCmd(c),
+ newCreateCmd(c),
+ newUpdateCmd(c),
+ newDeleteCmd(c),
+ newRevisionsCmd(c),
+ )
+ return cmd
+}
+func newRevisionsCmd(c *client.Client) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "revisions",
+ Short: "Manage revisions of workflow (IaC) templates",
+ Long: `Manage revisions of workflow (IaC) templates`,
+ Run: func(cmd *cobra.Command, args []string) {
+ cmd.Println(`Sub-commands:
+ create Create a new revision of a workflow template
+ read Get a workflow template revision
+ update Update a workflow template revision
+ delete Delete a workflow template revision`)
+ },
+ }
+ cmd.AddCommand(
+ newRevisionsCreateCmd(c),
+ newRevisionsReadCmd(c),
+ newRevisionsUpdateCmd(c),
+ newRevisionsDeleteCmd(c),
+ )
+ return cmd
+}
diff --git a/go/go.mod b/go/go.mod
index 77fa3c0..ce3cf37 100644
--- a/go/go.mod
+++ b/go/go.mod
@@ -3,7 +3,7 @@ module github.com/StackGuardian/sg-cli
go 1.22.4
require (
- github.com/StackGuardian/sg-sdk-go v1.1.0
+ github.com/StackGuardian/sg-sdk-go v1.5.7-0.20260904121004-674afe6f5c4c
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
)
diff --git a/go/go.sum b/go/go.sum
index 7b5d0f2..461f109 100644
--- a/go/go.sum
+++ b/go/go.sum
@@ -1,5 +1,5 @@
-github.com/StackGuardian/sg-sdk-go v1.1.0 h1:rE56fGomuuT7KLudgYSWdyPLgj4b72965V1mojtQbAU=
-github.com/StackGuardian/sg-sdk-go v1.1.0/go.mod h1:iCrgHE0WbxEaaLx6ATsRe81Qjp82kahCwLGJ2t66mZ0=
+github.com/StackGuardian/sg-sdk-go v1.5.7-0.20260904121004-674afe6f5c4c h1:m92lop+JvQ7kmeog/g99dlSyKSkcbubzlEITDdLZrUU=
+github.com/StackGuardian/sg-sdk-go v1.5.7-0.20260904121004-674afe6f5c4c/go.mod h1:iCrgHE0WbxEaaLx6ATsRe81Qjp82kahCwLGJ2t66mZ0=
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
diff --git a/go/tests/matrix_a_test.go b/go/tests/matrix_a_test.go
new file mode 100644
index 0000000..cd628d1
--- /dev/null
+++ b/go/tests/matrix_a_test.go
@@ -0,0 +1,169 @@
+package tests
+
+import (
+ "net/url"
+ "testing"
+
+ "github.com/StackGuardian/sg-cli/cmd/apiaccess"
+ "github.com/StackGuardian/sg-cli/cmd/apitoken"
+ "github.com/StackGuardian/sg-cli/cmd/auditlog"
+ "github.com/StackGuardian/sg-cli/cmd/benchmarkreport"
+ "github.com/StackGuardian/sg-cli/cmd/billing"
+ "github.com/StackGuardian/sg-cli/cmd/chat"
+ "github.com/StackGuardian/sg-cli/cmd/connector"
+ "github.com/StackGuardian/sg-cli/cmd/connectorgroup"
+ "github.com/StackGuardian/sg-cli/cmd/organization"
+ "github.com/StackGuardian/sg-cli/cmd/policy"
+ "github.com/StackGuardian/sg-cli/cmd/resource"
+ "github.com/StackGuardian/sg-cli/cmd/role"
+ "github.com/StackGuardian/sg-cli/cmd/rolebinding"
+ "github.com/StackGuardian/sg-cli/cmd/runnergroup"
+ "github.com/StackGuardian/sg-cli/cmd/secret"
+ "github.com/StackGuardian/sg-cli/cmd/statebackend"
+ "github.com/StackGuardian/sg-cli/cmd/user"
+)
+
+const org = "/api/v1/orgs/demo-org/"
+
+func TestOrganizationCommands(t *testing.T) {
+ runMatrix(t, []matrixCase{
+ {name: "read", ctor: organization.NewOrganizationCmd, args: []string{"read", "--org", "demo-org"}, method: "GET", path: org},
+ {name: "create", ctor: organization.NewOrganizationCmd, args: []string{"create", "@payload"}, payloadJSON: `{"ResourceName":"neworg"}`, method: "POST", path: "/api/v1/orgs/", body: `{"ResourceName":"neworg"}`, wantOut: "Organization created successfully."},
+ {name: "list", ctor: organization.NewOrganizationCmd, args: []string{"list"}, method: "GET", path: "/api/v1/orgs/listall/", resp: `{"msg":["a"]}`},
+ {name: "update", ctor: organization.NewOrganizationCmd, args: []string{"update", "--org", "demo-org", "@payload"}, payloadJSON: `{"ExtraSgCreditsLimit":5}`, method: "PATCH", path: org, body: `{"ExtraSgCreditsLimit":5}`, wantOut: "Organization updated successfully."},
+ {name: "delete", ctor: organization.NewOrganizationCmd, args: []string{"delete", "--org", "demo-org"}, method: "DELETE", path: org, wantOut: "Organization archived successfully."},
+ {name: "workflows", ctor: organization.NewOrganizationCmd, args: []string{"workflows", "--org", "demo-org", "--limit", "5", "--fetch-sg-owned-wfs=false", "--resource-names", "n"}, method: "GET", path: org + "wfs/listall/", query: url.Values{"limit": {"5"}, "fetchSgOwnedWfs": {"false"}, "resourceNames": {"n"}}, resp: `{"msg":[]}`},
+ {name: "count", ctor: organization.NewOrganizationCmd, args: []string{"count-workflows", "--org", "demo-org", "--tags", "t"}, method: "GET", path: org + "wfs/listall/", query: url.Values{"onlyCount": {"1"}, "tags": {"t"}}, resp: `{"msg":3}`},
+ {name: "bulk action", ctor: organization.NewOrganizationCmd, args: []string{"bulk-action", "--org", "demo-org", "--action", "activate", "--resource-ids", "/wfgrps/g/wfs/w,/wfgrps/g/stacks/s"}, method: "POST", path: org + "wfs/bulk-action/", body: `{"action":"activate","resourceIds":["/wfgrps/g/wfs/w","/wfgrps/g/stacks/s"]}`, wantOut: "Bulk action submitted."},
+ })
+}
+
+func TestAccessCommands(t *testing.T) {
+ runMatrix(t, []matrixCase{
+ {name: "user read", ctor: user.NewUserCmd, args: []string{"read", "--org", "demo-org", "--user-id", "u@x"}, method: "POST", path: org + "get_user/", body: `{"userId":"u@x"}`},
+ {name: "user create", ctor: user.NewUserCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"userId":"u@x","role":"ADMIN"}`, method: "POST", path: org + "invite_user/", body: `{"userId":"u@x","role":"ADMIN"}`, wantOut: "User invited successfully."},
+ {name: "user delete", ctor: user.NewUserCmd, args: []string{"delete", "--org", "demo-org", "--alias", "grp"}, method: "POST", path: org + "remove_user/", body: `{"alias":"grp"}`, wantOut: "User removed successfully."},
+ {name: "user update", ctor: user.NewUserCmd, args: []string{"update", "--org", "demo-org", "@payload"}, payloadJSON: `{"userId":"u@x","role":"USER"}`, method: "POST", path: org + "update_user/", body: `{"userId":"u@x","role":"USER"}`, wantOut: "User updated successfully."},
+ {name: "user list", ctor: user.NewUserCmd, args: []string{"list", "--org", "demo-org", "--entity-type", "EMAIL", "--roles", "ADMIN"}, method: "GET", path: org + "users/listall/", query: url.Values{"entityType": {"EMAIL"}, "roles": {"ADMIN"}}},
+ {name: "role create", ctor: role.NewRoleCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"r1"}`, method: "POST", path: org + "roles/", body: `{"ResourceName":"r1"}`, wantOut: "Role created successfully."},
+ {name: "role read", ctor: role.NewRoleCmd, args: []string{"read", "--org", "demo-org", "--role-id", "r1"}, method: "GET", path: org + "roles/r1/"},
+ {name: "role update", ctor: role.NewRoleCmd, args: []string{"update", "--org", "demo-org", "--role-id", "r1", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: org + "roles/r1/", body: `{"ResourceName":"r1","Description":"d"}`, wantOut: "Role updated successfully."},
+ {name: "role delete", ctor: role.NewRoleCmd, args: []string{"delete", "--org", "demo-org", "--role-id", "r1"}, method: "DELETE", path: org + "roles/r1/", wantOut: "Role deleted successfully."},
+ {name: "role list", ctor: role.NewRoleCmd, args: []string{"list", "--org", "demo-org", "--include-predefined-roles"}, method: "GET", path: org + "roles/listall/", query: url.Values{"includePredefinedRoles": {"true"}}, resp: `{"msg":[]}`},
+ {name: "role binding", ctor: rolebinding.NewRoleBindingCmd, args: []string{"read", "--org", "demo-org"}, method: "GET", path: org + "rolebindings/default/"},
+ {name: "api access create", ctor: apiaccess.NewApiAccessCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"k1"}`, method: "POST", path: org + "apiaccesses/", body: `{"ResourceName":"k1"}`, wantOut: "API access created successfully."},
+ {name: "api access read", ctor: apiaccess.NewApiAccessCmd, args: []string{"read", "--org", "demo-org", "--access-id", "id1"}, method: "GET", path: org + "apiaccesses/id1/"},
+ {name: "api access update", ctor: apiaccess.NewApiAccessCmd, args: []string{"update", "--org", "demo-org", "--access-id", "id1", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: org + "apiaccesses/id1/", body: `{"Description":"d"}`, wantOut: "API access updated successfully."},
+ {name: "api access delete", ctor: apiaccess.NewApiAccessCmd, args: []string{"delete", "--org", "demo-org", "--access-id", "id1"}, method: "DELETE", path: org + "apiaccesses/id1/", wantOut: "API access deleted successfully."},
+ {name: "api access regenerate", ctor: apiaccess.NewApiAccessCmd, args: []string{"regenerate-key", "--org", "demo-org", "--access-id", "id1", "--no-expiration"}, method: "POST", path: org + "apiaccesses/id1/regenerate/", body: `{"ExpiresAt":null}`, wantOut: "API key regenerated."},
+ {name: "api access list", ctor: apiaccess.NewApiAccessCmd, args: []string{"list", "--org", "demo-org", "--access-type", "APIKEY", "--limit", "10", "--status", "active"}, method: "GET", path: org + "apiaccesses/listall/", query: url.Values{"accessType": {"APIKEY"}, "limit": {"10"}, "status": {"active"}}},
+ {name: "api token create", ctor: apitoken.NewApiTokenCmd, args: []string{"create", "--org", "demo-org", "--regenerate"}, method: "POST", path: org + "api_token/", body: `{"regenerate":true}`, wantOut: "API token request completed."},
+ {name: "api token delete", ctor: apitoken.NewApiTokenCmd, args: []string{"delete", "--org", "demo-org", "--principal-id", "pool/idp/u@x"}, method: "DELETE", path: org + "api_token/", body: `"pool/idp/u@x"`, wantOut: "API token revoked."},
+ {name: "audit logs", ctor: auditlog.NewAuditLogCmd, args: []string{"list", "--org", "demo-org", "--effect", "Allow", "--start-time", "1", "--limit", "5"}, method: "GET", path: org + "audit_logs/", query: url.Values{"effect": {"Allow"}, "startTime": {"1"}, "limit": {"5"}}},
+ {name: "benchmark", ctor: benchmarkreport.NewBenchmarkReportCmd, args: []string{"read", "--org", "demo-org", "--detailed", "--filter-csp", "AWS", "--limit", "2"}, method: "GET", path: org + "reports/benchmark/", query: url.Values{"detailed": {"true"}, "filter:CSP": {"AWS"}, "limit": {"2"}}, resp: `[]`},
+ })
+}
+
+func TestSecretPolicyCommands(t *testing.T) {
+ runMatrix(t, []matrixCase{
+ {name: "secret create", ctor: secret.NewSecretCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"s","ResourceValue":"v"}`, method: "POST", path: org + "secrets/", body: `{"ResourceName":"s","ResourceValue":"v"}`, wantOut: "Secret created successfully."},
+ {name: "secret update", ctor: secret.NewSecretCmd, args: []string{"update", "--org", "demo-org", "--secret-id", "s", "@payload"}, payloadJSON: `{"ResourceValue":"v2"}`, method: "PATCH", path: org + "secrets/s/", body: `{"ResourceName":"s","ResourceValue":"v2"}`, wantOut: "Secret updated successfully."},
+ {name: "secret delete", ctor: secret.NewSecretCmd, args: []string{"delete", "--org", "demo-org", "--secret-id", "s"}, method: "DELETE", path: org + "secrets/s/", wantOut: "Secret deleted successfully."},
+ {name: "secret list", ctor: secret.NewSecretCmd, args: []string{"list", "--org", "demo-org"}, method: "GET", path: org + "secrets/listall/"},
+ {name: "secret read bulk", ctor: secret.NewSecretCmd, args: []string{"read-bulk", "--org", "demo-org", "--names", "a,b"}, method: "POST", path: org + "secrets/listall/", body: `{"ResourceNames":["a","b"]}`, resp: `{"msg":[]}`},
+ {name: "policy create", ctor: policy.NewPolicyCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"PolicyType":"GENERAL","ResourceName":"p"}`, method: "POST", path: org + "policies/", body: `{"PolicyType":"GENERAL","ResourceName":"p"}`, wantOut: "Policy created successfully."},
+ {name: "policy read", ctor: policy.NewPolicyCmd, args: []string{"read", "--org", "demo-org", "--policy-id", "p"}, method: "GET", path: org + "policies/p/"},
+ {name: "policy update", ctor: policy.NewPolicyCmd, args: []string{"update", "--org", "demo-org", "--policy-id", "p", "@payload"}, payloadJSON: `{"PolicyType":"GENERAL","Description":"d"}`, method: "PATCH", path: org + "policies/p/", body: `{"PolicyType":"GENERAL","Description":"d"}`, wantOut: "Policy updated successfully."},
+ {name: "policy delete", ctor: policy.NewPolicyCmd, args: []string{"delete", "--org", "demo-org", "--policy-id", "p"}, method: "DELETE", path: org + "policies/p/", wantOut: "Policy deleted successfully."},
+ {name: "policy list", ctor: policy.NewPolicyCmd, args: []string{"list", "--org", "demo-org", "--search-query", "q", "--limit", "5"}, method: "GET", path: org + "policies/listall/", query: url.Values{"searchQuery": {"q"}, "limit": {"5"}}, resp: `{"msg":[]}`},
+ })
+}
+
+func TestConnectorCommands(t *testing.T) {
+ base := org + "integrations/"
+ gbase := org + "integrationgroups/"
+ runMatrix(t, []matrixCase{
+ {name: "create", ctor: connector.NewConnectorCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"c"}`, method: "POST", path: base, body: `{"ResourceName":"c"}`, wantOut: "Connector created successfully."},
+ {name: "read", ctor: connector.NewConnectorCmd, args: []string{"read", "--org", "demo-org", "--connector-id", "c"}, method: "GET", path: base + "c/"},
+ {name: "update", ctor: connector.NewConnectorCmd, args: []string{"update", "--org", "demo-org", "--connector-id", "c", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: base + "c/", body: `{"Description":"d"}`, wantOut: "Connector updated successfully."},
+ {name: "delete", ctor: connector.NewConnectorCmd, args: []string{"delete", "--org", "demo-org", "--connector-id", "c"}, method: "DELETE", path: base + "c/", wantOut: "Connector deleted successfully."},
+ {name: "list", ctor: connector.NewConnectorCmd, args: []string{"list", "--org", "demo-org", "--kind", "AWS_RBAC", "--limit", "5"}, method: "GET", path: base + "listall/", query: url.Values{"kind": {"AWS_RBAC"}, "limit": {"5"}}},
+ {name: "authenticate", ctor: connector.NewConnectorCmd, args: []string{"authenticate", "--org", "demo-org", "--connector-id", "c"}, method: "GET", path: base + "c/authenticate/"},
+ {name: "list accounts", ctor: connector.NewConnectorCmd, args: []string{"list-accounts", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceId":"g"}`, method: "POST", path: base + "list_accounts/", body: `{"ResourceId":"g"}`, resp: `{"msg":[]}`, wantOut: `"msg": []`},
+ {name: "github repos", ctor: connector.NewConnectorCmd, args: []string{"github-repos", "--org", "demo-org", "--connector-id", "c"}, method: "GET", path: base + "c/get_githubcom_repos/", resp: `{"msg":["o/r"]}`},
+ {name: "repos", ctor: connector.NewConnectorCmd, args: []string{"repos", "--org", "demo-org", "--connector-id", "c", "--login", "l", "--page", "2", "--limit", "5"}, method: "GET", path: base + "c/repos/", query: url.Values{"login": {"l"}, "page": {"2"}, "limit": {"5"}}},
+ {name: "group create", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"g"}`, method: "POST", path: gbase, body: `{"ResourceName":"g"}`, wantOut: "Connector group created successfully."},
+ {name: "group read", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"read", "--org", "demo-org", "--connector-group", "g"}, method: "GET", path: gbase + "g/"},
+ {name: "group update", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"update", "--org", "demo-org", "--connector-group", "g", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: gbase + "g/", body: `{"Description":"d"}`, wantOut: "Connector group updated successfully."},
+ {name: "group delete", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"delete", "--org", "demo-org", "--connector-group", "g"}, method: "DELETE", path: gbase + "g/", wantOut: "Connector group deleted successfully."},
+ {name: "group authenticate", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"authenticate", "--org", "demo-org", "--connector-group", "g"}, method: "GET", path: gbase + "g/authenticate/"},
+ {name: "group list", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"list", "--org", "demo-org", "--scope", "s"}, method: "GET", path: gbase + "listall/", query: url.Values{"scope": {"s"}}},
+ {name: "group discovery scan", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"discovery-scan", "--org", "demo-org", "--connector-group", "g", "--benchmark", "inventory"}, method: "POST", path: gbase + "g/discovery_scan/", query: url.Values{"benchmark": {"inventory"}}, wantOut: "Discovery scan triggered."},
+ {name: "child read", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"connectors", "read", "--org", "demo-org", "--connector-group", "g", "--connector-id", "c"}, method: "GET", path: gbase + "g/integrations/c/"},
+ {name: "child update", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"connectors", "update", "--org", "demo-org", "--connector-group", "g", "--connector-id", "c", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: gbase + "g/integrations/c/", body: `{"Description":"d"}`, wantOut: "Connector updated successfully."},
+ {name: "child delete", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"connectors", "delete", "--org", "demo-org", "--connector-group", "g", "--connector-id", "c"}, method: "DELETE", path: gbase + "g/integrations/c/", wantOut: "Connector deleted successfully."},
+ {name: "child list", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"connectors", "list", "--org", "demo-org", "--connector-group", "g", "--kind", "k"}, method: "GET", path: gbase + "g/integrations/listall/", query: url.Values{"kind": {"k"}}},
+ {name: "child authenticate", ctor: connectorgroup.NewConnectorGroupCmd, args: []string{"connectors", "authenticate", "--org", "demo-org", "--connector-group", "g", "--connector-id", "c"}, method: "GET", path: gbase + "g/integrations/c/authenticate/"},
+ })
+}
+
+func TestRunnerStateBackendResourceCommands(t *testing.T) {
+ rbase := org + "runnergroups/"
+ sbase := org + "statebackends/"
+ runMatrix(t, []matrixCase{
+ {name: "runner create", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"rg"}`, method: "POST", path: rbase, body: `{"ResourceName":"rg"}`, wantOut: "Runner group created successfully."},
+ {name: "runner read", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"read", "--org", "demo-org", "--runner-group", "rg", "--get-active-workflows"}, method: "GET", path: rbase + "rg/", query: url.Values{"getActiveWorkflows": {"true"}}},
+ {name: "runner update", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"update", "--org", "demo-org", "--runner-group", "rg", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: rbase + "rg/", body: `{"Description":"d"}`, wantOut: "Runner group updated successfully."},
+ {name: "runner delete", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"delete", "--org", "demo-org", "--runner-group", "rg"}, method: "DELETE", path: rbase + "rg/", wantOut: "Runner group deleted successfully."},
+ {name: "runner list", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"list", "--org", "demo-org", "--limit", "5"}, method: "GET", path: rbase + "listall/", query: url.Values{"limit": {"5"}}, resp: `{"msg":[]}`},
+ {name: "runner register", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"register", "--org", "demo-org", "--runner-group", "rg"}, method: "POST", path: rbase + "rg/register/", wantOut: "Runner registered."},
+ {name: "runner storage auth", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"storage-backend-auth", "--org", "demo-org", "--runner-group", "rg"}, method: "POST", path: rbase + "rg/storage-backend-auth/"},
+ {name: "runner deregister", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"deregister-runner", "--org", "demo-org", "--runner-group", "rg", "--runner-id", "r1", "--container-instance-ids", "a,b", "--force"}, method: "POST", path: rbase + "rg/deregister/", body: `{"RunnerId":"r1","ContainerInstanceIds":["a","b"],"ForceDeregister":true}`, wantOut: "Runner deregistered."},
+ {name: "runner state", ctor: runnergroup.NewRunnerGroupCmd, args: []string{"update-runner-state", "--org", "demo-org", "--runner-group", "rg", "--status", "DRAINING", "--runner-id", "r1"}, method: "POST", path: rbase + "rg/runner_status/", body: `{"RunnerId":"r1","Status":"DRAINING"}`, wantOut: "Runner state updated."},
+ {name: "state backend create", ctor: statebackend.NewStateBackendCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"sb","Statefiles":[],"StateBackendConfig":{"type":"aws_s3","s3BucketName":"b","auth":{"integrationId":"/integrations/aws"}}}`, method: "POST", path: sbase, body: `{"ResourceName":"sb","Statefiles":[],"StateBackendConfig":{"type":"aws_s3","s3BucketName":"b","auth":{"integrationId":"/integrations/aws"}}}`, wantOut: "State backend created successfully."},
+ {name: "state backend read", ctor: statebackend.NewStateBackendCmd, args: []string{"read", "--org", "demo-org", "--state-backend", "sb"}, method: "GET", path: sbase + "sb/"},
+ {name: "state backend update", ctor: statebackend.NewStateBackendCmd, args: []string{"update", "--org", "demo-org", "--state-backend", "sb", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: sbase + "sb/", body: `{"Description":"d"}`, wantOut: "State backend updated successfully."},
+ {name: "state backend delete", ctor: statebackend.NewStateBackendCmd, args: []string{"delete", "--org", "demo-org", "--state-backend", "sb"}, method: "DELETE", path: sbase + "sb/", wantOut: "State backend deleted successfully."},
+ {name: "state backend list", ctor: statebackend.NewStateBackendCmd, args: []string{"list", "--org", "demo-org", "--search-query", "q"}, method: "GET", path: sbase + "listall/", query: url.Values{"searchQuery": {"q"}}},
+ {name: "state backend statefiles", ctor: statebackend.NewStateBackendCmd, args: []string{"list-statefiles", "--org", "demo-org", "--config", "abc"}, method: "GET", path: sbase + "list_statefiles/", query: url.Values{"config": {"abc"}}},
+ {name: "resource move", ctor: resource.NewResourceCmd, args: []string{"move", "--org", "demo-org", "--source-ids", "/a,/b", "--destination", "/wfgrps/g"}, method: "POST", path: org + "resources/move/", body: `{"SourceResourceIds":["/a","/b"],"DestinationParentId":"/wfgrps/g"}`, wantOut: "Resources moved."},
+ {name: "resource search", ctor: resource.NewResourceCmd, args: []string{"search", "--org", "demo-org", "--search-query", "q", "--resource-types", "WORKFLOW,STACK", "--limit", "5"}, method: "POST", path: org + "search/", body: `{"SearchQuery":"q","ResourceTypes":["WORKFLOW","STACK"],"Limit":5}`, wantOut: `"msg"`},
+ {name: "resource tags", ctor: resource.NewResourceCmd, args: []string{"tags", "--org", "demo-org", "--context-tag-key", "env", "--limit", "5"}, method: "GET", path: org + "search/tags/", query: url.Values{"ContextTagKey": {"env"}, "Limit": {"5"}}},
+ })
+}
+
+func TestBillingChatCommands(t *testing.T) {
+ bbase := org + "billing/"
+ cbase := org + "chats/"
+ runMatrix(t, []matrixCase{
+ {name: "balance", ctor: billing.NewBillingCmd, args: []string{"balance", "--org", "demo-org"}, method: "GET", path: bbase + "list-balance/"},
+ {name: "dashboard", ctor: billing.NewBillingCmd, args: []string{"dashboard-url", "--org", "demo-org", "--type", "usage"}, method: "GET", path: bbase + "dashboard/", query: url.Values{"type": {"usage"}}},
+ {name: "invoices", ctor: billing.NewBillingCmd, args: []string{"invoices", "--org", "demo-org", "--limit", "5", "--next-page", "c"}, method: "GET", path: bbase + "invoices/", query: url.Values{"limit": {"5"}, "next_page": {"c"}}},
+ {name: "details", ctor: billing.NewBillingCmd, args: []string{"details", "--org", "demo-org"}, method: "GET", path: bbase + "details/"},
+ {name: "change plan", ctor: billing.NewBillingCmd, args: []string{"change-plan", "--org", "demo-org", "--target-package", "SG | Standard"}, method: "POST", path: bbase + "change-plan/", body: `{"TargetPackage":"SG | Standard"}`, wantOut: "Plan change submitted."},
+ {name: "profile setup", ctor: billing.NewBillingCmd, args: []string{"profile", "setup", "--org", "demo-org", "@payload"}, payloadJSON: `{"Email":"e@x"}`, method: "POST", path: bbase + "profile/", body: `{"Email":"e@x"}`, wantOut: "Billing profile created."},
+ {name: "profile update", ctor: billing.NewBillingCmd, args: []string{"profile", "update", "--org", "demo-org", "@payload"}, payloadJSON: `{"Name":"n"}`, method: "PATCH", path: bbase + "profile/", body: `{"Name":"n"}`, wantOut: "Billing profile updated."},
+ {name: "payment list", ctor: billing.NewBillingCmd, args: []string{"payment-methods", "list", "--org", "demo-org"}, method: "GET", path: bbase + "payment-methods/"},
+ {name: "payment intent", ctor: billing.NewBillingCmd, args: []string{"payment-methods", "setup-intent", "--org", "demo-org"}, method: "POST", path: bbase + "payment-methods/"},
+ {name: "payment default", ctor: billing.NewBillingCmd, args: []string{"payment-methods", "set-default", "--org", "demo-org", "--payment-method-id", "pm_1"}, method: "POST", path: bbase + "set-default-payment-method/", body: `{"PaymentMethodId":"pm_1"}`, wantOut: "Default payment method set."},
+ {name: "payment detach", ctor: billing.NewBillingCmd, args: []string{"payment-methods", "detach", "--org", "demo-org", "--payment-method-id", "pm_1"}, method: "POST", path: bbase + "detach-card/", body: `{"PaymentMethodId":"pm_1"}`, wantOut: "Card detached."},
+ {name: "chat create", ctor: chat.NewChatCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ChatType":"kyro","Config":{}}`, method: "POST", path: cbase, body: `{"ChatType":"kyro","Config":{}}`, wantOut: "Chat created successfully."},
+ {name: "chat list", ctor: chat.NewChatCmd, args: []string{"list", "--org", "demo-org", "--chat-type", "kyro", "--refresh-pr-status"}, method: "GET", path: cbase + "listall/", query: url.Values{"chatType": {"kyro"}, "refreshPrStatus": {"true"}}, resp: `{"msg":[]}`},
+ {name: "chat read", ctor: chat.NewChatCmd, args: []string{"read", "--org", "demo-org", "--chat-id", "c1"}, method: "GET", path: cbase + "c1/"},
+ {name: "chat update", ctor: chat.NewChatCmd, args: []string{"update", "--org", "demo-org", "--chat-id", "c1", "@payload"}, payloadJSON: `{"Status":"archived"}`, method: "PATCH", path: cbase + "c1/", body: `{"Status":"archived"}`, wantOut: "Chat updated successfully."},
+ {name: "chat delete", ctor: chat.NewChatCmd, args: []string{"delete", "--org", "demo-org", "--chat-id", "c1"}, method: "DELETE", path: cbase + "c1/", wantOut: "Chat archived successfully."},
+ {name: "chat commit", ctor: chat.NewChatCmd, args: []string{"commit-bundle", "--org", "demo-org", "--chat-id", "c1", "--expected-version", "3"}, method: "POST", path: cbase + "c1/commit_bundle/", body: `{"expected_version":3}`, wantOut: "Bundle committed."},
+ {name: "chat create pr", ctor: chat.NewChatCmd, args: []string{"create-pr", "--org", "demo-org", "--chat-id", "c1", "@payload"}, payloadJSON: `{"vcsConnector":"v","repoUrl":"https://x"}`, method: "POST", path: cbase + "c1/create_pr/", body: `{"vcsConnector":"v","repoUrl":"https://x"}`, wantOut: "Pull request request completed."},
+ {name: "chat pr status", ctor: chat.NewChatCmd, args: []string{"pr-status", "--org", "demo-org", "--chat-id", "c1"}, method: "GET", path: cbase + "c1/pr_status/"},
+ {name: "chat pr sync", ctor: chat.NewChatCmd, args: []string{"pr-sync-status", "--org", "demo-org", "--chat-id", "c1"}, method: "GET", path: cbase + "c1/pr_sync_status/"},
+ {name: "chat artifacts list", ctor: chat.NewChatCmd, args: []string{"artifacts", "list", "--org", "demo-org", "--chat-id", "c1", "--prefix", "p"}, method: "GET", path: cbase + "c1/listall_artifacts/", query: url.Values{"prefix": {"p"}}},
+ {name: "chat artifact url", ctor: chat.NewChatCmd, args: []string{"artifacts", "get-url", "--org", "demo-org", "--chat-id", "c1", "--artifact-path", "a"}, method: "GET", path: cbase + "c1/get_artifact/", query: url.Values{"artifactPath": {"a"}}},
+ {name: "chat artifact upload", ctor: chat.NewChatCmd, args: []string{"artifacts", "upload-url", "--org", "demo-org", "--chat-id", "c1", "--artifact-path", "a", "--content-type", "text/plain"}, method: "POST", path: cbase + "c1/save_artifact/", query: url.Values{"artifactPath": {"a"}, "contentType": {"text/plain"}}},
+ {name: "message create", ctor: chat.NewChatCmd, args: []string{"messages", "create", "--org", "demo-org", "--chat-id", "c1", "--text", "hi", "--client-request-id", "r1"}, method: "POST", path: cbase + "c1/messages/", body: `{"content":[{"type":"text","text":"hi"}],"clientRequestId":"r1"}`, wantOut: "Message sent."},
+ {name: "message create payload", ctor: chat.NewChatCmd, args: []string{"messages", "create", "--org", "demo-org", "--chat-id", "c1", "@payload"}, payloadJSON: `{"content":[{"type":"tool_result","toolUseId":"t","isError":true}]}`, method: "POST", path: cbase + "c1/messages/", body: `{"content":[{"type":"tool_result","toolUseId":"t","isError":true}]}`, wantOut: "Message sent."},
+ {name: "messages list", ctor: chat.NewChatCmd, args: []string{"messages", "list", "--org", "demo-org", "--chat-id", "c1", "--limit", "5"}, method: "GET", path: cbase + "c1/messages/listall/", query: url.Values{"limit": {"5"}}, resp: `{"msg":[]}`},
+ {name: "message read", ctor: chat.NewChatCmd, args: []string{"messages", "read", "--org", "demo-org", "--chat-id", "c1", "--message-id", "m1"}, method: "GET", path: cbase + "c1/messages/m1/"},
+ {name: "message cancel", ctor: chat.NewChatCmd, args: []string{"messages", "cancel", "--org", "demo-org", "--chat-id", "c1", "--message-id", "m1"}, method: "POST", path: cbase + "c1/messages/m1/cancel/", wantOut: "Message cancelled."},
+ {name: "message retry", ctor: chat.NewChatCmd, args: []string{"messages", "retry", "--org", "demo-org", "--chat-id", "c1", "--message-id", "m1"}, method: "POST", path: cbase + "c1/messages/m1/retry/", wantOut: "Message retried."},
+ })
+}
diff --git a/go/tests/matrix_b_test.go b/go/tests/matrix_b_test.go
new file mode 100644
index 0000000..6db1c4b
--- /dev/null
+++ b/go/tests/matrix_b_test.go
@@ -0,0 +1,182 @@
+package tests
+
+import (
+ "net/url"
+ "testing"
+
+ artifactscmd "github.com/StackGuardian/sg-cli/cmd/artifacts"
+ stackcmd "github.com/StackGuardian/sg-cli/cmd/stack"
+ "github.com/StackGuardian/sg-cli/cmd/stackrun"
+ "github.com/StackGuardian/sg-cli/cmd/stacktemplate"
+ "github.com/StackGuardian/sg-cli/cmd/stackworkflow"
+ "github.com/StackGuardian/sg-cli/cmd/stackworkflowrun"
+ "github.com/StackGuardian/sg-cli/cmd/template"
+ workflowcmd "github.com/StackGuardian/sg-cli/cmd/workflow"
+ "github.com/StackGuardian/sg-cli/cmd/workflowgroup"
+ "github.com/StackGuardian/sg-cli/cmd/workflowrun"
+ "github.com/StackGuardian/sg-cli/cmd/workflowsteptemplate"
+ "github.com/StackGuardian/sg-cli/cmd/workflowtemplate"
+)
+
+func TestWorkflowGroupCommands(t *testing.T) {
+ base := org + "wfgrps/"
+ runMatrix(t, []matrixCase{
+ {name: "create", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"ResourceName":"g"}`, method: "POST", path: base, body: `{"ResourceName":"g"}`, wantOut: "Workflow group created successfully."},
+ {name: "read nested", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"read", "--org", "demo-org", "--workflow-group", "parent/child"}, method: "GET", path: base + "parent/child/"},
+ {name: "update", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"update", "--org", "demo-org", "--workflow-group", "g", "@payload"}, payloadJSON: `{"Description":"d"}`, method: "PATCH", path: base + "g/", body: `{"Description":"d"}`, wantOut: "Workflow group updated successfully."},
+ {name: "delete", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"delete", "--org", "demo-org", "--workflow-group", "g"}, method: "DELETE", path: base + "g/", wantOut: "Workflow group deleted successfully."},
+ {name: "create child", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"create-child", "--org", "demo-org", "--parent", "g", "@payload"}, payloadJSON: `{"ResourceName":"c"}`, method: "POST", path: base + "g/wfgrps/", body: `{"ResourceName":"c"}`, wantOut: "Child workflow group created successfully."},
+ {name: "list children", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"list-children", "--org", "demo-org", "--parent", "g", "--limit", "5"}, method: "GET", path: base + "g/wfgrps/listall/", query: url.Values{"limit": {"5"}}},
+ {name: "list", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"list", "--org", "demo-org", "--search-query", "q"}, method: "GET", path: base + "listall/", query: url.Values{"searchQuery": {"q"}}},
+ {name: "list resources", ctor: workflowgroup.NewWorkflowGroupCmd, args: []string{"list-resources", "--org", "demo-org", "--workflow-group", "g", "--resource-types", "WORKFLOW,STACK", "--limit", "5"}, method: "GET", path: base + "g/listall/", query: url.Values{"resourceTypes": {"WORKFLOW,STACK"}, "limit": {"5"}}, resp: `{"msg":[]}`},
+ })
+}
+
+func TestWorkflowExtraCommands(t *testing.T) {
+ base := org + "wfgrps/g/wfs/w/"
+ scope := []string{"--org", "demo-org", "--workflow-group", "g"}
+ with := func(args ...string) []string { return append(args, scope...) }
+ runMatrix(t, []matrixCase{
+ {name: "update", ctor: workflowcmd.NewWorkflowCmd, args: with("update", "--workflow-id", "w", "--upgrade-mode", "MANUAL", "@payload"), payloadJSON: `{"Description":"d"}`, method: "PATCH", path: base, query: url.Values{"upgradeMode": {"MANUAL"}}, body: `{"Description":"d"}`, wantOut: "Workflow updated successfully."},
+ {name: "outputs", ctor: workflowcmd.NewWorkflowCmd, args: with("outputs", "--workflow-id", "w"), method: "GET", path: base + "outputs/"},
+ {name: "compare", ctor: workflowcmd.NewWorkflowCmd, args: with("compare", "--workflow-id", "w", "--target-template-id", "/o/t"), method: "POST", path: base + "compare/", body: `{"targetTemplateId":"/o/t"}`, wantOut: `"msg"`},
+ {name: "file upload url", ctor: workflowcmd.NewWorkflowCmd, args: with("file-upload-url", "--workflow-id", "w", "--filename", "f", "--folder", "d"), method: "GET", path: base + "file_upload_url/", query: url.Values{"filename": {"f"}, "folder": {"d"}}},
+ {name: "tfstate upload url", ctor: workflowcmd.NewWorkflowCmd, args: with("tfstate-upload-url", "--workflow-id", "w", "--filename", "s.json"), method: "GET", path: base + "tfstate_upload_url/", query: url.Values{"filename": {"s.json"}}},
+ {name: "vcs triggers", ctor: workflowcmd.NewWorkflowCmd, args: with("vcs-triggers", "--workflow-id", "w", "@payload"), payloadJSON: `{}`, method: "POST", path: base + "webhooks/vcs_triggers/", body: `{"VCSConfig":null,"VCSTriggers":null}`, wantOut: "VCS triggers created successfully."},
+ {name: "artifact url", ctor: artifactscmd.NewArtifactsCmd, args: with("get-url", "--workflow-id", "w", "--artifact-path", "p", "--version-id", "v"), method: "GET", path: base + "get_artifact/", query: url.Values{"artifactPath": {"p"}, "versionId": {"v"}}},
+ {name: "artifact read", ctor: artifactscmd.NewArtifactsCmd, args: with("read", "--workflow-id", "w", "--artifact-id", "a/b.json"), method: "GET", path: base + "artifacts/a/b.json/", resp: `{"v":4}`},
+ {name: "artifact create", ctor: artifactscmd.NewArtifactsCmd, args: with("create", "--workflow-id", "w", "--artifact-id", "tf", "@payload"), payloadJSON: `{"version":4}`, method: "POST", path: base + "artifacts/tf/", body: `{"version":4}`, wantOut: "Artifact created successfully."},
+ {name: "artifact delete", ctor: artifactscmd.NewArtifactsCmd, args: with("delete", "--workflow-id", "w", "--artifact-id", "tf"), method: "DELETE", path: base + "artifacts/tf/", wantOut: "Artifact deleted successfully."},
+ {name: "artifact versions", ctor: artifactscmd.NewArtifactsCmd, args: with("versions", "--workflow-id", "w", "--artifact-id", "tf", "--limit", "5"), method: "GET", path: base + "artifacts/tf/versions/", query: url.Values{"limit": {"5"}}},
+ {name: "artifact rollback", ctor: artifactscmd.NewArtifactsCmd, args: with("rollback", "--workflow-id", "w", "--artifact-id", "tf", "--version-id", "v"), method: "POST", path: base + "artifacts/tf/rollback/", body: `{"VersionId":"v"}`, wantOut: "Artifact rolled back."},
+ {name: "artifact lock", ctor: artifactscmd.NewArtifactsCmd, args: with("lock", "--workflow-id", "w", "--artifact-id", "tf"), method: "POST", path: base + "artifacts/tf/lock/", resp: `{"ID":"x"}`, wantOut: "Artifact locked."},
+ {name: "artifact unlock", ctor: artifactscmd.NewArtifactsCmd, args: with("unlock", "--workflow-id", "w", "--artifact-id", "tf"), method: "DELETE", path: base + "artifacts/tf/lock/", resp: `{"ID":"x"}`, wantOut: "Artifact unlocked."},
+ })
+}
+
+func TestStackCommands(t *testing.T) {
+ base := org + "wfgrps/g/stacks/"
+ scope := []string{"--org", "demo-org", "--workflow-group", "g"}
+ with := func(args ...string) []string { return append(args, scope...) }
+ runMatrix(t, []matrixCase{
+ {name: "read", ctor: stackcmd.NewStackCmd, args: with("read", "--stack-id", "s"), method: "GET", path: base + "s/"},
+ {name: "update", ctor: stackcmd.NewStackCmd, args: with("update", "--stack-id", "s", "@payload"), payloadJSON: `{"Description":"d"}`, method: "PATCH", path: base + "s/", body: `{"Description":"d"}`, wantOut: "Stack updated successfully."},
+ {name: "list", ctor: stackcmd.NewStackCmd, args: with("list", "--tags", "t"), method: "GET", path: base + "listall/", query: url.Values{"Tags": {"t"}}},
+ {name: "compare", ctor: stackcmd.NewStackCmd, args: with("compare", "--stack-id", "s", "--target-template-group-id", "/o/t", "--upgrade-mode", "MANUAL"), method: "POST", path: base + "s/compare/", body: `{"targetTemplateGroupId":"/o/t","upgradeMode":"MANUAL"}`, wantOut: `"msg"`},
+ {name: "run create", ctor: stackrun.NewStackRunCmd, args: with("create", "--stack-id", "s", "--action-type", "APPLY"), method: "POST", path: base + "s/stackruns/", body: `{"ActionType":"APPLY"}`, wantOut: "Stack run created successfully."},
+ {name: "run read", ctor: stackrun.NewStackRunCmd, args: with("read", "--stack-id", "s", "--run-id", "r1"), method: "GET", path: base + "s/stackruns/r1/"},
+ {name: "run list", ctor: stackrun.NewStackRunCmd, args: with("list", "--stack-id", "s", "--limit", "5"), method: "GET", path: base + "s/stackruns/listall/", query: url.Values{"limit": {"5"}}},
+ })
+}
+
+func TestStackWorkflowCommands(t *testing.T) {
+ base := org + "wfgrps/g/stacks/s/wfs/"
+ scope := []string{"--org", "demo-org", "--workflow-group", "g", "--stack-id", "s"}
+ with := func(args ...string) []string { return append(args, scope...) }
+ runMatrix(t, []matrixCase{
+ {name: "create", ctor: stackworkflow.NewStackWorkflowCmd, args: with("create", "@payload"), payloadJSON: `{"ResourceName":"w"}`, method: "POST", path: base, body: `{"ResourceName":"w"}`, wantOut: "Stack workflow created successfully."},
+ {name: "read", ctor: stackworkflow.NewStackWorkflowCmd, args: with("read", "--workflow-id", "w"), method: "GET", path: base + "w/"},
+ {name: "update", ctor: stackworkflow.NewStackWorkflowCmd, args: with("update", "--workflow-id", "w", "@payload"), payloadJSON: `{"Description":"d"}`, method: "PATCH", path: base + "w/", body: `{"Description":"d"}`, wantOut: "Stack workflow updated successfully."},
+ {name: "delete", ctor: stackworkflow.NewStackWorkflowCmd, args: with("delete", "--workflow-id", "w"), method: "DELETE", path: base + "w/", wantOut: "Stack workflow deleted successfully."},
+ {name: "list", ctor: stackworkflow.NewStackWorkflowCmd, args: with("list", "--latest-wf-run-statuses", "3", "--limit", "5"), method: "GET", path: base + "listall/", query: url.Values{"LatestWfRunStatuses": {"3"}, "limit": {"5"}}},
+ {name: "outputs", ctor: stackworkflow.NewStackWorkflowCmd, args: with("outputs", "--workflow-id", "w"), method: "GET", path: base + "w/outputs/"},
+ {name: "tfstate url", ctor: stackworkflow.NewStackWorkflowCmd, args: with("tfstate-upload-url", "--workflow-id", "w", "--filename", "s.json"), method: "GET", path: base + "w/tfstate_upload_url/", query: url.Values{"filename": {"s.json"}}},
+ {name: "file upload url", ctor: stackworkflow.NewStackWorkflowCmd, args: with("file-upload-url", "--workflow-id", "w", "--filename", "f"), method: "GET", path: base + "w/file_upload_url/", query: url.Values{"filename": {"f"}}},
+ {name: "compare", ctor: stackworkflow.NewStackWorkflowCmd, args: with("compare", "--workflow-id", "w", "--target-template-id", "/o/t"), method: "POST", path: base + "w/compare/", body: `{"targetTemplateId":"/o/t"}`, wantOut: `"msg"`},
+ {name: "vcs triggers", ctor: stackworkflow.NewStackWorkflowCmd, args: with("vcs-triggers", "--workflow-id", "w", "@payload"), payloadJSON: `{}`, method: "POST", path: base + "w/webhooks/vcs_triggers/", body: `{"VCSConfig":null,"VCSTriggers":null}`, wantOut: "VCS triggers created successfully."},
+ {name: "artifacts list", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "list", "--workflow-id", "w"), method: "GET", path: base + "w/listall_artifacts/"},
+ {name: "artifact url", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "get-url", "--workflow-id", "w", "--artifact-path", "p"), method: "GET", path: base + "w/get_artifact/", query: url.Values{"artifactPath": {"p"}}},
+ {name: "artifact read", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "read", "--workflow-id", "w", "--artifact-id", "tf"), method: "GET", path: base + "w/artifacts/tf/", resp: `{"v":1}`},
+ {name: "artifact create", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "create", "--workflow-id", "w", "--artifact-id", "tf", "@payload"), payloadJSON: `[1,2]`, method: "POST", path: base + "w/artifacts/tf/", body: `[1,2]`, wantOut: "Artifact created successfully."},
+ {name: "artifact delete", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "delete", "--workflow-id", "w", "--artifact-id", "tf"), method: "DELETE", path: base + "w/artifacts/tf/", wantOut: "Artifact deleted successfully."},
+ {name: "artifact lock", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "lock", "--workflow-id", "w", "--artifact-id", "tf"), method: "POST", path: base + "w/artifacts/tf/lock/", resp: `{"ID":"x"}`, wantOut: "Artifact locked."},
+ {name: "artifact unlock", ctor: stackworkflow.NewStackWorkflowCmd, args: with("artifacts", "unlock", "--workflow-id", "w", "--artifact-id", "tf"), method: "DELETE", path: base + "w/artifacts/tf/lock/", resp: `{"ID":"x"}`, wantOut: "Artifact unlocked."},
+ })
+}
+
+func TestRunCommands(t *testing.T) {
+ base := org + "wfgrps/g/wfs/w/wfruns/"
+ sbase := org + "wfgrps/g/stacks/s/wfs/w/wfruns/"
+ scope := []string{"--org", "demo-org", "--workflow-group", "g", "--workflow-id", "w"}
+ with := func(args ...string) []string { return append(args, scope...) }
+ sscope := []string{"--org", "demo-org", "--workflow-group", "g", "--stack-id", "s", "--workflow-id", "w"}
+ swith := func(args ...string) []string { return append(args, sscope...) }
+ runMatrix(t, []matrixCase{
+ {name: "create empty", ctor: workflowrun.NewWorkflowRunCmd, args: with("create"), method: "POST", path: base, body: `{}`, wantOut: "Workflow run created successfully."},
+ {name: "create payload", ctor: workflowrun.NewWorkflowRunCmd, args: with("create", "@payload"), payloadJSON: `{"WfType":"TERRAFORM"}`, method: "POST", path: base, body: `{"WfType":"TERRAFORM"}`, wantOut: "Workflow run created successfully."},
+ {name: "read", ctor: workflowrun.NewWorkflowRunCmd, args: with("read", "--run-id", "r1"), method: "GET", path: base + "r1/"},
+ {name: "update", ctor: workflowrun.NewWorkflowRunCmd, args: with("update", "--run-id", "r1", "@payload"), payloadJSON: `{"WfType":"CUSTOM"}`, method: "PATCH", path: base + "r1/", body: `{"WfType":"CUSTOM"}`, wantOut: "Workflow run updated successfully."},
+ {name: "cancel", ctor: workflowrun.NewWorkflowRunCmd, args: with("cancel", "--run-id", "r1"), method: "PATCH", path: base + "r1/cancel/", wantOut: "Workflow run cancelled."},
+ {name: "delete", ctor: workflowrun.NewWorkflowRunCmd, args: with("delete", "--run-id", "r1"), method: "DELETE", path: base + "r1/", wantOut: "Workflow run cancelled."},
+ {name: "logs", ctor: workflowrun.NewWorkflowRunCmd, args: with("logs", "--run-id", "r1"), method: "GET", path: base + "r1/logs/"},
+ {name: "approve", ctor: workflowrun.NewWorkflowRunCmd, args: with("approve", "--run-id", "r1", "--message", "ok"), method: "POST", path: base + "r1/resume/", body: `{"Approve":true,"Message":"ok"}`, wantOut: "Approval decision submitted."},
+ {name: "reject", ctor: workflowrun.NewWorkflowRunCmd, args: with("approve", "--run-id", "r1", "--reject", "--approval-step", "plan"), method: "POST", path: base + "r1/resume/", body: `{"Approve":false,"ApprovalStep":"plan"}`, wantOut: "Approval decision submitted."},
+ {name: "list", ctor: workflowrun.NewWorkflowRunCmd, args: with("list", "--context-tags", "c", "--limit", "5"), method: "GET", path: base + "listall/", query: url.Values{"contextTags": {"c"}, "limit": {"5"}}},
+ {name: "read by ksuid", ctor: workflowrun.NewWorkflowRunCmd, args: []string{"read-by-ksuid", "--org", "demo-org", "--parent-ksuid", "pk", "--resource-ksuid", "rk"}, method: "GET", path: org + "wfs/pk/wfruns/rk/"},
+ {name: "update by ksuid", ctor: workflowrun.NewWorkflowRunCmd, args: []string{"update-by-ksuid", "--org", "demo-org", "--parent-ksuid", "pk", "--resource-ksuid", "rk", "@payload"}, payloadJSON: `{"WfType":"CUSTOM"}`, method: "PATCH", path: org + "wfs/pk/wfruns/rk/", body: `{"WfType":"CUSTOM"}`, wantOut: "Workflow run updated successfully."},
+ {name: "facts read", ctor: workflowrun.NewWorkflowRunCmd, args: with("facts", "read", "--run-id", "r1", "--facts-id", "f1"), method: "GET", path: base + "r1/wfrunfacts/f1/", resp: `{"facts":1}`},
+ {name: "facts create", ctor: workflowrun.NewWorkflowRunCmd, args: with("facts", "create", "--run-id", "r1", "--facts-id", "f1", "@payload"), payloadJSON: `{"TfDrift":{"a":1}}`, method: "POST", path: base + "r1/wfrunfacts/f1/", body: `{"TfDrift":{"a":1}}`, resp: `{"msg":"ok"}`, wantOut: "Workflow run facts created."},
+ {name: "facts update", ctor: workflowrun.NewWorkflowRunCmd, args: with("facts", "update", "--run-id", "r1", "--facts-id", "f1", "@payload"), payloadJSON: `{"Tags":["a"]}`, method: "PATCH", path: base + "r1/wfrunfacts/f1/", body: `{"Tags":["a"]}`, resp: `{"msg":"ok"}`, wantOut: "Workflow run facts updated."},
+ {name: "stack create empty", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("create"), method: "POST", path: sbase, body: `{}`, wantOut: "Stack workflow run created successfully."},
+ {name: "stack read", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("read", "--run-id", "r1"), method: "GET", path: sbase + "r1/"},
+ {name: "stack update", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("update", "--run-id", "r1", "@payload"), payloadJSON: `{"WfType":"CUSTOM"}`, method: "PATCH", path: sbase + "r1/", body: `{"WfType":"CUSTOM"}`, wantOut: "Stack workflow run updated successfully."},
+ {name: "stack delete", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("delete", "--run-id", "r1"), method: "DELETE", path: sbase + "r1/", wantOut: "Stack workflow run cancelled."},
+ {name: "stack logs", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("logs", "--run-id", "r1"), method: "GET", path: sbase + "r1/logs/"},
+ {name: "stack approve", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("approve", "--run-id", "r1", "--reject"), method: "POST", path: sbase + "r1/resume/", body: `{"Approve":false}`, wantOut: "Approval decision submitted."},
+ {name: "stack list", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("list", "--latest-status", "RUNNING", "--limit", "5"), method: "GET", path: sbase + "listall/", query: url.Values{"latestStatus": {"RUNNING"}, "limit": {"5"}}, resp: `{"msg":[]}`},
+ {name: "stack facts read", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("facts", "read", "--run-id", "r1", "--facts-id", "f1"), method: "GET", path: sbase + "r1/wfrunfacts/f1/", resp: `{"facts":1}`},
+ {name: "stack facts create", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("facts", "create", "--run-id", "r1", "--facts-id", "f1", "@payload"), payloadJSON: `{"TfDrift":{}}`, method: "POST", path: sbase + "r1/wfrunfacts/f1/", body: `{"TfDrift":{}}`, resp: `{"msg":"ok"}`, wantOut: "Stack workflow run facts created."},
+ {name: "stack facts update", ctor: stackworkflowrun.NewStackWorkflowRunCmd, args: swith("facts", "update", "--run-id", "r1", "--facts-id", "f1", "@payload"), payloadJSON: `{"IsActive":"0"}`, method: "PATCH", path: sbase + "r1/wfrunfacts/f1/", body: `{"IsActive":"0"}`, resp: `{"msg":"ok"}`, wantOut: "Stack workflow run facts updated."},
+ })
+}
+
+func TestTemplateCommands(t *testing.T) {
+ tt := "/api/v1/templatetypes/"
+ runMatrix(t, []matrixCase{
+ {name: "list", ctor: template.NewTemplateCmd, args: []string{"list", "--org", "demo-org", "--template-type", "IAC", "--owner-orgs", "o1", "--search-query", "q"}, method: "GET", path: tt + "IAC/templates/listall/", query: url.Values{"OwnerOrgs": {"o1"}, "SearchQuery": {"q"}}},
+ {name: "list by owner", ctor: template.NewTemplateCmd, args: []string{"list-by-owner", "--org", "demo-org", "--owner-org", "owner-org", "--shared"}, method: "GET", path: "/api/v1/orgs/owner-org/templates/listall/", query: url.Values{"isSharedTemplate": {"true"}}},
+ {name: "create", ctor: template.NewTemplateCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"TemplateType":"IAC","TemplateName":"t1"}`, method: "POST", path: "/api/v1/templates/", body: `{"TemplateType":"IAC","TemplateName":"t1","OwnerOrg":"","SourceConfigKind":""}`, resp: `{"TemplateType":"IAC","TemplateName":"t1"}`, wantOut: "Template created successfully."},
+ {name: "read", ctor: template.NewTemplateCmd, args: []string{"read", "--org", "demo-org", "--template-id", "t1:5", "--template-type", "IAC"}, method: "GET", path: tt + "IAC/demo-org/t1:5/"},
+ {name: "read other owner", ctor: template.NewTemplateCmd, args: []string{"read", "--org", "demo-org", "--template-id", "t1", "--template-type", "IAC_GROUP", "--owner-org", "stackguardian"}, method: "GET", path: tt + "IAC_GROUP/stackguardian/t1/"},
+ {name: "update", ctor: template.NewTemplateCmd, args: []string{"update", "--org", "demo-org", "--template-id", "t1:2", "--template-type", "WORKFLOW_STEP", "@payload"}, payloadJSON: `{"TemplateName":"t2"}`, method: "PATCH", path: tt + "WORKFLOW_STEP/demo-org/t1:2/", body: `{"TemplateName":"t2"}`, wantOut: "Template updated successfully."},
+ {name: "delete", ctor: template.NewTemplateCmd, args: []string{"delete", "--org", "demo-org", "--template-id", "t1", "--template-type", "IAC_POLICY"}, method: "DELETE", path: tt + "IAC_POLICY/demo-org/t1/", wantOut: "Template deleted successfully."},
+ {name: "group iac", ctor: template.NewTemplateCmd, args: []string{"group-iac", "--org", "demo-org", "--template-id", "grp", "--iac-template-id", "sub:1", "--owner-org", "stackguardian"}, method: "GET", path: tt + "IAC_GROUP/stackguardian/grp/IAC/sub:1/"},
+ {name: "input schema", ctor: template.NewTemplateCmd, args: []string{"input-schema", "--org", "demo-org", "--template-id", "t1:2", "--template-type", "IAC", "--schema-type", "FORM_JSONSCHEMA"}, method: "GET", path: tt + "IAC/demo-org/t1:2/get_input_schema/", query: url.Values{"SchemaType": {"FORM_JSONSCHEMA"}}},
+ {name: "vcs triggers", ctor: template.NewTemplateCmd, args: []string{"vcs-triggers", "--org", "demo-org", "--template-id", "t1", "--template-type", "IAC", "@payload"}, payloadJSON: `{}`, method: "POST", path: tt + "IAC/demo-org/t1/webhooks/vcs_triggers/", body: `{"VCSConfig":null,"VCSTriggers":null}`, wantOut: "VCS triggers created successfully."},
+ {name: "subscriptions read", ctor: template.NewTemplateCmd, args: []string{"subscriptions", "read", "--org", "demo-org", "--subscription-type", "IACSubscriptions"}, method: "GET", path: org + "subscriptions/default/", query: url.Values{"subscriptionType": {"IACSubscriptions"}}},
+ {name: "subscriptions create", ctor: template.NewTemplateCmd, args: []string{"subscriptions", "create", "--org", "demo-org", "@payload"}, payloadJSON: `{"IACSubscriptions":{},"WfStepSubscriptions":{},"PolicySubscriptions":{},"IACGroupSubscriptions":{}}`, method: "POST", path: org + "subscriptions/", body: `{"IACSubscriptions":{},"WfStepSubscriptions":{},"PolicySubscriptions":{},"IACGroupSubscriptions":{}}`, wantOut: "Subscription created successfully."},
+ {name: "subscriptions update", ctor: template.NewTemplateCmd, args: []string{"subscriptions", "update", "--org", "demo-org", "--action", "subscribe", "@payload"}, payloadJSON: `{"IACSubscriptions":{"/o/t":{}}}`, method: "PATCH", path: org + "subscriptions/default/subscribe/", body: `{"IACSubscriptions":{"/o/t":{}}}`, wantOut: "Subscription updated successfully."},
+ {name: "artifacts list", ctor: template.NewTemplateCmd, args: []string{"artifacts", "list", "--org", "demo-org", "--template-id", "t:1", "--template-type", "IAC", "--prefix", "p"}, method: "GET", path: tt + "IAC/demo-org/t:1/listall_artifacts/", query: url.Values{"artifactPrefix": {"p"}}},
+ {name: "artifact download", ctor: template.NewTemplateCmd, args: []string{"artifacts", "download-url", "--org", "demo-org", "--template-id", "t", "--template-type", "IAC", "--artifact-id", "a", "--owner-org", "stackguardian"}, method: "GET", path: tt + "IAC/stackguardian/t/artifacts/a/download/presigned-url/"},
+ {name: "artifact upload", ctor: template.NewTemplateCmd, args: []string{"artifacts", "upload-url", "--org", "demo-org", "--template-id", "t", "--template-type", "IAC_GROUP", "--artifact-id", "a"}, method: "GET", path: tt + "IAC_GROUP/demo-org/t/artifacts/a/upload/presigned-url/"},
+ {name: "artifact delete", ctor: template.NewTemplateCmd, args: []string{"artifacts", "delete", "--org", "demo-org", "--template-id", "t", "--template-type", "IAC", "--artifact-id", "a"}, method: "DELETE", path: tt + "IAC/demo-org/t/artifacts/a/", wantOut: "Artifact deleted successfully."},
+ {name: "public list", ctor: template.NewTemplateCmd, args: []string{"public", "list", "--org", "demo-org", "--template-type", "IAC", "--owner-orgs", "stackguardian"}, method: "GET", path: "/api/v1/public/templatetypes/IAC/templates/listall/", query: url.Values{"OwnerOrgs": {"stackguardian"}}},
+ {name: "public list all", ctor: template.NewTemplateCmd, args: []string{"public", "list-all", "--org", "demo-org", "--template-types", "IAC,IAC_GROUP"}, method: "GET", path: "/api/v1/public/templates/listall/", query: url.Values{"templateTypes": {"IAC,IAC_GROUP"}}},
+ {name: "public read", ctor: template.NewTemplateCmd, args: []string{"public", "read", "--org", "demo-org", "--template-id", "t:1", "--template-type", "IAC", "--owner-org", "stackguardian"}, method: "GET", path: "/api/v1/public/templatetypes/IAC/stackguardian/t:1/"},
+ // typed template packages
+ {name: "wf tpl read", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"read", "--org", "demo-org", "--template-id", "t1"}, method: "GET", path: tt + "IAC/demo-org/t1/"},
+ {name: "wf tpl create", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"create", "--org", "demo-org", "--create-first-revision=false", "@payload"}, payloadJSON: `{"TemplateName":"t1"}`, method: "POST", path: "/api/v1/templates/", query: url.Values{"createFirstRevision": {"false"}}, body: `{"TemplateType":"IAC","TemplateName":"t1"}`, wantOut: "Workflow template created successfully."},
+ {name: "wf tpl update", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"update", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"TemplateName":"t2"}`, method: "PATCH", path: tt + "IAC/demo-org/t1/", body: `{"TemplateName":"t2"}`, wantOut: "Workflow template updated successfully."},
+ {name: "wf tpl delete", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"delete", "--org", "demo-org", "--template-id", "t1"}, method: "DELETE", path: tt + "IAC/demo-org/t1/", wantOut: "Workflow template deleted successfully."},
+ {name: "wf rev create", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"revisions", "create", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"LongDescription":"d"}`, method: "POST", path: tt + "IAC/demo-org/t1/revisions/", body: `{"TemplateType":"IAC","LongDescription":"d"}`, wantOut: "Revision created successfully."},
+ {name: "wf rev read", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"revisions", "read", "--org", "demo-org", "--revision-id", "t1:1"}, method: "GET", path: tt + "IAC/demo-org/t1:1/"},
+ {name: "wf rev update", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"revisions", "update", "--org", "demo-org", "--revision-id", "t1:1", "@payload"}, payloadJSON: `{"Alias":"a"}`, method: "PATCH", path: tt + "IAC/demo-org/t1:1/", body: `{"Alias":"a"}`, wantOut: "Revision updated successfully."},
+ {name: "wf rev delete", ctor: workflowtemplate.NewWorkflowTemplateCmd, args: []string{"revisions", "delete", "--org", "demo-org", "--revision-id", "t1:1", "--keep-parent-template"}, method: "DELETE", path: tt + "IAC/demo-org/t1:1/", query: url.Values{"keepParentTemplate": {"true"}}, wantOut: "Revision deleted successfully."},
+ {name: "step tpl read", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"read", "--org", "demo-org", "--template-id", "t1"}, method: "GET", path: tt + "WORKFLOW_STEP/demo-org/t1/"},
+ {name: "step tpl create", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"TemplateName":"t1"}`, method: "POST", path: "/api/v1/templates/", body: `{"TemplateType":"WORKFLOW_STEP","TemplateName":"t1"}`, wantOut: "Workflow step template created successfully."},
+ {name: "step tpl update", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"update", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"ShortDescription":"d"}`, method: "PATCH", path: tt + "WORKFLOW_STEP/demo-org/t1/", body: `{"ShortDescription":"d"}`, wantOut: "Workflow step template updated successfully."},
+ {name: "step tpl delete", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"delete", "--org", "demo-org", "--template-id", "t1"}, method: "DELETE", path: tt + "WORKFLOW_STEP/demo-org/t1/", wantOut: "Workflow step template deleted successfully."},
+ {name: "step rev create", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"revisions", "create", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"LongDescription":"d"}`, method: "POST", path: tt + "WORKFLOW_STEP/demo-org/t1/revisions/", body: `{"TemplateType":"WORKFLOW_STEP","LongDescription":"d"}`, wantOut: "Revision created successfully."},
+ {name: "step rev read", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"revisions", "read", "--org", "demo-org", "--revision-id", "t1:1"}, method: "GET", path: tt + "WORKFLOW_STEP/demo-org/t1:1/"},
+ {name: "step rev update", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"revisions", "update", "--org", "demo-org", "--revision-id", "t1:1", "@payload"}, payloadJSON: `{"LongDescription":"d"}`, method: "PATCH", path: tt + "WORKFLOW_STEP/demo-org/t1:1/", body: `{"LongDescription":"d"}`, wantOut: "Revision updated successfully."},
+ {name: "step rev delete", ctor: workflowsteptemplate.NewWorkflowStepTemplateCmd, args: []string{"revisions", "delete", "--org", "demo-org", "--revision-id", "t1:1"}, method: "DELETE", path: tt + "WORKFLOW_STEP/demo-org/t1:1/", wantOut: "Revision deleted successfully."},
+ {name: "stack tpl read", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"read", "--org", "demo-org", "--template-id", "t1"}, method: "GET", path: tt + "IAC_GROUP/demo-org/t1/"},
+ {name: "stack tpl create", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"create", "--org", "demo-org", "@payload"}, payloadJSON: `{"OwnerOrg":"demo-org"}`, method: "POST", path: "/api/v1/templates/", body: `{"TemplateType":"IAC_GROUP","OwnerOrg":"demo-org"}`, wantOut: "Stack template created successfully."},
+ {name: "stack tpl update", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"update", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"Tags":["a"]}`, method: "PATCH", path: tt + "IAC_GROUP/demo-org/t1/", body: `{"Tags":["a"]}`, wantOut: "Stack template updated successfully."},
+ {name: "stack tpl delete", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"delete", "--org", "demo-org", "--template-id", "t1"}, method: "DELETE", path: tt + "IAC_GROUP/demo-org/t1/", wantOut: "Stack template deleted successfully."},
+ {name: "stack rev create", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"revisions", "create", "--org", "demo-org", "--template-id", "t1", "@payload"}, payloadJSON: `{"Tags":["a"]}`, method: "POST", path: tt + "IAC_GROUP/demo-org/t1/revisions/", body: `{"TemplateType":"IAC_GROUP","Tags":["a"]}`, wantOut: "Revision created successfully."},
+ {name: "stack rev read", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"revisions", "read", "--org", "demo-org", "--revision-id", "t1:1"}, method: "GET", path: tt + "IAC_GROUP/demo-org/t1:1/"},
+ {name: "stack rev update", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"revisions", "update", "--org", "demo-org", "--revision-id", "t1:1", "@payload"}, payloadJSON: `{"LongDescription":"d"}`, method: "PATCH", path: tt + "IAC_GROUP/demo-org/t1:1/", body: `{"LongDescription":"d"}`, wantOut: "Revision updated successfully."},
+ {name: "stack rev delete", ctor: stacktemplate.NewStackTemplateCmd, args: []string{"revisions", "delete", "--org", "demo-org", "--revision-id", "t1:1", "--keep-parent-template"}, method: "DELETE", path: tt + "IAC_GROUP/demo-org/t1:1/", query: url.Values{"keepParentTemplate": {"true"}}, wantOut: "Revision deleted successfully."},
+ })
+}
diff --git a/go/tests/matrix_test.go b/go/tests/matrix_test.go
new file mode 100644
index 0000000..787329f
--- /dev/null
+++ b/go/tests/matrix_test.go
@@ -0,0 +1,118 @@
+package tests
+
+import (
+ "bytes"
+ "encoding/json"
+ "io"
+ "net/http"
+ "net/url"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/StackGuardian/sg-sdk-go/client"
+ "github.com/StackGuardian/sg-sdk-go/option"
+ "github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// recorder is an http.RoundTripper that captures the last request and answers
+// with a canned JSON body, so a command's wire format can be asserted exactly.
+type recorder struct {
+ status int
+ resp string
+
+ method string
+ path string
+ query url.Values
+ body string
+ auth string
+ calls int
+}
+
+func (r *recorder) RoundTrip(req *http.Request) (*http.Response, error) {
+ var body []byte
+ if req.Body != nil {
+ body, _ = io.ReadAll(req.Body)
+ }
+ r.method, r.path, r.query, r.body, r.auth = req.Method, req.URL.Path, req.URL.Query(), string(body), req.Header.Get("Authorization")
+ r.calls++
+ status := r.status
+ if status == 0 {
+ status = http.StatusOK
+ }
+ resp := r.resp
+ if resp == "" {
+ resp = "{}"
+ }
+ return &http.Response{
+ StatusCode: status,
+ Status: http.StatusText(status),
+ Header: http.Header{"Content-Type": {"application/json"}},
+ Body: io.NopCloser(strings.NewReader(resp)),
+ }, nil
+}
+
+// matrixCase describes one CLI invocation and the request it must produce.
+// "@payload" in args is replaced by a temp file holding payloadJSON.
+type matrixCase struct {
+ name string
+ ctor func(*client.Client) *cobra.Command
+ args []string
+ payloadJSON string
+ method string
+ path string
+ query url.Values // nil asserts no query string
+ body string // "" asserts no body
+ resp string
+ wantOut string // substring expected on stdout
+}
+
+func runMatrix(t *testing.T, cases []matrixCase) {
+ t.Helper()
+ for _, tc := range cases {
+ tc := tc
+ t.Run(tc.name, func(t *testing.T) {
+ rec := &recorder{resp: tc.resp}
+ c := client.NewClient(option.WithApiKey("apikey test-token"), option.WithHTTPClient(&http.Client{Transport: rec}))
+ cmd := tc.ctor(c)
+ args := make([]string, 0, len(tc.args))
+ for _, a := range tc.args {
+ if a == "@payload" {
+ p := filepath.Join(t.TempDir(), "payload.json")
+ require.NoError(t, os.WriteFile(p, []byte(tc.payloadJSON), 0o600))
+ a = p
+ }
+ args = append(args, a)
+ }
+ cmd.SetArgs(args)
+ var out, errOut bytes.Buffer
+ cmd.SetOut(&out)
+ cmd.SetErr(&errOut)
+ require.NoError(t, cmd.Execute(), "stderr: %s", errOut.String())
+ require.Equal(t, 1, rec.calls, "expected exactly one request")
+ assert.Equal(t, tc.method, rec.method, "method")
+ assert.Equal(t, tc.path, rec.path, "path")
+ if tc.query == nil {
+ assert.Empty(t, rec.query, "query")
+ } else {
+ assert.Equal(t, tc.query, rec.query, "query")
+ }
+ if tc.body == "" {
+ assert.Empty(t, rec.body, "body")
+ } else {
+ assert.JSONEq(t, tc.body, rec.body, "body")
+ }
+ assert.Equal(t, "apikey test-token", rec.auth)
+ if tc.wantOut != "" {
+ assert.Contains(t, out.String(), tc.wantOut)
+ } else {
+ // read commands print the response as JSON
+ var parsed interface{}
+ assert.NoError(t, json.Unmarshal([]byte(strings.TrimSpace(out.String())), &parsed), "stdout should be JSON: %s", out.String())
+ }
+ })
+ }
+}
diff --git a/go/tests/tree_test.go b/go/tests/tree_test.go
new file mode 100644
index 0000000..60712fa
--- /dev/null
+++ b/go/tests/tree_test.go
@@ -0,0 +1,274 @@
+package tests
+
+import (
+ "sort"
+ "strings"
+ "testing"
+
+ "github.com/StackGuardian/sg-cli/cmd"
+ "github.com/spf13/cobra"
+ "github.com/stretchr/testify/assert"
+)
+
+// expectedLeaves pins the complete command surface (one leaf per SDK method plus
+// the apply/destroy conveniences). Update it deliberately when commands change.
+const expectedLeaves = `
+api-access create
+api-access delete
+api-access list
+api-access read
+api-access regenerate-key
+api-access update
+api-token create
+api-token delete
+artifacts create
+artifacts delete
+artifacts get-url
+artifacts list
+artifacts lock
+artifacts read
+artifacts rollback
+artifacts unlock
+artifacts versions
+audit-log list
+benchmark-report read
+billing balance
+billing change-plan
+billing dashboard-url
+billing details
+billing invoices
+billing payment-methods detach
+billing payment-methods list
+billing payment-methods set-default
+billing payment-methods setup-intent
+billing profile setup
+billing profile update
+chat artifacts get-url
+chat artifacts list
+chat artifacts upload-url
+chat commit-bundle
+chat create
+chat create-pr
+chat delete
+chat list
+chat messages cancel
+chat messages create
+chat messages list
+chat messages read
+chat messages retry
+chat pr-status
+chat pr-sync-status
+chat read
+chat update
+connector authenticate
+connector create
+connector delete
+connector github-repos
+connector list
+connector list-accounts
+connector read
+connector repos
+connector update
+connector-group authenticate
+connector-group connectors authenticate
+connector-group connectors delete
+connector-group connectors list
+connector-group connectors read
+connector-group connectors update
+connector-group create
+connector-group delete
+connector-group discovery-scan
+connector-group list
+connector-group read
+connector-group update
+organization bulk-action
+organization count-workflows
+organization create
+organization delete
+organization list
+organization read
+organization update
+organization workflows
+policy create
+policy delete
+policy list
+policy read
+policy update
+resource move
+resource search
+resource tags
+role create
+role delete
+role list
+role read
+role update
+role-binding read
+runner-group create
+runner-group delete
+runner-group deregister-runner
+runner-group list
+runner-group read
+runner-group register
+runner-group storage-backend-auth
+runner-group update
+runner-group update-runner-state
+secret create
+secret delete
+secret list
+secret read-bulk
+secret update
+stack apply
+stack compare
+stack create
+stack delete
+stack destroy
+stack list
+stack outputs
+stack read
+stack update
+stack-run create
+stack-run list
+stack-run read
+stack-template create
+stack-template delete
+stack-template read
+stack-template revisions create
+stack-template revisions delete
+stack-template revisions read
+stack-template revisions update
+stack-template update
+stack-workflow artifacts create
+stack-workflow artifacts delete
+stack-workflow artifacts get-url
+stack-workflow artifacts list
+stack-workflow artifacts lock
+stack-workflow artifacts read
+stack-workflow artifacts unlock
+stack-workflow compare
+stack-workflow create
+stack-workflow delete
+stack-workflow file-upload-url
+stack-workflow list
+stack-workflow outputs
+stack-workflow read
+stack-workflow tfstate-upload-url
+stack-workflow update
+stack-workflow vcs-triggers
+stack-workflow-run approve
+stack-workflow-run create
+stack-workflow-run delete
+stack-workflow-run facts create
+stack-workflow-run facts read
+stack-workflow-run facts update
+stack-workflow-run list
+stack-workflow-run logs
+stack-workflow-run read
+stack-workflow-run update
+state-backend create
+state-backend delete
+state-backend list
+state-backend list-statefiles
+state-backend read
+state-backend update
+template artifacts delete
+template artifacts download-url
+template artifacts list
+template artifacts upload-url
+template create
+template delete
+template group-iac
+template input-schema
+template list
+template list-by-owner
+template public list
+template public list-all
+template public read
+template read
+template subscriptions create
+template subscriptions read
+template subscriptions update
+template update
+template vcs-triggers
+user create
+user delete
+user list
+user read
+user update
+workflow apply
+workflow compare
+workflow create
+workflow delete
+workflow destroy
+workflow file-upload-url
+workflow list
+workflow outputs
+workflow read
+workflow tfstate-upload-url
+workflow update
+workflow vcs-triggers
+workflow-group create
+workflow-group create-child
+workflow-group delete
+workflow-group list
+workflow-group list-children
+workflow-group list-resources
+workflow-group read
+workflow-group update
+workflow-run approve
+workflow-run cancel
+workflow-run create
+workflow-run delete
+workflow-run facts create
+workflow-run facts read
+workflow-run facts update
+workflow-run list
+workflow-run logs
+workflow-run read
+workflow-run read-by-ksuid
+workflow-run update
+workflow-run update-by-ksuid
+workflow-step-template create
+workflow-step-template delete
+workflow-step-template read
+workflow-step-template revisions create
+workflow-step-template revisions delete
+workflow-step-template revisions read
+workflow-step-template revisions update
+workflow-step-template update
+workflow-template create
+workflow-template delete
+workflow-template read
+workflow-template revisions create
+workflow-template revisions delete
+workflow-template revisions read
+workflow-template revisions update
+workflow-template update
+`
+
+func leafCommands(root *cobra.Command) []string {
+ var leaves []string
+ var walk func(c *cobra.Command, prefix string)
+ walk = func(c *cobra.Command, prefix string) {
+ if c.Name() == "help" || c.Name() == "completion" {
+ return
+ }
+ if !c.HasSubCommands() {
+ leaves = append(leaves, prefix+c.Name())
+ return
+ }
+ for _, sub := range c.Commands() {
+ walk(sub, prefix+c.Name()+" ")
+ }
+ }
+ for _, sub := range root.Commands() {
+ walk(sub, "")
+ }
+ sort.Strings(leaves)
+ return leaves
+}
+
+func TestCommandTree(t *testing.T) {
+ want := strings.Split(strings.TrimSpace(expectedLeaves), "\n")
+ assert.Equal(t, want, leafCommands(cmd.RootCommand()))
+ assert.Len(t, want, 230)
+}
diff --git a/go/tests/workflow_test.go b/go/tests/workflow_test.go
index e7ac627..1e0d343 100644
--- a/go/tests/workflow_test.go
+++ b/go/tests/workflow_test.go
@@ -98,8 +98,8 @@ func TestReadWorkflow(t *testing.T) {
tc.expectedStruct.Msg.Authors,
actualResponse.Msg.Authors)
}
- if actualResponse.Msg.Description != tc.expectedStruct.Msg.Description {
- t.Fatalf("expected \"%s\" got \"%s\"",
+ if !reflect.DeepEqual(actualResponse.Msg.Description, tc.expectedStruct.Msg.Description) {
+ t.Fatalf("expected \"%v\" got \"%v\"",
tc.expectedStruct.Msg.Description,
actualResponse.Msg.Description)
}