public async Task StartRunbookAsync(IDialogContext context, LuisResult result) { EntityRecommendation runbookEntity; var accessToken = await context.GetAccessToken(resourceId.Value); if (string.IsNullOrEmpty(accessToken)) { return; } var subscriptionId = context.GetSubscriptionId(); var availableAutomationAccounts = await new AutomationDomain().ListRunbooksAsync(accessToken, subscriptionId); // check if the user specified a runbook name in the command if (result.TryFindEntity("Runbook", out runbookEntity)) { // obtain the name specified by the user - text in LUIS result is different var runbookName = runbookEntity.GetEntityOriginalText(result.Query); EntityRecommendation automationAccountEntity; if (result.TryFindEntity("AutomationAccount", out automationAccountEntity)) { // obtain the name specified by the user - text in LUIS result is different var automationAccountName = automationAccountEntity.GetEntityOriginalText(result.Query); var selectedAutomationAccount = availableAutomationAccounts.SingleOrDefault(x => x.AutomationAccountName.Equals(automationAccountName, StringComparison.InvariantCultureIgnoreCase)); if (selectedAutomationAccount == null) { await context.PostAsync($"The '{automationAccountName}' automation account was not found in the current subscription"); context.Done <string>(null); return; } var runbook = selectedAutomationAccount.Runbooks.SingleOrDefault(x => x.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase)); // ensure that the runbook exists in the specified automation account if (runbook == null) { await context.PostAsync($"The '{runbookName}' runbook was not found in the '{automationAccountName}' automation account."); context.Done <string>(null); return; } if (!runbook.RunbookState.Equals("Published", StringComparison.InvariantCultureIgnoreCase)) { await context.PostAsync($"The '{runbookName}' runbook that you are trying to run is not published (State: {runbook.RunbookState}). Please go the Azure Portal and publish the runbook."); context.Done <string>(null); return; } runbookEntity.Entity = runbookName; runbookEntity.Type = "RunbookName"; automationAccountEntity.Entity = selectedAutomationAccount.AutomationAccountName; automationAccountEntity.Type = "AutomationAccountName"; } else { // ensure that the runbook exists in at least one of the automation accounts var selectedAutomationAccounts = availableAutomationAccounts.Where(x => x.Runbooks.Any(r => r.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase))); if (selectedAutomationAccounts == null || !selectedAutomationAccounts.Any()) { await context.PostAsync($"The '{runbookName}' runbook was not found in any of your automation accounts."); context.Done <string>(null); return; } var runbooks = selectedAutomationAccounts.SelectMany(x => x.Runbooks.Where(r => r.RunbookName.Equals(runbookName, StringComparison.InvariantCultureIgnoreCase) && r.RunbookState.Equals("Published", StringComparison.InvariantCultureIgnoreCase))); if (runbooks == null || !runbooks.Any()) { await context.PostAsync($"The '{runbookName}' runbook that you are trying to run is not Published. Please go the Azure Portal and publish the runbook."); context.Done <string>(null); return; } runbookEntity.Entity = runbookName; runbookEntity.Type = "RunbookName"; // todo: handle runbooks with same name in different automation accounts availableAutomationAccounts = selectedAutomationAccounts.ToList(); } } if (availableAutomationAccounts.Any()) { var formState = new RunbookFormState(availableAutomationAccounts); if (availableAutomationAccounts.Count() == 1) { formState.AutomationAccountName = availableAutomationAccounts.Single().AutomationAccountName; } var form = new FormDialog <RunbookFormState>( formState, AutomationForms.BuildRunbookForm, FormOptions.PromptInStart, result.Entities); context.Call(form, this.StartRunbookParametersAsync); } else { await context.PostAsync($"No automations accounts were found in the current subscription. Please create an Azure automation account or switch to a subscription which has an automation account in it."); context.Done <string>(null); } }
private async Task RunbookFormComplete(IDialogContext context, RunbookFormState runbookFormState) { try { var accessToken = await context.GetAccessToken(resourceId.Value); if (string.IsNullOrEmpty(accessToken)) { return; } var runbookJob = await new AutomationDomain().StartRunbookAsync( accessToken, runbookFormState.SelectedAutomationAccount.SubscriptionId, runbookFormState.SelectedAutomationAccount.ResourceGroup, runbookFormState.SelectedAutomationAccount.AutomationAccountName, runbookFormState.RunbookName, runbookFormState.RunbookParameters.Where(param => !string.IsNullOrWhiteSpace(param.ParameterValue)) .ToDictionary(param => param.ParameterName, param => param.ParameterValue)); IList <RunbookJob> automationJobs = context.GetAutomationJobs(runbookFormState.SelectedAutomationAccount.SubscriptionId); if (automationJobs == null) { runbookJob.FriendlyJobId = AutomationJobsHelper.NextFriendlyJobId(automationJobs); automationJobs = new List <RunbookJob> { runbookJob }; } else { runbookJob.FriendlyJobId = AutomationJobsHelper.NextFriendlyJobId(automationJobs); automationJobs.Add(runbookJob); } context.StoreAutomationJobs(runbookFormState.SelectedAutomationAccount.SubscriptionId, automationJobs); await context.PostAsync($"Created Job '{runbookJob.JobId}' for the '{runbookFormState.RunbookName}' runbook in '{runbookFormState.AutomationAccountName}' automation account. You'll receive a message when it is completed."); var notCompletedStatusList = new List <string> { "Stopped", "Suspended", "Failed" }; var completedStatusList = new List <string> { "Completed" }; var notifyStatusList = new List <string> { "Running" }; notifyStatusList.AddRange(completedStatusList); notifyStatusList.AddRange(notCompletedStatusList); accessToken = await context.GetAccessToken(resourceId.Value); if (string.IsNullOrEmpty(accessToken)) { return; } #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed CheckLongRunningOperationStatus( context, runbookJob, accessToken, new AutomationDomain().GetAutomationJobAsync, rj => rj.EndDateTime.HasValue, (previous, last, job) => { if (!string.Equals(previous?.Status, last?.Status) && notifyStatusList.Contains(last.Status)) { if (notCompletedStatusList.Contains(last.Status)) { return($"The runbook '{job.RunbookName}' (job '{job.JobId}') did not complete with status '{last.Status}'. Please go to the Azure Portal for more detailed information on why."); } else if (completedStatusList.Contains(last.Status)) { return($"Runbook '{job.RunbookName}' is currently in '{last.Status}' status. Type **show {job.FriendlyJobId} output** to see the output."); } else { return($"Runbook '{job.RunbookName}' job '{job.JobId}' is currently in '{last.Status}' status."); } } return(null); }); #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed } catch (Exception e) { await context.PostAsync($"Oops! Something went wrong :(. Technical Details: {e.InnerException.Message}"); } context.Done <string>(null); }
public static void StoreRunbookFormState(this IBotContext context, RunbookFormState runbookFormState) { context.PrivateConversationData.SetValue(ContextConstants.RunbookFormStateKey, runbookFormState); }