func (i *EC2IaaS) buildRunInstancesOptions(params map[string]string) (ec2.RunInstancesInput, error) { result := ec2.RunInstancesInput{ MaxCount: aws.Int64(1), MinCount: aws.Int64(1), } forbiddenFields := []string{ "maxcount", "mincount", "dryrun", "monitoring", } aliases := map[string]string{ "image": "imageid", "type": "instancetype", "securitygroup": "securitygroups", "ebs-optimized": "ebsoptimized", } refType := reflect.TypeOf(result) refValue := reflect.ValueOf(&result) for key, value := range params { field, ok := refType.FieldByNameFunc(func(name string) bool { lowerName := strings.ToLower(name) for _, field := range forbiddenFields { if lowerName == field { return false } } lowerKey := strings.ToLower(key) if aliased, ok := aliases[lowerKey]; ok { lowerKey = aliased } return lowerName == lowerKey }) if !ok { continue } fieldType := field.Type fieldValue := refValue.Elem().FieldByIndex(field.Index) if !fieldValue.IsValid() || !fieldValue.CanSet() { continue } switch fieldType.Kind() { case reflect.Ptr: switch fieldType.Elem().Kind() { case reflect.String: copy := value fieldValue.Set(reflect.ValueOf(©)) case reflect.Int64: intValue, err := strconv.ParseInt(value, 10, 64) if err != nil { return result, &invalidFieldError{ fieldName: key, convertError: err, } } fieldValue.Set(reflect.ValueOf(&intValue)) case reflect.Bool: boolValue, err := strconv.ParseBool(value) if err != nil { return result, &invalidFieldError{ fieldName: key, convertError: err, } } fieldValue.Set(reflect.ValueOf(&boolValue)) case reflect.Struct: err := i.loadStruct(fieldValue, fieldType, []byte(value)) if err != nil { return result, &invalidFieldError{ fieldName: key, convertError: err, } } } case reflect.Slice: switch fieldType.Elem().Elem().Kind() { case reflect.String: parts := strings.Split(value, ",") values := make([]*string, len(parts)) for i, part := range parts { values[i] = aws.String(part) } fieldValue.Set(reflect.ValueOf(values)) case reflect.Struct: var raw []map[string]interface{} err := json.Unmarshal([]byte(value), &raw) if err != nil { return result, &invalidFieldError{ fieldName: key, convertError: err, } } val, err := i.translateSlice(raw, fieldType) if err != nil { return result, &invalidFieldError{ fieldName: key, convertError: err, } } fieldValue.Set(val) } } } // Manual configuration if monitoring, ok := params["monitoring-enabled"]; ok { value, _ := strconv.ParseBool(monitoring) result.Monitoring = &ec2.RunInstancesMonitoringEnabled{ Enabled: aws.Bool(value), } } return result, nil }