Skip to content
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

[Azure.Monitor.Ingestion] Fix Sovereign Support for Ingestion #39078

Merged
merged 9 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
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 IngestionAudience : System.IEquatable<Azure.Monitor.Ingestion.IngestionAudience>
{
private readonly object _dummy;
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
private readonly int _dummyPrimitive;
public IngestionAudience(string value) { throw null; }
public static Azure.Monitor.Ingestion.IngestionAudience AzureChina { get { throw null; } }
public static Azure.Monitor.Ingestion.IngestionAudience AzureGovernment { get { throw null; } }
public static Azure.Monitor.Ingestion.IngestionAudience AzurePublicCloud { get { throw null; } }
public bool Equals(Azure.Monitor.Ingestion.IngestionAudience 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.IngestionAudience left, Azure.Monitor.Ingestion.IngestionAudience right) { throw null; }
public static implicit operator Azure.Monitor.Ingestion.IngestionAudience (string value) { throw null; }
public static bool operator !=(Azure.Monitor.Ingestion.IngestionAudience left, Azure.Monitor.Ingestion.IngestionAudience 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.IngestionAudience? 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 IngestionAudience : System.IEquatable<Azure.Monitor.Ingestion.IngestionAudience>
{
private readonly object _dummy;
private readonly int _dummyPrimitive;
public IngestionAudience(string value) { throw null; }
public static Azure.Monitor.Ingestion.IngestionAudience AzureChina { get { throw null; } }
public static Azure.Monitor.Ingestion.IngestionAudience AzureGovernment { get { throw null; } }
public static Azure.Monitor.Ingestion.IngestionAudience AzurePublicCloud { get { throw null; } }
public bool Equals(Azure.Monitor.Ingestion.IngestionAudience 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.IngestionAudience left, Azure.Monitor.Ingestion.IngestionAudience right) { throw null; }
public static implicit operator Azure.Monitor.Ingestion.IngestionAudience (string value) { throw null; }
public static bool operator !=(Azure.Monitor.Ingestion.IngestionAudience left, Azure.Monitor.Ingestion.IngestionAudience 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.IngestionAudience? 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/IngestionAudience.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 IngestionAudience : IEquatable<IngestionAudience>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
{
private readonly string _value;

/// <summary>
/// Initializes a new instance of the <see cref="IngestionAudience"/> 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://docs.microsoft.com/azure/azure-government/documentation-government-cognitiveservices" />.</param>
/// <exception cref="ArgumentNullException"> <paramref name="value"/> is null. </exception>
/// <remarks>Please use one of the constant members over creating a custom value unless you have special needs for doing so.</remarks>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
public IngestionAudience(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 IngestionAudience AzureChina { get; } = new IngestionAudience(AzureChinaValue);

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

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

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

/// <inheritdoc />
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) => obj is IngestionAudience other && Equals(other);
/// <inheritdoc />
public bool Equals(IngestionAudience 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;
}
}
22 changes: 22 additions & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/src/LogsIngestionClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -14,13 +15,34 @@ namespace Azure.Monitor.Ingestion
{
/// <summary> The IngestionUsingDataCollectionRules service client. </summary>
[CodeGenClient("IngestionUsingDataCollectionRulesClient")]
[CodeGenSuppress("LogsIngestionClient", typeof(Uri), typeof(TokenCredential), typeof(LogsIngestionClientOptions))]
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
public partial class LogsIngestionClient
{
/// <summary> Initializes a new instance of LogsIngestionClient for mocking. </summary>
protected LogsIngestionClient()
{
}

/// <summary> Initializes a new instance of LogsIngestionClient. </summary>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
/// <param name="endpoint"> The Data Collection Endpoint for the Data Collection Rule, for example https://dce-name.eastus-2.ingest.monitor.azure.com. </param>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
/// <param name="credential"> A credential used to authenticate to an Azure Service. </param>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
/// <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()) ? IngestionAudience.AzurePublicCloud : options.Audience)}";
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
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 LogsIngestionClient. </summary>
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
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.
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
/// </summary>
/// <value>If <c>null</c>, <see cref="IngestionAudience.AzurePublicCloud" /> will be assumed.</value>
public IngestionAudience? Audience { get; set; }
}
}
7 changes: 7 additions & 0 deletions sdk/monitor/Azure.Monitor.Ingestion/src/autorest.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,10 @@ directive:
where: $.paths["/dataCollectionRules/{ruleId}/streams/{stream}"].post.parameters[3]
transform: $["description"] = "If content is already gzipped, put \"gzip\". Default behavior is to gzip all input";
```
### Suppress LogsingestionClient constructor that takes in Options
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
``` yaml
directive:
- from: swagger-document
where: $.definitions.LogsIngestionClient.properties
transform: $["x-ms-client-flatten"] = true;
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
```
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -49,6 +49,9 @@ private LogsIngestionClient CreateClient(HttpPipelinePolicy policy = null)
options.AddPolicy(policy, HttpPipelinePosition.PerCall);
}
var clientOptions = InstrumentClientOptions(options);
// Set audience for testing including soveriegn support clouds
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
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 IngestionAudience GetAudience()
{
Uri authorityHost = new(AuthorityHostUrl);

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

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

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

throw new NotSupportedException($"Cloud for authority host {authorityHost} is not supported.");
nisha-bhatia marked this conversation as resolved.
Show resolved Hide resolved
}
}
}