Exemplo n.º 1
0
func (s *Route) CheckChanges(a, e, changes *Route) error {
	if a == nil {
		// TODO: Create validate method?
		if e.RouteTable == nil {
			return fi.RequiredField("RouteTable")
		}
		if e.CIDR == nil {
			return fi.RequiredField("CIDR")
		}
		targetCount := 0
		if e.InternetGateway != nil {
			targetCount++
		}
		if e.Instance != nil {
			targetCount++
		}
		if targetCount == 0 {
			return fmt.Errorf("InternetGateway or Instance is required")
		}
		if targetCount != 1 {
			return fmt.Errorf("Cannot set both InternetGateway and Instance")
		}
	}

	if a != nil {
		if changes.RouteTable != nil {
			return fi.CannotChangeField("RouteTable")
		}
		if changes.CIDR != nil {
			return fi.CannotChangeField("CIDR")
		}
	}
	return nil
}
Exemplo n.º 2
0
func (s *Subnet) CheckChanges(a, e, changes *Subnet) error {
	if a == nil {
		if e.VPC == nil {
			return fi.RequiredField("VPC")
		}

		if e.CIDR == nil {
			// TODO: Auto-assign CIDR?
			return fi.RequiredField("CIDR")
		}
	}

	if a != nil {
		if changes.VPC != nil {
			// TODO: Do we want to destroy & recreate the subnet?
			return fi.CannotChangeField("VPC")
		}
		if changes.AvailabilityZone != nil {
			// TODO: Do we want to destroy & recreate the subnet?
			return fi.CannotChangeField("AvailabilityZone")
		}
		if changes.CIDR != nil {
			// TODO: Do we want to destroy & recreate the subnet?
			return fi.CannotChangeField("CIDR")
		}
	}
	return nil
}
Exemplo n.º 3
0
func (s *LoadBalancerHealthChecks) CheckChanges(a, e, changes *LoadBalancerHealthChecks) error {
	if a == nil {
		if e.LoadBalancer == nil {
			return fi.RequiredField("LoadBalancer")
		}
		if e.Target == nil {
			return fi.RequiredField("Target")
		}
	}
	return nil
}
Exemplo n.º 4
0
func (s *LoadBalancerAttachment) CheckChanges(a, e, changes *LoadBalancerAttachment) error {
	if a == nil {
		if e.LoadBalancer == nil {
			return fi.RequiredField("LoadBalancer")
		}
		if e.AutoscalingGroup == nil {
			return fi.RequiredField("AutoscalingGroup")
		}
	}
	return nil
}
Exemplo n.º 5
0
func (s *IAMInstanceProfileRole) CheckChanges(a, e, changes *IAMInstanceProfileRole) error {
	if a != nil {
		if e.Role == nil {
			return fi.RequiredField("Role")
		}
		if e.InstanceProfile == nil {
			return fi.RequiredField("InstanceProfile")
		}
	}
	return nil
}
Exemplo n.º 6
0
func (s *LoadBalancer) CheckChanges(a, e, changes *LoadBalancer) error {
	if a == nil {
		if fi.StringValue(e.Name) == "" {
			return fi.RequiredField("Name")
		}
		if len(e.SecurityGroups) == 0 {
			return fi.RequiredField("SecurityGroups")
		}
		if len(e.Subnets) == 0 {
			return fi.RequiredField("Subnets")
		}
	}
	return nil
}
Exemplo n.º 7
0
func (s *LaunchConfiguration) CheckChanges(a, e, changes *LaunchConfiguration) error {
	if e.ImageID == nil {
		return fi.RequiredField("ImageID")
	}
	if e.InstanceType == nil {
		return fi.RequiredField("InstanceType")
	}

	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 8
0
func (s *IAMInstanceProfile) CheckChanges(a, e, changes *IAMInstanceProfile) error {
	if a != nil {
		if fi.StringValue(e.Name) == "" {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 9
0
func (_ *SecurityGroupRule) CheckChanges(a, e, changes *SecurityGroupRule) error {
	if a == nil {
		if e.SecurityGroup == nil {
			return fi.RequiredField("SecurityGroup")
		}
	}
	return nil
}
Exemplo n.º 10
0
func (_ *Instance) CheckChanges(a, e, changes *Instance) error {
	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 11
0
func (s *VPCDHCPOptionsAssociation) CheckChanges(a, e, changes *VPCDHCPOptionsAssociation) error {
	if e.VPC == nil {
		return fi.RequiredField("VPC")
	}
	if e.DHCPOptions == nil {
		return fi.RequiredField("DHCPOptions")
	}

	if a != nil && changes != nil {
		if changes.VPC != nil {
			// Should be impossible anyway because VPC is our primary key...
			return fi.CannotChangeField("VPC")
		}
	}

	return nil
}
Exemplo n.º 12
0
func (s *AutoscalingGroup) CheckChanges(a, e, changes *AutoscalingGroup) error {
	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 13
0
func (s *IAMRolePolicy) CheckChanges(a, e, changes *IAMRolePolicy) error {
	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 14
0
func (s *DNSName) CheckChanges(a, e, changes *DNSName) error {
	if a == nil {
		if fi.StringValue(e.Name) == "" {
			return fi.RequiredField("Name")
		}
	}
	return nil
}
Exemplo n.º 15
0
func (s *RouteTableAssociation) CheckChanges(a, e, changes *RouteTableAssociation) error {
	if a != nil {
		if e.RouteTable == nil {
			return fi.RequiredField("RouteTable")
		}
		if e.Subnet == nil {
			return fi.RequiredField("Subnet")
		}
	}
	if a != nil {
		if changes.RouteTable != nil {
			return fi.CannotChangeField("RouteTable")
		}
		if changes.Subnet != nil {
			return fi.CannotChangeField("Subnet")
		}
	}
	return nil
}
Exemplo n.º 16
0
func (s *IAMRole) CheckChanges(a, e, changes *IAMRole) error {
	if a != nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	} else {
		if changes.Name == nil {
			return fi.CannotChangeField("Name")
		}
	}
	return nil
}
Exemplo n.º 17
0
func (_ *LaunchConfiguration) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LaunchConfiguration) error {
	launchConfigurationName := *e.Name + "-" + fi.BuildTimestampString()
	glog.V(2).Infof("Creating AutoscalingLaunchConfiguration with Name:%q", launchConfigurationName)

	if e.ImageID == nil {
		return fi.RequiredField("ImageID")
	}
	image, err := t.Cloud.ResolveImage(*e.ImageID)
	if err != nil {
		return err
	}

	request := &autoscaling.CreateLaunchConfigurationInput{}
	request.LaunchConfigurationName = &launchConfigurationName
	request.ImageId = image.ImageId
	request.InstanceType = e.InstanceType
	if e.SSHKey != nil {
		request.KeyName = e.SSHKey.Name
	}
	securityGroupIDs := []*string{}
	for _, sg := range e.SecurityGroups {
		securityGroupIDs = append(securityGroupIDs, sg.ID)
	}
	request.SecurityGroups = securityGroupIDs
	request.AssociatePublicIpAddress = e.AssociatePublicIP
	if e.BlockDeviceMappings != nil {
		request.BlockDeviceMappings = []*autoscaling.BlockDeviceMapping{}
		for device, bdm := range e.BlockDeviceMappings {
			request.BlockDeviceMappings = append(request.BlockDeviceMappings, bdm.ToAutoscaling(device))
		}
	}

	if e.UserData != nil {
		d, err := e.UserData.AsBytes()
		if err != nil {
			return fmt.Errorf("error rendering AutoScalingLaunchConfiguration UserData: %v", err)
		}
		request.UserData = aws.String(base64.StdEncoding.EncodeToString(d))
	}
	if e.IAMInstanceProfile != nil {
		request.IamInstanceProfile = e.IAMInstanceProfile.Name
	}

	_, err = t.Cloud.Autoscaling.CreateLaunchConfiguration(request)
	if err != nil {
		return fmt.Errorf("error creating AutoscalingLaunchConfiguration: %v", err)
	}

	e.ID = fi.String(launchConfigurationName)

	return nil // No tags on a launch configuration
}
Exemplo n.º 18
0
func (_ *EBSVolume) CheckChanges(a, e, changes *EBSVolume) error {
	if a == nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	if a != nil {
		if changes.ID != nil {
			return fi.CannotChangeField("ID")
		}
	}
	return nil
}
Exemplo n.º 19
0
func (s *RouteTable) CheckChanges(a, e, changes *RouteTable) error {
	if a == nil {
		if e.VPC == nil {
			return fi.RequiredField("VPC")
		}
	}
	if a != nil {
		if changes.VPC != nil && changes.VPC.ID != nil {
			return fi.CannotChangeField("VPC")
		}
	}
	return nil
}
Exemplo n.º 20
0
func (_ *LaunchConfiguration) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *LaunchConfiguration) error {
	cloud := t.Cloud.(*awsup.AWSCloud)

	if e.ImageID == nil {
		return fi.RequiredField("ImageID")
	}
	image, err := cloud.ResolveImage(*e.ImageID)
	if err != nil {
		return err
	}

	tf := &terraformLaunchConfiguration{
		NamePrefix:   fi.String(*e.Name + "-"),
		ImageID:      image.ImageId,
		InstanceType: e.InstanceType,
	}

	if e.SSHKey != nil {
		tf.KeyName = e.SSHKey.TerraformLink()
	}

	for _, sg := range e.SecurityGroups {
		tf.SecurityGroups = append(tf.SecurityGroups, sg.TerraformLink())
	}
	tf.AssociatePublicIpAddress = e.AssociatePublicIP

	if e.BlockDeviceMappings != nil {
		tf.EphemeralBlockDevice = []*terraformBlockDevice{}
		for deviceName, bdm := range e.BlockDeviceMappings {
			tf.EphemeralBlockDevice = append(tf.EphemeralBlockDevice, &terraformBlockDevice{
				VirtualName: bdm.VirtualName,
				DeviceName:  fi.String(deviceName),
			})
		}
	}

	if e.UserData != nil {
		tf.UserData, err = t.AddFile("aws_launch_configuration", *e.Name, "user_data", e.UserData)
		if err != nil {
			return err
		}
	}
	if e.IAMInstanceProfile != nil {
		tf.IAMInstanceProfile = e.IAMInstanceProfile.TerraformLink()
	}

	// So that we can update configurations
	tf.Lifecycle = &terraformLifecycle{CreateBeforeDestroy: fi.Bool(true)}

	return t.RenderResource("aws_launch_configuration", *e.Name, tf)
}
Exemplo n.º 21
0
func (_ *Secret) Render(c *fi.Context, a, e, changes *Secret) error {
	name := fi.StringValue(e.Name)
	if name == "" {
		return fi.RequiredField("Name")
	}

	secrets := c.SecretStore

	_, _, err := secrets.GetOrCreateSecret(name)
	if err != nil {
		return fmt.Errorf("error creating secret %q: %v", name, err)
	}

	return nil
}
Exemplo n.º 22
0
func (s *InstanceVolumeAttachment) CheckChanges(a, e, changes *InstanceVolumeAttachment) error {
	if a != nil {
		if changes.Device != nil {
			// TODO: Support this?
			return fi.CannotChangeField("Device")
		}
	}

	if a == nil {
		if e.Device == nil {
			return fi.RequiredField("Device")
		}
	}
	return nil
}
Exemplo n.º 23
0
Arquivo: vpc.go Projeto: crohling/kops
func (s *VPC) CheckChanges(a, e, changes *VPC) error {
	if a == nil {
		if e.CIDR == nil {
			// TODO: Auto-assign CIDR?
			return fi.RequiredField("CIDR")
		}
	}
	if a != nil {
		if changes.CIDR != nil {
			// TODO: Do we want to destroy & recreate the VPC?
			return fi.CannotChangeField("CIDR")
		}
	}
	return nil
}
Exemplo n.º 24
0
func (_ *PersistentDisk) CheckChanges(a, e, changes *PersistentDisk) error {
	if a != nil {
		if changes.SizeGB != nil {
			return fi.CannotChangeField("SizeGB")
		}
		if changes.Zone != nil {
			return fi.CannotChangeField("Zone")
		}
		if changes.VolumeType != nil {
			return fi.CannotChangeField("VolumeType")
		}
	} else {
		if e.Zone == nil {
			return fi.RequiredField("Zone")
		}
	}
	return nil
}
Exemplo n.º 25
0
func addEphemeralDevices(instanceTypeName *string, blockDeviceMappings map[string]*BlockDeviceMapping) (map[string]*BlockDeviceMapping, error) {
	// TODO: Any reason not to always attach the ephemeral devices?
	if instanceTypeName == nil {
		return nil, fi.RequiredField("InstanceType")
	}
	instanceType, err := awsup.GetMachineTypeInfo(*instanceTypeName)
	if err != nil {
		return nil, err
	}
	if blockDeviceMappings == nil {
		blockDeviceMappings = make(map[string]*BlockDeviceMapping)
	}
	for _, ed := range instanceType.EphemeralDevices() {
		if _, found := blockDeviceMappings[ed.DeviceName]; found {
			glog.Warningf("not attach ephemeral device - found duplicate device mapping: %q", ed.DeviceName)
			continue
		}
		blockDeviceMappings[ed.DeviceName] = &BlockDeviceMapping{VirtualName: fi.String(ed.VirtualName)}
	}
	return blockDeviceMappings, nil
}
Exemplo n.º 26
0
func (s *DHCPOptions) CheckChanges(a, e, changes *DHCPOptions) error {
	if a == nil {
		if e.Name == nil {
			return fi.RequiredField("Name")
		}
	}
	if a != nil {
		if changes.ID != nil {
			return fi.CannotChangeField("ID")
		}

		// TODO: Delete & create new DHCPOptions
		// We can't delete the DHCPOptions while it is attached, but we can change the tag (add a timestamp suffix?)
		if changes.DomainName != nil {
			return fi.CannotChangeField("DomainName")
		}
		if changes.DomainNameServers != nil {
			return fi.CannotChangeField("DomainNameServers")
		}
	}
	return nil
}
Exemplo n.º 27
0
func (_ *RouteTable) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *RouteTable) error {
	if a == nil {
		vpcID := e.VPC.ID
		if vpcID == nil {
			return fi.RequiredField("VPC.ID")
		}

		glog.V(2).Infof("Creating RouteTable with VPC: %q", *vpcID)

		request := &ec2.CreateRouteTableInput{
			VpcId: vpcID,
		}

		response, err := t.Cloud.EC2.CreateRouteTable(request)
		if err != nil {
			return fmt.Errorf("error creating RouteTable: %v", err)
		}

		rt := response.RouteTable
		e.ID = rt.RouteTableId
	}

	return t.AddAWSTags(*e.ID, t.Cloud.BuildTags(e.Name))
}
Exemplo n.º 28
0
func (_ *Keypair) Render(c *fi.Context, a, e, changes *Keypair) error {
	name := fi.StringValue(e.Name)
	if name == "" {
		return fi.RequiredField("Name")
	}

	castore := c.CAStore

	template, err := buildCertificateTemplate(e.Type)
	if err != nil {
		return err
	}

	subjectPkix, err := parsePkixName(e.Subject)
	if err != nil {
		return fmt.Errorf("error parsing Subject: %v", err)
	}

	if len(subjectPkix.ToRDNSequence()) == 0 {
		return fmt.Errorf("Subject name was empty for SSL keypair %q", name)
	}

	template.Subject = *subjectPkix

	var alternateNames []string
	alternateNames = append(alternateNames, e.AlternateNames...)

	for _, san := range alternateNames {
		san = strings.TrimSpace(san)
		if san == "" {
			continue
		}
		if ip := net.ParseIP(san); ip != nil {
			template.IPAddresses = append(template.IPAddresses, ip)
		} else {
			template.DNSNames = append(template.DNSNames, san)
		}
	}

	createCertificate := false
	if a == nil {
		createCertificate = true
	} else if changes != nil {
		if changes.AlternateNames != nil {
			createCertificate = true
		} else {
			glog.Warningf("Ignoring changes in key: %v", fi.DebugAsJsonString(changes))
		}
	}

	if createCertificate {
		glog.V(2).Infof("Creating PKI keypair %q", name)

		// TODO: Reuse private key if already exists?
		cert, _, err := castore.CreateKeypair(name, template)
		if err != nil {
			return err
		}

		glog.V(8).Infof("created certificate %v", cert)
	}

	// TODO: Check correct subject / flags

	return nil
}
Exemplo n.º 29
0
func (_ *LoadBalancer) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *LoadBalancer) error {
	elbName := e.ID
	if elbName == nil {
		elbName = e.Name
	}

	if elbName == nil {
		return fi.RequiredField("ID")
	}

	if a == nil {
		request := &elb.CreateLoadBalancerInput{}
		request.LoadBalancerName = elbName

		for _, subnet := range e.Subnets {
			request.Subnets = append(request.Subnets, subnet.ID)
		}

		for _, sg := range e.SecurityGroups {
			request.SecurityGroups = append(request.SecurityGroups, sg.ID)
		}

		request.Listeners = []*elb.Listener{}

		for loadBalancerPort, listener := range e.Listeners {
			loadBalancerPortInt, err := strconv.ParseInt(loadBalancerPort, 10, 64)
			if err != nil {
				return fmt.Errorf("error parsing load balancer listener port: %q", loadBalancerPort)
			}
			awsListener := listener.mapToAWS(loadBalancerPortInt)
			request.Listeners = append(request.Listeners, awsListener)
		}

		glog.V(2).Infof("Creating ELB with Name:%q", *e.ID)

		response, err := t.Cloud.ELB.CreateLoadBalancer(request)
		if err != nil {
			return fmt.Errorf("error creating ELB: %v", err)
		}

		e.DNSName = response.DNSName
		e.ID = elbName

		lb, err := findELB(t.Cloud, *e.ID)
		if err != nil {
			return err
		}
		if lb == nil {
			// TODO: Retry?  Is this async
			return fmt.Errorf("Unable to find newly created ELB")
		}

		e.HostedZoneId = lb.CanonicalHostedZoneNameID
	} else {
		if changes.Subnets != nil {
			return fmt.Errorf("subnet changes on LoadBalancer not yet implemented")
		}

		if changes.Listeners != nil {
			request := &elb.CreateLoadBalancerListenersInput{}
			request.LoadBalancerName = elbName

			for loadBalancerPort, listener := range changes.Listeners {
				loadBalancerPortInt, err := strconv.ParseInt(loadBalancerPort, 10, 64)
				if err != nil {
					return fmt.Errorf("error parsing load balancer listener port: %q", loadBalancerPort)
				}
				awsListener := listener.mapToAWS(loadBalancerPortInt)
				request.Listeners = append(request.Listeners, awsListener)
			}

			glog.V(2).Infof("Creating LoadBalancer listeners")

			_, err := t.Cloud.ELB.CreateLoadBalancerListeners(request)
			if err != nil {
				return fmt.Errorf("error creating LoadBalancerListeners: %v", err)
			}
		}
	}

	return t.AddELBTags(*e.ID, t.Cloud.BuildTags(e.Name))
}
Exemplo n.º 30
0
func (_ *Instance) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Instance) error {
	if a == nil {
		if e.ImageID == nil {
			return fi.RequiredField("ImageID")
		}
		image, err := t.Cloud.ResolveImage(*e.ImageID)
		if err != nil {
			return err
		}

		glog.V(2).Infof("Creating Instance with Name:%q", *e.Name)
		request := &ec2.RunInstancesInput{
			ImageId:      image.ImageId,
			InstanceType: e.InstanceType,
			MinCount:     aws.Int64(1),
			MaxCount:     aws.Int64(1),
		}

		if e.SSHKey != nil {
			request.KeyName = e.SSHKey.Name
		}

		securityGroupIDs := []*string{}
		for _, sg := range e.SecurityGroups {
			securityGroupIDs = append(securityGroupIDs, sg.ID)
		}
		request.NetworkInterfaces = []*ec2.InstanceNetworkInterfaceSpecification{
			{
				DeviceIndex:              aws.Int64(0),
				AssociatePublicIpAddress: e.AssociatePublicIP,
				SubnetId:                 e.Subnet.ID,
				PrivateIpAddress:         e.PrivateIPAddress,
				Groups:                   securityGroupIDs,
			},
		}

		if e.BlockDeviceMappings != nil {
			request.BlockDeviceMappings = []*ec2.BlockDeviceMapping{}
			for deviceName, bdm := range e.BlockDeviceMappings {
				request.BlockDeviceMappings = append(request.BlockDeviceMappings, bdm.ToEC2(deviceName))
			}
		}

		if e.UserData != nil {
			d, err := fi.ResourceAsBytes(e.UserData)
			if err != nil {
				return fmt.Errorf("error rendering Instance UserData: %v", err)
			}
			if len(d) > MaxUserDataSize {
				// TODO: Re-enable gzip?
				// But it exposes some bugs in the AWS console, so if we can avoid it, we should
				//d, err = fi.GzipBytes(d)
				//if err != nil {
				//	return fmt.Errorf("error while gzipping UserData: %v", err)
				//}
				return fmt.Errorf("Instance UserData was too large (%d bytes)", len(d))
			}
			request.UserData = aws.String(base64.StdEncoding.EncodeToString(d))
		}

		if e.IAMInstanceProfile != nil {
			request.IamInstanceProfile = &ec2.IamInstanceProfileSpecification{
				Name: e.IAMInstanceProfile.Name,
			}
		}

		response, err := t.Cloud.EC2.RunInstances(request)
		if err != nil {
			return fmt.Errorf("error creating Instance: %v", err)
		}

		e.ID = response.Instances[0].InstanceId
	}

	return t.AddAWSTags(*e.ID, e.Tags)
}