Skip to content

Fixes for Azure Automation module #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
using System.Runtime.Serialization.Json;
using System.Text;
using System.Xml.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace Microsoft.Azure.Commands.Automation.Cmdlet
{
Expand Down Expand Up @@ -86,17 +88,49 @@ public override void ExecuteCmdlet()
{
if (string.IsNullOrEmpty(ErrorResponseException.Body.Code) && string.IsNullOrEmpty(ErrorResponseException.Body.Message))
{
string message = this.ParseErrorMessage(ErrorResponseException.Response.Content);
if (!string.IsNullOrEmpty(message))
if (!string.IsNullOrEmpty(ErrorResponseException.Response.Content))
{
throw new ErrorResponseException(message, ErrorResponseException);
var message = ParseJson(ErrorResponseException.Response.Content);
if (!string.IsNullOrEmpty(message))
{
throw new ErrorResponseException(message, ErrorResponseException);
}
}
}

throw new ErrorResponseException(ErrorResponseException.Body.Message, ErrorResponseException);
}
}

// This function parses two type of Json contents:
// 1) "{\"error\":{\"code\":\"ResourceGroupNotFound\",\"message\":\"Resource group 'foobar' could not be found.\"}}"
// 2) "{\"code\":\"ResourceGroupNotFound\",\"message\":\"Resource group 'foobar' could not be found.\"}"
private string ParseJson(string value)
{
value = value.Trim();
try
{
var nestedError = JsonConvert.DeserializeObject<AzureAutomationErrorResponseMessage>(value);
return nestedError.Error.Message;
}
catch
{
// Ignore the parsing error.
}

try
{
var error = JsonConvert.DeserializeObject<AzureAutomationErrorInfo>(value);
return error.Message;
}
catch
{
// Ignore the parsing error.
}

return null;
}

protected bool GenerateCmdletOutput(object result)
{
var ret = true;
Expand Down Expand Up @@ -130,30 +164,5 @@ protected bool GenerateCmdletOutput(IEnumerable<object> results)

return ret;
}

private string ParseErrorMessage(string errorMessage)
{
// The errorMessage is expected to be the error details in JSON format.
// e.g. <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">{"code":"NotFound","message":"Certificate not found."}</string>
try
{
using (var memoryStream = new MemoryStream(Encoding.UTF8.GetBytes(XDocument.Load(new StringReader(errorMessage)).Root.Value)))
{
var serializer = new DataContractJsonSerializer(typeof(ErrorResponseException));
var errorResponse = (ErrorResponseException)serializer.ReadObject(memoryStream);

if (!string.IsNullOrWhiteSpace(errorResponse.Message))
{
return errorResponse.Message;
}
}
}
catch (Exception)
{
// swallow the exception as we cannot parse the error message
}

return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class GetAzureAutomationSourceControlSyncJobOutput : AzureAutomationBaseC
public string SourceControlName { get; set; }

/// <summary>
/// Gets or sets the source contorl sync job id.
/// Gets or sets the source control sync job id.
/// </summary>
[Parameter(Mandatory = true, ValueFromPipelineByPropertyName = true,
HelpMessage = "The source control sync job id.")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@
<Compile Include="Common\AutomationPSClientSourceControl.cs" />
<Compile Include="Common\AutomationPSClientWebhook.cs" />
<Compile Include="Common\AutomationCmdletParameterSet.cs" />
<Compile Include="Common\AzureAutomationErrorInfo.cs" />
<Compile Include="Common\AzureAutomationErrorResponseMessage.cs" />
<Compile Include="Common\AzureAutomationOperationException.cs" />
<Compile Include="Common\Constants.cs" />
<Compile Include="Common\DscNodeStatus.cs" />
Expand Down Expand Up @@ -263,7 +265,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
</ItemGroup>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\..\..\tools\Common.Dependencies.targets" />
<Target Name="AfterBuild">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,23 +67,6 @@ public Model.SourceControl CreateSourceControl(
Requires.Argument("branch", branch).NotNullOrEmpty();
}

bool sourceControlExists = true;

try
{
this.GetSourceControl(resourceGroupName, automationAccountName, name);
}
catch (ResourceNotFoundException)
{
sourceControlExists = false;
}

if (sourceControlExists)
{
throw new AzureAutomationOperationException(
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlAlreadyExists, name));
}

var decryptedAccessToken = Utils.GetStringFromSecureString(accessToken);

var createParams = new SourceControlCreateOrUpdateParameters(
Expand All @@ -102,7 +85,14 @@ public Model.SourceControl CreateSourceControl(
name,
createParams);

return new Model.SourceControl(sdkSourceControl, automationAccountName, resourceGroupName);
Model.SourceControl result = null;

if (sdkSourceControl != null)
{
result = new Model.SourceControl(sdkSourceControl, automationAccountName, resourceGroupName);
}

return result;
}

public Model.SourceControl UpdateSourceControl(
Expand All @@ -119,17 +109,6 @@ public Model.SourceControl UpdateSourceControl(
Requires.Argument("ResourceGroupName", resourceGroupName).NotNullOrEmpty();
Requires.Argument("AutomationAccountName", automationAccountName).NotNullOrEmpty();
Requires.Argument("name", name).NotNullOrEmpty();

Model.SourceControl existingSourceControl = null;
try
{
existingSourceControl = this.GetSourceControl(resourceGroupName, automationAccountName, name);
}
catch (ResourceNotFoundException)
{
throw new AzureAutomationOperationException(
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlNotFound, name));
}

var updateParams = new AutomationManagement.Models.SourceControlUpdateParameters();

Expand Down Expand Up @@ -170,7 +149,14 @@ public Model.SourceControl UpdateSourceControl(
name,
updateParams);

return new Model.SourceControl(sdkSourceControl, automationAccountName, resourceGroupName);
Model.SourceControl result = null;

if (sdkSourceControl != null)
{
result = new Model.SourceControl(sdkSourceControl, automationAccountName, resourceGroupName);
}

return result;
}

public void DeleteSourceControl(
Expand All @@ -182,20 +168,7 @@ public void DeleteSourceControl(
Requires.Argument("automationAccountName", automationAccountName).NotNullOrEmpty();
Requires.Argument("name", name).NotNullOrEmpty();

try
{
this.automationManagementClient.SourceControl.Delete(resourceGroupName, automationAccountName, name);
}
catch (CloudException cloudException)
{
if (cloudException.Response.StatusCode == System.Net.HttpStatusCode.NoContent)
{
throw new ResourceNotFoundException(typeof(SourceControl),
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlNotFound, name));
}

throw;
}
this.automationManagementClient.SourceControl.Delete(resourceGroupName, automationAccountName, name);
}

public Model.SourceControl GetSourceControl(
Expand All @@ -207,39 +180,16 @@ public Model.SourceControl GetSourceControl(
Requires.Argument("automationAccountName", automationAccountName).NotNullOrEmpty();
Requires.Argument("name", name).NotNullOrEmpty();

Model.SourceControl result = null;
bool throwException = false;

try
{
var existingSourceControl = this.automationManagementClient.SourceControl.Get(
resourceGroupName,
automationAccountName,
name);
var existingSourceControl = this.automationManagementClient.SourceControl.Get(
resourceGroupName,
automationAccountName,
name);

if (existingSourceControl != null)
{
result = new Model.SourceControl(existingSourceControl, automationAccountName, resourceGroupName);
}
else
{
throwException = true;
}
}
catch (Exception ex)
{
if (ex is CloudException || ex is ErrorResponseException)
{
throwException = true;
}
else
throw;
}
Model.SourceControl result = null;

if (throwException)
if (existingSourceControl != null)
{
throw new ResourceNotFoundException(typeof(SourceControl),
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlNotFound, name));
result = new Model.SourceControl(existingSourceControl, automationAccountName, resourceGroupName);
}

return result;
Expand Down Expand Up @@ -283,30 +233,21 @@ public Model.SourceControlSyncJob StartSourceControlSyncJob(
Requires.Argument("sourceControlName", sourceControlName).NotNullOrEmpty();
Requires.Argument("syncJobId", syncJobId).NotNullOrEmpty();

bool syncJobExists = true;
try
{
this.GetSourceControlSyncJob(resourceGroupName, automationAccountName, sourceControlName, syncJobId);
}
catch (ResourceNotFoundException)
{
syncJobExists = false;
}

if (syncJobExists)
{
throw new AzureAutomationOperationException(
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlSyncJobAlreadyExist, syncJobId.ToString()));
}

var sdkSyncJob = this.automationManagementClient.SourceControlSyncJob.Create(
resourceGroupName,
automationAccountName,
sourceControlName,
syncJobId,
new SourceControlSyncJobCreateParameters(""));

return new Model.SourceControlSyncJob(resourceGroupName, automationAccountName, sourceControlName, sdkSyncJob);
Model.SourceControlSyncJob result = null;

if (sdkSyncJob != null)
{
result = new Model.SourceControlSyncJob(resourceGroupName, automationAccountName, sourceControlName, sdkSyncJob);
}

return result;
}

public Model.SourceControlSyncJobRecord GetSourceControlSyncJob(
Expand All @@ -320,25 +261,17 @@ public Model.SourceControlSyncJobRecord GetSourceControlSyncJob(
Requires.Argument("sourceControlName", sourceControlName).NotNullOrEmpty();
Requires.Argument("syncJobId", syncJobId).NotNullOrEmpty();

Model.SourceControlSyncJobRecord result = null;

try
{
var existingSyncJob = this.automationManagementClient.SourceControlSyncJob.Get(
var existingSyncJob = this.automationManagementClient.SourceControlSyncJob.Get(
resourceGroupName,
automationAccountName,
sourceControlName,
syncJobId);

if (existingSyncJob != null)
{
result = new Model.SourceControlSyncJobRecord(resourceGroupName, automationAccountName, sourceControlName, existingSyncJob);
}
}
catch (ErrorResponseException)
Model.SourceControlSyncJobRecord result = null;

if (existingSyncJob != null)
{
throw new ResourceNotFoundException(typeof(SourceControl),
string.Format(CultureInfo.CurrentCulture, Resources.SourceControlSyncJobNotFound, syncJobId.ToString()));
result = new Model.SourceControlSyncJobRecord(resourceGroupName, automationAccountName, sourceControlName, existingSyncJob);
}

return result;
Expand All @@ -354,7 +287,6 @@ public Model.SourceControlSyncJobRecord GetSourceControlSyncJob(
Requires.Argument("automationAccountName", automationAccountName).NotNullOrEmpty();
Requires.Argument("sourceControlName", sourceControlName).NotNullOrEmpty();

// SourceControlListResponse comes from metadata.
Rest.Azure.IPage<AutomationManagement.Models.SourceControlSyncJob> response;

if (string.IsNullOrEmpty(nextLink))
Expand Down Expand Up @@ -406,7 +338,7 @@ public Model.SourceControlSyncJobRecord GetSourceControlSyncJob(

nextLink = response.NextPageLink;

return response.Select(
return response.Select(
stream => new Model.SourceControlSyncJobStream(stream, resourceGroupName, automationAccountName, sourceControlName, syncJobId));
}

Expand All @@ -430,8 +362,15 @@ public SourceControlSyncJobStreamRecord GetSourceControlSyncJobStreamRecord(
syncJobId,
syncJobStreamId);

return new SourceControlSyncJobStreamRecord(
response, resourceGroupName, automationAccountName, sourceControlName, syncJobId);
SourceControlSyncJobStreamRecord result = null;

if (response != null)
{
result = new SourceControlSyncJobStreamRecord(
response, resourceGroupName, automationAccountName, sourceControlName, syncJobId);
}

return result;
}

#region private helper functions
Expand Down
Loading