public static string BuildMof(IDscRes res, CimClass cls) { StringBuilder buff = new StringBuilder(); foreach (var p in res.Properties) { var cp = cls.CimClassProperties.FirstOrDefault(cp => cp.Name.Equals(p.Key, StringComparison.OrdinalIgnoreCase)); var line = $"{p.Key} = {ConvertToQuoted(p.Value, cp.CimType)};"; buff.AppendLine(line.Replace("\\", "\\\\")); } var mof = $@" instance of {res.TypeName} {{ ResourceID = ""[TFDscRes]TFDscRes""; ModuleName = ""{res.ModuleName}""; ModuleVersion = ""{res.ModuleVersion}""; ConfigurationName = ""TerrascapeDSC""; {buff.ToString()} }}; instance of OMI_ConfigurationDocument {{ Version = ""2.0.0""; MinimumCompatibleVersion = ""1.0.0""; }}; "; return(mof); }
private IDscRes DscResApplyConfig(IHasDiagnostics result, IDscRes config, out bool rebootRequired) { using var ses = CimSession.Create(config.ComputerName ?? DscRes.DefaultCimHostname); using var cls = ses.GetClass(DscRes.DscCimNamespace, config.TypeName); using var cim = new CimInstance(DscRes.LcmCimClassName, DscRes.DscCimNamespace); var mofBody = DscRes.BuildMof(config, cls); _log.LogDebug("Generated MOF:\n{0}", mofBody); var mofBodyBytes = DscRes.ToUint8(mofBody); var methodParams = new CimMethodParametersCollection { CimMethodParameter.Create("ModuleName", config.ModuleName, CimFlags.None), CimMethodParameter.Create("ResourceType", config.TypeName, CimFlags.None), CimMethodParameter.Create("resourceProperty", mofBodyBytes, CimFlags.None), }; CimMethodResult methodResult; lock (_dscSync) { methodResult = ses.InvokeMethod(cim, "ResourceSet", methodParams); } rebootRequired = (bool)methodResult.OutParameters["RebootRequired"].Value; lock (_dscSync) { methodResult = ses.InvokeMethod(cim, "ResourceGet", methodParams); } var dscResConfigs = (CimInstance)methodResult.OutParameters["configurations"].Value; var state = config; state.Results = new Dictionary <string, string>(); foreach (var p in dscResConfigs.CimInstanceProperties) { state.Results[p.Name] = p.Value?.ToString() ?? string.Empty; } lock (_dscSync) { methodResult = ses.InvokeMethod(cim, "ResourceTest", methodParams); } state.InDesiredState = (bool)methodResult.OutParameters["InDesiredState"].Value; return(state); }
private bool DscResTestConfig(IHasDiagnostics result, IDscRes config) { using var ses = CimSession.Create(config.ComputerName ?? DscRes.DefaultCimHostname); using var cls = ses.GetClass(DscRes.DscCimNamespace, config.TypeName); using var cim = new CimInstance(DscRes.LcmCimClassName, DscRes.DscCimNamespace); var mofBody = DscRes.BuildMof(config, cls); _log.LogDebug("Generated MOF:\n{0}", mofBody); var mofBodyBytes = DscRes.ToUint8(mofBody); var methodParams = new CimMethodParametersCollection { CimMethodParameter.Create("ModuleName", config.ModuleName, CimFlags.None), CimMethodParameter.Create("ResourceType", config.TypeName, CimFlags.None), CimMethodParameter.Create("resourceProperty", mofBodyBytes, CimFlags.None), }; CimMethodResult methodResult; lock (_dscSync) { methodResult = ses.InvokeMethod(cim, "ResourceTest", methodParams); } return((bool)methodResult.OutParameters["InDesiredState"].Value); }
private void DscResValidateConfig(IHasDiagnostics result, IDscRes config) { using var ses = CimSession.Create(config.ComputerName ?? DscRes.DefaultCimHostname); using var cls = ses.GetClass(DscRes.DscCimNamespace, config.TypeName); _log.LogDebug("Got CIM Class: {0}", config.TypeName); foreach (var p in cls.CimClassProperties) { _log.LogDebug(" * {0}: {1}; {2}; {3}; {4}", p.Name, p.CimType, p.Flags, p.ReferenceClassName, string.Join(",", p.Qualifiers?.Select(q => q.Name))); } if (cls.CimClassProperties.Count == 0) { result.AddError("Failed to get CIM Class properties"); } // First check for required params foreach (var p in cls.CimClassProperties) { if (p.Qualifiers.Any(q => q.Name == "key")) { if (!config.Properties.ContainsKey(p.Name)) { result.AddError($"missing mandatory DSC resource property: [{p.Name}]"); } } } // Check for existence, writability and value compatibility foreach (var c in config.Properties) { var p = cls.CimClassProperties.FirstOrDefault(p => p.Name.Equals(c.Key, StringComparison.OrdinalIgnoreCase)); if (p == null) { result.AddError($"unknown DSC resource property [{c.Key}]"); continue; } if (!p.Qualifiers.Any(q => q.Name == "write" || q.Name == "key")) { result.AddError($"cannot set readonly DSC resource property [{p.Name}]"); continue; } if (p.CimType == CimType.Unknown) { result.AddError($"cannot convert DSC resource property [{p.Name}] to [{p.CimType}]"); continue; } if (!DscRes.CanConvertTo(c.Value, p.CimType)) { result.AddError($"cannot convert DSC resource property [{p.Name}] to [{p.CimType}]"); continue; } if (p.Qualifiers.FirstOrDefault(q => q.Name == "ValueMap") is CimQualifier q) { var validValues = (IEnumerable <string>)q.Value; if (p.CimType == CimType.String) { if (!validValues.Contains(c.Value)) { result.AddError($"invalid DSC resource property [{p.Name}]" + $" - must be one of [{string.Join(",", validValues)}]"); } } else if (p.CimType == CimType.StringArray) { var canConvert = DscRes.TryConvertToArray <string>(c.Value, out var values); if (values.Any(v => !validValues.Contains(v))) { result.AddError($"invalid DSC resource property [{p.Name}]" + $" - must restrict to [{string.Join(",", validValues)}]"); } } else { result.AddError($"invalid DSC resource property [{p.Name}]" + $" - don't know how to match {p.CimType} to restricted values"); } continue; } } }