diff --git a/cmd/environment.go b/cmd/environment.go index 60a3b66..17dddc8 100644 --- a/cmd/environment.go +++ b/cmd/environment.go @@ -87,30 +87,80 @@ func NewCmdEnvironment() *cobra.Command { RunE: runEnvironmentDefault, } - environmentPreviewCmd := &cobra.Command{ - Use: "preview [ID]", - Short: "Converge a preview environment from a YAML config", - Long: helpdocs.MustRender("environment/preview"), - Args: cobra.ExactArgs(1), - RunE: runEnvironmentPreview, - } - environmentPreviewCmd.Flags().StringP("file", "f", "preview.yaml", "Path to the preview config YAML") - environmentPreviewCmd.Flags().StringP("name", "n", "", "Environment name (defaults to ID if not provided)") - environmentPreviewCmd.Flags().StringP("description", "d", "", "Optional environment description") - environmentPreviewCmd.Flags().StringToStringP("attributes", "a", nil, "Custom attributes for ABAC (e.g. -a environment=preview,region=uswest). Overrides `attributes:` in the config file.") - environmentPreviewCmd.Flags().Bool("follow", false, "Stream every deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id.") - environmentCmd.AddCommand(environmentExportCmd) environmentCmd.AddCommand(environmentGetCmd) environmentCmd.AddCommand(environmentListCmd) environmentCmd.AddCommand(environmentCreateCmd) environmentCmd.AddCommand(environmentUpdateCmd) environmentCmd.AddCommand(environmentDefaultCmd) - environmentCmd.AddCommand(environmentPreviewCmd) + environmentCmd.AddCommand(newEnvironmentPreviewCmd()) + environmentCmd.AddCommand(newEnvironmentForkCmd()) + environmentCmd.AddCommand(newEnvironmentDeployCmd()) + environmentCmd.AddCommand(newEnvironmentDecommissionCmd()) return environmentCmd } +func newEnvironmentPreviewCmd() *cobra.Command { + c := &cobra.Command{ + Use: "preview [ID]", + Short: "Converge a preview environment from a YAML config", + Long: helpdocs.MustRender("environment/preview"), + Args: cobra.ExactArgs(1), + RunE: runEnvironmentPreview, + } + c.Flags().StringP("file", "f", "preview.yaml", "Path to the preview config YAML") + c.Flags().StringP("name", "n", "", "Environment name (defaults to ID if not provided)") + c.Flags().StringP("description", "d", "", "Optional environment description") + c.Flags().StringToStringP("attributes", "a", nil, "Custom attributes for ABAC (e.g. -a environment=preview,region=uswest). Overrides `attributes:` in the config file.") + c.Flags().Bool("follow", false, "Stream every deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id.") + return c +} + +func newEnvironmentForkCmd() *cobra.Command { + c := &cobra.Command{ + Use: "fork [parent-environment] [new-ID]", + Short: "Fork an existing environment", + Example: `mass environment fork ecomm-production staging`, + Long: helpdocs.MustRender("environment/fork"), + Args: cobra.ExactArgs(2), + RunE: runEnvironmentFork, + } + c.Flags().StringP("name", "n", "", "Environment name (defaults to new-ID if not provided)") + c.Flags().StringP("description", "d", "", "Optional environment description") + c.Flags().StringToStringP("attributes", "a", nil, "Custom attributes for ABAC (e.g. -a region=uswest)") + c.Flags().Bool("copy-environment-defaults", false, "Copy the parent's default resource connections into the fork") + c.Flags().Bool("copy-secrets", false, "Copy every instance's secrets from the parent into the fork") + c.Flags().Bool("copy-remote-references", false, "Copy every instance's remote references from the parent into the fork") + return c +} + +func newEnvironmentDeployCmd() *cobra.Command { + c := &cobra.Command{ + Use: "deploy [environment]", + Short: "Deploy every instance in an environment, in dependency order", + Example: `mass environment deploy ecomm-staging --follow`, + Long: helpdocs.MustRender("environment/deploy"), + Args: cobra.ExactArgs(1), + RunE: runEnvironmentDeploy, + } + c.Flags().Bool("follow", false, "Stream every deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id.") + return c +} + +func newEnvironmentDecommissionCmd() *cobra.Command { + c := &cobra.Command{ + Use: "decommission [environment]", + Short: "Decommission every instance in an environment, in reverse dependency order", + Example: `mass environment decommission ecomm-pr42 --follow`, + Long: helpdocs.MustRender("environment/decommission"), + Args: cobra.ExactArgs(1), + RunE: runEnvironmentDecommission, + } + c.Flags().Bool("follow", false, "Stream every decommission deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id.") + return c +} + func runEnvironmentExport(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -443,3 +493,124 @@ func runEnvironmentPreview(cmd *cobra.Command, args []string) error { } return nil } + +func runEnvironmentFork(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + parentID := args[0] + newLocalID := args[1] + name, err := cmd.Flags().GetString("name") + if err != nil { + return err + } + description, err := cmd.Flags().GetString("description") + if err != nil { + return err + } + attrs, err := cmd.Flags().GetStringToString("attributes") + if err != nil { + return err + } + copyDefaults, err := cmd.Flags().GetBool("copy-environment-defaults") + if err != nil { + return err + } + copySecrets, err := cmd.Flags().GetBool("copy-secrets") + if err != nil { + return err + } + copyRefs, err := cmd.Flags().GetBool("copy-remote-references") + if err != nil { + return err + } + + if name == "" { + name = newLocalID + } + + cmd.SilenceUsage = true + + mdClient, mdClientErr := massdriver.NewClient() + if mdClientErr != nil { + return fmt.Errorf("error initializing massdriver client: %w", mdClientErr) + } + + input := environments.ForkInput{ + ID: newLocalID, + Name: name, + Description: description, + Attributes: cli.AttributesToAnyMap(attrs), + CopyEnvironmentDefaults: copyDefaults, + CopySecrets: copySecrets, + CopyRemoteReferences: copyRefs, + } + + env, err := mdClient.Environments.Fork(ctx, parentID, input) + if err != nil { + return err + } + + fmt.Printf("✅ Environment `%s` forked from `%s`\n", env.ID, parentID) + fmt.Printf("🔗 %s\n", mdClient.URLs.Helper(ctx).EnvironmentURL(env.ID)) + return nil +} + +func runEnvironmentDeploy(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + environmentID := args[0] + follow, err := cmd.Flags().GetBool("follow") + if err != nil { + return err + } + + cmd.SilenceUsage = true + + mdClient, mdClientErr := massdriver.NewClient() + if mdClientErr != nil { + return fmt.Errorf("error initializing massdriver client: %w", mdClientErr) + } + + env, err := mdClient.Environments.Deploy(ctx, environmentID) + if err != nil { + return err + } + + fmt.Printf("🚀 Deploying environment `%s` — instances roll out in dependency order asynchronously\n", env.ID) + fmt.Printf("🔗 %s\n", mdClient.URLs.Helper(ctx).EnvironmentURL(env.ID)) + + if follow { + return environment.FollowEnvironment(ctx, environment.NewFollowAPI(mdClient), env.ID, os.Stdout) + } + return nil +} + +func runEnvironmentDecommission(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + environmentID := args[0] + follow, err := cmd.Flags().GetBool("follow") + if err != nil { + return err + } + + cmd.SilenceUsage = true + + mdClient, mdClientErr := massdriver.NewClient() + if mdClientErr != nil { + return fmt.Errorf("error initializing massdriver client: %w", mdClientErr) + } + + env, err := mdClient.Environments.Decommission(ctx, environmentID) + if err != nil { + return err + } + + fmt.Printf("🔻 Decommissioning environment `%s` — instances tear down in reverse dependency order asynchronously\n", env.ID) + fmt.Printf("🔗 %s\n", mdClient.URLs.Helper(ctx).EnvironmentURL(env.ID)) + + if follow { + return environment.FollowEnvironment(ctx, environment.NewFollowAPI(mdClient), env.ID, os.Stdout) + } + return nil +} diff --git a/cmd/instance.go b/cmd/instance.go index f5d63af..04dbdd3 100644 --- a/cmd/instance.go +++ b/cmd/instance.go @@ -124,10 +124,29 @@ func NewCmdInstance() *cobra.Command { instanceCmd.AddCommand(instanceVersionCmd) instanceCmd.AddCommand(instanceDestroyCmd) instanceCmd.AddCommand(instanceOrphanCmd) + instanceCmd.AddCommand(newInstanceCopyCmd()) return instanceCmd } +func newInstanceCopyCmd() *cobra.Command { + c := &cobra.Command{ + Use: `copy [source] --to [destination]`, + Aliases: []string{"promote"}, + Short: "Copy an instance's configuration to another instance of the same component", + Example: `mass instance promote ecomm-staging-db --to ecomm-production-db --copy-secrets`, + Long: helpdocs.MustRender("instance/copy"), + Args: cobra.ExactArgs(1), + RunE: runInstanceCopy, + } + c.Flags().String("to", "", "Destination instance (required). Must be built from the same component as the source.") + c.Flags().StringP("overrides", "o", "", "Path to a JSON or YAML file of param overrides deep-merged onto the source params") + c.Flags().Bool("copy-secrets", false, "Copy secrets from the source instance to the destination") + c.Flags().Bool("copy-remote-references", false, "Copy remote-reference overrides from the source instance to the destination") + _ = c.MarkFlagRequired("to") + return c +} + func runInstanceGet(cmd *cobra.Command, args []string) error { ctx := context.Background() @@ -306,6 +325,58 @@ func readParams(path string) (map[string]any, error) { return params, nil } +func runInstanceCopy(cmd *cobra.Command, args []string) error { + ctx := context.Background() + + sourceID := args[0] + destinationID, err := cmd.Flags().GetString("to") + if err != nil { + return err + } + overridesPath, err := cmd.Flags().GetString("overrides") + if err != nil { + return err + } + copySecrets, err := cmd.Flags().GetBool("copy-secrets") + if err != nil { + return err + } + copyRefs, err := cmd.Flags().GetBool("copy-remote-references") + if err != nil { + return err + } + + cmd.SilenceUsage = true + + var overrides map[string]any + if overridesPath != "" { + overrides, err = readParams(overridesPath) + if err != nil { + return err + } + } + + mdClient, mdClientErr := massdriver.NewClient() + if mdClientErr != nil { + return fmt.Errorf("error initializing massdriver client: %w", mdClientErr) + } + + input := instances.CopyInput{ + Overrides: overrides, + CopySecrets: copySecrets, + CopyRemoteReferences: copyRefs, + } + + inst, err := mdClient.Instances.Copy(ctx, sourceID, destinationID, input) + if err != nil { + return err + } + + fmt.Printf("✅ Instance `%s` configuration copied to `%s`\n", sourceID, destinationID) + fmt.Printf("🔗 %s\n", mdClient.URLs.Helper(ctx).InstanceURL(inst.ID)) + return nil +} + func runInstanceExport(cmd *cobra.Command, args []string) error { ctx := context.Background() diff --git a/docs/generated/mass_environment.md b/docs/generated/mass_environment.md index f64efb1..d6a9837 100644 --- a/docs/generated/mass_environment.md +++ b/docs/generated/mass_environment.md @@ -27,8 +27,11 @@ Environments can be modeled by application stage (production, staging, developme * [mass](/cli/commands/mass) - Massdriver Cloud CLI * [mass environment create](/cli/commands/mass_environment_create) - Create an environment +* [mass environment decommission](/cli/commands/mass_environment_decommission) - Decommission every instance in an environment, in reverse dependency order * [mass environment default](/cli/commands/mass_environment_default) - Set an environment default connection +* [mass environment deploy](/cli/commands/mass_environment_deploy) - Deploy every instance in an environment, in dependency order * [mass environment export](/cli/commands/mass_environment_export) - Export an environment from Massdriver +* [mass environment fork](/cli/commands/mass_environment_fork) - Fork an existing environment * [mass environment get](/cli/commands/mass_environment_get) - Get an environment from Massdriver * [mass environment list](/cli/commands/mass_environment_list) - List environments * [mass environment preview](/cli/commands/mass_environment_preview) - Converge a preview environment from a YAML config diff --git a/docs/generated/mass_environment_decommission.md b/docs/generated/mass_environment_decommission.md new file mode 100644 index 0000000..642e85a --- /dev/null +++ b/docs/generated/mass_environment_decommission.md @@ -0,0 +1,80 @@ +--- +id: mass_environment_decommission.md +slug: /cli/commands/mass_environment_decommission +title: Mass Environment Decommission +sidebar_label: Mass Environment Decommission +--- +## mass environment decommission + +Decommission every instance in an environment, in reverse dependency order + +### Synopsis + +# Decommission Environment + +Tears down every instance in an environment in reverse dependency order. +The environment shell stays in place so it can be redeployed; run +`mass environment delete` afterwards to remove the empty environment. + +Any in-flight environment deployment is cancelled and replaced. The +command returns as soon as the decommission wave is enqueued; instances +are torn down asynchronously. + +Decommissioning is blocked when the environment has +`decommissionProtection: true`. Disable it first with +`mass environment update --decommission-protection=false` (or via the +UI / API) before retrying. + +## Usage + +```bash +mass environment decommission +``` + +## Arguments + +- `environment`: full identifier of the environment to decommission + (e.g. `ecomm-pr42`). + +## Flags + +- `--follow`: stream every decommission deployment's logs to stdout + until the rollout completes. Each line is prefixed with the instance + id so the interleaved output stays grep-friendly when multiple + decommissions run in parallel. + +## Examples + +```bash +# Tear down every instance in a preview env. +mass environment decommission ecomm-pr42 + +# Tear it down and watch the logs. +mass environment decommission ecomm-pr42 --follow + +# Full preview-env teardown: decommission instances, then delete the shell. +mass environment decommission ecomm-pr42 --follow +mass environment delete ecomm-pr42 +``` + + +``` +mass environment decommission [environment] [flags] +``` + +### Examples + +``` +mass environment decommission ecomm-pr42 --follow +``` + +### Options + +``` + --follow Stream every decommission deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id. + -h, --help help for decommission +``` + +### SEE ALSO + +* [mass environment](/cli/commands/mass_environment) - Environment management diff --git a/docs/generated/mass_environment_deploy.md b/docs/generated/mass_environment_deploy.md new file mode 100644 index 0000000..fa136c6 --- /dev/null +++ b/docs/generated/mass_environment_deploy.md @@ -0,0 +1,70 @@ +--- +id: mass_environment_deploy.md +slug: /cli/commands/mass_environment_deploy +title: Mass Environment Deploy +sidebar_label: Mass Environment Deploy +--- +## mass environment deploy + +Deploy every instance in an environment, in dependency order + +### Synopsis + +# Deploy Environment + +Triggers a deployment of every instance in an environment, in dependency +order. Any in-flight environment deployment is cancelled and replaced. + +The command returns as soon as the deployment is enqueued; instances are +provisioned asynchronously. Watch the deployments stream in the UI or list +them with `mass deployment list`. + +## Usage + +```bash +mass environment deploy +``` + +## Arguments + +- `environment`: full identifier of the environment to deploy + (e.g. `ecomm-staging`). + +## Flags + +- `--follow`: stream every deployment's logs to stdout until the rollout + completes. Each line is prefixed with the instance id so the interleaved + output stays grep-friendly when multiple deployments run in parallel. + +## Examples + +```bash +# Deploy every instance in the staging environment. +mass environment deploy ecomm-staging + +# Deploy a freshly-forked preview env. +mass environment fork ecomm-production pr42 --copy-environment-defaults +mass environment deploy ecomm-pr42 +``` + + +``` +mass environment deploy [environment] [flags] +``` + +### Examples + +``` +mass environment deploy ecomm-staging --follow +``` + +### Options + +``` + --follow Stream every deployment's logs to stdout until the rollout completes. Each line is prefixed with the instance id. + -h, --help help for deploy +``` + +### SEE ALSO + +* [mass environment](/cli/commands/mass_environment) - Environment management diff --git a/docs/generated/mass_environment_fork.md b/docs/generated/mass_environment_fork.md new file mode 100644 index 0000000..5ddc2f4 --- /dev/null +++ b/docs/generated/mass_environment_fork.md @@ -0,0 +1,88 @@ +--- +id: mass_environment_fork.md +slug: /cli/commands/mass_environment_fork +title: Mass Environment Fork +sidebar_label: Mass Environment Fork +--- +## mass environment fork + +Fork an existing environment + +### Synopsis + +# Fork Environment + +Creates a new environment by forking an existing one. The fork is linked to +its parent via `parent_target_id`, and every instance is seeded with the +parent's params, version, and release channel. + +Re-running `fork` against the same parent with the same `new-ID` resets +the existing fork's state back to the parent's — params reset, defaults +re-apply, and any `--copy-*` flags re-fire. Re-running with a *different* +parent is rejected; a fork's parent is immutable. + +## Usage + +```bash +mass environment fork [flags] +``` + +## Arguments + +- `parent-environment`: full identifier of the environment to fork from + (e.g. `ecomm-production`). +- `new-ID`: local segment of the new environment's identifier. Must match + `^[a-z0-9]{1,20}$` — lowercase alphanumeric only, no dashes. The full + stored identifier becomes `-`. + +## Flags + +- `--name, -n`: human-readable name (defaults to `new-ID`). +- `--description, -d`: optional environment description. +- `--attributes, -a`: custom attributes for ABAC, e.g. + `-a region=us-east-1,data_classification=pii`. +- `--copy-environment-defaults`: also copy the parent's default resource + connections into the fork. +- `--copy-secrets`: copy every instance's secrets from the parent into the + fork. +- `--copy-remote-references`: copy every instance's remote references from + the parent into the fork. + +## Examples + +```bash +# Stand up a staging environment as a copy of production. +mass environment fork ecomm-production staging \ + --copy-environment-defaults \ + --copy-secrets + +# Re-fork to reset edits back to the parent's current state. +mass environment fork ecomm-production staging --copy-environment-defaults +``` + + +``` +mass environment fork [parent-environment] [new-ID] [flags] +``` + +### Examples + +``` +mass environment fork ecomm-production staging +``` + +### Options + +``` + -a, --attributes stringToString Custom attributes for ABAC (e.g. -a region=uswest) (default []) + --copy-environment-defaults Copy the parent's default resource connections into the fork + --copy-remote-references Copy every instance's remote references from the parent into the fork + --copy-secrets Copy every instance's secrets from the parent into the fork + -d, --description string Optional environment description + -h, --help help for fork + -n, --name string Environment name (defaults to new-ID if not provided) +``` + +### SEE ALSO + +* [mass environment](/cli/commands/mass_environment) - Environment management diff --git a/docs/generated/mass_instance.md b/docs/generated/mass_instance.md index 6eb699b..c00e6dc 100644 --- a/docs/generated/mass_instance.md +++ b/docs/generated/mass_instance.md @@ -30,6 +30,7 @@ Instances are used to: ### SEE ALSO * [mass](/cli/commands/mass) - Massdriver Cloud CLI +* [mass instance copy](/cli/commands/mass_instance_copy) - Copy an instance's configuration to another instance of the same component * [mass instance deploy](/cli/commands/mass_instance_deploy) - Deploy instances * [mass instance destroy](/cli/commands/mass_instance_destroy) - Destroy (decommission) an instance * [mass instance export](/cli/commands/mass_instance_export) - Export instances diff --git a/docs/generated/mass_instance_copy.md b/docs/generated/mass_instance_copy.md new file mode 100644 index 0000000..261a2cd --- /dev/null +++ b/docs/generated/mass_instance_copy.md @@ -0,0 +1,88 @@ +--- +id: mass_instance_copy.md +slug: /cli/commands/mass_instance_copy +title: Mass Instance Copy +sidebar_label: Mass Instance Copy +--- +## mass instance copy + +Copy an instance's configuration to another instance of the same component + +### Synopsis + +# Copy Instance + +Copies one instance's configuration to another instance of the same +component. The source's params (minus any fields the bundle marks +non-copyable) are written to the destination, optionally deep-merged with +`--overrides`. Deployment is a separate action — run `mass instance +deploy ` when you're ready to apply. + +Aliased as `promote` — same command, friendlier shape for the common +"promote staging to production" flow: + +```bash +mass instance promote ecomm-staging-db --to ecomm-production-db +mass instance deploy ecomm-production-db +``` + +## Usage + +```bash +mass instance copy --to [flags] +mass instance promote --to [flags] +``` + +## Arguments + +- `source`: full identifier of the instance to copy from + (e.g. `ecomm-staging-db`). + +## Flags + +- `--to`: destination instance (required). Must be built from the same + component as the source (e.g. `ecomm-production-db`). +- `--overrides, -o`: path to a JSON or YAML file of param overrides + deep-merged onto the source params before writing. +- `--copy-secrets`: also copy the source's secret values to the destination. +- `--copy-remote-references`: also copy the source's remote-reference + overrides to the destination. + +## Examples + +```bash +# Promote staging's config to production. +mass instance promote ecomm-staging-db --to ecomm-production-db +mass instance deploy ecomm-production-db + +# Promote with a size override and copy secrets. +mass instance copy ecomm-staging-db \ + --to ecomm-production-db \ + --overrides ./prod-overrides.yaml \ + --copy-secrets +``` + + +``` +mass instance copy [source] --to [destination] [flags] +``` + +### Examples + +``` +mass instance promote ecomm-staging-db --to ecomm-production-db --copy-secrets +``` + +### Options + +``` + --copy-remote-references Copy remote-reference overrides from the source instance to the destination + --copy-secrets Copy secrets from the source instance to the destination + -h, --help help for copy + -o, --overrides string Path to a JSON or YAML file of param overrides deep-merged onto the source params + --to string Destination instance (required). Must be built from the same component as the source. +``` + +### SEE ALSO + +* [mass instance](/cli/commands/mass_instance) - Manage instances of IaC deployed in environments. diff --git a/docs/helpdocs/environment/decommission.md b/docs/helpdocs/environment/decommission.md new file mode 100644 index 0000000..c313d08 --- /dev/null +++ b/docs/helpdocs/environment/decommission.md @@ -0,0 +1,46 @@ +# Decommission Environment + +Tears down every instance in an environment in reverse dependency order. +The environment shell stays in place so it can be redeployed; run +`mass environment delete` afterwards to remove the empty environment. + +Any in-flight environment deployment is cancelled and replaced. The +command returns as soon as the decommission wave is enqueued; instances +are torn down asynchronously. + +Decommissioning is blocked when the environment has +`decommissionProtection: true`. Disable it first with +`mass environment update --decommission-protection=false` (or via the +UI / API) before retrying. + +## Usage + +```bash +mass environment decommission +``` + +## Arguments + +- `environment`: full identifier of the environment to decommission + (e.g. `ecomm-pr42`). + +## Flags + +- `--follow`: stream every decommission deployment's logs to stdout + until the rollout completes. Each line is prefixed with the instance + id so the interleaved output stays grep-friendly when multiple + decommissions run in parallel. + +## Examples + +```bash +# Tear down every instance in a preview env. +mass environment decommission ecomm-pr42 + +# Tear it down and watch the logs. +mass environment decommission ecomm-pr42 --follow + +# Full preview-env teardown: decommission instances, then delete the shell. +mass environment decommission ecomm-pr42 --follow +mass environment delete ecomm-pr42 +``` diff --git a/docs/helpdocs/environment/deploy.md b/docs/helpdocs/environment/deploy.md new file mode 100644 index 0000000..5a6935e --- /dev/null +++ b/docs/helpdocs/environment/deploy.md @@ -0,0 +1,36 @@ +# Deploy Environment + +Triggers a deployment of every instance in an environment, in dependency +order. Any in-flight environment deployment is cancelled and replaced. + +The command returns as soon as the deployment is enqueued; instances are +provisioned asynchronously. Watch the deployments stream in the UI or list +them with `mass deployment list`. + +## Usage + +```bash +mass environment deploy +``` + +## Arguments + +- `environment`: full identifier of the environment to deploy + (e.g. `ecomm-staging`). + +## Flags + +- `--follow`: stream every deployment's logs to stdout until the rollout + completes. Each line is prefixed with the instance id so the interleaved + output stays grep-friendly when multiple deployments run in parallel. + +## Examples + +```bash +# Deploy every instance in the staging environment. +mass environment deploy ecomm-staging + +# Deploy a freshly-forked preview env. +mass environment fork ecomm-production pr42 --copy-environment-defaults +mass environment deploy ecomm-pr42 +``` diff --git a/docs/helpdocs/environment/fork.md b/docs/helpdocs/environment/fork.md new file mode 100644 index 0000000..a2d112c --- /dev/null +++ b/docs/helpdocs/environment/fork.md @@ -0,0 +1,49 @@ +# Fork Environment + +Creates a new environment by forking an existing one. The fork is linked to +its parent via `parent_target_id`, and every instance is seeded with the +parent's params, version, and release channel. + +Re-running `fork` against the same parent with the same `new-ID` resets +the existing fork's state back to the parent's — params reset, defaults +re-apply, and any `--copy-*` flags re-fire. Re-running with a *different* +parent is rejected; a fork's parent is immutable. + +## Usage + +```bash +mass environment fork [flags] +``` + +## Arguments + +- `parent-environment`: full identifier of the environment to fork from + (e.g. `ecomm-production`). +- `new-ID`: local segment of the new environment's identifier. Must match + `^[a-z0-9]{1,20}$` — lowercase alphanumeric only, no dashes. The full + stored identifier becomes `-`. + +## Flags + +- `--name, -n`: human-readable name (defaults to `new-ID`). +- `--description, -d`: optional environment description. +- `--attributes, -a`: custom attributes for ABAC, e.g. + `-a region=us-east-1,data_classification=pii`. +- `--copy-environment-defaults`: also copy the parent's default resource + connections into the fork. +- `--copy-secrets`: copy every instance's secrets from the parent into the + fork. +- `--copy-remote-references`: copy every instance's remote references from + the parent into the fork. + +## Examples + +```bash +# Stand up a staging environment as a copy of production. +mass environment fork ecomm-production staging \ + --copy-environment-defaults \ + --copy-secrets + +# Re-fork to reset edits back to the parent's current state. +mass environment fork ecomm-production staging --copy-environment-defaults +``` diff --git a/docs/helpdocs/instance/copy.md b/docs/helpdocs/instance/copy.md new file mode 100644 index 0000000..658aafa --- /dev/null +++ b/docs/helpdocs/instance/copy.md @@ -0,0 +1,51 @@ +# Copy Instance + +Copies one instance's configuration to another instance of the same +component. The source's params (minus any fields the bundle marks +non-copyable) are written to the destination, optionally deep-merged with +`--overrides`. Deployment is a separate action — run `mass instance +deploy ` when you're ready to apply. + +Aliased as `promote` — same command, friendlier shape for the common +"promote staging to production" flow: + +```bash +mass instance promote ecomm-staging-db --to ecomm-production-db +mass instance deploy ecomm-production-db +``` + +## Usage + +```bash +mass instance copy --to [flags] +mass instance promote --to [flags] +``` + +## Arguments + +- `source`: full identifier of the instance to copy from + (e.g. `ecomm-staging-db`). + +## Flags + +- `--to`: destination instance (required). Must be built from the same + component as the source (e.g. `ecomm-production-db`). +- `--overrides, -o`: path to a JSON or YAML file of param overrides + deep-merged onto the source params before writing. +- `--copy-secrets`: also copy the source's secret values to the destination. +- `--copy-remote-references`: also copy the source's remote-reference + overrides to the destination. + +## Examples + +```bash +# Promote staging's config to production. +mass instance promote ecomm-staging-db --to ecomm-production-db +mass instance deploy ecomm-production-db + +# Promote with a size override and copy secrets. +mass instance copy ecomm-staging-db \ + --to ecomm-production-db \ + --overrides ./prod-overrides.yaml \ + --copy-secrets +``` diff --git a/go.mod b/go.mod index a6aeb39..a62e962 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/itchyny/gojq v0.12.16 github.com/manifoldco/promptui v0.9.0 github.com/massdriver-cloud/airlock v0.0.9 - github.com/massdriver-cloud/massdriver-sdk-go v0.2.3 + github.com/massdriver-cloud/massdriver-sdk-go v0.2.4 github.com/mattn/go-runewidth v0.0.16 github.com/opencontainers/image-spec v1.1.1 github.com/osteele/liquid v1.7.0 diff --git a/go.sum b/go.sum index 780e02a..7594b09 100644 --- a/go.sum +++ b/go.sum @@ -127,6 +127,8 @@ github.com/massdriver-cloud/airlock v0.0.9 h1:t+jTY6nZEiPZNTKx0wEgQTPztIxL4u0RFv github.com/massdriver-cloud/airlock v0.0.9/go.mod h1:igJm33JvINiUtbyEspUeKUWyWewG+jYyxO1UDHqLp9Q= github.com/massdriver-cloud/massdriver-sdk-go v0.2.3 h1:gKRiSbJPI1uWVBRmoexPNbi9IJEYZ2upciMTjxRHb5I= github.com/massdriver-cloud/massdriver-sdk-go v0.2.3/go.mod h1:6NrSP+wfGQvUOAggsz10/Wkln8CKmk3VBnD+OJzZgFY= +github.com/massdriver-cloud/massdriver-sdk-go v0.2.4 h1:5UqNA0vBkzvqNa3H94SoVlDmxiJiRPltklO/j9/H+F0= +github.com/massdriver-cloud/massdriver-sdk-go v0.2.4/go.mod h1:6NrSP+wfGQvUOAggsz10/Wkln8CKmk3VBnD+OJzZgFY= github.com/massdriver-cloud/terraform-config-inspect v0.0.1 h1:eLtKFRaklHIxcPvUtZmNacl28n4QIHr29pJzw/u/FKU= github.com/massdriver-cloud/terraform-config-inspect v0.0.1/go.mod h1:3AbDpWxIRMdMAg7FDmTJuVBhCGNwdm49cBIOmUHjqRg= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=