コード例 #1
0
ファイル: CimDSCParser.cs プロジェクト: 40a/PowerShell
        /// <summary>
        /// A method to generate a keyword from a CIM class object. This is used for DSC.
        /// </summary>
        /// <param name="moduleName"></param>
        /// <param name="moduleVersion"></param>
        /// <param name="cimClass"></param>
        /// <param name="functionsToDefine">If true, don't define the keywords, just create the functions.</param>
        /// <param name="runAsBehavior"> To specify RunAs behavior of the class </param>
        private static DynamicKeyword CreateKeywordFromCimClass(string moduleName, Version moduleVersion, Microsoft.Management.Infrastructure.CimClass cimClass, Dictionary<string, ScriptBlock> functionsToDefine, DSCResourceRunAsCredential runAsBehavior)
        {
            var resourceName = cimClass.CimSystemProperties.ClassName;
            string alias = GetFriendlyName(cimClass);
            var keywordString = string.IsNullOrEmpty(alias) ? resourceName : alias;

            //
            // Skip all of the base, meta, registration and other classes that are not intended to be used directly by a script author
            //
            if (System.Text.RegularExpressions.Regex.Match(keywordString, "^OMI_Base|^OMI_.*Registration", System.Text.RegularExpressions.RegexOptions.IgnoreCase).Success)
            {
                return null;
            }
            var keyword = new DynamicKeyword()
            {
                BodyMode = DynamicKeywordBodyMode.Hashtable,
                Keyword = keywordString,
                ResourceName = resourceName,
                ImplementingModule = moduleName,
                ImplementingModuleVersion = moduleVersion,
                SemanticCheck = CheckMandatoryPropertiesPresent
            };

            // If it's one of reserved dynamic keyword, mark it
            if (System.Text.RegularExpressions.Regex.Match(keywordString, reservedDynamicKeywords, System.Text.RegularExpressions.RegexOptions.IgnoreCase).Success)
            {
                keyword.IsReservedKeyword = true;
            }

            // see if it's a resource type i.e. it inherits from OMI_BaseResource
            bool isResourceType = false;
            for (var classToCheck = cimClass; !string.IsNullOrEmpty(classToCheck.CimSuperClassName); classToCheck = classToCheck.CimSuperClass)
            {
                if (string.Equals("OMI_BaseResource", classToCheck.CimSuperClassName, StringComparison.OrdinalIgnoreCase) || string.Equals("OMI_MetaConfigurationResource", classToCheck.CimSuperClassName, StringComparison.OrdinalIgnoreCase))
                {
                    isResourceType = true;
                    break;
                }
            }

            // If it's a resource type, then a resource name is required.
            keyword.NameMode = isResourceType ? DynamicKeywordNameMode.NameRequired : DynamicKeywordNameMode.NoName;

            //
            // Add the settable properties to the keyword object
            //
            foreach (var prop in cimClass.CimClassProperties)
            {
                // If the property is marked as readonly, skip it...
                if ((prop.Flags & Microsoft.Management.Infrastructure.CimFlags.ReadOnly) == Microsoft.Management.Infrastructure.CimFlags.ReadOnly)
                {
                    continue;
                }

                try
                {
                    // If the property has the Read qualifier, also skip it.
                    if (prop.Qualifiers["Read"] != null)
                    {
                        continue;
                    }
                }
                catch (Microsoft.Management.Infrastructure.CimException)
                {
                    // Cim exception means Read wasn't found so continue...
                }

                // If it's one of our magic properties, skip it
                if (IsMagicProperty(prop.Name))
                {
                    continue;
                }

                if (runAsBehavior == DSCResourceRunAsCredential.NotSupported)
                {
                    if (String.Equals(prop.Name, "PsDscRunAsCredential", StringComparison.OrdinalIgnoreCase))
                    {
                        // skip adding PsDscRunAsCredential to the dynamic word for the dsc resource. 
                        continue;
                    }
                }
                // If it's one of our reserved properties, save it for error reporting
                if (System.Text.RegularExpressions.Regex.Match(prop.Name, reservedProperties, System.Text.RegularExpressions.RegexOptions.IgnoreCase).Success)
                {
                    keyword.HasReservedProperties = true;
                    continue;
                }

                // Otherwise, add it to the Keyword List.
                var keyProp = new System.Management.Automation.Language.DynamicKeywordProperty();
                keyProp.Name = prop.Name;

                // Set the mandatory flag if appropriate
                if ((prop.Flags & Microsoft.Management.Infrastructure.CimFlags.Key) == Microsoft.Management.Infrastructure.CimFlags.Key)
                {
                    keyProp.Mandatory = true;
                    keyProp.IsKey = true;
                }

                // Copy the type name string. If it's an embedded instance, need to grab it from the ReferenceClassName
                bool referenceClassNameIsNullOrEmpty = string.IsNullOrEmpty(prop.ReferenceClassName);
                if (prop.CimType == CimType.Instance && !referenceClassNameIsNullOrEmpty)
                {
                    keyProp.TypeConstraint = prop.ReferenceClassName;
                }
                else if (prop.CimType == CimType.InstanceArray && !referenceClassNameIsNullOrEmpty)
                {
                    keyProp.TypeConstraint = prop.ReferenceClassName + "[]";
                }
                else
                {
                    keyProp.TypeConstraint = prop.CimType.ToString();
                }

                string[] valueMap = null;
                foreach (var qualifier in prop.Qualifiers)
                {
                    // Check to see if there is a Values attribute and save the list of allowed values if so.
                    if (string.Equals(qualifier.Name, "Values", StringComparison.OrdinalIgnoreCase) && qualifier.CimType == Microsoft.Management.Infrastructure.CimType.StringArray)
                    {
                        keyProp.Values.AddRange((string[])qualifier.Value);
                    }

                    // Check to see if there is a ValueMap attribute and save the list of allowed values if so.
                    if (string.Equals(qualifier.Name, "ValueMap", StringComparison.OrdinalIgnoreCase) && qualifier.CimType == Microsoft.Management.Infrastructure.CimType.StringArray)
                    {
                        valueMap = (string[])qualifier.Value;
                    }

                    // Check to see if this property has the Required qualifier associated with it.
                    if (string.Equals(qualifier.Name, "Required", StringComparison.OrdinalIgnoreCase) &&
                        qualifier.CimType == Microsoft.Management.Infrastructure.CimType.Boolean &&
                            (bool)qualifier.Value)
                    {
                        keyProp.Mandatory = true;
                    }

                    // set the property to mandatory is specified for the resource. 
                    if (runAsBehavior == DSCResourceRunAsCredential.Mandatory)
                    {
                        if (String.Equals(prop.Name, "PsDscRunAsCredential", StringComparison.OrdinalIgnoreCase))
                        {
                            keyProp.Mandatory = true;
                        }
                    }
                }

                if (valueMap != null && keyProp.Values.Count > 0)
                {
                    if (valueMap.Length != keyProp.Values.Count)
                    {
                        s_tracer.WriteLine(
                            "DSC CreateDynamicKeywordFromClass: the count of values for qualifier 'Values' and 'ValueMap' doesn't match. count of 'Values': {0}, count of 'ValueMap': {1}. Skip the keyword '{2}'.",
                            keyProp.Values.Count, valueMap.Length, keyword.Keyword);
                        return null;
                    }

                    for (int index = 0; index < valueMap.Length; index++)
                    {
                        string key = keyProp.Values[index];
                        string value = valueMap[index];

                        if (keyProp.ValueMap.ContainsKey(key))
                        {
                            s_tracer.WriteLine(
                                "DSC CreateDynamicKeywordFromClass: same string value '{0}' appears more than once in qualifier 'Values'. Skip the keyword '{1}'.",
                                key, keyword.Keyword);
                            return null;
                        }

                        keyProp.ValueMap.Add(key, value);
                    }
                }

                keyword.Properties.Add(prop.Name, keyProp);
            }

            // update specific keyword with range constraints
            UpdateKnownRestriction(keyword);

            return keyword;
        }
コード例 #2
0
ファイル: CimDSCParser.cs プロジェクト: 40a/PowerShell
        private static void ProcessMofForDynamicKeywords(PSModuleInfo module, ICollection<string> resourcesFound,
            Dictionary<string, ScriptBlock> functionsToDefine, CimDSCParser parser, string mof, DSCResourceRunAsCredential runAsBehavior)
        {
            foreach (var c in parser.ParseSchemaMofFileBuffer(mof))
            {
                var className = c.CimSystemProperties.ClassName;
                if (!CacheResourcesFromMultipleModuleVersions)
                {
                    // Find & remove the previous version of the resource.
                    List<KeyValuePair<string, Tuple<DSCResourceRunAsCredential, Microsoft.Management.Infrastructure.CimClass>>> resourceList =
                        FindResourceInCache(module.Name, className);

                    if (resourceList.Count > 0 && !string.IsNullOrEmpty(resourceList[0].Key))
                    {
                        ClassCache.Remove(resourceList[0].Key);
                    }
                }
                var moduleQualifiedResourceName = GetModuleQualifiedResourceName(module.Name, module.Version.ToString(), className);
                ClassCache[moduleQualifiedResourceName] = new Tuple<DSCResourceRunAsCredential, Microsoft.Management.Infrastructure.CimClass>(runAsBehavior, c);
                ByClassModuleCache[className] = new Tuple<string, Version>(module.Name, module.Version);
                resourcesFound.Add(className);
                CreateAndRegisterKeywordFromCimClass(module.Name, module.Version, c, functionsToDefine, runAsBehavior);
            }
        }
コード例 #3
0
ファイル: CimDSCParser.cs プロジェクト: 40a/PowerShell
        /// <summary>
        /// A method to generate a keyword from a CIM class object and register it to DynamicKeyword table.
        /// </summary>
        /// <param name="moduleName"></param>
        /// <param name="moduleVersion"></param>
        /// <param name="cimClass"></param>
        /// <param name="functionsToDefine">If true, don't define the keywords, just create the functions.</param>
        /// <param name="runAsBehavior"> To Specify RunAsBehavior of the class</param>
        private static void CreateAndRegisterKeywordFromCimClass(string moduleName, Version moduleVersion, Microsoft.Management.Infrastructure.CimClass cimClass, Dictionary<string, ScriptBlock> functionsToDefine, DSCResourceRunAsCredential runAsBehavior)
        {
            var keyword = CreateKeywordFromCimClass(moduleName, moduleVersion, cimClass, functionsToDefine, runAsBehavior);
            if (keyword == null)
            {
                return;
            }

            // keyword is already defined and we don't allow redefine it
            if (!CacheResourcesFromMultipleModuleVersions && DynamicKeyword.ContainsKeyword(keyword.Keyword))
            {
                var oldKeyword = DynamicKeyword.GetKeyword(keyword.Keyword);
                if (oldKeyword.ImplementingModule == null ||
                    !oldKeyword.ImplementingModule.Equals(moduleName, StringComparison.OrdinalIgnoreCase) || oldKeyword.ImplementingModuleVersion != moduleVersion)
                {
                    var e = PSTraceSource.NewInvalidOperationException(ParserStrings.DuplicateKeywordDefinition, keyword.Keyword);
                    e.SetErrorId("DuplicateKeywordDefinition");
                    throw e;
                }
            }
            // Add the dynamic keyword to the table
            DynamicKeyword.AddKeyword(keyword);

            // And now define the driver functions in the current scope...
            if (functionsToDefine != null)
            {
                functionsToDefine[moduleName + "\\" + keyword.Keyword] = CimKeywordImplementationFunction;
            }
        }