Esempio n. 1
1
func (aws *RealAWSService) RunInstances(idef *InstancesDefinition) ([]string, error) {
	count := int64(idef.Count)
	rs := int64(20)
	vt := "gp2"
	rdn := "/dev/xvda"
	ud, err := encodeUserData(idef.UserData)
	if err != nil {
		return []string{}, err
	}
	if idef.RootSizeGB != 0 {
		rs = int64(idef.RootSizeGB)
	}
	root := ec2.BlockDeviceMapping{
		DeviceName: &rdn,
		Ebs: &ec2.EbsBlockDevice{
			DeleteOnTermination: &True,
			VolumeSize:          &rs,
			VolumeType:          &vt,
		},
	}
	if idef.EncryptedRoot {
		root.Ebs.Encrypted = &idef.EncryptedRoot // leave nil otherwise
	}
	bdm := []*ec2.BlockDeviceMapping{&root}
	for _, bd := range idef.BlockDevices {
		vt := strings.ToLower(bd.Type.String())
		nbd := &ec2.BlockDeviceMapping{
			DeviceName: &bd.Name,
			Ebs: &ec2.EbsBlockDevice{
				DeleteOnTermination: &bd.DeleteOnTermination,
				Encrypted:           &bd.Encrypted,
				Iops:                &bd.Iops,
				SnapshotId:          &bd.SnapshotID,
				VolumeSize:          &bd.Size,
				VolumeType:          &vt,
			},
		}
		bdm = append(bdm, nbd)
	}
	ri := ec2.RunInstancesInput{
		ImageId:             &idef.AMI,
		MinCount:            &count,
		MaxCount:            &count,
		KeyName:             &idef.Keypair,
		InstanceType:        &idef.Type,
		BlockDeviceMappings: bdm,
		UserData:            &ud,
	}
	if idef.GetPublicIP {
		devindx := int64(0)
		ri.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{&ec2.InstanceNetworkInterfaceSpecification{
			AssociatePublicIpAddress: &True,
			Groups:      []*string{&idef.SecurityGroup},
			DeviceIndex: &devindx,
			SubnetId:    &idef.Subnet,
		}}
	} else {
		ri.SubnetId = &idef.Subnet
		ri.SecurityGroupIds = []*string{&idef.SecurityGroup}
	}
	r, err := aws.ec2.RunInstances(&ri)
	if err != nil {
		return []string{}, err
	}
	instances := []string{}
	for _, inst := range r.Instances {
		instances = append(instances, *(inst.InstanceId))
	}
	return instances, nil
}
Esempio n. 2
0
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(&copy))
			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
}
Esempio n. 3
0
func (e *EC2) CreateInstance(instance *compute.Instance) (*compute.Instance, error) {
	imageID, err := common.GetMatchingImageID(e, &instance.Image)
	if err != nil {
		return nil, err
	}
	flavorID, err := common.GetMatchingFlavorID(e, &instance.Flavor)
	if err != nil {
		return nil, err
	}

	region := DEFAULT_REGION
	if instance.Region != "" {
		region = instance.Region
	}
	svc := e.getService(region)

	opts := ec2.RunInstancesInput{
		ImageId:      aws.String(imageID),
		InstanceType: aws.String(flavorID),
		MinCount:     aws.Int64(1),
		MaxCount:     aws.Int64(1),
	}

	password := instance.Password
	if password == "" {
		password = utils.Uid(16)
	}
	userData := "#cloud-config\npassword: "******"\nchpasswd: { expire: False }\nssh_pwauth: True\n"
	opts.UserData = aws.String(base64.StdEncoding.EncodeToString([]byte(userData)))

	if instance.Flavor.DiskGB > 0 {
		opts.BlockDeviceMappings = []*ec2.BlockDeviceMapping{
			{
				Ebs: &ec2.EbsBlockDevice{
					VolumeSize:          aws.Int64(int64(instance.Flavor.DiskGB)),
					DeleteOnTermination: aws.Bool(true),
					VolumeType:          aws.String("gp2"),
				},
			},
		}
	}

	if len(instance.PublicKey.Key) > 0 {
		keyName := utils.Uid(8)
		_, err := svc.ImportKeyPair(&ec2.ImportKeyPairInput{
			KeyName:           aws.String(keyName),
			PublicKeyMaterial: instance.PublicKey.Key,
		})
		if err != nil {
			return nil, fmt.Errorf("failed to import public key: %v", err)
		}
		defer svc.DeleteKeyPair(&ec2.DeleteKeyPairInput{
			KeyName: aws.String(keyName),
		})
		opts.KeyName = aws.String(keyName)
	}

	res, err := svc.RunInstances(&opts)
	if err != nil {
		return nil, err
	} else if len(res.Instances) != 1 {
		return nil, fmt.Errorf("attempted to provision a single instance, but reservation contains %d instances", len(res.Instances))
	}
	resInstance := res.Instances[0]

	return &compute.Instance{
		ID:       encodeID(String(resInstance.InstanceId), region),
		Status:   e.mapInstanceStatus(String(resInstance.State.Name)),
		Password: password,
	}, nil
}