Skip to content

Commit

Permalink
[Azure.Monitor.Ingestion] Fix Sovereign Support for Ingestion (#39078)
Browse files Browse the repository at this point in the history
  • Loading branch information
nisha-bhatia authored Oct 5, 2023
1 parent 4916207 commit 5fa15a4
Show file tree
Hide file tree
Showing 11 changed files with 175 additions and 18 deletions.
1 change: 1 addition & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
### Breaking Changes

### Bugs Fixed
- Fix sovereign support for US Gov and China clouds

### Other Changes

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
namespace Azure.Monitor.Ingestion
{
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct LogsIngestionAudience : System.IEquatable<Azure.Monitor.Ingestion.LogsIngestionAudience>
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public LogsIngestionAudience(string value) { throw null; }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzureChina { get { throw null; } }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzureGovernment { get { throw null; } }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzurePublicCloud { get { throw null; } }
public bool Equals(Azure.Monitor.Ingestion.LogsIngestionAudience other) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public override bool Equals(object obj) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Monitor.Ingestion.LogsIngestionAudience left, Azure.Monitor.Ingestion.LogsIngestionAudience right) { throw null; }
public static implicit operator Azure.Monitor.Ingestion.LogsIngestionAudience (string value) { throw null; }
public static bool operator !=(Azure.Monitor.Ingestion.LogsIngestionAudience left, Azure.Monitor.Ingestion.LogsIngestionAudience right) { throw null; }
public override string ToString() { throw null; }
}
public partial class LogsIngestionClient
{
protected LogsIngestionClient() { }
Expand All @@ -14,6 +33,7 @@ public LogsIngestionClient(System.Uri endpoint, Azure.Core.TokenCredential crede
public partial class LogsIngestionClientOptions : Azure.Core.ClientOptions
{
public LogsIngestionClientOptions(Azure.Monitor.Ingestion.LogsIngestionClientOptions.ServiceVersion version = Azure.Monitor.Ingestion.LogsIngestionClientOptions.ServiceVersion.V2023_01_01) { }
public Azure.Monitor.Ingestion.LogsIngestionAudience? Audience { get { throw null; } set { } }
public enum ServiceVersion
{
V2023_01_01 = 1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
namespace Azure.Monitor.Ingestion
{
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public readonly partial struct LogsIngestionAudience : System.IEquatable<Azure.Monitor.Ingestion.LogsIngestionAudience>
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public LogsIngestionAudience(string value) { throw null; }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzureChina { get { throw null; } }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzureGovernment { get { throw null; } }
public static Azure.Monitor.Ingestion.LogsIngestionAudience AzurePublicCloud { get { throw null; } }
public bool Equals(Azure.Monitor.Ingestion.LogsIngestionAudience other) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public override bool Equals(object obj) { throw null; }
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Monitor.Ingestion.LogsIngestionAudience left, Azure.Monitor.Ingestion.LogsIngestionAudience right) { throw null; }
public static implicit operator Azure.Monitor.Ingestion.LogsIngestionAudience (string value) { throw null; }
public static bool operator !=(Azure.Monitor.Ingestion.LogsIngestionAudience left, Azure.Monitor.Ingestion.LogsIngestionAudience right) { throw null; }
public override string ToString() { throw null; }
}
public partial class LogsIngestionClient
{
protected LogsIngestionClient() { }
Expand All @@ -14,6 +33,7 @@ public LogsIngestionClient(System.Uri endpoint, Azure.Core.TokenCredential crede
public partial class LogsIngestionClientOptions : Azure.Core.ClientOptions
{
public LogsIngestionClientOptions(Azure.Monitor.Ingestion.LogsIngestionClientOptions.ServiceVersion version = Azure.Monitor.Ingestion.LogsIngestionClientOptions.ServiceVersion.V2023_01_01) { }
public Azure.Monitor.Ingestion.LogsIngestionAudience? Audience { get { throw null; } set { } }
public enum ServiceVersion
{
V2023_01_01 = 1,
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

59 changes: 59 additions & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/src/LogsIngestionAudience.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.ComponentModel;
using Azure.Core;

namespace Azure.Monitor.Ingestion
{
/// <summary> Cloud audiences available for Ingestion. </summary>
public readonly partial struct LogsIngestionAudience : IEquatable<LogsIngestionAudience>
{
private readonly string _value;

/// <summary>
/// Initializes a new instance of the <see cref="LogsIngestionAudience"/> object.
/// </summary>
/// <param name="value">The Azure Active Directory audience to use when forming authorization scopes. For the language service, this value corresponds to a URL that identifies the Azure cloud where the resource is located. For more information: <see href="https://learn.microsoft.com/azure/azure-government/documentation-government-cognitiveservices" />.</param>
/// <exception cref="ArgumentNullException"> <paramref name="value"/> is null. </exception>
/// <remarks>Use one of the constant members over creating a custom value, unless you have special needs for doing so.</remarks>
public LogsIngestionAudience(string value)
{
Argument.AssertNotNullOrEmpty(value, nameof(value));
_value = value;
}

private const string AzureChinaValue = "https://monitor.azure.cn//.default";
private const string AzureGovernmentValue = "https://monitor.azure.us//.default";
private const string AzurePublicCloudValue = "https://monitor.azure.com//.default";

/// <summary> Azure China. </summary>
public static LogsIngestionAudience AzureChina { get; } = new LogsIngestionAudience(AzureChinaValue);

/// <summary> Azure Government. </summary>
public static LogsIngestionAudience AzureGovernment { get; } = new LogsIngestionAudience(AzureGovernmentValue);

/// <summary> Azure Public Cloud. </summary>
public static LogsIngestionAudience AzurePublicCloud { get; } = new LogsIngestionAudience(AzurePublicCloudValue);

/// <summary> Determines if two <see cref="LogsIngestionAudience"/> values are the same. </summary>
public static bool operator ==(LogsIngestionAudience left, LogsIngestionAudience right) => left.Equals(right);
/// <summary> Determines if two <see cref="LogsIngestionAudience"/> values are not the same. </summary>
public static bool operator !=(LogsIngestionAudience left, LogsIngestionAudience right) => !left.Equals(right);
/// <summary> Converts a string to a <see cref="LogsIngestionAudience"/>. </summary>
public static implicit operator LogsIngestionAudience(string value) => new LogsIngestionAudience(value);

/// <inheritdoc />
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is LogsIngestionAudience other && Equals(other);
/// <inheritdoc />
public bool Equals(LogsIngestionAudience other) => string.Equals(_value, other._value, StringComparison.InvariantCultureIgnoreCase);

/// <inheritdoc />
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() => _value?.GetHashCode() ?? 0;
/// <inheritdoc />
public override string ToString() => _value;
}
}
21 changes: 21 additions & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/src/LogsIngestionClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,34 @@ namespace Azure.Monitor.Ingestion
{
/// <summary> The IngestionUsingDataCollectionRules service client. </summary>
[CodeGenClient("IngestionUsingDataCollectionRulesClient")]
[CodeGenSuppress("LogsIngestionClient", typeof(Uri), typeof(TokenCredential), typeof(LogsIngestionClientOptions))]
public partial class LogsIngestionClient
{
/// <summary> Initializes a new instance of LogsIngestionClient for mocking. </summary>
protected LogsIngestionClient()
{
}

/// <summary> Initializes a new instance of <see cref="LogsIngestionClient"/>. </summary>
/// <param name="endpoint"> The Data Collection Endpoint for the Data Collection Rule. For example, https://dce-name.eastus-2.ingest.monitor.azure.com. </param>
/// <param name="credential"> A credential used to authenticate to an Azure service. </param>
/// <param name="options"> The options for configuring the client. </param>
/// <exception cref="ArgumentNullException"> <paramref name="endpoint"/> or <paramref name="credential"/> is null. </exception>
public LogsIngestionClient(Uri endpoint, TokenCredential credential, LogsIngestionClientOptions options)
{
Argument.AssertNotNull(endpoint, nameof(endpoint));
Argument.AssertNotNull(credential, nameof(credential));
options ??= new LogsIngestionClientOptions();

ClientDiagnostics = new ClientDiagnostics(options, true);
_tokenCredential = credential;
var authorizationScope = $"{(string.IsNullOrEmpty(options.Audience?.ToString()) ? LogsIngestionAudience.AzurePublicCloud : options.Audience)}";
var scopes = new List<string> { authorizationScope };
_pipeline = HttpPipelineBuilder.Build(options, Array.Empty<HttpPipelinePolicy>(), new HttpPipelinePolicy[] { new BearerTokenAuthenticationPolicy(_tokenCredential, scopes) }, new ResponseClassifier());
_endpoint = endpoint;
_apiVersion = options.Version;
}

// The size we use to determine whether to upload as a single PUT BLOB
// request or stage as multiple blocks.
// 1 Mb in byte format
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Azure.Core;

namespace Azure.Monitor.Ingestion
{
/// <summary> Client options for <see cref="LogsIngestionClient"/>. </summary>
public partial class LogsIngestionClientOptions : ClientOptions
{
/// <summary>
/// Gets or sets the audience to use for authentication with Azure Active Directory (AAD). The audience is not considered when using a shared key.
/// </summary>
/// <value>If <c>null</c>, <see cref="LogsIngestionAudience.AzurePublicCloud" /> will be assumed.</value>
public LogsIngestionAudience? Audience { get; set; }
}
}
8 changes: 8 additions & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,12 @@ extends:
template: /eng/pipelines/templates/stages/archetype-sdk-tests.yml
parameters:
ServiceDirectory: monitor
CloudConfig:
Public:
SubscriptionConfiguration: $(sub-config-azure-cloud-test-resources)
UsGov:
SubscriptionConfiguration: $(sub-config-gov-test-resources)
China:
SubscriptionConfiguration: $(sub-config-cn-test-resources)
SupportedClouds: 'Public,UsGov,China'
Project: Azure.Monitor.Ingestion
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ private LogsIngestionClient CreateClient(HttpPipelinePolicy policy = null)
options.AddPolicy(policy, HttpPipelinePosition.PerCall);
}
var clientOptions = InstrumentClientOptions(options);
clientOptions.Audience = TestEnvironment.GetAudience();
return InstrumentClient(new LogsIngestionClient(new Uri(TestEnvironment.DCREndpoint), TestEnvironment.Credential, clientOptions));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ private LogsIngestionClient CreateClient(HttpPipelinePolicy policy = null)
options.AddPolicy(policy, HttpPipelinePosition.PerCall);
}
var clientOptions = InstrumentClientOptions(options);
// Set audience for testing including sovereign cloud support
clientOptions.Audience = TestEnvironment.GetAudience();

return InstrumentClient(new LogsIngestionClient(new Uri(TestEnvironment.DCREndpoint), TestEnvironment.Credential, clientOptions));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using Azure.Core.TestFramework;
using Azure.Identity;

namespace Azure.Monitor.Ingestion.Tests
{
Expand All @@ -16,5 +18,27 @@ public class MonitorIngestionTestEnvironment : TestEnvironment
public string StreamName => GetRecordedVariable("INGESTION_STREAM_NAME");

public string TableName => GetRecordedVariable("INGESTION_TABLE_NAME");

public LogsIngestionAudience GetAudience()
{
Uri authorityHost = new(AuthorityHostUrl);

if (authorityHost == AzureAuthorityHosts.AzurePublicCloud)
{
return LogsIngestionAudience.AzurePublicCloud;
}

if (authorityHost == AzureAuthorityHosts.AzureChina)
{
return LogsIngestionAudience.AzureChina;
}

if (authorityHost == AzureAuthorityHosts.AzureGovernment)
{
return LogsIngestionAudience.AzureGovernment;
}

throw new NotSupportedException($"Cloud for authority host {authorityHost} is not supported.");
}
}
}

0 comments on commit 5fa15a4

Please sign in to comment.