/// <summary>
        /// Gets the resource components for the resources in an ARM template
        /// </summary>
        /// <param name="template">The object containing the ARM Template</param>
        /// <param name="paramvalue">The object containing the values in the Parameter file</param>
        /// <param name="location">The Azure Location</param>
        /// <param name="cspCreds">CSP Account credentials object. A token will be generated using these credentials and used for making the online ARM API call</param>
        /// <param name="log">The object that will contain the exception messages</param>
        /// <returns> Returns the list of resource components</returns>
        public static List <ResourceComponent> GetResourceComponentsForTemplate(ARMTemplate template, ARMParamValue paramvalue, string location, CSPAccountCreds cspCreds, out StringBuilder log)
        {
            List <ResourceComponent> components = new List <ResourceComponent>();

            log = new StringBuilder(string.Empty);
            string locationAsPerARMSpecs = null;

            try
            {
                // Fetch the location as per ARM Specs from the mapping
                if (!LocationConstants.LocationAsPerARMSpecsMap.TryGetValue(location, out locationAsPerARMSpecs))
                {
                    throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("Location", location, "ARMTemplate"));
                }

                if (template.Resources != null && template.Resources.Count > 0)
                {
                    // Loop thru each resource in the ARM Template
                    foreach (Resource res in template.Resources)
                    {
                        ARMResourceType resType        = null;
                        string          nameOfResource = string.Empty;
                        if (res != null && res.Name != null)
                        {
                            // Fetch the name of the current resource
                            nameOfResource = PropertyHelper.GetValueIfVariableOrParam(res.Name, template.Variables, template.Parameters, paramvalue.Parameters);
                        }

                        // Check if resource or resource type is not null
                        if (res != null && res.Type != null)
                        {
                            // Check if resource type is in supported by this application
                            resType = ResourceTypeHelper.ResourceTypeList.Find(x => res.Type.Equals(x.ARMResourceTypeText, StringComparison.OrdinalIgnoreCase));

                            if (resType != null)
                            {
                                List <ResourceComponent> currentResourceComponents = new List <ResourceComponent>();

                                // Check if the resource type of the current resource does not have chargeable components
                                if (!resType.HasChargableComponents)
                                {
                                    currentResourceComponents.Add(new ResourceComponent()
                                    {
                                        ResourceType = res.Type,
                                        Quantity     = 0,
                                        IsChargeable = false
                                    });
                                }
                                else
                                {
                                    IComponentFetcher resCompFetcher = null;

                                    // Create the appropriate object to fetch the components of the resource
                                    switch (resType.ARMResourceTypeText)
                                    {
                                    // Public IP Resource
                                    case ARMResourceTypeConstants.ARMPublicIPResourceType:
                                        resCompFetcher = new PublicIPComponentFetcher();
                                        break;

                                    // Virtual Machine Resource
                                    case ARMResourceTypeConstants.ARMVMResourceType:
                                        resCompFetcher = new VMComponentFetcher();
                                        break;

                                    default:

                                        // Has Chargable Components but not yet supported
                                        log.AppendLine(ExceptionLogger.GenerateLoggerTextForUnSupportedResource(res.Type));
                                        break;
                                    }

                                    StringBuilder resLog = new StringBuilder(string.Empty);

                                    // Call the method to fetch the resource components
                                    List <ResourceComponent> resComp = resCompFetcher.GetResourceComponents(res, template, paramvalue, locationAsPerARMSpecs, cspCreds, out resLog);
                                    if (resLog != null)
                                    {
                                        log.Append(resLog);
                                    }

                                    if (resComp != null && resComp.Count > 0)
                                    {
                                        currentResourceComponents.AddRange(resComp);
                                    }
                                    else
                                    {
                                        log.AppendLine(ExceptionLogger.GenerateLoggerTextForNoResourceOutput(nameOfResource));
                                    }
                                }

                                foreach (ResourceComponent component in currentResourceComponents)
                                {
                                    component.ResourceName = nameOfResource;
                                }

                                components.AddRange(currentResourceComponents);
                            }
                            else
                            {
                                log.AppendLine(ExceptionLogger.GenerateLoggerTextForUnSupportedResource(res.Type));
                            }
                        }
                        else
                        {
                            if (res != null)
                            {
                                // Type of the resourse is missing/null, generate the message
                                log.AppendLine(ExceptionLogger.GenerateLoggerTextForMissingField("Type", nameOfResource));
                            }
                            else
                            {
                                // Resourse is missing/null, generate the message
                                log.AppendLine(ExceptionLogger.GenerateLoggerTextForMissingField("Resource", "ARMTemplate"));
                            }
                        }
                    }
                }
                else
                {
                    // Resources section in ARM template is missing/null, generate a message
                    throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("RESOURCES", "ARMTemplate"));
                }
            }
            catch (Exception ex)
            {
                // Catch any exception and log the message
                components = null;
                log.AppendLine(ex.Message);
            }

            // Return the list of components obtained for the resources in the ARM template
            return(components);
        }
Example #2
0
        /// <summary>
        /// Gets the resource components for the Disks of the Virtual machine resource.
        /// </summary>
        /// <param name="diskURI">The URI of the disk</param>
        /// <param name="diskSize">The size of the Disk</param>
        /// <param name="storageResourceList">The list of storage resources in the ARM Template</param>
        /// <param name="isOSDisk">Set true for OS Disk and false for Data Disk</param>
        /// <returns> Returns the list of resource components </returns>
        private List <ResourceComponent> GetResourceComponentForDiskStorage(string diskURI, string diskSize, List <Resource> storageResourceList, bool isOSDisk)
        {
            List <ResourceComponent> storageComponentList            = new List <ResourceComponent>();
            List <ResourceComponent> storageDiskComponentList        = new List <ResourceComponent>();
            List <ResourceComponent> storageTransactionComponentList = new List <ResourceComponent>();

            // Get the Storage resource corresponding to the Storage of the Disk of the VM
            Resource diskStorageResource = PropertyHelper.SearchResourceInListByName(storageResourceList, diskURI);

            // Create the resource component for Storage of the VM disk, MeterSubCategory and MeterName will be set later
            ResourceComponent storageDiskComponent = new ResourceComponent
            {
                ResourceType     = this.resource.Type,
                MeterCategory    = StorageResourceConstants.StorageMeterCategory,
                MeterSubCategory = null,
                MeterName        = null,
                IsChargeable     = true
            };

            string storageAccountType = null;
            bool   isPremiumStorage   = false;

            StorageProperties storageProp = null;

            if (diskStorageResource != null && diskStorageResource.Properties != null)
            {
                // Get properties of the Storage resource
                storageProp = this.GetStoragePropertiesForStorageResource(diskStorageResource);
            }

            if (storageProp != null)
            {
                // Get Account Type of the Storage resource
                storageAccountType = PropertyHelper.GetValueIfVariableOrParam(storageProp.AccountType, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
            }

            // If Unable to fetch Storage Account Type, then, the template may be using existing storage account, Take Default Storage Account Type
            if (storageAccountType == null)
            {
                storageAccountType = StorageResourceConstants.StorageDefaultAccountType;
            }

            string meterSubCategory = null;

            // Set the Meter SubCategory based on the Storage Account Type
            if (StorageResourceConstants.StorageTypeAndMeterSubCategoryMap.TryGetValue(storageAccountType, out meterSubCategory))
            {
                storageDiskComponent.MeterSubCategory = meterSubCategory;
            }
            else
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("StorageAccountType", storageAccountType, this.nameOfResource));
            }

            // Check if premium storage is used
            if (storageAccountType.Equals(StorageResourceConstants.StoragePremiumAccountType, StringComparison.OrdinalIgnoreCase))
            {
                isPremiumStorage = true;
            }

            double diskQuantity = 0;

            if (isOSDisk)
            {
                // Get default Storage for OS Disk from Constants/Config
                diskQuantity = isPremiumStorage ? VMResourceConstants.StoragePremiumOSDiskSize : VMResourceConstants.StorageOSDiskSize;
            }
            else
            {
                // Get the Storage size for the Data Disk
                double dataDiskQuantityValue = 0;
                if (diskSize != null && double.TryParse(diskSize, out dataDiskQuantityValue))
                {
                    if (isPremiumStorage)
                    {
                        // If Premium Storage, Map the disk size to the next greater available size of premium disk
                        for (int i = 0; i < StorageResourceConstants.StoragePremiumDiskValuesArray.Count(); i++)
                        {
                            double premiumDiskSizeValue = StorageResourceConstants.StoragePremiumDiskValuesArray[i];
                            if ((dataDiskQuantityValue <= premiumDiskSizeValue) || (i == StorageResourceConstants.StoragePremiumDiskValuesArray.Count() - 1))
                            {
                                diskQuantity = premiumDiskSizeValue;
                                break;
                            }
                        }
                    }
                    else
                    {
                        diskQuantity = dataDiskQuantityValue < VMResourceConstants.StorageDataDiskSize ? dataDiskQuantityValue : VMResourceConstants.StorageDataDiskSize;
                    }
                }
            }

            // Set the meter name for the Disk resource based on premium and standard
            if (isPremiumStorage)
            {
                string meterName = null;
                if (StorageResourceConstants.StoragePremiumDiskSizeAndMeterNameMap.TryGetValue(diskQuantity, out meterName))
                {
                    storageDiskComponent.MeterName = meterName;
                }
            }
            else
            {
                storageDiskComponent.MeterName = StorageResourceConstants.StorageMeterNameForVMDisk;
            }

            // Set the Quantity of the component to the Disk Size, Set 1 if its premium disk
            storageDiskComponent.Quantity = isPremiumStorage ? 1 : diskQuantity;
            storageComponentList.Add(storageDiskComponent);

            if (!isPremiumStorage)
            {
                // Add Storage transactions component if not a premium disk
                storageTransactionComponentList.Add(new ResourceComponent()
                {
                    ResourceType     = this.resource.Type,
                    MeterCategory    = StorageResourceConstants.DataManagementMeterCategory,
                    MeterSubCategory = StorageResourceConstants.DataManagementMeterSubCategoryForVMDisk,
                    MeterName        = StorageResourceConstants.DataManagementMeterNameForStorageTrans,
                    Quantity         = isOSDisk ? VMResourceConstants.DataManagementVMStorageOSDiskTrans : VMResourceConstants.DataManagementVMStorageDataDiskTrans,
                    IsChargeable     = true
                });
            }

            // Add the list of components obtained for the Storage Disk of the VM resource
            storageComponentList.AddRange(storageDiskComponentList);
            storageComponentList.AddRange(storageTransactionComponentList);
            return(storageComponentList);
        }
Example #3
0
        /// <summary>
        /// Gets the resource components for the Diagnostics if applicable/enabled for the Virtual machine resource.
        /// </summary>
        /// <returns> Returns the list of resource components </returns>
        private List <ResourceComponent> GetResourceComponentForDiagnostics()
        {
            List <ResourceComponent> componentList = new List <ResourceComponent>();

            string diagnosticsEnabled = null;

            if (this.prop.DiagnosticsProfile != null && this.prop.DiagnosticsProfile.BootDiagnostics != null)
            {
                // Fetch the Enabled property for Diagnostics of the VM resource
                diagnosticsEnabled = this.prop.DiagnosticsProfile.BootDiagnostics.Enabled;
            }

            if (diagnosticsEnabled != null && diagnosticsEnabled.Equals("true", StringComparison.OrdinalIgnoreCase))
            {
                // Get list of all storage resources in template
                List <Resource> storageResourceList   = this.template.Resources.FindAll(x => ARMResourceTypeConstants.ARMStorageResourceType.Equals(x.Type, StringComparison.OrdinalIgnoreCase));
                string          diagnosticsStorageURI = null;
                if (this.prop.DiagnosticsProfile != null && this.prop.DiagnosticsProfile.BootDiagnostics != null)
                {
                    // Fetch the URI of Diagnostics
                    diagnosticsStorageURI = this.prop.DiagnosticsProfile.BootDiagnostics.StorageUri;
                }

                Resource diagnosticsStorageResource = null;
                if (diagnosticsStorageResource != null)
                {
                    diagnosticsStorageResource = PropertyHelper.SearchResourceInListByName(storageResourceList, diagnosticsStorageURI);
                }

                string            storageAccountType = null;
                StorageProperties storageProp        = null;
                if (diagnosticsStorageResource != null && diagnosticsStorageResource.Properties != null)
                {
                    // Get the Properties of the Storage Resource associated with storing the Diagnostics of the VM
                    storageProp = this.GetStoragePropertiesForStorageResource(diagnosticsStorageResource);
                }

                if (storageProp != null)
                {
                    // Get the Storage Account Type
                    storageAccountType = PropertyHelper.GetValueIfVariableOrParam(storageProp.AccountType, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
                }

                // Use Default Storage Account Type, as template may be using existing storage account
                if (storageAccountType == null)
                {
                    storageAccountType = StorageResourceConstants.StorageDefaultAccountType;
                }

                if (storageAccountType != null && storageAccountType != StorageResourceConstants.StoragePremiumAccountType)
                {
                    // Create the resource component for Diagnostics
                    ResourceComponent diagnosticsComponent = new ResourceComponent
                    {
                        ResourceType     = this.resource.Type,
                        MeterCategory    = StorageResourceConstants.StorageMeterCategory,
                        MeterSubCategory = null,
                        MeterName        = StorageResourceConstants.StorageMeterNameForTable,
                        Quantity         = VMResourceConstants.StorageDiagnosticsTableSize,
                        IsChargeable     = true
                    };

                    string meterSubCategory = null;

                    // Set the Meter SubCategory based on the Storage Account Type
                    if (StorageResourceConstants.StorageTypeAndMeterSubCategoryMap.TryGetValue(storageAccountType, out meterSubCategory))
                    {
                        diagnosticsComponent.MeterSubCategory = meterSubCategory;
                    }
                    else
                    {
                        throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("StorageAccountType", storageAccountType, this.nameOfResource));
                    }

                    componentList.Add(diagnosticsComponent);

                    // Add the Storage Transactions component
                    componentList.Add(new ResourceComponent()
                    {
                        ResourceType     = this.resource.Type,
                        MeterCategory    = StorageResourceConstants.DataManagementMeterCategory,
                        MeterSubCategory = StorageResourceConstants.DataManagementMeterSubCategoryForVMDisk,
                        MeterName        = StorageResourceConstants.DataManagementMeterNameForStorageTrans,
                        Quantity         = VMResourceConstants.DataManagementVMDiagnosticsStorageTrans,
                        IsChargeable     = true
                    });
                }
                else
                {
                    throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("StorageAccountType for Diagnostics", storageAccountType, this.nameOfResource));
                }
            }

            return(componentList);
        }
Example #4
0
        /// <summary>
        /// Gets the resource components for the compute hours of the Virtual machine resource. This includes components for software cost if present.
        /// </summary>
        /// <returns> Returns the list of resource components </returns>
        private List <ResourceComponent> GetResourceComponentForComputeHours()
        {
            List <ResourceComponent> componentList = new List <ResourceComponent>();

            // Create the compute hours component, Meter SubCategory value will be set later
            ResourceComponent computeHoursComponent = new ResourceComponent
            {
                ResourceType     = this.resource.Type,
                MeterCategory    = VMResourceConstants.VMMeterCategory,
                MeterSubCategory = null,
                MeterName        = VMResourceConstants.VMMeterName,
                Quantity         = Constants.HoursinaMonth,
                IsChargeable     = true
            };

            // Create the software cost component, Meter SubCategory value will be set later
            ResourceComponent softwareCostComponent = new ResourceComponent
            {
                ResourceType     = this.resource.Type,
                MeterCategory    = VMResourceConstants.VMMeterCategory,
                MeterSubCategory = null,
                MeterName        = VMResourceConstants.VMMeterName,
                Quantity         = Constants.HoursinaMonth,
                IsChargeable     = true
            };

            string vmSize = null, osType = null, createOption = null;

            if (this.prop.HardwareProfile != null && this.prop.HardwareProfile.VmSize != null)
            {
                // Fetch the VM Size
                vmSize = PropertyHelper.GetValueIfVariableOrParam(this.prop.HardwareProfile.VmSize, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
            }
            else
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.hardwareProfile.vmSize", this.nameOfResource));
            }

            if (vmSize.Equals(string.Empty))
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.hardwareProfile.vmSize", this.nameOfResource));
            }

            if (this.prop.StorageProfile != null && this.prop.StorageProfile.OsDisk != null)
            {
                // Fetch the OS Disk related info
                osType       = PropertyHelper.GetValueIfVariableOrParam(this.prop.StorageProfile.OsDisk.OsType, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
                createOption = PropertyHelper.GetValueIfVariableOrParam(this.prop.StorageProfile.OsDisk.CreateOption, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
            }
            else
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.storageProfile.osDisk", this.nameOfResource));
            }

            if (createOption == null)
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.storageProfile.osDisk.createOption", this.nameOfResource));
            }

            if (osType == null)
            {
                if (createOption != null && createOption.Equals("FromImage", StringComparison.OrdinalIgnoreCase))
                {
                    string vmImagePublisher = null, vmImageOffer = null, vmImageSKU = null;

                    // Fetch the VM Image info - Publisher, Offer and SKU
                    if (this.prop.StorageProfile != null && this.prop.StorageProfile.ImageReference != null)
                    {
                        vmImagePublisher = PropertyHelper.GetValueIfVariableOrParam(this.prop.StorageProfile.ImageReference.Publisher, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
                        vmImageOffer     = PropertyHelper.GetValueIfVariableOrParam(this.prop.StorageProfile.ImageReference.Offer, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
                        vmImageSKU       = PropertyHelper.GetValueIfVariableOrParam(this.prop.StorageProfile.ImageReference.Sku, this.template.Variables, this.template.Parameters, this.paramValue.Parameters);
                    }
                    else
                    {
                        throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.storageProfile.imageReference", this.nameOfResource));
                    }

                    if (vmImagePublisher != null && vmImageOffer != null && vmImageSKU != null)
                    {
                        // Get the OS Type of the VM Image from the Online Helper method
                        osType = VMOnlineHelper.GetVMImageOSType(this.cspCreds, vmImagePublisher, vmImageOffer, vmImageSKU, this.location);
                        string meterSubCategoryForVMImageWithSoftwareCost = null;

                        // Get the Meter SubCategory for software cost of the VM Image is applicable
                        meterSubCategoryForVMImageWithSoftwareCost = VMImageHelper.GetMeterSubCategoryForVMImageWithSoftwareCost(this.cspCreds, vmImagePublisher, vmImageOffer, vmImageSKU, vmSize, this.location);
                        if (meterSubCategoryForVMImageWithSoftwareCost != null)
                        {
                            // Set the Meter SubCategory for Software Cost component, Add to the List of resource components
                            softwareCostComponent.MeterSubCategory = meterSubCategoryForVMImageWithSoftwareCost;
                            componentList.Add(softwareCostComponent);
                        }
                    }
                    else
                    {
                        throw new Exception(ExceptionLogger.GenerateLoggerTextForMissingField("properties.storageProfile.publisher/offer/sku", this.nameOfResource));
                    }
                }
                else
                {
                    throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("storageProfile.osDisk.createOption", createOption, this.nameOfResource));
                }
            }

            string meterSubCategory     = null;
            string modifiedVMSizeString = VMHelper.ModifyVMSizeStringAsPerPricingSpecs(vmSize);

            if (osType != null)
            {
                // Fetch the Meter SubCategory as per the OS Type
                switch (osType.ToUpper())
                {
                case "WINDOWS":
                    meterSubCategory = string.Format(VMResourceConstants.VMMeterSubCategoryWindowsString, modifiedVMSizeString, osType);
                    break;

                case "LINUX":
                    meterSubCategory = string.Format(VMResourceConstants.VMMeterSubCategoryLinuxString, modifiedVMSizeString);
                    break;

                default:
                    throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("OSType", osType, this.nameOfResource));
                }
            }
            else
            {
                throw new Exception(ExceptionLogger.GenerateLoggerTextForInvalidField("OSType", string.Empty, this.nameOfResource));
            }

            // Set the Meter SubCategory for Compute Hours Cost component, Add to the List of resource components
            computeHoursComponent.MeterSubCategory = meterSubCategory;
            componentList.Add(computeHoursComponent);

            return(componentList);
        }