Ejemplo n.º 1
0
// Update an existing Pool Stack
func stackUpdatePool(c *cli.Context) {
	ensureEnvArg(c)
	ensurePoolArg(c)

	if c.String("region") != "" {
		stack.Region = c.String("region")
	}

	poolName := utils.GalaxyPool(c)
	baseStack := getBase(c)
	poolEnv := utils.GalaxyEnv(c)

	stackName := fmt.Sprintf("%s-%s-%s", baseStack, poolEnv, poolName)

	pool, err := stack.GetPool(stackName)
	if err != nil {
		log.Fatal(err)
	}

	options := make(map[string]string)
	if policy := c.String("policy"); policy != "" {
		policyJSON, err := jsonFromArg(policy)
		if err != nil {
			log.Fatal("policy error:", err)
		}

		options["StackPolicyDuringUpdateBody"] = string(policyJSON)
	}

	resources := sharedResources(c, baseStack)

	asg := pool.ASG()
	if asg == nil {
		log.Fatal("missing ASG")
	}

	if c.Int("desired-size") > 0 {
		asg.Properties.DesiredCapacity = c.Int("desired-size")
	}

	if c.Int("min-size") > 0 {
		asg.Properties.MinSize = c.Int("min-size")
	}

	if c.Int("max-size") > 0 {
		asg.Properties.MaxSize = c.Int("max-size")
	}

	if c.Bool("auto-update") {
		// note that the max pause is only PT5M30S
		asg.SetASGUpdatePolicy(c.Int("update-min"), c.Int("update-batch"), c.Duration("update-pause"))
	}

	numZones := c.Int("availability-zones")
	if numZones == 0 {
		numZones = len(asg.Properties.VPCZoneIdentifier)
	}

	// start with the current settings
	subnetIDs := []string{}
	azIDs := []string{}

	// only update the subnets/AZs if we changed the count
	if len(asg.Properties.VPCZoneIdentifier) != numZones {
		subnets := resources.Subnets
		if numZones <= len(subnets) {
			subnets = subnets[:numZones]
		} else {
			log.Fatal("ERROR: cannot run in %d zones, only %d available.", numZones, len(subnets))
		}

		for _, sn := range subnets {
			subnetIDs = append(subnetIDs, sn.ID)
			azIDs = append(azIDs, sn.AvailabilityZone)
		}
		asg.Properties.VPCZoneIdentifier = subnetIDs
		asg.Properties.AvailabilityZones = azIDs

	}

	elb := pool.ELB()

	sslCert := ""
	if cert := c.String("ssl-cert"); cert != "" {
		sslCert = resources.ServerCerts[cert]
		if sslCert == "" {
			log.Fatalf("Could not find certificate '%s'", cert)
		}
	}

	httpPort := c.Int("http-port")

	if (sslCert != "" || httpPort > 0) && elb == nil {
		log.Fatal("ERROR: Pool does not have an ELB")
	}

	// we can set the default now that we've verified that elb can be nil
	if httpPort == 0 {
		httpPort = 80
	}

	if elb != nil {
		certAdded := false
		for _, l := range elb.Properties.Listeners {
			if sslCert != "" && l.Protocol == "HTTPS" {
				l.SSLCertificateId = sslCert
				certAdded = true
			}

			if httpPort > 0 {
				l.InstancePort = httpPort
			}
		}

		// the elb needs a cert, but doesn't have an https listener
		if sslCert != "" && !certAdded {
			elb.AddListener(443, "HTTPS", httpPort, "HTTP", sslCert, nil)
		}

		healthCheck := c.String("http-health-check")
		if healthCheck != "" && healthCheck != elb.Properties.HealthCheck.Target {
			elb.Properties.HealthCheck.Target = healthCheck
		}

		// always make sure the ELB is in the same subnets as the ASG
		elb.Properties.Subnets = asg.Properties.VPCZoneIdentifier
	}

	lc := pool.LC()
	if amiID := c.String("ami"); amiID != "" {
		lc.Properties.ImageId = amiID
	}

	if insType := c.String("instance-type"); insType != "" {
		lc.Properties.InstanceType = insType
	}

	// add autoscaling if it's required
	setCPUAutoScale(c, pool)

	poolTmpl, err := json.MarshalIndent(pool, "", "    ")
	if err != nil {
		log.Fatal(err)
	}

	if c.Bool("print") {
		fmt.Println(string(poolTmpl))
		return
	}

	log.Println("Updating stack:", stackName)
	if _, err := stack.Update(stackName, poolTmpl, options); err != nil {
		log.Fatal(err)
	}

	// do we want to wait on this by default?
	if err := stack.Wait(stackName, 5*time.Minute); err != nil {
		log.Fatal(err)
	}

	log.Println("UpdateStack complete")
}
Ejemplo n.º 2
0
// update the base stack
func stackUpdate(c *cli.Context) {
	var stackTmpl []byte
	var err error

	stackName := c.Args().First()
	if stackName == "" {
		log.Fatal("ERROR: stack name required")
	}

	if c.String("region") != "" {
		stack.Region = c.String("region")
	}

	params := make(map[string]string)
	if p := c.String("parameters"); p != "" {
		paramJSON, err := jsonFromArg(p)
		if err != nil {
			log.Fatal("ERROR: decoding parameters:", err)
		}

		err = json.Unmarshal(paramJSON, &params)
		if err != nil {
			log.Fatal(err)
		}
	}

	template := c.String("template")
	if template != "" {
		stackTmpl, err = jsonFromArg(template)
		if err != nil {
			log.Fatalf("ERROR: %s", err)
		}
	}

	if policy := c.String("policy"); policy != "" {
		policyJSON, err := jsonFromArg(policy)
		if err != nil {
			log.Fatal("policy error:", err)
		}

		params["StackPolicyDuringUpdateBody"] = string(policyJSON)
	}

	if len(stackTmpl) == 0 {
		// get the current running template
		stackTmpl, err = stack.GetTemplate(stackName)
		if err != nil {
			log.Fatal(err)
		}
	}

	// this reads the Parameters supplied for our current stack for us
	shared := sharedResources(c, stackName)

	// add any missing parameters to our
	for key, val := range shared.Parameters {
		if params[key] == "" {
			params[key] = val
		}
	}

	p, _ := json.MarshalIndent(params, "", "  ")
	ok := promptValue(fmt.Sprintf("\nUpdate the [%s] stack with:\n%s\nAccept?", stackName, string(p)), "n")
	switch strings.ToLower(ok) {
	case "y", "yes":
		_, err = stack.Update(stackName, stackTmpl, params)
		if err != nil {
			log.Fatal(err)
		}
		log.Println("Updating stack:", stackName)
	default:
		log.Fatal("aborted")
	}
}