stackset

package
v1.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 15, 2023 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var StackSetCmd = &cobra.Command{
	Use:   "stackset <stack_set command>",
	Short: "This command manipulates stack sets.",
	Long:  "This command manipulates stack sets. It has no action if specific stack set command is not added.",
}
View Source
var StackSetDeployCmd = &cobra.Command{
	Use:   "deploy <template> [stackset] [flags]",
	Short: "Deploy a CloudFormation stack set from a local template",
	Long: `Creates or updates a CloudFormation stack set <stackset> from the template file <template>.
If you don't specify a stack set name, rain will use the template filename minus its extension.
If you do not specify a template file, rain will asume that you want to add a new instance to an existing template,
If a template needs to be packaged before it can be deployed, rain will package the template first.
Rain will attempt to create an S3 bucket to store artifacts that it packages and deploys.
The bucket's name will be of the format rain-artifacts-<AWS account id>-<AWS region>.

The config flags can be used to set accounts, regions to operate and tags with parameters to use.
Configuration file with extended options can be provided along with '--config' flag in YAML or JSON format (see example file for details).

YAML:
Parameters:
	Name: Value
Tags:
	Name: Value
StackSet:
	description: "test description"
	...
StackSetInstanses:
	accounts:
		- "123456789123"
	regions:
		- us-east-1
		- us-east-2
...

Account(s) and region(s) provideed as flags OVERRIDE values from configuration files. Tags and parameters from the configuration file are MERGED with CLI flag values. 
`,
	Args:                  cobra.RangeArgs(1, 2),
	DisableFlagsInUseLine: false,
	Run: func(cmd *cobra.Command, args []string) {

		templateFilePath := args[0]

		stackSetName := createStackSetName(args)

		cliTagFlags := deploy.ListToMap("tag", tags)
		cliParamFlags := deploy.ListToMap("param", params)

		configData := readConfiguration(configFilePath)

		combineConfigDataWithCliFlags(&configData, cliParamFlags, cliTagFlags, accounts, regions)

		spinner.Push(fmt.Sprintf("Checking current status of stack set '%s'", stackSetName))
		existingStackSet, err := cfn.GetStackSet(stackSetName)
		spinner.Pop()
		isStacksetExists := false
		if err == nil && existingStackSet.Status != types.StackSetStatusDeleted {
			isStacksetExists = true
		}
		configData.StackSet.StackSetName = stackSetName
		configData.StackSetInstanses.StackSetName = stackSetName

		spinner.Push(fmt.Sprintf("Preparing template '%s'", templateFilePath))
		configData.StackSet.Template = deploy.PackageTemplate(templateFilePath, yes)
		spinner.Pop()

		config.Debugln("Handling parameters")
		configData.StackSet.Parameters = buildParameterTypes(configData.StackSet.Template, configData.Parameters, existingStackSet)

		config.Debugln("Handling tags")
		configData.StackSet.Tags = cfn.MakeTags(configData.Tags)

		if config.Debug {
			for _, param := range configData.StackSet.Parameters {
				val := ptr.ToString(param.ParameterValue)
				if ptr.ToBool(param.UsePreviousValue) {
					val = "<previous value>"
				}
				config.Debugf("  %s: %s", ptr.ToString(param.ParameterKey), val)
			}
		}

		if isStacksetExists {
			if console.Confirm(true, "Stack set already exists. Do you want to update it?") {
				updateStackSet(configData)
				addInstances(configData)

			} else {
				fmt.Println(console.Yellow("operation was cancelled by user"))
			}
		} else {
			createStackSet(configData)
		}
	},
}

StackSetDeployCmd is the deploy command's entrypoint

View Source
var StackSetLsCmd = &cobra.Command{
	Use:                   "ls <stack set>",
	Short:                 "List a CloudFormation stack sets in a given region",
	Long:                  "List a CloudFormation stack sets in a given region. If you specify a stack set name it will show all the stack instances and last 10 operations.",
	Args:                  cobra.MaximumNArgs(1),
	Aliases:               []string{"list"},
	DisableFlagsInUseLine: true,
	Run: func(cmd *cobra.Command, args []string) {
		if len(args) == 1 {
			displayStackSetSummaryWithInstancesAndLast10Operations(args[0])
		} else {
			var err error
			regions := []string{aws.Config().Region}

			if all {
				spinner.Push("Fetching region list")
				regions, err = ec2.GetRegions()
				if err != nil {
					panic(ui.Errorf(err, "unable to get region list"))
				}
				spinner.Pop()
			}

			origRegion := aws.Config().Region

			for _, region := range regions {
				spinner.Push(fmt.Sprintf("Fetching stack sets in %s", region))
				aws.SetRegion(region)
				stackSets, err := cfn.ListStackSets()
				if err != nil {
					panic(ui.Errorf(err, "failed to list stack sets"))
				}
				spinner.Pop()

				if len(stackSets) == 0 && all {
					continue
				}

				stackSetNames := make(sort.StringSlice, 0)
				stackSetMap := make(map[string]types.StackSetSummary)
				for _, stack := range stackSets {
					if stack.Status != types.StackSetStatusDeleted {
						stackSetNames = append(stackSetNames, *stack.StackSetName)
						stackSetMap[*stack.StackSetName+region] = stack
					}
				}
				sort.Strings(stackSetNames)

				fmt.Println(console.Yellow(fmt.Sprintf("CloudFormation stack sets in %s:", region)))
				for _, stackSetName := range stackSetNames {
					out := strings.Builder{}
					out.WriteString(fmt.Sprintf("%s: %s\n",
						stackSetName,
						ui.ColouriseStatus(string(stackSetMap[stackSetName+region].Status)),
					))
					fmt.Println(ui.Indent("  ", out.String()))
				}
			}

			aws.SetRegion(origRegion)
		}

		all = false
	},
}

StackSetLsCmd is the ls command's entrypoint

View Source
var StackSetRmCmd = &cobra.Command{
	Use:                   "rm <stackset>",
	Short:                 "Delete a CloudFormation stack set and/or its instances.",
	Long:                  "Delete a CloudFormation stack set <stackset> and/or its instances.",
	Args:                  cobra.ExactArgs(1),
	Aliases:               []string{"delete", "remove"},
	DisableFlagsInUseLine: true,
	Run: func(cmd *cobra.Command, args []string) {
		stackSetName := args[0]
		config.Debugf("Deleting stack set: %s\n", stackSetName)

		stackSet, err := cfn.GetStackSet(stackSetName)
		if err != nil {
			panic(ui.Errorf(err, "Could not find stack set '%s'", stackSetName))
		} else if stackSet.Status == types.StackSetStatusDeleted {
			panic(ui.Errorf(err, "Stack set '%s' is already in DELETED state ", stackSetName))
		}

		spinner.Push("Deleting stack set..")
		err = cfn.DeleteStackSet(stackSetName)
		spinner.Pop()
		if err != nil {
			var notEmptyException *types.StackSetNotEmptyException
			if errors.As(err, &notEmptyException) {

				instancesOut, instances := getStackInstances(stackSetName)
				fmt.Printf("%s", instancesOut)
				inputString := console.Ask("Select instances number to delete or 0 to delete all. For multiple selects separate with comma:")

				accounts, regions, deleteAll := convertInputString(inputString, instances)

				spinner.Push("Deleting stack set instances...")
				if deleteAll {
					err = cfn.DeleteAllStackSetInstances(stackSetName, !detach, false)
				} else {
					err = cfn.DeleteStackSetInstances(stackSetName, accounts, regions, !detach, false)
				}
				spinner.Pop()

				if err != nil {
					panic(ui.Errorf(err, "error while deleting stack set instances "))
				}

				if deleteAll {
					spinner.Push("Deleting stack set...")
					err = cfn.DeleteStackSet(stackSetName)
					spinner.Pop()
					if err != nil {
						panic(ui.Errorf(err, "Could not delete stack set '%s'", stackSetName))
					} else {
						fmt.Println("Stack set deletion has been completed.")
					}
				}
			} else {
				panic(ui.Errorf(err, "Could not delete stack set '%s'", stackSetName))
			}

		} else {
			fmt.Println("Success!")
		}

	},
}

StackSetRmCmd is the rm command's entrypoint

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL