Example #1
0
func EnvironmentSet(rw http.ResponseWriter, r *http.Request) *httperr.Error {
	vars := mux.Vars(r)

	app := vars["app"]

	_, err := models.GetEnvironment(app)

	if awsError(err) == "ValidationError" {
		return httperr.Errorf(404, "no such app: %s", app)
	}

	body, err := ioutil.ReadAll(r.Body)

	if err != nil {
		return httperr.Server(err)
	}

	releaseId, err := models.PutEnvironment(app, models.LoadEnvironment(body))

	if err != nil {
		return httperr.Server(err)
	}

	rw.Header().Set("Release-Id", releaseId)

	env, err := models.GetEnvironment(app)

	if err != nil {
		return httperr.Server(err)
	}

	return RenderJson(rw, env)
}
Example #2
0
func EnvironmentSet(rw http.ResponseWriter, r *http.Request) error {
	vars := mux.Vars(r)

	app := vars["app"]

	_, err := models.GetEnvironment(app)

	if awsError(err) == "ValidationError" {
		return RenderNotFound(rw, fmt.Sprintf("no such app: %s", app))
	}

	body, err := ioutil.ReadAll(r.Body)

	if err != nil {
		return err
	}

	err = models.PutEnvironment(app, models.LoadEnvironment(body))

	if err != nil {
		return err
	}

	env, err := models.GetEnvironment(app)

	if err != nil {
		return err
	}

	return RenderJson(rw, env)
}
Example #3
0
File: ecs.go Project: gmelika/rack
func ECSTaskDefinitionCreate(req Request) (string, map[string]string, error) {
	// return "", fmt.Errorf("fail")

	tasks := req.ResourceProperties["Tasks"].([]interface{})

	r := &ecs.RegisterTaskDefinitionInput{
		Family: aws.String(req.ResourceProperties["Name"].(string)),
	}

	// get environment from S3 URL
	// 'Environment' is a CloudFormation Template Property that references 'Environment' CF Parameter with S3 URL
	// S3 body may be encrypted with KMS key
	var env models.Environment

	if envUrl, ok := req.ResourceProperties["Environment"].(string); ok && envUrl != "" {
		res, err := http.Get(envUrl)

		if err != nil {
			return "invalid", nil, err
		}

		defer res.Body.Close()

		data, err := ioutil.ReadAll(res.Body)

		if key, ok := req.ResourceProperties["Key"].(string); ok && key != "" {
			cr := crypt.New(*Region(&req), os.Getenv("AWS_ACCESS_KEY_ID"), os.Getenv("AWS_SECRET_ACCESS_KEY"))
			cr.AwsToken = os.Getenv("AWS_SESSION_TOKEN")

			dec, err := cr.Decrypt(key, data)

			if err != nil {
				return "invalid", nil, err
			}

			data = dec
		}

		env = models.LoadEnvironment(data)
	}

	r.ContainerDefinitions = make([]*ecs.ContainerDefinition, len(tasks))

	for i, itask := range tasks {
		task := itask.(map[string]interface{})

		cpu := 0
		var err error

		if c, ok := task["Cpu"].(string); ok && c != "" {
			cpu, err = strconv.Atoi(c)
			if err != nil {
				return "invalid", nil, err
			}
		}

		memory, err := strconv.Atoi(task["Memory"].(string))
		if err != nil {
			return "invalid", nil, err
		}

		privileged := false

		if p, ok := task["Privileged"].(string); ok && p != "" {
			privileged, err = strconv.ParseBool(p)
			if err != nil {
				return "invalid", nil, err
			}
		}

		r.ContainerDefinitions[i] = &ecs.ContainerDefinition{
			Name:       aws.String(task["Name"].(string)),
			Essential:  aws.Bool(true),
			Image:      aws.String(task["Image"].(string)),
			Cpu:        aws.Int64(int64(cpu)),
			Memory:     aws.Int64(int64(memory)),
			Privileged: aws.Bool(privileged),
		}

		// set Command from either -
		// a single string (shell form) - ["sh", "-c", command]
		// an array of strings (exec form) - ["cmd1", "cmd2"]
		switch commands := task["Command"].(type) {
		case string:
			if commands != "" {
				r.ContainerDefinitions[i].Command = []*string{aws.String("sh"), aws.String("-c"), aws.String(commands)}
			}
		case []interface{}:
			r.ContainerDefinitions[i].Command = make([]*string, len(commands))
			for j, command := range commands {
				r.ContainerDefinitions[i].Command[j] = aws.String(command.(string))
			}
		}

		// set Task environment from CF Tasks[].Environment key/values
		// These key/values are read from the app manifest environment hash
		if oenv, ok := task["Environment"].(map[string]interface{}); ok {
			for key, val := range oenv {
				r.ContainerDefinitions[i].Environment = append(r.ContainerDefinitions[i].Environment, &ecs.KeyValuePair{
					Name:  aws.String(key),
					Value: aws.String(val.(string)),
				})
			}
		}

		// set Task environment from decrypted S3 URL body of key/values
		// These key/values take precident over the above environment
		for key, val := range env {
			r.ContainerDefinitions[i].Environment = append(r.ContainerDefinitions[i].Environment, &ecs.KeyValuePair{
				Name:  aws.String(key),
				Value: aws.String(val),
			})
		}

		// set Release value in Task environment
		if release, ok := req.ResourceProperties["Release"].(string); ok {
			r.ContainerDefinitions[i].Environment = append(r.ContainerDefinitions[i].Environment, &ecs.KeyValuePair{
				Name:  aws.String("RELEASE"),
				Value: aws.String(release),
			})
		}

		// set links
		if links, ok := task["Links"].([]interface{}); ok {
			r.ContainerDefinitions[i].Links = make([]*string, len(links))

			for j, link := range links {
				r.ContainerDefinitions[i].Links[j] = aws.String(link.(string))
			}
		}

		// set portmappings
		if ports, ok := task["PortMappings"].([]interface{}); ok {

			r.ContainerDefinitions[i].PortMappings = make([]*ecs.PortMapping, len(ports))

			for j, port := range ports {
				parts := strings.Split(port.(string), ":")
				host, _ := strconv.Atoi(parts[0])
				container, _ := strconv.Atoi(parts[1])

				r.ContainerDefinitions[i].PortMappings[j] = &ecs.PortMapping{
					ContainerPort: aws.Int64(int64(container)),
					HostPort:      aws.Int64(int64(host)),
				}
			}
		}

		// set volumes
		if volumes, ok := task["Volumes"].([]interface{}); ok {
			for j, volume := range volumes {
				name := fmt.Sprintf("%s-%d-%d", task["Name"].(string), i, j)
				parts := strings.Split(volume.(string), ":")

				r.Volumes = append(r.Volumes, &ecs.Volume{
					Name: aws.String(name),
					Host: &ecs.HostVolumeProperties{
						SourcePath: aws.String(parts[0]),
					},
				})

				r.ContainerDefinitions[i].MountPoints = append(r.ContainerDefinitions[i].MountPoints, &ecs.MountPoint{
					SourceVolume:  aws.String(name),
					ContainerPath: aws.String(parts[1]),
					ReadOnly:      aws.Bool(false),
				})
			}
		}

		// set extra hosts
		if extraHosts, ok := task["ExtraHosts"].([]interface{}); ok {
			for _, host := range extraHosts {
				hostx, oky := host.(map[string]interface{})
				if oky {
					r.ContainerDefinitions[i].ExtraHosts = append(r.ContainerDefinitions[i].ExtraHosts, &ecs.HostEntry{
						Hostname:  aws.String(hostx["HostName"].(string)),
						IpAddress: aws.String(hostx["IpAddress"].(string)),
					})
				}
			}
		}
	}

	res, err := ECS(req).RegisterTaskDefinition(r)
	if err != nil {
		return "invalid", nil, err
	}

	return *res.TaskDefinition.TaskDefinitionArn, nil, nil
}