// handled on a policy-basis via the manifest

        // Method takes in a string and parses it into a DeveloperOptions class.
        public static DeveloperParameters Parse(IEnumerable<AddonParameter> developerParameters, AddonManifest manifest)
        {
            var dParams = new DeveloperParameters(new Volume());
            foreach (var param in developerParameters)
            {
                MapToOption(dParams, param.Key.Trim().ToLowerInvariant(), param.Value.Trim());
            }
            dParams = LoadItemsFromManifest(dParams, manifest);
            return dParams;
        }
Exemplo n.º 2
0
        // handled on a policy-basis via the manifest

        // Method takes in a string and parses it into a DeveloperOptions class.
        public static DeveloperParameters Parse(IEnumerable <AddonParameter> developerParameters, AddonManifest manifest)
        {
            var dParams = new DeveloperParameters(new Volume());

            foreach (var param in developerParameters)
            {
                MapToOption(dParams, param.Key.Trim().ToLowerInvariant(), param.Value.Trim());
            }
            dParams = LoadItemsFromManifest(dParams, manifest);
            return(dParams);
        }
Exemplo n.º 3
0
        // Deprovision NetApp
        // Input: AddonDeprovisionRequest request
        // Output: OperationResult
        public override OperationResult Deprovision(AddonDeprovisionRequest request)
        {
            var deprovisionResult = new OperationResult {
                IsSuccess = false
            };

            try
            {
                // this loads in the developer options and the manifest parameters
                // validation will also occur here, so if this fails it will be caught prior to any invocation on the cluster.
                var developerOptions = DeveloperParameters.Parse(request.DeveloperParameters, request.Manifest);
                // for assumptions now, delete a volume
                var netappresponse = NetAppFactory.DeleteVolume(developerOptions, request.ConnectionData);
                // use the class's conversion method.
                return(netappresponse.ToOperationResult());
            }
            catch (Exception e)
            {
                deprovisionResult.EndUserMessage = e.Message;
            }
            return(deprovisionResult);
        }
Exemplo n.º 4
0
        // Provision NetApp Volume
        // Input: AddonDeprovisionRequest request
        // Output: ProvisionAddOnResult
        public override ProvisionAddOnResult Provision(AddonProvisionRequest request)
        {
            var provisionResult = new ProvisionAddOnResult("")
            {
                IsSuccess = false
            };

            try
            {
                var developerParameters = DeveloperParameters.Parse(request.DeveloperParameters, request.Manifest);
                var netappresponse      = NetAppFactory.CreateVolume(developerParameters);
                provisionResult = netappresponse.ToAddOnResult();
                // this appears to be wrong. we need to check what's coming back from the powershell script
                //provisionResult.IsSuccess = true;
                provisionResult.ConnectionData = developerParameters.VolumeToProvision.BuildConnectionString();
            }
            catch (Exception e)
            {
                provisionResult.IsSuccess      = false;
                provisionResult.EndUserMessage = e.Message + "\n" + e.StackTrace;
            }
            return(provisionResult);
        }
        // Presumption - developers have knowledge regarding order of magnitude. this doesn't cover inappropriate requests such as 5000MB, 25000GB, etc.
        /// <summary>
        /// The check if storage request is compliant.
        /// </summary>
        /// <param name="developerParameters">
        /// The developer parameters.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/>.
        /// </returns>
        private static bool CheckIfStorageRequestIsCompliant(DeveloperParameters developerParameters)
        {
            var           mAs = developerParameters.MaxAllocatedStorage;
            var           requestedStorage = developerParameters.VolumeToProvision.Size;
            SizeMagnitude mAsMagnitude, requestedMagnitude;

            // testing that the parse works to enum, and that the order of magnitude on the limit is less than the order of magnitude on the size requested
            if (!Enum.TryParse(mAs.Last().ToString(), false, out mAsMagnitude) ||
                !Enum.TryParse(requestedStorage.Last().ToString(), false, out requestedMagnitude) ||
                (requestedMagnitude > mAsMagnitude))
            {
                return(false);
            }
            // ok, need to put a check in here to make sure mAsMagnitude > requestedMagnitude, return true
            if (mAsMagnitude > requestedMagnitude)
            {
                return(true);
            }
            int mASnumber, requestedNumber;

            return((int.TryParse(mAs.Substring(0, mAs.Length - 1), out mASnumber)) &&
                   (int.TryParse(requestedStorage.Substring(0, requestedStorage.Length - 1), out requestedNumber)) &&
                   requestedNumber < mASnumber);
        }
Exemplo n.º 6
0
        // Interior method takes in instance of DeveloperOptions (aptly named existingOptions) and maps them to the proper value. In essence, a setter method.
        private static void MapToOption(DeveloperParameters requiredParams, string key, string value)
        {
            // Begin Required Parameters.
            // this is called only if the developer wishes to overwrite the platform operator's default aggregate
            if ("name".Equals(key))
            {
                requiredParams.VolumeToProvision.Name = value;
                return;
            }
            if ("aggregatename".Equals(key))
            {
                requiredParams.VolumeToProvision.AggregateName = value;
                return;
            }
            // with version 1.2, we've removed the need to specify a junction path, that's now taken care of based on policy.
            // this is advantageous since we've abstracted another level of complexity away from the dev.
            if ("size".Equals(key))
            {
                requiredParams.VolumeToProvision.Size = value;
                return;
            }

            // Begin Optional Parameters
            if ("comment".Equals(key))
            {
                requiredParams.VolumeToProvision.Comment = value;
                return;
            }

            if ("antivirusonaccesspolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.AntiVirusOnAccessPolicy = value;
                return;
            }

            if ("exportpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.ExportPolicy = value;
                return;
            }

            if ("flexcachecachepolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheCachePolicy = value;
                return;
            }

            if ("flexcachefillpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheFillPolicy = value;
                return;
            }

            if ("flexcacheoriginvolume".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheOriginVolume = value;
                return;
            }

            if ("groupid".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("GroupId must be an integer value");
                }
                requiredParams.VolumeToProvision.GroupId = tmp;
                return;
            }

            if ("indexdirectoryformat".Equals(key))
            {
                requiredParams.VolumeToProvision.IndexDirectoryFormat = value;
                return;
            }

            if ("junctionactive".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("JunctionActive must be a boolean type");
                }
                requiredParams.VolumeToProvision.JunctionActive = tmp;
                return;
            }

            if ("maxdirectorysize".Equals(key))
            {
                double tmp;
                if (!(double.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.MaxDirectorySize = tmp;
                return;
            }

            if ("nvfailenabled".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.NvFailEnabled = tmp;
                return;
            }

            if ("securitystyle".Equals(key))
            {
                requiredParams.VolumeToProvision.SecurityStyle = value;
                return;
            }

            if ("snapshotpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.SnapshotPolicy = value;
                return;
            }

            if ("spacereserver".Equals(key))
            {
                requiredParams.VolumeToProvision.SpaceReserver = value;
                return;
            }

            if ("state".Equals(key))
            {
                requiredParams.VolumeToProvision.State = value;
                return;
            }

            if ("type".Equals(key))
            {
                requiredParams.VolumeToProvision.Type = value;
                return;
            }

            if ("unixpermissions".Equals(key))
            {
                requiredParams.VolumeToProvision.UnixPermissions = value;
                return;
            }

            if ("userid".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.UserId = tmp;
                return;
            }

            if ("vserverroot".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.VserverRoot = tmp;
                return;
            }

            if ("snapshotreserver".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.SnapshotReserver = tmp;
                return;
            }

            if ("vmalignsector".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.VmAlignSector = tmp;
                return;
            }

            if ("vmalignsuffic".Equals(key))
            {
                requiredParams.VolumeToProvision.VmAlignSuffic = value;
                return;
            }

            if ("qospolicygroup".Equals(key))
            {
                requiredParams.VolumeToProvision.QosPolicyGroup = value;
                return;
            }
            // for multi-national support
            if ("language".Equals(key))
            {
                requiredParams.VolumeToProvision.Language = value;
                return;
            }
            // only if there are both nfs and cifs shares should this ever be used.
            if ("protocol".Equals(key))
            {
                requiredParams.VolumeToProvision.Protocol = value;
            }

            throw new ArgumentException(
                      string.Format("The developer option '{0}' was not expected and is not understood.", key));
        }
Exemplo n.º 7
0
        public static DeveloperParameters LoadItemsFromManifest(DeveloperParameters parameters, AddonManifest manifest)
        {
            try
            {
                var manifestProperties = manifest.GetProperties();
                foreach (var manifestProperty in manifestProperties)
                {
                    switch (manifestProperty.Key.Trim().ToLowerInvariant())
                    {
                    case ("vserver"):
                        parameters.VServer = manifestProperty.Value;
                        break;

                    case ("adminusername"):
                        parameters.AdminUserName = manifestProperty.Value;
                        break;

                    case ("adminpassword"):
                        parameters.AdminPassword = manifestProperty.Value;
                        break;

                    case ("clustermgtendpoint"):
                        parameters.ClusterMgtEndpoint = manifestProperty.Value;
                        break;

                    case ("defaultprotocol"):
                        parameters.VolumeToProvision.Protocol = manifestProperty.Value;
                        break;

                    case ("defaultaggregate"):
                        parameters.VolumeToProvision.AggregateName = manifestProperty.Value;
                        break;

                    case ("defaultrootpath"):
                        parameters.VolumeToProvision.JunctionPath = manifestProperty.Value;
                        break;

                    case ("snapenable"):
                        bool snaptest;
                        bool.TryParse(manifestProperty.Value, out snaptest);
                        parameters.VolumeToProvision.SnapEnable = snaptest;
                        break;

                    case ("vaultenable"):
                        bool test;
                        bool.TryParse(manifestProperty.Value, out test);
                        parameters.VolumeToProvision.VaultEnable = test;
                        break;

                    case ("snapshotschedule"):
                        parameters.VolumeToProvision.SnapshotSchedule = manifestProperty.Value;
                        break;

                    case ("defaultacl"):
                        break;

                    case ("snapmirrorpolicyname"):
                        parameters.VolumeToProvision.SnapMirrorPolicyName = manifestProperty.Value;
                        break;

                    case ("snapvaultpolicyname"):
                        parameters.VolumeToProvision.SnapVaultPolicyName = manifestProperty.Value;
                        break;

                    case ("snapmirrorschedule"):
                        parameters.VolumeToProvision.SnapMirrorSchedule = manifestProperty.Value;
                        break;

                    case ("snapvaultschedule"):
                        parameters.VolumeToProvision.SnapVaultSchedule = manifestProperty.Value;
                        break;

                    case ("snaptype"):
                        parameters.VolumeToProvision.SnapType = manifestProperty.Value;
                        break;

                    case ("shareendpoint"):
                        parameters.VolumeToProvision.CifsRootServer = manifestProperty.Value;
                        break;

                    case ("scriptrepotype"):
                        parameters.ScriptRepositoryType = manifestProperty.Value;
                        break;

                    case ("scriptrepo"):
                        parameters.ScriptRepository = manifestProperty.Value;
                        break;

                    case ("maxallocatedstorage"):
                        parameters.MaxAllocatedStorage = manifestProperty.Value;
                        break;

                    default:     // means there are other manifest properties we don't need.
                        Console.WriteLine("Parse failed on key: " + manifestProperty.Key);
                        break;
                    }
                }
                return(parameters);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message + "\n Debug information: " + manifest.GetProperties());
            }
        }
        public static NetAppResponse CreateVolume([NotNull] DeveloperParameters d)
        {
            // need to perform validation checks
            if (!CheckIfStorageRequestIsCompliant(d))
            {
                return(new NetAppResponse
                {
                    ConnectionData = string.Empty,
                    IsSuccess = false,
                    ErrorOut =
                        "Your request does not meet the compliance requirements set forth by your platform administrator. Please check your configuration and try again."
                });
            }
            try
            {
                using (var psInstance = PowerShell.Create())
                {
                    // STEP 1: first things first. we need to set the execution policy for this script to be unrestricted. because we're assuming not everyone signs their powershell scripts.
                    psInstance.AddCommand("Set-ExecutionPolicy");
                    psInstance.AddArgument("Unrestricted");
                    psInstance.AddArgument("Process");
                    psInstance.AddParameter("-Force");
                    psInstance.Invoke();
                    var debugStream = string.Empty;
                    debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                    debugStream += psInstance.Streams.Progress.Aggregate(
                        debugStream,
                        (current, debug) => current + debug);
                    psInstance.Commands.Clear();

                    // -------------------------------------------------------------------------------------------/
                    // STEP 2: We need to copy the file locally. Now - for all intensive purposes, we're going to assume the file is in 1 of three places
                    //  - Locally on the platform (in which an absolute path is provided)
                    //  - Accessible server within the datacenter (in which a server name and path are provided)
                    //  - Cloud Storage (in which an HTTPS link is provided)
                    //
                    //   Anything else is custom or Phase II at this time.
                    // -------------------------------------------------------------------------------------------/
                    const string ExecutingPs1File = ".\\CreateVolume.ps1";

                    if (!File.Exists(ExecutingPs1File))
                    {
                        File.WriteAllText(ExecutingPs1File, Constants.CreateVolume);
                    }

                    // this snipped it for server-based local storage. we need to write some additional routines for this.

                    /*
                     * var remotePs1File = d.ScriptRepository + "\\CreateVolume.ps1";
                     * psInstance.AddCommand("Copy-Item");
                     * psInstance.AddParameter("-Path", remotePs1File);
                     * psInstance.AddParameter("-Destination", executingPs1File);
                     * psInstance.AddParameter("-Force");
                     * psInstance.Invoke();
                     * debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                     * debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                     *  (current, debug) => current + debug);
                     * if (psInstance.Streams.Error.Count > 0)
                     * {
                     *  errorStream += psInstance.Streams.Error.Aggregate(errorStream,
                     *      (current, error) => current + error);
                     *  return new NetAppResponse
                     *  {
                     *      IsSuccess = false,
                     *      ErrorOut = errorStream,
                     *      ConnectionData = "",
                     *      ConsoleOut = "Could not copy file to execute. Please check connectivity to the server.",
                     *      ReturnCode = -1
                     *  };
                     * }
                     */

                    // -------------------------------------------------------------------------------------------/
                    // STEP 3: Execute the script!
                    // -------------------------------------------------------------------------------------------/
                    psInstance.AddCommand(ExecutingPs1File);
                    psInstance.AddParameter("-username", d.AdminUserName);
                    psInstance.AddParameter("-password", d.AdminPassword);
                    psInstance.AddParameter("-vserver", d.VServer);
                    psInstance.AddParameter("-endpoint", d.ClusterMgtEndpoint);

                    // add in additional parameters. i tried to make it easier. but PowerShell object is readonly :(
                    // Required Parameters
                    psInstance.AddParameter("-aggregateName", d.VolumeToProvision.AggregateName);
                    psInstance.AddParameter("-junctionPath", d.VolumeToProvision.JunctionPath);
                    psInstance.AddParameter("-Size", d.VolumeToProvision.Size);
                    psInstance.AddParameter("-volName", d.VolumeToProvision.Name);

                    // and a whole SLEW of optional parameters
                    if (d.VolumeToProvision.Comment != null)
                    {
                        psInstance.AddParameter("-Comment", d.VolumeToProvision.Comment);
                    }

                    if (d.VolumeToProvision.AntiVirusOnAccessPolicy != null)
                    {
                        psInstance.AddParameter("-AntiVirusOnAccessPolicy", d.VolumeToProvision.AntiVirusOnAccessPolicy);
                    }

                    if (d.VolumeToProvision.ExportPolicy != null)
                    {
                        psInstance.AddParameter("-ExportPolicy", d.VolumeToProvision.ExportPolicy);
                    }

                    if (d.VolumeToProvision.FlexCacheCachePolicy != null)
                    {
                        psInstance.AddParameter("-FlexCacheCachePolicy", d.VolumeToProvision.FlexCacheCachePolicy);
                    }

                    if (d.VolumeToProvision.FlexCacheFillPolicy != null)
                    {
                        psInstance.AddParameter("-FlexCacheFillPolicy", d.VolumeToProvision.FlexCacheFillPolicy);
                    }

                    if (d.VolumeToProvision.FlexCacheOriginVolume != null)
                    {
                        psInstance.AddParameter("-FlexCacheOriginVolume", d.VolumeToProvision.FlexCacheOriginVolume);
                    }

                    if (!(-1).Equals(d.VolumeToProvision.GroupId))
                    {
                        psInstance.AddParameter(
                            "-GroupId",
                            d.VolumeToProvision.GroupId.ToString(CultureInfo.InvariantCulture));
                    }

                    if (d.VolumeToProvision.IndexDirectoryFormat != null)
                    {
                        psInstance.AddParameter("-IndexDirectoryFormat", d.VolumeToProvision.IndexDirectoryFormat);
                    }

                    if (d.VolumeToProvision.JunctionActive)
                    {
                        psInstance.AddParameter("-JunctionActive", "$true");
                    }

                    if (!(Math.Abs(d.VolumeToProvision.MaxDirectorySize - (-1)) < 0))
                    {
                        psInstance.AddParameter(
                            "-MaxDirectorySize",
                            d.VolumeToProvision.MaxDirectorySize.ToString(CultureInfo.InvariantCulture));
                    }

                    if (!d.VolumeToProvision.NvFailEnabled == false)
                    {
                        psInstance.AddParameter("-NvFailEnabled", d.VolumeToProvision.NvFailEnabled.ToString());
                    }

                    if (d.VolumeToProvision.SecurityStyle != null)
                    {
                        psInstance.AddParameter("-SecurityStyle", d.VolumeToProvision.SecurityStyle);
                    }

                    if (d.VolumeToProvision.SnapshotPolicy != null)
                    {
                        psInstance.AddParameter("-SnapshotPolicy", d.VolumeToProvision.SnapshotPolicy);
                    }

                    if (d.VolumeToProvision.SpaceReserver != null)
                    {
                        psInstance.AddParameter(
                            "-SpaceReserver",
                            d.VolumeToProvision.SnapshotReserver.ToString(CultureInfo.InvariantCulture));
                    }

                    if (d.VolumeToProvision.State != null)
                    {
                        psInstance.AddParameter("-State", d.VolumeToProvision.State);
                    }

                    if (d.VolumeToProvision.Type != null)
                    {
                        psInstance.AddParameter("-Type", d.VolumeToProvision.Type);
                    }

                    if (d.VolumeToProvision.UserId != -1)
                    {
                        psInstance.AddParameter(
                            "-UserId",
                            d.VolumeToProvision.UserId.ToString(CultureInfo.InvariantCulture));
                    }

                    if (d.VolumeToProvision.VserverRoot)
                    {
                        psInstance.AddParameter("-VserverRoot", "$true");
                    }

                    if (d.VolumeToProvision.SnapshotReserver != -1)
                    {
                        psInstance.AddParameter(
                            "-SnapshotReserver",
                            d.VolumeToProvision.SnapshotReserver.ToString(CultureInfo.InvariantCulture));
                    }

                    if (d.VolumeToProvision.VmAlignSector != -1)
                    {
                        psInstance.AddParameter(
                            "-VmAlignSector",
                            d.VolumeToProvision.VmAlignSector.ToString(CultureInfo.InvariantCulture));
                    }

                    if (d.VolumeToProvision.VmAlignSuffic != null)
                    {
                        psInstance.AddParameter("-VmAlignSuffic", d.VolumeToProvision.VmAlignSuffic);
                    }

                    if (d.VolumeToProvision.QosPolicyGroup != null)
                    {
                        psInstance.AddParameter("-QosPolicyGroup", d.VolumeToProvision.QosPolicyGroup);
                    }

                    if (d.VolumeToProvision.Language != null)
                    {
                        psInstance.AddParameter("-Language", d.VolumeToProvision.Language);
                    }

                    if (d.VolumeToProvision.Protocol != null)
                    {
                        psInstance.AddParameter("-Protocol", d.VolumeToProvision.Protocol);
                    }

                    if (d.VolumeToProvision.UnixPermissions != null)
                    {
                        psInstance.AddParameter("-UnixPermissions", d.VolumeToProvision.UnixPermissions);
                    }

                    if (d.VolumeToProvision.SnapEnable)
                    {
                        psInstance.AddParameter("-EnableSnapMirror", d.VolumeToProvision.SnapEnable);
                    }

                    if (d.VolumeToProvision.SnapMirrorPolicyName != null)
                    {
                        psInstance.AddParameter("-snapmirrorpolicyname", d.VolumeToProvision.SnapMirrorPolicyName);
                    }

                    if (d.VolumeToProvision.SnapVaultPolicyName != null)
                    {
                        psInstance.AddParameter("-snapvaultpolicyname", d.VolumeToProvision.SnapVaultPolicyName);
                    }

                    if (d.VolumeToProvision.SnapMirrorSchedule != null)
                    {
                        psInstance.AddParameter("-snapmirrorschedule", d.VolumeToProvision.SnapMirrorSchedule);
                    }

                    if (d.VolumeToProvision.SnapVaultSchedule != null)
                    {
                        psInstance.AddParameter("-snapvaultschedule", d.VolumeToProvision.SnapVaultSchedule);
                    }

                    if (d.VolumeToProvision.SnapType != null)
                    {
                        psInstance.AddParameter("-snaptype", d.VolumeToProvision.SnapType);
                    }

                    var output      = psInstance.Invoke();
                    var errorStream = string.Empty;

                    if (psInstance.Streams.Error.Count <= 0)
                    {
                        return(new NetAppResponse
                        {
                            ConnectionData = d.VolumeToProvision.Name,
                            IsSuccess = true,
                            ReturnCode = 0,
                            ConsoleOut = output.ToString()
                        });
                    }

                    errorStream += psInstance.Streams.Error.Aggregate(errorStream, (current, error) => current + error);
                    debugStream += psInstance.Streams.Progress.Aggregate(debugStream, (current, debug) => current + debug);
                    return(new NetAppResponse
                    {
                        IsSuccess = false,
                        ReturnCode = 1,
                        ConsoleOut = debugStream,
                        ErrorOut = errorStream
                    });
                }
            }
            catch (Exception e)
            {
                throw new Exception(e.ToString(), e);
            }
        }
        // This will delete a volume off of a given filer.
        public static NetAppResponse DeleteVolume(DeveloperParameters d, string connectionData)
        {
            using (var psInstance = PowerShell.Create())
            {
                // STEP 1: first things first. we need to set the execution policy for this script to be unrestricted. because we're assuming not everyone signs their powershell scripts.
                psInstance.AddCommand("Set-ExecutionPolicy");
                psInstance.AddArgument("Unrestricted");
                psInstance.AddArgument("Process");
                psInstance.AddParameter("-Force");
                psInstance.Invoke();
                var debugStream = string.Empty;
                var errorStream = string.Empty;
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                                                                     (current, debug) => current + debug);
                psInstance.Commands.Clear();

                // -------------------------------------------------------------------------------------------/
                // STEP 2: We need to copy the file locally. Now - for all intensive purposes, we're going to assume the file is in 1 of three places
                //  - Locally on the platform (in which an absolute path is provided)
                //  - Accessible server within the datacenter (in which a server name and path are provided)
                //  - Cloud Storage (in which an HTTPS link is provided)
                //
                //   Anything else is custom or Phase II at this time.
                // -------------------------------------------------------------------------------------------/

                // case 1, 2: local or server
                const string executingPs1File = ".\\DeleteVolume.ps1";
                var          remotePs1File    = d.ScriptRepository + "\\DeleteVolume.ps1";
                psInstance.AddCommand("Copy-Item");
                psInstance.AddParameter("-Path", remotePs1File);
                psInstance.AddParameter("-Destination", executingPs1File);
                psInstance.AddParameter("-Force");
                psInstance.Invoke();
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                                                                     (current, debug) => current + debug);
                if (psInstance.Streams.Error.Count > 0)
                {
                    errorStream += psInstance.Streams.Error.Aggregate(errorStream, (current, error) => current + error);
                    return(new NetAppResponse
                    {
                        IsSuccess = false,
                        ErrorOut = errorStream,
                        ConnectionData = string.Empty,
                        ConsoleOut = "Could not copy file to execute. Please check connectivity to the server.",
                        ReturnCode = -1
                    });
                }

                // Step 3 - let's remove the volume.
                // So normally the only change here from our existing provisioning process is that we need to pull the volume name from the
                // connection string. so, let's extract it.

                var volumeToDelete = ExtractFromConnectionString(connectionData);
                psInstance.AddCommand(executingPs1File);
                psInstance.AddParameter("-username", d.AdminUserName);
                psInstance.AddParameter("-password", d.AdminPassword);
                psInstance.AddParameter("-vserver", d.VServer);
                psInstance.AddParameter("-endpoint", d.ClusterMgtEndpoint);
                psInstance.AddParameter("-volName", volumeToDelete);

                psInstance.Invoke();
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                                                                     (current, debug) => current + debug);
                if (psInstance.Streams.Error.Count <= 0)
                {
                    return new NetAppResponse
                           {
                               IsSuccess      = true,
                               ErrorOut       = string.Empty,
                               ConnectionData = string.Empty,
                               ConsoleOut     = debugStream
                           }
                }
                ;
                errorStream += psInstance.Streams.Error.Aggregate(errorStream, (current, error) => current + error);
                return(new NetAppResponse
                {
                    IsSuccess = false,
                    ErrorOut = errorStream,
                    ConnectionData = string.Empty,
                    ConsoleOut = "Could not copy file to execute. Please check connectivity to the server.",
                    ReturnCode = -1
                });
            }
        }
        // This will delete a volume off of a given filer.
        public static NetAppResponse DeleteVolume(DeveloperParameters d, string connectionData)
        {
            using (var psInstance = PowerShell.Create())
            {
                // STEP 1: first things first. we need to set the execution policy for this script to be unrestricted. because we're assuming not everyone signs their powershell scripts.
                psInstance.AddCommand("Set-ExecutionPolicy");
                psInstance.AddArgument("Unrestricted");
                psInstance.AddArgument("Process");
                psInstance.AddParameter("-Force");
                psInstance.Invoke();
                var debugStream = string.Empty;
                var errorStream = string.Empty;
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                    (current, debug) => current + debug);
                psInstance.Commands.Clear();

                // -------------------------------------------------------------------------------------------/
                // STEP 2: We need to copy the file locally. Now - for all intensive purposes, we're going to assume the file is in 1 of three places
                //  - Locally on the platform (in which an absolute path is provided)
                //  - Accessible server within the datacenter (in which a server name and path are provided)
                //  - Cloud Storage (in which an HTTPS link is provided)
                //
                //   Anything else is custom or Phase II at this time.
                // -------------------------------------------------------------------------------------------/

                // case 1, 2: local or server
                const string executingPs1File = ".\\DeleteVolume.ps1";
                var remotePs1File = d.ScriptRepository + "\\DeleteVolume.ps1";
                psInstance.AddCommand("Copy-Item");
                psInstance.AddParameter("-Path", remotePs1File);
                psInstance.AddParameter("-Destination", executingPs1File);
                psInstance.AddParameter("-Force");
                psInstance.Invoke();
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                    (current, debug) => current + debug);
                if (psInstance.Streams.Error.Count > 0)
                {
                    errorStream += psInstance.Streams.Error.Aggregate(errorStream, (current, error) => current + error);
                    return new NetAppResponse
                    {
                        IsSuccess = false,
                        ErrorOut = errorStream,
                        ConnectionData = string.Empty,
                        ConsoleOut = "Could not copy file to execute. Please check connectivity to the server.",
                        ReturnCode = -1
                    };
                }

                // Step 3 - let's remove the volume.
                // So normally the only change here from our existing provisioning process is that we need to pull the volume name from the
                // connection string. so, let's extract it.

                var volumeToDelete = ExtractFromConnectionString(connectionData);
                psInstance.AddCommand(executingPs1File);
                psInstance.AddParameter("-username", d.AdminUserName);
                psInstance.AddParameter("-password", d.AdminPassword);
                psInstance.AddParameter("-vserver", d.VServer);
                psInstance.AddParameter("-endpoint", d.ClusterMgtEndpoint);
                psInstance.AddParameter("-volName", volumeToDelete);

                psInstance.Invoke();
                debugStream += psInstance.Streams.Debug.Aggregate(debugStream, (current, debug) => current + debug);
                debugStream += psInstance.Streams.Progress.Aggregate(debugStream,
                    (current, debug) => current + debug);
                if (psInstance.Streams.Error.Count <= 0)
                    return new NetAppResponse
                    {
                        IsSuccess = true,
                        ErrorOut = string.Empty,
                        ConnectionData = string.Empty,
                        ConsoleOut = debugStream
                    };
                errorStream += psInstance.Streams.Error.Aggregate(errorStream, (current, error) => current + error);
                return new NetAppResponse
                {
                    IsSuccess = false,
                    ErrorOut = errorStream,
                    ConnectionData = string.Empty,
                    ConsoleOut = "Could not copy file to execute. Please check connectivity to the server.",
                    ReturnCode = -1
                };
            }
        }
 // Presumption - developers have knowledge regarding order of magnitude. this doesn't cover inappropriate requests such as 5000MB, 25000GB, etc.
 /// <summary>
 /// The check if storage request is compliant.
 /// </summary>
 /// <param name="developerParameters">
 /// The developer parameters.
 /// </param>
 /// <returns>
 /// The <see cref="bool"/>.
 /// </returns>
 private static bool CheckIfStorageRequestIsCompliant(DeveloperParameters developerParameters)
 {
     var mAs = developerParameters.MaxAllocatedStorage;
     var requestedStorage = developerParameters.VolumeToProvision.Size;
     SizeMagnitude mAsMagnitude, requestedMagnitude;
     // testing that the parse works to enum, and that the order of magnitude on the limit is less than the order of magnitude on the size requested
     if (!Enum.TryParse(mAs.Last().ToString(), false, out mAsMagnitude) ||
         !Enum.TryParse(requestedStorage.Last().ToString(), false, out requestedMagnitude) ||
         (requestedMagnitude > mAsMagnitude)) return false;
     // ok, need to put a check in here to make sure mAsMagnitude > requestedMagnitude, return true
     if (mAsMagnitude > requestedMagnitude) return true;
     int mASnumber, requestedNumber;
     return (int.TryParse(mAs.Substring(0, mAs.Length - 1), out mASnumber)) &&
            (int.TryParse(requestedStorage.Substring(0, requestedStorage.Length - 1), out requestedNumber)) &&
            requestedNumber < mASnumber;
 }
        // Interior method takes in instance of DeveloperOptions (aptly named existingOptions) and maps them to the proper value. In essence, a setter method.
        private static void MapToOption(DeveloperParameters requiredParams, string key, string value)
        {
            // Begin Required Parameters.
            // this is called only if the developer wishes to overwrite the platform operator's default aggregate
            if ("name".Equals(key))
            {
                requiredParams.VolumeToProvision.Name = value;
                return;
            }
            if ("aggregatename".Equals(key))
            {
                requiredParams.VolumeToProvision.AggregateName = value;
                return;
            }
            // with version 1.2, we've removed the need to specify a junction path, that's now taken care of based on policy.
            // this is advantageous since we've abstracted another level of complexity away from the dev.
            if ("size".Equals(key))
            {
                requiredParams.VolumeToProvision.Size = value;
                return;
            }

            // Begin Optional Parameters
            if ("comment".Equals(key))
            {
                requiredParams.VolumeToProvision.Comment = value;
                return;
            }

            if ("antivirusonaccesspolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.AntiVirusOnAccessPolicy = value;
                return;
            }

            if ("exportpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.ExportPolicy = value;
                return;
            }

            if ("flexcachecachepolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheCachePolicy = value;
                return;
            }

            if ("flexcachefillpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheFillPolicy = value;
                return;
            }

            if ("flexcacheoriginvolume".Equals(key))
            {
                requiredParams.VolumeToProvision.FlexCacheOriginVolume = value;
                return;
            }

            if ("groupid".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("GroupId must be an integer value");
                }
                requiredParams.VolumeToProvision.GroupId = tmp;
                return;
            }

            if ("indexdirectoryformat".Equals(key))
            {
                requiredParams.VolumeToProvision.IndexDirectoryFormat = value;
                return;
            }

            if ("junctionactive".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("JunctionActive must be a boolean type");
                }
                requiredParams.VolumeToProvision.JunctionActive = tmp;
                return;
            }

            if ("maxdirectorysize".Equals(key))
            {
                double tmp;
                if (!(double.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.MaxDirectorySize = tmp;
                return;
            }

            if ("nvfailenabled".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.NvFailEnabled = tmp;
                return;
            }

            if ("securitystyle".Equals(key))
            {
                requiredParams.VolumeToProvision.SecurityStyle = value;
                return;
            }

            if ("snapshotpolicy".Equals(key))
            {
                requiredParams.VolumeToProvision.SnapshotPolicy = value;
                return;
            }

            if ("spacereserver".Equals(key))
            {
                requiredParams.VolumeToProvision.SpaceReserver = value;
                return;
            }

            if ("state".Equals(key))
            {
                requiredParams.VolumeToProvision.State = value;
                return;
            }

            if ("type".Equals(key))
            {
                requiredParams.VolumeToProvision.Type = value;
                return;
            }

            if ("unixpermissions".Equals(key))
            {
                requiredParams.VolumeToProvision.UnixPermissions = value;
                return;
            }

            if ("userid".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.UserId = tmp;
                return;
            }

            if ("vserverroot".Equals(key))
            {
                bool tmp;
                if (!(bool.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.VserverRoot = tmp;
                return;
            }

            if ("snapshotreserver".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("MaxDirectorySize must be a boolean type");
                }
                requiredParams.VolumeToProvision.SnapshotReserver = tmp;
                return;
            }

            if ("vmalignsector".Equals(key))
            {
                int tmp;
                if (!(int.TryParse(value, out tmp)))
                {
                    throw new ArgumentException("NvFailEnabled must be a boolean type");
                }
                requiredParams.VolumeToProvision.VmAlignSector = tmp;
                return;
            }

            if ("vmalignsuffic".Equals(key))
            {
                requiredParams.VolumeToProvision.VmAlignSuffic = value;
                return;
            }

            if ("qospolicygroup".Equals(key))
            {
                requiredParams.VolumeToProvision.QosPolicyGroup = value;
                return;
            }
            // for multi-national support
            if ("language".Equals(key))
            {
                requiredParams.VolumeToProvision.Language = value;
                return;
            }
            // only if there are both nfs and cifs shares should this ever be used.
            if ("protocol".Equals(key))
            {
                requiredParams.VolumeToProvision.Protocol = value;
            }

            throw new ArgumentException(
                string.Format("The developer option '{0}' was not expected and is not understood.", key));
        }
        public static DeveloperParameters LoadItemsFromManifest(DeveloperParameters parameters, AddonManifest manifest)
        {
            try
            {
                var manifestProperties = manifest.GetProperties();
                foreach (var manifestProperty in manifestProperties)
                {
                    switch (manifestProperty.Key.Trim().ToLowerInvariant())
                    {
                        case ("vserver"):
                            parameters.VServer = manifestProperty.Value;
                            break;

                        case ("adminusername"):
                            parameters.AdminUserName = manifestProperty.Value;
                            break;

                        case ("adminpassword"):
                            parameters.AdminPassword = manifestProperty.Value;
                            break;

                        case ("clustermgtendpoint"):
                            parameters.ClusterMgtEndpoint = manifestProperty.Value;
                            break;

                        case ("defaultprotocol"):
                            parameters.VolumeToProvision.Protocol = manifestProperty.Value;
                            break;

                        case ("defaultaggregate"):
                            parameters.VolumeToProvision.AggregateName = manifestProperty.Value;
                            break;

                        case ("defaultrootpath"):
                            parameters.VolumeToProvision.JunctionPath = manifestProperty.Value;
                            break;

                        case ("snapenable"):
                            bool snaptest;
                            bool.TryParse(manifestProperty.Value, out snaptest);
                            parameters.VolumeToProvision.SnapEnable = snaptest;
                            break;

                        case ("vaultenable"):
                            bool test;
                            bool.TryParse(manifestProperty.Value, out test);
                            parameters.VolumeToProvision.VaultEnable = test;
                            break;

                        case ("snapshotschedule"):
                            parameters.VolumeToProvision.SnapshotSchedule = manifestProperty.Value;
                            break;

                        case ("defaultacl"):
                            break;

                        case ("snapmirrorpolicyname"):
                            parameters.VolumeToProvision.SnapMirrorPolicyName = manifestProperty.Value;
                            break;

                        case ("snapvaultpolicyname"):
                            parameters.VolumeToProvision.SnapVaultPolicyName = manifestProperty.Value;
                            break;

                        case ("snapmirrorschedule"):
                            parameters.VolumeToProvision.SnapMirrorSchedule = manifestProperty.Value;
                            break;

                        case ("snapvaultschedule"):
                            parameters.VolumeToProvision.SnapVaultSchedule = manifestProperty.Value;
                            break;

                        case ("snaptype"):
                            parameters.VolumeToProvision.SnapType = manifestProperty.Value;
                            break;

                        case ("shareendpoint"):
                            parameters.VolumeToProvision.CifsRootServer = manifestProperty.Value;
                            break;

                        case ("scriptrepotype"):
                            parameters.ScriptRepositoryType = manifestProperty.Value;
                            break;

                        case ("scriptrepo"):
                            parameters.ScriptRepository = manifestProperty.Value;
                            break;

                        case ("maxallocatedstorage"):
                            parameters.MaxAllocatedStorage = manifestProperty.Value;
                            break;

                        default: // means there are other manifest properties we don't need.
                            Console.WriteLine("Parse failed on key: " + manifestProperty.Key);
                            break;
                    }
                }
                return parameters;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message + "\n Debug information: " + manifest.GetProperties());
            }
        }