Example #1
0
        public void Execute(Guid profileId)
        {
            IAwsClient awsClient;

            if (!TryInitializeClient(profileId, out awsClient))
            {
                return;
            }

            List <InstanceResource> awsInstances = awsClient.InstanceService.GetAllInstances().ToList();

            Dictionary <string, List <SecurityGroupResource> > securityGroupsFor = awsClient.SecurityGroupService.GetSecurityGroupMap(awsInstances);

            foreach (InstanceResource awsInstance in awsInstances)
            {
                List <SecurityGroupEntity> securityGroups = securityGroupsFor[awsInstance.InstanceId]
                                                            .Select(x => new SecurityGroupEntity {
                    Name = x.GroupName, ResourceId = x.GroupId
                }).ToList();

                string instanceId = awsInstance.InstanceId;

                InstanceEntity dbInstance = _instanceRepository.FindAll()
                                            .FirstOrDefault(x => StackItIdTagsMatch(x, awsInstance) || x.ResourceId == instanceId);
                InstanceEntity instanceToPersist = dbInstance ?? new InstanceEntity();

                SaveMechanic saveMechanic = dbInstance == null ? SaveMechanic.Add : SaveMechanic.Update;

                UpdateInstance.Map(awsInstance, instanceToPersist, saveMechanic);
                instanceToPersist.OwnerProfileId = profileId;
                instanceToPersist.SecurityGroups = securityGroups;
                UpdateInstance.Persist(_instanceRepository, instanceToPersist, saveMechanic);
            }
        }
        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);
        }
        internal static void Persist(IRepository <Instance> instanceRepository, Instance instanceToPersist, SaveMechanic saveMechanic)
        {
            switch (saveMechanic)
            {
            case SaveMechanic.Add:
                instanceRepository.Add(instanceToPersist);
                break;

            case SaveMechanic.Update:
                instanceRepository.Update(instanceToPersist);
                break;

            default:
                throw new InvalidOperationException("Unknown save mechanic. This should never happen.");
            }
        }
        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;
        }
Example #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);
        }
 internal static void Persist(IRepository<Instance> instanceRepository, Instance instanceToPersist, SaveMechanic saveMechanic)
 {
     switch(saveMechanic)
     {
         case SaveMechanic.Add:
             instanceRepository.Add(instanceToPersist);
             break;
         case SaveMechanic.Update:
             instanceRepository.Update(instanceToPersist);
             break;
         default:
             throw new InvalidOperationException("Unknown save mechanic. This should never happen.");
     }
 }
        public ActionResult CreateStack(CreateStackViewModel viewModel)
        {
            // If the user doesn't have permission to the selected profile, fail early
            string currentUserName             = _owinContext.Authentication.User.Identity.Name;
            var    userProfiles                = _userProfileAccessManager.GetProfilesForUser(currentUserName).ToList();
            var    selectedProfile             = userProfiles.FirstOrDefault(x => x.Id == viewModel.SelectedProfileId);
            bool   userHasPermissionForProfile = selectedProfile != null;

            if (!userHasPermissionForProfile)
            {
                throw new InvalidOperationException("User does not have permission to use this profile.");
            }

            var stackComponentDefinition = viewModel.SelectedProductIds
                                           .Zip(viewModel.SelectedVersionNames, (productId, versionName) => new { productId, versionName })
                                           .Zip(viewModel.SelectedRoleNames, (prodVer, roleName) => new { prodVer.productId, prodVer.versionName, roleName })
                                           .Zip(viewModel.Options, (prodVerRole, options) => new { prodVerRole.productId, prodVerRole.versionName, prodVerRole.roleName, options })
                                           .Select(x => new { x.productId, x.versionName, x.roleName, x.options }).ToList();

            var configuration = new StackConfiguration
            {
                StackName              = viewModel.StackName,
                OwnerProfileId         = viewModel.SelectedProfileId,
                OwnerUserName          = currentUserName,
                VpcId                  = viewModel.SelectedVpcId,
                SubnetId               = viewModel.SelectedSubnetId,
                HostedZone             = userProfiles.Single(x => x.Id == viewModel.SelectedProfileId).HostedZone,
                BootstrapperUrl        = _stackItConfiguration.PuppetConfiguration.BootstrapperUrl,
                PuppetInstallerUrl     = _stackItConfiguration.PuppetConfiguration.PuppetInstallerUrl,
                PuppetHost             = _stackItConfiguration.PuppetConfiguration.PuppetHost,
                DefaultSecurityGroupId = selectedProfile.DefaultSecurityGroupId,
                Notes                  = viewModel.Notes,
                ScheduleId             = viewModel.SelectedScheduleId,
                ScheduleEnabled        = viewModel.ScheduleEnabled
            };

            foreach (var entry in stackComponentDefinition)
            {
                var     scopedEntry = entry;
                Product product     = _productRepository.Find(scopedEntry.productId);
                Version version     = product.Versions.Single(x => x.Name == scopedEntry.versionName);
                Role    role        = version.Roles.Single(x => x.Name == scopedEntry.roleName);

                OverwriteRoleOptions(role, scopedEntry.options);

                // If the instance type is not whitelisted, fail.
                // Do so after the role mapping so that website defaults (i.e. when a user doesn't alter the options)
                // values can be handled first.
                if (!_stackItConfiguration.InstanceTypes.Select(x => x.Name).Contains(role.Options.InstanceType))
                {
                    throw new InvalidOperationException("Instance type not supported.");
                }

                bool   useDefaultName = scopedEntry.options == null || string.IsNullOrEmpty(scopedEntry.options.InstanceName);
                string instanceName   = useDefaultName
                                        ? string.Format("{0}{1}{2}", viewModel.StackName, product.Name, role.Name)
                                        .RemoveAllWhitespace()
                                        .RemoveNonAlphaNumericCharacters()
                                        : scopedEntry.options.InstanceName;

                instanceName = _numberedStringGenerator.GetNextString(instanceName);

                var instance = new Instance
                {
                    Name         = instanceName,
                    InstanceType = role.Options.InstanceType,
                    Role         = role,
                    Tags         = new List <Tag> {
                        new Tag {
                            Name = "Name", Value = instanceName
                        }
                    },
                    VpcId           = configuration.VpcId,
                    SubnetId        = configuration.SubnetId,
                    ProductName     = product.Name,
                    VersionName     = version.Name,
                    NeedsRefreshing = true,
                    OwnerProfileId  = configuration.OwnerProfileId,
                    IamRole         = entry.options.IamRole ?? version.IamRole
                };

                configuration.Instances.Add(instance);
            }

            _backgroundJobClient.Enqueue <CreateStack>(x => x.Execute(viewModel.SelectedProfileId, configuration));

            return(RedirectToAction("Index"));
        }