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) }
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) }
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 }