public async Task ProcessTags(Amazon.EC2.Model.Instance instance, string cOn, string cOff, string cKill, string cTargetGroupRegister, string cTargetGroupDeregister, IEnumerable <(string name, int port)> targetGroups,
internal static void Map(AwsInstance src, Instance dest, SaveMechanic mechanic) { var nameTag = src.Tags.FirstOrDefault(x => x.Key.Equals("name", StringComparison.InvariantCultureIgnoreCase)); string name = nameTag == null?string.Format("Unknown-{0}", src.InstanceId) : nameTag.Value; List <IPAddress> privateIpAddresses = src.PrivateIpAddress == null ? new List <IPAddress>() : new List <IPAddress> { IPAddress.Parse(src.PrivateIpAddress) }; List <IPAddress> publicIpAddresses = src.PublicIpAddress == null ? new List <IPAddress>() : new List <IPAddress> { IPAddress.Parse(src.PublicIpAddress) }; List <string> volumeResourceIds = src.BlockDeviceMappings.Select(x => x.Ebs.VolumeId).ToList(); dest.AvailabilityZone = src.Placement.AvailabilityZone; dest.InstanceType = src.InstanceType.Value; dest.KeyName = src.KeyName; dest.LaunchTime = src.LaunchTime; dest.MonitoringState = src.Monitoring.State != MonitoringState.Disabled; dest.Name = name; dest.PrivateAddresses = privateIpAddresses.Select(x => x.ToString()).ToList(); dest.PublicAddresses = publicIpAddresses.Select(x => x.ToString()).ToList(); dest.VolumeResourceIds = volumeResourceIds; dest.ResourceId = src.InstanceId; dest.State = src.State.Name; dest.StorageType = src.RootDeviceType.Value; dest.SubnetId = src.SubnetId; dest.VirtualizationType = src.VirtualizationType.Value; dest.VpcId = src.VpcId; dest.NeedsRefreshing = false; if (mechanic == SaveMechanic.Add) { dest.Id = Guid.NewGuid(); } }
internal static void Map(AwsInstance src, Instance dest, SaveMechanic mechanic) { var nameTag = src.Tags.FirstOrDefault(x => x.Key.Equals("name", StringComparison.InvariantCultureIgnoreCase)); string name = nameTag == null ? string.Format("Unknown-{0}", src.InstanceId) : nameTag.Value; List<IPAddress> privateIpAddresses = src.PrivateIpAddress == null ? new List<IPAddress>() : new List<IPAddress> {IPAddress.Parse(src.PrivateIpAddress)}; List<IPAddress> publicIpAddresses = src.PublicIpAddress == null ? new List<IPAddress>() : new List<IPAddress> {IPAddress.Parse(src.PublicIpAddress)}; List<string> volumeResourceIds = src.BlockDeviceMappings.Select(x => x.Ebs.VolumeId).ToList(); dest.AvailabilityZone = src.Placement.AvailabilityZone; dest.InstanceType = src.InstanceType.Value; dest.KeyName = src.KeyName; dest.LaunchTime = src.LaunchTime; dest.MonitoringState = src.Monitoring.State != MonitoringState.Disabled; dest.Name = name; dest.PrivateAddresses = privateIpAddresses.Select(x => x.ToString()).ToList(); dest.PublicAddresses = publicIpAddresses.Select(x => x.ToString()).ToList(); dest.VolumeResourceIds = volumeResourceIds; dest.ResourceId = src.InstanceId; dest.State = src.State.Name; dest.StorageType = src.RootDeviceType.Value; dest.SubnetId = src.SubnetId; dest.VirtualizationType = src.VirtualizationType.Value; dest.VpcId = src.VpcId; dest.NeedsRefreshing = false; if(mechanic == SaveMechanic.Add) { dest.Id = Guid.NewGuid(); } }
public void Execute(Guid profileId, string instanceId) { IAwsClient awsClient; if (!TryInitializeClient(profileId, out awsClient)) { return; } AwsInstance awsInstance = awsClient.InstanceService.GetInstance(instanceId); if (awsInstance == null) { // Don't do any work if the instance isn't even in Amazon anymore return; } IEnumerable <SecurityGroup> awsSecurityGroups = awsClient.InstanceService.GetSecurityGroups(awsInstance); List <Core.Entities.SecurityGroup> securityGroups = awsSecurityGroups.Select(x => new Core.Entities.SecurityGroup { Name = x.GroupName, ResourceId = x.GroupId }).ToList(); Instance dbInstance = _instanceRepository.FindAll().FirstOrDefault(x => x.ResourceId == instanceId); Instance instanceToPersist = dbInstance ?? new Instance(); SaveMechanic saveMechanic = dbInstance == null ? SaveMechanic.Add : SaveMechanic.Update; Map(awsInstance, instanceToPersist, saveMechanic); instanceToPersist.OwnerProfileId = profileId; instanceToPersist.SecurityGroups = securityGroups; Persist(_instanceRepository, instanceToPersist, saveMechanic); }
public Task <DeregisterTargetsResponse> DeregisterTargetAsync( TargetGroup targetGroup, Amazon.EC2.Model.Instance instance, CancellationToken cancellationToken = default(CancellationToken)) => _clientV2.DeregisterTargetsAsync( new DeregisterTargetsRequest() { TargetGroupArn = targetGroup.TargetGroupArn, Targets = new List <TargetDescription>() { new TargetDescription() { Id = instance.InstanceId } } }, cancellationToken: cancellationToken).EnsureSuccessAsync();
private static bool StackItIdTagsMatch(InstanceEntity instanceEntity, InstanceResource instanceResource) { const string tagName = "StackItId"; var instanceEntityTag = instanceEntity.Tags.FirstOrDefault(x => x.Name == tagName); if (instanceEntityTag == null) { return false; } var instanceResourceTag = instanceResource.Tags.FirstOrDefault(x => x.Key == tagName); if (instanceResourceTag == null) { return false; } return instanceEntityTag.Value == instanceResourceTag.Value; }
private static bool StackItIdTagsMatch(InstanceEntity instanceEntity, InstanceResource instanceResource) { const string tagName = "StackItId"; var instanceEntityTag = instanceEntity.Tags.FirstOrDefault(x => x.Name == tagName); if (instanceEntityTag == null) { return(false); } var instanceResourceTag = instanceResource.Tags.FirstOrDefault(x => x.Key == tagName); if (instanceResourceTag == null) { return(false); } return(instanceEntityTag.Value == instanceResourceTag.Value); }
public async Task ProcessRecord(string zoneId, ResourceRecordSet record, Amazon.EC2.Model.Instance instance, bool enabled, string name, long ttl, string address) { if (!enabled) { if (record == null) { Log($"No need to destroy, record '{name}' does not exists for zone '{zoneId}'. Tags Origin: EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")})"); return; //no need to update, record does not exist } else { Log($"Destroying record {record.Name} linked to EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")})..."); await _R53.DestroyRecord(zoneId, record.Name, record.Type); } return; } if (record?.Type == RRType.A && record?.ResourceRecords.Any(r => r.Value == address) == true && record?.TTL == ttl) { Log($"Correct record already exists for EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")})"); return; //no need to update, correct record already exists } Log($"Updating record of EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")}), Old Record Name: '{record?.Name}'..."); await _R53.UpsertRecordAsync( zoneId : zoneId, Name : name, Value : address, Type : RRType.A, TTL : ttl); }
public async Task Process(Amazon.EC2.Model.Instance instance, ILambdaLogger logger) { if (!instance.Tags.Any(x => x.Key.Contains("Auto"))) { return; } logger.Log($"Processing Update and Tag Validation of EC2 Instance {instance.InstanceId}, Name: {instance.GetTagValueOrDefault("Name")}"); var disableAll = instance.GetTagValueOrDefault("Terminator Disable All").ToBoolOrDefault(false); if (!disableAll) { var targetGroups = instance.GetTagValueOrDefault($"Target Groups") ?? instance.GetTagValueOrDefault($"TG"); var targetGroupsList = new List <(string name, int port)>(); if (!targetGroups.IsNullOrEmpty()) { var arrTGNames = targetGroups.Split(','); var arrTGPorts = targetGroups.Split(','); while (arrTGNames.Length > arrTGPorts.Length) //extrapolate by last or default 80 { arrTGPorts = arrTGPorts.Merge(((arrTGPorts?.Length ?? 0) > 0) ? arrTGPorts[arrTGPorts.Length - 1] : "80"); } while (arrTGPorts.Length > arrTGNames.Length) //extrapolate names by last { arrTGNames = arrTGNames.Merge(arrTGNames[arrTGNames.Length - 1]); } for (int i = 0; i < arrTGNames.Length; i++) { var tg = arrTGNames[i]?.Trim(" ")?.Split(':'); if (tg.IsNullOrEmpty() || tg.Length != 2 || tg[0].IsNullOrWhitespace() || tg[1].IsNullOrWhitespace() || !tg[1].ToIntOrDefault(-1).InClosedInterval(1, 65535)) { logger.Log($"WARINING!!! Invalid Target Groups (TG) Name definition '{(arrTGNames[i] ?? "undefined")}' for instance {instance.InstanceId}."); continue; } targetGroupsList.Add((tg[0].Trim(" "), tg[1].ToInt32())); } } await ParallelEx.ForAsync(0, _maxPeriodsPerInstance, async i => { var suffix = i == 0 ? " 1" : $" {i + 1}"; var disabled = instance.GetTagValueOrDefault($"Terminator Disable{suffix}").ToBoolOrDefault(false); if (disabled) { return; } var cOn = instance.GetTagValueOrDefault($"Auto On{suffix}"); var cOff = instance.GetTagValueOrDefault($"Auto Off{suffix}"); var cKill = instance.GetTagValueOrDefault($"Auto Kill{suffix}"); var cTargetGroupRegister = instance.GetTagValueOrDefault($"Auto TGR{suffix}"); var cTargetGroupDeregister = instance.GetTagValueOrDefault($"Auto TGD{suffix}"); if (cOn.IsNullOrEmpty() && cOff.IsNullOrEmpty() && cKill.IsNullOrEmpty() && cTargetGroupRegister.IsNullOrEmpty() && cTargetGroupDeregister.IsNullOrEmpty()) { return; //skip no instance control tagg's were found } var ex = await ProcessTags(instance, cOn: cOn, cOff: cOff, cKill: cKill, cTargetGroupRegister: cTargetGroupRegister, cTargetGroupDeregister: cTargetGroupDeregister, targetGroups: targetGroupsList, logger: logger).CatchExceptionAsync(); if (ex != null) { logger.Log($"Failed Update or Tag Validation of EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")}), Auto On: '{cOn}', Auto Off: '{cOff}', Auto Kill: '{cKill}', Exception: {ex.JsonSerializeAsPrettyException()}"); } }); } logger.Log($"Finished Processing and Tag Validation of EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")}), DisableAll: {disableAll}"); }
public static string GetEC2PropFromString(string input, Amazon.EC2.Model.Instance i) { string result = ""; input = input.Replace(" ", string.Empty); string[] inputArr = input.Split('='); if (inputArr.Length > 1) { if (inputArr[0].ToLower() == "tag") { result = GetEC2Tag(i.Tags, inputArr[1]); } } else { switch (input.ToLower()) { case "architecture": result = i.Architecture; break; case "blockdevicemappings": result = ""; break; case "ebsoptimized": result = i.EbsOptimized.ToString(); break; case "enasupport": result = i.EnaSupport.ToString(); break; case "hypervisor": result = i.Hypervisor; break; case "iaminstanceprofile": result = i.IamInstanceProfile.Id; break; case "instanceid": result = i.InstanceId; break; case "instancetype": result = i.InstanceType; break; case "kernelid": result = i.KernelId; break; case "keyname": result = i.KeyName; break; case "launchtime": result = i.LaunchTime.ToString("yyyy-MM-dd HH:mm:ss"); break; case "monitoring": result = i.Monitoring.State.Value; break; case "networkinterfaces": result = ""; break; case "placement": result = ""; break; case "platform": result = i.Platform.Value; break; case "privatednsname": result = i.PrivateDnsName; break; case "privateipaddress": result = i.PrivateIpAddress; break; case "publicdnsname": result = i.PublicDnsName; break; case "publicipaddress": result = i.PublicIpAddress; break; case "rootdevicename": result = i.RootDeviceName; break; case "rootdevicetype": result = i.RootDeviceType.Value; break; case "securitygroups": result = GetEC2SecurityGroups(i.SecurityGroups); break; case "subnetid": result = i.SubnetId; break; case "state": result = i.State.Name; break; case "imageid": result = i.ImageId; break; case "vpcid": result = i.VpcId; break; case "name": result = GetEC2Tag(i.Tags, "name"); break; default: break; } } return(result); }
public async Task Process(Dictionary <HostedZone, ResourceRecordSet[]> zones, Amazon.EC2.Model.Instance instance) { Log($"Processing and Veryfying Route53 Recors for EC2 Instance {instance.InstanceId}, Name: {instance.GetTagValueOrDefault("Name")}"); var disableAll = instance.GetTagValueOrDefault("Route53 Disable All").ToBoolOrDefault(false); await ParallelEx.ForAsync(0, _maxRoutesPerInstance, async i => { var suffix = i == 0 ? "" : $" {i - 1}"; var name = instance.GetTagValueOrDefault($"Route53 Name{suffix}"); var type = instance.GetTagValueOrDefault($"Route53 Address{suffix}").CoalesceNullOrEmpty("public").ToLower(); string address = null; if (type == "public") { address = instance.PublicIpAddress; } else if (type == "private") { address = instance.PrivateIpAddress; } else { Log($"Invalid Tag: 'Route53 Address{suffix}' expected 'public' or 'private' but was '{type}', Tags Origin: EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")})"); return; } var enabled = !disableAll && //not globally disabled !address.IsNullOrEmpty() && //has valid public or private IP instance.State.Name == InstanceStateName.Running && //instance is running instance.GetTagValueOrDefault($"Route53 Enable{suffix}").ToBoolOrDefault(false); //is locally enabled var zoneId = instance.GetTagValueOrDefault($"Route53 Zone{suffix}"); var ttl = instance.GetTagValueOrDefault($"Route53 TTL{suffix}").ToIntOrDefault(60); if (!name.IsNullOrEmpty() && zones.Any(z => z.Key.Id.Contains(zoneId))) { var zone = zones.First(z => z.Key.Id.Contains(zoneId)); var recordName = $"{name.Trim(' ', '.')}.{zone.Key.Name.Trim(' ', '.')}"; //for whatever reason those names end with dot once they are saved... var record = zone.Value.FirstOrDefault(r => r.Name.Equals($"{recordName}.", StringComparison.InvariantCultureIgnoreCase)); var ex = await ProcessRecord(zoneId, record, instance, enabled, recordName, ttl, address).CatchExceptionAsync(); if (ex != null) { Log($"Failed during Update or Validation of Route53 record for EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")}), ZoneId: {zoneId}, Name: {name}, Old Record Name: {record?.Name}, Enable: {enabled}, TTL: {ttl}, Address: {address}, Error: {ex.JsonSerializeAsPrettyException()}"); } } }); Log($"Finished Processing and Veryfying Route53 Recors for EC2 Instance {instance.InstanceId} ({instance.GetTagValueOrDefault("Name")})"); }