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