func createCluster(context *cli.Context, rdwr config.ReadWriter, ecsClient ecsclient.ECSClient, cfnClient cloudformation.CloudformationClient, amiIds ami.ECSAmiIds) error { // Validate cli flags if !isIAMAcknowledged(context) { return fmt.Errorf("Please acknowledge that this command may create IAM resources with the '--%s' flag", capabilityIAMFlag) } ecsParams, err := config.NewCliParams(context, rdwr) if err != nil { return err } // Check if cfn stack already exists cfnClient.Initialize(ecsParams) stackName := ecsParams.GetCfnStackName() if err := cfnClient.ValidateStackExists(stackName); err == nil { return fmt.Errorf("A CloudFormation stack already exists for the cluster '%s'", ecsParams.Cluster) } // Populate cfn params cfnParams := cliFlagsToCfnStackParams(context) cfnParams.Add(cloudformation.ParameterKeyCluster, ecsParams.Cluster) // Check if key pair exists _, err = cfnParams.GetParameter(cloudformation.ParameterKeyKeyPairName) if err == cloudformation.ParameterNotFoundError { return fmt.Errorf("Please specify the keypair name with '--%s' flag", keypairNameFlag) } else if err != nil { return err } // Check if image id was supplied, else populate _, err = cfnParams.GetParameter(cloudformation.ParameterKeyAmiId) if err == cloudformation.ParameterNotFoundError { amiId, err := amiIds.Get(aws.StringValue(ecsParams.Config.Region)) if err != nil { return err } cfnParams.Add(cloudformation.ParameterKeyAmiId, amiId) } else if err != nil { return err } if err := cfnParams.Validate(); err != nil { return err } // Create ECS cluster ecsClient.Initialize(ecsParams) if _, err := ecsClient.CreateCluster(ecsParams.Cluster); err != nil { return err } // Create cfn stack template := cloudformation.GetTemplate() if _, err := cfnClient.CreateStack(template, stackName, cfnParams); err != nil { return err } logrus.Info("Waiting for your cluster resources to be created") // Wait for stack creation return cfnClient.WaitUntilCreateComplete(stackName) }
// validateCluster validates if the cluster exists in ECS and is in "ACTIVE" state. func validateCluster(clusterName string, ecsClient ecsclient.ECSClient) error { isClusterActive, err := ecsClient.IsActiveCluster(clusterName) if err != nil { return err } if !isClusterActive { return fmt.Errorf("Cluster '%s' is not active. Ensure that it exists", clusterName) } return nil }
func clusterPS(context *cli.Context, rdwr config.ReadWriter, ecsClient ecsclient.ECSClient) (project.InfoSet, error) { ecsParams, err := newCliParams(context, rdwr) if err != nil { return nil, err } // Validate that cluster exists in ECS ecsClient.Initialize(ecsParams) if err := validateCluster(ecsParams.Cluster, ecsClient); err != nil { return nil, err } ec2Client := ec2client.NewEC2Client(ecsParams) ecsContext := &ecscompose.Context{ECSClient: ecsClient, EC2Client: ec2Client} task := ecscompose.NewTask(ecsContext) return task.Info(false) }
// scaleCluster executes the 'scale' command. func scaleCluster(context *cli.Context, rdwr config.ReadWriter, ecsClient ecsclient.ECSClient, cfnClient cloudformation.CloudformationClient) error { // Validate cli flags if !isIAMAcknowledged(context) { return fmt.Errorf("Please acknowledge that this command may create IAM resources with the '--%s' flag", capabilityIAMFlag) } size, err := getClusterSize(context) if err != nil { return err } if size == "" { return fmt.Errorf("Missing required flag '--%s'", asgMaxSizeFlag) } ecsParams, err := newCliParams(context, rdwr) if err != nil { return err } // Validate that cluster exists in ECS ecsClient.Initialize(ecsParams) if err := validateCluster(ecsParams.Cluster, ecsClient); err != nil { return err } // Validate that we have a cfn stack for the cluster cfnClient.Initialize(ecsParams) stackName := ecsParams.GetCfnStackName() if err := cfnClient.ValidateStackExists(stackName); err != nil { return fmt.Errorf("CloudFormation stack not found for cluster '%s'", ecsParams.Cluster) } // Populate update params for the cfn stack cfnParams := cloudformation.NewCfnStackParamsForUpdate() cfnParams.Add(cloudformation.ParameterKeyAsgMaxSize, size) // Update the stack. if _, err := cfnClient.UpdateStack(stackName, cfnParams); err != nil { return err } logrus.Info("Waiting for your cluster resources to be updated...") return cfnClient.WaitUntilUpdateComplete(stackName) }
func deleteCluster(context *cli.Context, rdwr config.ReadWriter, ecsClient ecsclient.ECSClient, cfnClient cloudformation.CloudformationClient) error { // Validate cli flags if !isForceSet(context) { return fmt.Errorf("Missing required flag '--%s'", forceFlag) // TODO prompt override for force } ecsParams, err := newCliParams(context, rdwr) if err != nil { return err } // Validate that cluster exists in ECS ecsClient.Initialize(ecsParams) if err := validateCluster(ecsParams.Cluster, ecsClient); err != nil { return err } // Validate that a cfn stack exists for the cluster cfnClient.Initialize(ecsParams) stackName := ecsParams.GetCfnStackName() if err := cfnClient.ValidateStackExists(stackName); err != nil { return fmt.Errorf("CloudFormation stack not found for cluster '%s'", ecsParams.Cluster) } // Delete cfn stack if err := cfnClient.DeleteStack(stackName); err != nil { return err } logrus.Info("Waiting for your cluster resources to be deleted...") if err := cfnClient.WaitUntilDeleteComplete(stackName); err != nil { return err } // Delete cluster in ECS if _, err := ecsClient.DeleteCluster(ecsParams.Cluster); err != nil { return err } return nil }
func createCluster(context *cli.Context, rdwr config.ReadWriter, ecsClient ecsclient.ECSClient, cfnClient cloudformation.CloudformationClient, amiIds ami.ECSAmiIds) error { // Validate cli flags if !isIAMAcknowledged(context) { return fmt.Errorf("Please acknowledge that this command may create IAM resources with the '--%s' flag", capabilityIAMFlag) } ecsParams, err := newCliParams(context, rdwr) if err != nil { return err } // Check if cluster is specified if ecsParams.Cluster == "" { return fmt.Errorf("Please configure a cluster using the configure command.") } // Check if cfn stack already exists cfnClient.Initialize(ecsParams) stackName := ecsParams.GetCfnStackName() var deleteStack bool if err := cfnClient.ValidateStackExists(stackName); err == nil { if !isForceSet(context) { return fmt.Errorf("A CloudFormation stack already exists for the cluster '%s'. Please specify '--%s' to clean up your existing resources.", ecsParams.Cluster, forceFlag) } deleteStack = true } // Populate cfn params cfnParams := cliFlagsToCfnStackParams(context) cfnParams.Add(cloudformation.ParameterKeyCluster, ecsParams.Cluster) // Check if key pair exists _, err = cfnParams.GetParameter(cloudformation.ParameterKeyKeyPairName) if err == cloudformation.ParameterNotFoundError { return fmt.Errorf("Please specify the keypair name with '--%s' flag", keypairNameFlag) } else if err != nil { return err } // Check if vpc and AZs are not both specified. if validateMutuallyExclusiveParams(cfnParams, cloudformation.ParameterKeyVPCAzs, cloudformation.ParameterKeyVpcId) { return fmt.Errorf("You can only specify '--%s' or '--%s'", vpcIdFlag, vpcAzFlag) } // Check if 2 AZs are specified if validateCommaSeparatedParam(cfnParams, cloudformation.ParameterKeyVPCAzs, 2, 2) { return fmt.Errorf("You must specify 2 comma-separated availability zones with the '--%s' flag", vpcAzFlag) } // Check if vpc exists when security group is specified if validateDependentParams(cfnParams, cloudformation.ParameterKeySecurityGroup, cloudformation.ParameterKeyVpcId) { return fmt.Errorf("You have selected a security group. Please specify a VPC with the '--%s' flag", vpcIdFlag) } // Check only one security group is specified if validateCommaSeparatedParam(cfnParams, cloudformation.ParameterKeySecurityGroup, 1, 1) { return fmt.Errorf("You can only specify one security group with the '--%s' flag", securityGroupFlag) } // Check if subnets exists when vpc is specified if validateDependentParams(cfnParams, cloudformation.ParameterKeyVpcId, cloudformation.ParameterKeySubnetIds) { return fmt.Errorf("You have selected a VPC. Please specify 2 comma-separated subnets with the '--%s' flag", subnetIdsFlag) } // Check if vpc exists when subnets is specified if validateDependentParams(cfnParams, cloudformation.ParameterKeySubnetIds, cloudformation.ParameterKeyVpcId) { return fmt.Errorf("You have selected subnets. Please specify a VPC with the '--%s' flag", vpcIdFlag) } // Check if 2 subnets are specified if validateCommaSeparatedParam(cfnParams, cloudformation.ParameterKeySubnetIds, 2, 2) { return fmt.Errorf("You must specify 2 comma-separated subnets with the '--%s' flag", subnetIdsFlag) } // Check if image id was supplied, else populate _, err = cfnParams.GetParameter(cloudformation.ParameterKeyAmiId) if err == cloudformation.ParameterNotFoundError { amiId, err := amiIds.Get(aws.StringValue(ecsParams.Config.Region)) if err != nil { return err } cfnParams.Add(cloudformation.ParameterKeyAmiId, amiId) } else if err != nil { return err } if err := cfnParams.Validate(); err != nil { return err } // Create ECS cluster ecsClient.Initialize(ecsParams) if _, err := ecsClient.CreateCluster(ecsParams.Cluster); err != nil { return err } // Delete cfn stack if deleteStack { if err := cfnClient.DeleteStack(stackName); err != nil { return err } logrus.Info("Waiting for your CloudFormation stack resources to be deleted...") if err := cfnClient.WaitUntilDeleteComplete(stackName); err != nil { return err } } // Create cfn stack template := cloudformation.GetTemplate() if _, err := cfnClient.CreateStack(template, stackName, cfnParams); err != nil { return err } logrus.Info("Waiting for your cluster resources to be created...") // Wait for stack creation return cfnClient.WaitUntilCreateComplete(stackName) }