Beispiel #1
0
        public async Task <IHost[]> LaunchAsync(LaunchHostRequest launchRequest, ISecurityContext context)
        {
            Validate.NotNull(launchRequest, nameof(launchRequest));
            Validate.NotNull(context, nameof(context));

            var zoneId = LocationId.Create(launchRequest.Location.Id);

            if (zoneId.ZoneNumber == 0)
            {
                throw new Exception("Must launch within in availability zone. Was a region:" + launchRequest.Location.Name);
            }

            var cluster  = launchRequest.Cluster;
            var zone     = launchRequest.Location;
            var template = launchRequest.Template;

            var region = Locations.Get(zoneId.WithZoneNumber(0));

            var image = await imageService.GetAsync(template.ImageId);;

            var machineType = AwsInstanceType.Get(template.MachineTypeId);

            var request = new RunInstancesRequest {
                ClientToken       = Guid.NewGuid().ToString(),
                InstanceType      = machineType.Name,
                ImageId           = image.ResourceId,
                MinCount          = launchRequest.LaunchCount,
                MaxCount          = launchRequest.LaunchCount,
                Placement         = new Placement(availabilityZone: zone.Name),
                TagSpecifications = new[] {
                    new TagSpecification(
                        resourceType: "instance",
                        tags: new[] { new Amazon.Ec2.Tag("envId", cluster.EnvironmentId.ToString()) }
                        )
                }
            };

            var startupScript = launchRequest.StartupScript ?? template.StartupScript;

            if (startupScript != null)
            {
                request.UserData = Convert.ToBase64String(Encoding.UTF8.GetBytes(startupScript));
            }

            #region AWS Specific Properties

            foreach (var property in template.Properties)
            {
                switch (property.Key)
                {
                case HostTemplateProperties.IamRole:
                    // NOTE: This requires the PassRole permission
                    // https://aws.amazon.com/blogs/security/granting-permission-to-launch-ec2-instances-with-iam-roles-passrole-permission/

                    request.IamInstanceProfile = new IamInstanceProfileSpecification(property.Value);

                    break;

                case HostTemplateProperties.KernelId:
                    request.KernelId = property.Value;

                    break;

                case HostTemplateProperties.SecurityGroupIds:
                    request.SecurityGroupIds = property.Value.ToArrayOf <string>();

                    break;

                case HostTemplateProperties.EbsOptimized:
                    request.EbsOptimized = (bool)property.Value;

                    break;

                case HostTemplateProperties.Monitoring:
                    request.Monitoring = new RunInstancesMonitoringEnabled((bool)property.Value);

                    break;

                case HostTemplateProperties.Volume:
                    var volSpec = property.Value.As <AwsVolumeSpecification>();

                    // TODO: Device Name
                    request.BlockDeviceMappings = new[] {
                        new BlockDeviceMapping(BlockDeviceNames.Root, new EbsBlockDevice(
                                                   volumeType: volSpec.Type,
                                                   volumeSize: (int)volSpec.Size
                                                   ))
                    };

                    break;

                case HostTemplateProperties.KeyName:
                    request.KeyName = property.Value;

                    break;
                }
            }

            #endregion

            var runInstancesResponse = await ec2.RunInstancesAsync(request);;

            var hosts = new IHost[runInstancesResponse.Instances.Length];

            for (var i = 0; i < hosts.Length; i++)
            {
                var registerRequest = await GetRegistrationAsync(
                    instance : runInstancesResponse.Instances[i],
                    cluster : cluster,
                    image : image,
                    machineType : machineType,
                    location : zone
                    );

                hosts[i] = await hostService.RegisterAsync(registerRequest);;
            }

            #region Logging

            await eventLog.CreateAsync(new Event(
                                           action   : "launch",
                                           resource : "hosts",
                                           userId   : context.UserId)
                                       );;

            #endregion

            return(hosts);
        }
Beispiel #2
0
        private async Task <RegisterHostRequest> GetRegistrationAsync(
            Instance instance,
            Cluster cluster,
            IImage image             = null,
            ILocation location       = null,
            IMachineType machineType = null)
        {
            Validate.NotNull(instance, nameof(instance));

            // Ensure the instance is inside a VPC (no classic instances)
            if (instance.VpcId == null)
            {
                throw new ArgumentException("Must belong to a VPC", nameof(instance));
            }

            #region Data Binding / Mappings

            if (location == null)
            {
                location = Locations.Get(aws, instance.Placement.AvailabilityZone);
            }

            if (image == null)
            {
                // "imageId": "ami-1647537c",

                image = await imageService.GetAsync(aws, instance.ImageId);;
            }

            if (machineType == null)
            {
                machineType = AwsInstanceType.Get(instance.InstanceType);
            }

            var network = await db.Networks.FindAsync(aws, instance.VpcId);;

            #endregion

            // instance.LaunchTime

            int addressCount = 1;

            if (instance.IpAddress != null)
            {
                addressCount++;
            }

            var addresses = new string[addressCount];

            addresses[0] = instance.PrivateIpAddress;

            if (instance.IpAddress != null)
            {
                // the instance was assigned a public IP
                addresses[1] = instance.IpAddress;
            }

            var registerRequest = new RegisterHostRequest(
                addresses: addresses,
                cluster: cluster,
                image: image,
                machineType: machineType,
                program: null,
                location: location,
                status: instance.InstanceState.ToStatus(),
                ownerId: 1,
                resource: ManagedResource.Host(location, instance.InstanceId)
                );

            #region Network Interfaces

            try
            {
                var nics = new RegisterNetworkInterfaceRequest[instance.NetworkInterfaces.Length];

                for (var nicIndex = 0; nicIndex < nics.Length; nicIndex++)
                {
                    var ec2Nic = instance.NetworkInterfaces[nicIndex];

                    nics[nicIndex] = new RegisterNetworkInterfaceRequest(
                        mac: MacAddress.Parse(ec2Nic.MacAddress),
                        subnetId: 0,                            // TODO: lookup subnet
                        securityGroupIds: Array.Empty <long>(), // TODO: lookup security groupds
                        resource: ManagedResource.NetworkInterface(location, ec2Nic.NetworkInterfaceId)
                        );
                }

                registerRequest.NetworkInterfaces = nics;
            }
            catch { }

            #endregion

            #region Volumes

            try
            {
                var volumes = new RegisterVolumeRequest[instance.BlockDeviceMappings.Length];

                for (var volumeIndex = 0; volumeIndex < volumes.Length; volumeIndex++)
                {
                    var device = instance.BlockDeviceMappings[volumeIndex];

                    if (device.Ebs == null)
                    {
                        continue;
                    }

                    var volumeSize = device.Ebs.VolumeSize is int ebsSize
                        ? ByteSize.FromGiB(ebsSize)
                        : ByteSize.Zero;

                    volumes[volumeIndex] = new RegisterVolumeRequest(
                        ownerId: 1,
                        size: volumeSize,
                        resource: ManagedResource.Volume(location, device.Ebs.VolumeId)

                        );
                }

                registerRequest.Volumes = volumes;
            }
            catch { }

            #endregion

            return(registerRequest);
        }
 public void A()
 {
     Assert.Equal(4362403853, AwsInstanceTypes.M5Large.Id);
     Assert.Equal("m5.large", AwsInstanceType.Get(4362403853).Name);
 }