예제 #1
0
 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,
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
 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;
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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}");
        }
예제 #10
0
        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);
        }
예제 #11
0
        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")})");
        }