private void GivenDscConfigurationWithResources() { testDscConfiguration = new DscConfiguration { DscResources = new List <DscResource> { dockerChocolateyResource, chocolateySourceResource, visualStudioChocolateyResource } }; }
//Configuration exists both on disk and in the cloud. But are they in sync? public AutomationDSC(FileInfo localFile, DscConfiguration cloudConfiguration, DscConfiguration cloudConfigurationDraft) : base(cloudConfiguration.Name, localFile.LastWriteTime, cloudConfiguration.Properties.LastModifiedTime.LocalDateTime) { this.AuthoringState = cloudConfiguration.Properties.State; this.localFileInfo = localFile; this.Description = cloudConfiguration.Properties.Description; this.Parameters = cloudConfiguration.Properties.Parameters; if (cloudConfigurationDraft != null) { this.LastModifiedCloud = cloudConfigurationDraft.Properties.LastModifiedTime.LocalDateTime; UpdateSyncStatus(); } }
public void UpdateDscConfiguration(DscConfiguration configuration, string configContent, string description = null, string contentHashValue = null, string contentHashAlgorithm = "sha256", string contentType = null) { AutomationClient.DscConfiguration.CreateOrUpdate(ResourceGroup, AutomationAccount, configuration.Name, new DscConfigurationCreateOrUpdateParameters { Description = configuration.Description, Source = new ContentSource { Value = configContent, Type = contentType, Hash = new ContentHash { Value = contentHashValue, Algorithm = contentHashAlgorithm } }, Location = configuration.Location, Name = configuration.Name }); }
private async Task <DscCompilationJobCreateResponse> createDSCJob() { DscConfiguration draft = await AutomationDSCManager.GetConfigurationDraft(configurationName, iseClient.automationManagementClient, iseClient.accountResourceGroups[iseClient.currAccount].Name, iseClient.currAccount.Name); Dictionary <string, string> filePathForRunbook = new Dictionary <string, string>(); if (Directory.Exists(iseClient.currWorkspace)) { foreach (string path in localRunbookFilePaths) { if (path.EndsWith(Constants.nodeConfigurationIdentifier + ".ps1")) { filePathForRunbook.Add(System.IO.Path.GetFileNameWithoutExtension(path), path); } } } var jobCreationParams = new DscCompilationJobCreateParameters() { Properties = new DscCompilationJobCreateProperties() { Configuration = new DscConfigurationAssociationProperty() { Name = configurationName }, Parameters = null } }; jobCreationParams.Name = configurationName; if ((draft.Properties.Parameters.Count > 0) || filePathForRunbook.Count > 0) { /* User needs to specify some things */ var existingParams = await GetLastCompilationJobParams(); DSCConfigurationParamDialog paramDialog = new DSCConfigurationParamDialog(draft.Properties.Parameters, existingParams, filePathForRunbook); string configData = null; if (paramDialog.ShowDialog() == true) { if (!String.IsNullOrEmpty(paramDialog.configDataSelection) && !paramDialog.configDataSelection.Equals("None")) { configData = getConfigurationData(paramDialog.configDataSelection); } jobCreationParams.Properties.Parameters = GetDSCParameters(paramDialog.paramValues, configData); } else { return(null); } } /* start the compilation job */ CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(TIMEOUT_MS); DscCompilationJobCreateResponse jobResponse = await iseClient.automationManagementClient.CompilationJobs.CreateAsync( iseClient.accountResourceGroups[iseClient.currAccount].Name, iseClient.currAccount.Name, jobCreationParams, cts.Token); if (jobResponse == null || jobResponse.StatusCode != System.Net.HttpStatusCode.Created) { throw new Exception("The DSC compilation job could not be created: received HTTP status code " + jobResponse.StatusCode); } lastJobID = jobResponse.DscCompilationJob.Properties.JobId; return(jobResponse); }
public static async Task UploadConfigurationAsDraft(AutomationDSC configuration, AutomationManagementClient automationManagementClient, string resourceGroupName, AutomationAccount account) { string fileContent = null; try { if (File.Exists(Path.GetFullPath(configuration.localFileInfo.FullName))) { fileContent = System.IO.File.ReadAllText(configuration.localFileInfo.FullName); } } catch (Exception) { // exception in accessing the file path throw new FileNotFoundException( string.Format( CultureInfo.CurrentCulture, Resources.LocalConfigurationFileNotFound)); } DscConfigurationCreateOrUpdateProperties draftProperties; draftProperties = new DscConfigurationCreateOrUpdateProperties(); // Get current properties if is not a new configuration and set these on the draft also so they are preserved. DscConfigurationGetResponse response = null; CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(TIMEOUT_MS); if (configuration.SyncStatus != AutomationAuthoringItem.Constants.SyncStatus.LocalOnly) { response = await automationManagementClient.Configurations.GetAsync(resourceGroupName, account.Name, configuration.Name, cts.Token); } // Create properties DscConfigurationCreateOrUpdateParameters draftParams = new DscConfigurationCreateOrUpdateParameters(draftProperties); draftParams.Name = configuration.Name; draftParams.Location = account.Location; draftParams.Properties.Description = configuration.Description; // If this is not a new configuration, set the existing properties of the configuration if (response != null) { draftParams.Tags = response.Configuration.Tags; draftParams.Location = response.Configuration.Location; draftParams.Properties.LogVerbose = response.Configuration.Properties.LogVerbose; draftParams.Properties.Description = response.Configuration.Properties.Description; } cts = new CancellationTokenSource(); cts.CancelAfter(TIMEOUT_MS); /* Update the configuration content from .ps1 file */ DscConfigurationCreateOrUpdateParameters draftUpdateParams = new DscConfigurationCreateOrUpdateParameters() { Name = configuration.Name, Location = draftParams.Location, Tags = draftParams.Tags, Properties = new DscConfigurationCreateOrUpdateProperties() { Description = draftParams.Properties.Description, LogVerbose = draftParams.Properties.LogVerbose, Source = new Microsoft.Azure.Management.Automation.Models.ContentSource() { ContentType = ContentSourceType.EmbeddedContent, Value = fileContent } } }; cts = new CancellationTokenSource(); cts.CancelAfter(TIMEOUT_MS); await automationManagementClient.Configurations.CreateOrUpdateAsync(resourceGroupName, account.Name, draftUpdateParams, cts.Token); /* Ensure the correct sync status is detected */ DscConfiguration draft = await GetConfigurationDraft(configuration.Name, automationManagementClient, resourceGroupName, account.Name); configuration.localFileInfo.LastWriteTime = draft.Properties.LastModifiedTime.LocalDateTime; configuration.LastModifiedLocal = draft.Properties.LastModifiedTime.LocalDateTime; configuration.LastModifiedCloud = draft.Properties.LastModifiedTime.LocalDateTime; }
private void GivenDscConfigurationWithoutResources() { testDscConfiguration = new DscConfiguration(); }
private void WhenDscConfigurationIsCreatedFromMergeResult() { testDscConfiguration = DscConfiguration.FromMergedPreference(mergedPreference); }
public static async Task ConfigureAsync(IOperationExecutionContext context, ILogSink log, DscConfiguration template) { if (context.Simulation) { log.LogInformation("Invoking DscResource..."); return; } var jobRunner = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var propertyTypes = await GetPropertyTypesAsync(context, jobRunner, template.ResourceName, template.ModuleName, log); var job = CreateJob("Set", propertyTypes, template); job.MessageLogged += (s, e) => log.Log(e.Level, e.Message); await jobRunner.ExecuteJobAsync(job, context.CancellationToken); }
public static async Task <PersistedConfiguration> CollectAsync(IOperationCollectionContext context, ILogSink log, DscConfiguration template) { if (string.IsNullOrEmpty(template.ResourceName)) { log.LogError("Bad or missing DSC Resource name."); return(null); } var jobRunner = await context.Agent.GetServiceAsync <IRemoteJobExecuter>(); var propertyTypes = await GetPropertyTypesAsync(context, jobRunner, template.ResourceName, template.ModuleName, log); var collectJob = CreateJob("Get", propertyTypes, template); log.LogDebug(collectJob.ScriptText); collectJob.MessageLogged += (s, e) => log.Log(e.Level, e.Message); var result = (ExecutePowerShellJob.Result) await jobRunner.ExecuteJobAsync(collectJob, context.CancellationToken); var collectValues = result.Output?.FirstOrDefault().AsDictionary() ?? new Dictionary <string, RuntimeValue>(StringComparer.OrdinalIgnoreCase); var removeKeys = collectValues.Where(p => p.Value.ValueType == RuntimeValueType.Scalar && string.IsNullOrEmpty(p.Value.AsString())).Select(p => p.Key).ToList(); foreach (var k in removeKeys) { collectValues.Remove(k); } var testJob = CreateJob("Test", propertyTypes, template); log.LogDebug(testJob.ScriptText); testJob.MessageLogged += (s, e) => log.Log(e.Level, e.Message); var result2 = (ExecutePowerShellJob.Result) await jobRunner.ExecuteJobAsync(testJob, context.CancellationToken); var output = result2.Output; if (output.Count == 0) { log.LogError("Invoke-DscResource did not return any values."); return(null); } var testResult = output.FirstOrDefault(); bool?inDesiredState = null; if (testResult.ValueType == RuntimeValueType.Map && testResult.AsDictionary().ContainsKey("InDesiredState")) { if (bool.TryParse(testResult.AsDictionary()["InDesiredState"].AsString(), out bool d)) { inDesiredState = d; } } else { inDesiredState = testResult.AsBoolean(); } if (inDesiredState == null) { log.LogError("Invoke-DscResource did not return a boolean value or an object with an InDesiredState property."); return(null); } return(new DscConfiguration(collectValues) { ModuleName = template.ModuleName, ResourceName = template.ResourceName, ConfigurationKeyName = template.ConfigurationKeyName, InDesiredState = inDesiredState.Value }); }
private static ExecutePowerShellJob CreateJob(string method, Dictionary <string, RuntimeValueType> propertyTypes, DscConfiguration template) { var job = new ExecutePowerShellJob { CollectOutput = true, ScriptText = $"Invoke-DscResource -Name $Name -Method {method} -Property $Property -ModuleName $ModuleName", Variables = new Dictionary <string, RuntimeValue>(StringComparer.OrdinalIgnoreCase) { ["Name"] = template.ResourceName, ["Property"] = new RuntimeValue(template.ToPowerShellDictionary(propertyTypes)), ["ModuleName"] = AH.CoalesceString(template.ModuleName, "PSDesiredStateConfiguration") } }; return(job); }