diff --git a/DirectConnector/ArmFunctions.cs b/DirectConnector/ArmFunctions.cs new file mode 100644 index 0000000..eabe86e --- /dev/null +++ b/DirectConnector/ArmFunctions.cs @@ -0,0 +1,267 @@ +//------------------------------------------------------------ +// Copyright (c) Microsoft Corporation. All rights reserved. +//------------------------------------------------------------ + +using System.Net; +using System.Text.Json; +using Microsoft.Azure.Connectors.Sdk.Arm; +using Microsoft.Azure.Connectors.Sdk; +using Microsoft.Azure.Functions.Worker; +using Microsoft.Azure.Functions.Worker.Http; +using Microsoft.Extensions.Logging; + +namespace DirectConnector; + +/// +/// Azure Functions demonstrating Azure Resource Manager operations using the generated +/// from the DirectClient SDK. +/// +/// +/// ARM connector uses OAuth (user-delegated Azure AD token). +/// The connection requires OAuth consent via the consent link flow. +/// +public class ArmFunctions +{ + private static readonly JsonSerializerOptions JsonOptions = new() + { + PropertyNameCaseInsensitive = true + }; + + private readonly ILogger _logger; + private readonly ArmClient _armClient; + + public ArmFunctions( + ILogger logger, + ArmClient armClient) + { + this._logger = logger; + this._armClient = armClient; + } + + /// + /// Lists all subscriptions accessible to the authenticated user. + /// + [Function("ListSubscriptions")] + public async Task ListSubscriptionsAsync( + [HttpTrigger(AuthorizationLevel.Function, "get", Route = "arm/subscriptions")] HttpRequestData request, + CancellationToken cancellationToken) + { + this._logger.LogInformation("ListSubscriptions: Using generated ArmClient."); + + try + { + var subscriptions = new List(); + await foreach (var subscription in this._armClient + .SubscriptionsListAsync() + .WithCancellation(cancellationToken) + .ConfigureAwait(continueOnCapturedContext: false)) + { + subscriptions.Add(subscription); + } + + this._logger.LogInformation("Found '{Count}' subscriptions.", subscriptions.Count); + + var response = request.CreateResponse(HttpStatusCode.OK); + await response + .WriteAsJsonAsync(subscriptions) + .ConfigureAwait(continueOnCapturedContext: false); + return response; + } + catch (ConnectorException ex) + { + this._logger.LogError(ex, "ARM connector error: '{StatusCode}'.", ex.StatusCode); + + var errorResponse = request.CreateResponse(HttpStatusCode.BadGateway); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message, statusCode = ex.StatusCode, details = ex.ResponseBody }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + catch (Exception ex) when (!ex.IsFatal()) + { + this._logger.LogError(ex, "Error in ListSubscriptions."); + + var errorResponse = request.CreateResponse(HttpStatusCode.InternalServerError); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + } + + /// + /// Lists resource groups in a subscription. + /// + [Function("ListResourceGroups")] + public async Task ListResourceGroupsAsync( + [HttpTrigger(AuthorizationLevel.Function, "get", Route = "arm/subscriptions/{subscriptionId}/resourcegroups")] HttpRequestData request, + string subscriptionId, + CancellationToken cancellationToken) + { + this._logger.LogInformation("ListResourceGroups: subscription='{SubscriptionId}'.", subscriptionId); + + try + { + var resourceGroups = new List(); + await foreach (var resourceGroup in this._armClient + .ResourceGroupsListAsync(subscription: subscriptionId) + .WithCancellation(cancellationToken) + .ConfigureAwait(continueOnCapturedContext: false)) + { + resourceGroups.Add(resourceGroup); + } + + this._logger.LogInformation("Found '{Count}' resource groups.", resourceGroups.Count); + + var response = request.CreateResponse(HttpStatusCode.OK); + await response + .WriteAsJsonAsync(resourceGroups) + .ConfigureAwait(continueOnCapturedContext: false); + return response; + } + catch (ConnectorException ex) + { + this._logger.LogError(ex, "ARM connector error: '{StatusCode}'.", ex.StatusCode); + + var errorResponse = request.CreateResponse(HttpStatusCode.BadGateway); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message, statusCode = ex.StatusCode, details = ex.ResponseBody }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + catch (Exception ex) when (!ex.IsFatal()) + { + this._logger.LogError(ex, "Error in ListResourceGroups."); + + var errorResponse = request.CreateResponse(HttpStatusCode.InternalServerError); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + } + + /// + /// Reads a specific resource by its resource group, provider, and short resource ID. + /// + [Function("ReadResource")] + public async Task ReadResourceAsync( + [HttpTrigger(AuthorizationLevel.Function, "get", Route = "arm/resource")] HttpRequestData request, + CancellationToken cancellationToken) + { + var subscriptionId = request.Query["subscriptionId"]; + var resourceGroup = request.Query["resourceGroup"]; + var provider = request.Query["provider"]; + var shortResourceId = request.Query["shortResourceId"]; + var apiVersion = request.Query["apiVersion"]; + + if (string.IsNullOrWhiteSpace(subscriptionId) || + string.IsNullOrWhiteSpace(resourceGroup) || + string.IsNullOrWhiteSpace(provider) || + string.IsNullOrWhiteSpace(shortResourceId) || + string.IsNullOrWhiteSpace(apiVersion)) + { + var badRequest = request.CreateResponse(HttpStatusCode.BadRequest); + await badRequest + .WriteAsJsonAsync(new { error = "Query parameters 'subscriptionId', 'resourceGroup', 'provider', 'shortResourceId', and 'apiVersion' are required." }) + .ConfigureAwait(continueOnCapturedContext: false); + return badRequest; + } + + this._logger.LogInformation("ReadResource: '{Provider}/{ShortResourceId}' in '{ResourceGroup}'.", provider, shortResourceId, resourceGroup); + + try + { + var resource = await this._armClient + .ResourcesGetByIdAsync( + subscription: subscriptionId, + resourceGroup: resourceGroup, + resourceProvider: provider, + shortResourceId: shortResourceId, + clientApiVersion: apiVersion, + cancellationToken: cancellationToken) + .ConfigureAwait(continueOnCapturedContext: false); + + this._logger.LogInformation("Read resource '{Name}' of type '{Type}'.", resource.Name, resource.Type); + + var response = request.CreateResponse(HttpStatusCode.OK); + await response + .WriteAsJsonAsync(resource) + .ConfigureAwait(continueOnCapturedContext: false); + return response; + } + catch (ConnectorException ex) + { + this._logger.LogError(ex, "ARM connector error: '{StatusCode}'.", ex.StatusCode); + + var errorResponse = request.CreateResponse(HttpStatusCode.BadGateway); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message, statusCode = ex.StatusCode, details = ex.ResponseBody }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + catch (Exception ex) when (!ex.IsFatal()) + { + this._logger.LogError(ex, "Error in ReadResource."); + + var errorResponse = request.CreateResponse(HttpStatusCode.InternalServerError); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + } + + /// + /// Lists resources in a resource group. + /// + [Function("ListResourcesByResourceGroup")] + public async Task ListResourcesByResourceGroupAsync( + [HttpTrigger(AuthorizationLevel.Function, "get", Route = "arm/subscriptions/{subscriptionId}/resourcegroups/{resourceGroupName}/resources")] HttpRequestData request, + string subscriptionId, + string resourceGroupName, + CancellationToken cancellationToken) + { + this._logger.LogInformation("ListResourcesByResourceGroup: subscription='{SubscriptionId}', resourceGroup='{ResourceGroup}'.", subscriptionId, resourceGroupName); + + try + { + var resources = new List(); + await foreach (var resource in this._armClient + .ResourceGroupsListResourcesAsync(subscription: subscriptionId, resourceGroup: resourceGroupName) + .WithCancellation(cancellationToken) + .ConfigureAwait(continueOnCapturedContext: false)) + { + resources.Add(resource); + } + + this._logger.LogInformation("Found '{Count}' resources.", resources.Count); + + var response = request.CreateResponse(HttpStatusCode.OK); + await response + .WriteAsJsonAsync(resources) + .ConfigureAwait(continueOnCapturedContext: false); + return response; + } + catch (ConnectorException ex) + { + this._logger.LogError(ex, "ARM connector error: '{StatusCode}'.", ex.StatusCode); + + var errorResponse = request.CreateResponse(HttpStatusCode.BadGateway); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message, statusCode = ex.StatusCode, details = ex.ResponseBody }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + catch (Exception ex) when (!ex.IsFatal()) + { + this._logger.LogError(ex, "Error in ListResourcesByResourceGroup."); + + var errorResponse = request.CreateResponse(HttpStatusCode.InternalServerError); + await errorResponse + .WriteAsJsonAsync(new { success = false, error = ex.Message }) + .ConfigureAwait(continueOnCapturedContext: false); + return errorResponse; + } + } +} diff --git a/DirectConnector/AzureBlobFunctions.cs b/DirectConnector/AzureBlobFunctions.cs index 4dc8c38..74d6ae1 100644 --- a/DirectConnector/AzureBlobFunctions.cs +++ b/DirectConnector/AzureBlobFunctions.cs @@ -3,7 +3,7 @@ //------------------------------------------------------------ using System.Net; -using Microsoft.Azure.Connectors.DirectClient.Azureblob; +using Microsoft.Azure.Connectors.Sdk.Azureblob; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -71,7 +71,7 @@ await response .ConfigureAwait(continueOnCapturedContext: false); return response; } - catch (AzureblobConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Azure Blob connector error: '{StatusCode}'.", ex.StatusCode); @@ -140,7 +140,7 @@ await response.Body return response; } - catch (AzureblobConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Azure Blob connector error: '{StatusCode}'.", ex.StatusCode); @@ -210,7 +210,7 @@ await response .ConfigureAwait(continueOnCapturedContext: false); return response; } - catch (AzureblobConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Azure Blob connector error: '{StatusCode}'.", ex.StatusCode); @@ -271,7 +271,7 @@ await response .ConfigureAwait(continueOnCapturedContext: false); return response; } - catch (AzureblobConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Azure Blob connector error: '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/AzureLogAnalyticsFunctions.cs b/DirectConnector/AzureLogAnalyticsFunctions.cs index 04f3492..9ff5298 100644 --- a/DirectConnector/AzureLogAnalyticsFunctions.cs +++ b/DirectConnector/AzureLogAnalyticsFunctions.cs @@ -3,7 +3,7 @@ //------------------------------------------------------------ using System.Net; -using Microsoft.Azure.Connectors.DirectClient.Azureloganalytics; +using Microsoft.Azure.Connectors.Sdk.Azuremonitorlogs; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -13,16 +13,16 @@ namespace DirectConnector; /// /// Azure Functions demonstrating Azure Log Analytics operations using the generated -/// from the DirectClient SDK. +/// from the DirectClient SDK. /// public class AzureLogAnalyticsFunctions { private readonly ILogger _logger; - private readonly AzureloganalyticsClient _logAnalyticsClient; + private readonly AzuremonitorlogsClient _logAnalyticsClient; public AzureLogAnalyticsFunctions( ILogger logger, - AzureloganalyticsClient logAnalyticsClient) + AzuremonitorlogsClient logAnalyticsClient) { this._logger = logger; this._logAnalyticsClient = logAnalyticsClient; @@ -37,7 +37,7 @@ public async Task ListSubscriptionsAsync( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "loganalytics/subscriptions")] HttpRequestData request, CancellationToken cancellationToken) { - this._logger.LogInformation("ListLogAnalyticsSubscriptions: Using generated AzureloganalyticsClient from SDK."); + this._logger.LogInformation("ListLogAnalyticsSubscriptions: Using generated AzuremonitorlogsClient from SDK."); try { @@ -57,7 +57,7 @@ await response return response; } - catch (AzureloganalyticsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "ListLogAnalyticsSubscriptions failed with status '{StatusCode}'.", ex.StatusCode); @@ -94,7 +94,7 @@ public async Task ListWorkspacesAsync( [HttpTrigger(AuthorizationLevel.Function, "get", Route = "loganalytics/workspaces")] HttpRequestData request, CancellationToken cancellationToken) { - this._logger.LogInformation("ListLogAnalyticsWorkspaces: Using generated AzureloganalyticsClient from SDK."); + this._logger.LogInformation("ListLogAnalyticsWorkspaces: Using generated AzuremonitorlogsClient from SDK."); var subscription = request.Query["subscription"]; var resourceGroup = request.Query["resourceGroup"]; @@ -111,10 +111,10 @@ await badRequest try { - // Note: SDK returns ResourceGroup type for workspace entries per the connector API schema - var workspaces = new List(); + // Note: SDK returns ResourceItem type for workspace entries per the connector API schema + var workspaces = new List(); await foreach (var workspace in this._logAnalyticsClient - .ListWorkspaceNamesAsync(subscription: subscription, resourceGroup: resourceGroup) + .ListResourcesAsync(subscription: subscription, resourceGroup: resourceGroup, resourceType: "Microsoft.OperationalInsights/workspaces") .WithCancellation(cancellationToken) .ConfigureAwait(continueOnCapturedContext: false)) { @@ -128,7 +128,7 @@ await response return response; } - catch (AzureloganalyticsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "ListLogAnalyticsWorkspaces failed with status '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/Configuration/ConnectorOptions.cs b/DirectConnector/Configuration/ConnectorOptions.cs index 4e57886..1924336 100644 --- a/DirectConnector/Configuration/ConnectorOptions.cs +++ b/DirectConnector/Configuration/ConnectorOptions.cs @@ -47,6 +47,12 @@ public class ConnectorOptions [ValidateObjectMembers] public MsGraphOptions MsGraph { get; set; } = new MsGraphOptions(); + /// + /// Azure Resource Manager (ARM) connector options. + /// + [ValidateObjectMembers] + public ArmOptions Arm { get; set; } = new ArmOptions(); + /// /// Azure Blob Storage connector options. /// @@ -267,3 +273,22 @@ public class AzureLogAnalyticsOptions /// public string? ManagedIdentityClientId { get; set; } } + +/// +/// Configuration options for the Azure Resource Manager (ARM) connector. +/// +public class ArmOptions +{ + /// + /// The API connection runtime URL for Azure Resource Manager. + /// + [Required(ErrorMessage = "Connectors:Arm:ConnectionRuntimeUrl is required.")] + public string ConnectionRuntimeUrl { get; set; } = string.Empty; + + /// + /// Managed identity client ID for user-assigned identity. + /// Set to empty string for system-assigned managed identity. + /// Leave unset (null) to use the DefaultAzureCredential chain (CLI, env vars, etc.). + /// + public string? ManagedIdentityClientId { get; set; } +} diff --git a/DirectConnector/ConnectorFunctions.cs b/DirectConnector/ConnectorFunctions.cs index 81b52a1..83f82ee 100644 --- a/DirectConnector/ConnectorFunctions.cs +++ b/DirectConnector/ConnectorFunctions.cs @@ -5,14 +5,14 @@ using System.Net; using System.Text; using System.Text.Json; -using Microsoft.Azure.Connectors.DirectClient.Office365; -using Microsoft.Azure.Connectors.DirectClient.Sharepointonline; -using Microsoft.Azure.Connectors.DirectClient.Teams; +using Microsoft.Azure.Connectors.Sdk.Office365; +using Microsoft.Azure.Connectors.Sdk.Sharepointonline; +using Microsoft.Azure.Connectors.Sdk.Teams; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; -using SharePointBlobMetadata = Microsoft.Azure.Connectors.DirectClient.Sharepointonline.BlobMetadata; +using SharePointBlobMetadata = Microsoft.Azure.Connectors.Sdk.Sharepointonline.BlobMetadata; namespace DirectConnector; @@ -148,7 +148,7 @@ await response return response; } - catch (Office365ConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Connector error: '{StatusCode}'.", ex.StatusCode); @@ -212,7 +212,7 @@ await response return response; } - catch (Office365ConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Connector error: '{StatusCode}'.", ex.StatusCode); @@ -290,7 +290,7 @@ await response return response; } - catch (SharepointonlineConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SharePoint connector error: '{StatusCode}'.", ex.StatusCode); @@ -386,7 +386,7 @@ await response return response; } - catch (SharepointonlineConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SharePoint connector error: '{StatusCode}'.", ex.StatusCode); @@ -471,7 +471,7 @@ await response.Body return response; } - catch (SharepointonlineConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SharePoint connector error: '{StatusCode}'.", ex.StatusCode); @@ -593,7 +593,7 @@ await response return response; } - catch (SharepointonlineConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SharePoint connector error: '{StatusCode}'.", ex.StatusCode); @@ -670,7 +670,7 @@ await response.Body return response; } - catch (Office365ConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Connector error: '{StatusCode}'.", ex.StatusCode); @@ -928,7 +928,7 @@ await response return response; } - catch (TeamsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Teams connector error: '{StatusCode}'.", ex.StatusCode); @@ -1005,7 +1005,7 @@ await response return response; } - catch (TeamsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Teams connector error: '{StatusCode}'.", ex.StatusCode); @@ -1098,7 +1098,7 @@ await response return response; } - catch (TeamsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Teams connector error: '{StatusCode}'.", ex.StatusCode); @@ -1178,7 +1178,7 @@ await badRequest // The actual message body properties are determined at runtime by the connector's schema // discovery endpoint. With [JsonExtensionData] on AdditionalProperties, arbitrary properties // are now serialized correctly. Populate the dictionary with the expected message fields. - var messageRequest = new Microsoft.Azure.Connectors.DirectClient.Teams.DynamicPostMessageRequest(); + var messageRequest = new Microsoft.Azure.Connectors.Sdk.Teams.DynamicPostMessageRequest(); messageRequest.AdditionalProperties["recipient"] = JsonSerializer.SerializeToElement( new { @@ -1210,7 +1210,7 @@ await response return response; } - catch (TeamsConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Teams connector error: '{StatusCode}'.", ex.StatusCode); @@ -1323,7 +1323,7 @@ await response return response; } - catch (Office365ConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "Connector error: '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/ConnectorTriggerMetadataAttribute.cs b/DirectConnector/ConnectorTriggerMetadataAttribute.cs index fd4ac8e..a9e98fc 100644 --- a/DirectConnector/ConnectorTriggerMetadataAttribute.cs +++ b/DirectConnector/ConnectorTriggerMetadataAttribute.cs @@ -34,7 +34,7 @@ public sealed class ConnectorTriggerMetadataAttribute : Attribute /// /// The trigger operation name. Use constants from the connector's *TriggerOperations class - /// (e.g., ). + /// (e.g., ). /// public string OperationName { get; set; } = ""; diff --git a/DirectConnector/DirectConnector.csproj b/DirectConnector/DirectConnector.csproj index 25131d0..28e0ea5 100644 --- a/DirectConnector/DirectConnector.csproj +++ b/DirectConnector/DirectConnector.csproj @@ -14,7 +14,7 @@ - + diff --git a/DirectConnector/MqFunctions.cs b/DirectConnector/MqFunctions.cs index f5a1918..2bcb4af 100644 --- a/DirectConnector/MqFunctions.cs +++ b/DirectConnector/MqFunctions.cs @@ -4,7 +4,7 @@ using System.Net; using System.Text.Json; -using Microsoft.Azure.Connectors.DirectClient.Mq; +using Microsoft.Azure.Connectors.Sdk.Mq; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -85,7 +85,7 @@ await response return response; } - catch (MqConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MQ send failed with status '{StatusCode}'.", ex.StatusCode); @@ -156,7 +156,7 @@ await response return response; } - catch (MqConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MQ browse failed with status '{StatusCode}'.", ex.StatusCode); @@ -231,7 +231,7 @@ await response return response; } - catch (MqConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MQ browse batch failed with status '{StatusCode}'.", ex.StatusCode); @@ -302,7 +302,7 @@ await response return response; } - catch (MqConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MQ receive failed with status '{StatusCode}'.", ex.StatusCode); @@ -378,7 +378,7 @@ await response return response; } - catch (MqConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MQ delete failed with status '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/MsGraphFunctions.cs b/DirectConnector/MsGraphFunctions.cs index 7be6cbb..0c28171 100644 --- a/DirectConnector/MsGraphFunctions.cs +++ b/DirectConnector/MsGraphFunctions.cs @@ -3,7 +3,7 @@ //------------------------------------------------------------ using System.Net; -using Microsoft.Azure.Connectors.DirectClient.Msgraphgroupsanduser; +using Microsoft.Azure.Connectors.Sdk.Msgraphgroupsanduser; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -66,7 +66,7 @@ await response return response; } - catch (MsgraphgroupsanduserConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MS Graph connector error: '{StatusCode}'.", ex.StatusCode); @@ -130,7 +130,7 @@ await response return response; } - catch (MsgraphgroupsanduserConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MS Graph connector error: '{StatusCode}'.", ex.StatusCode); @@ -206,7 +206,7 @@ await response return response; } - catch (MsgraphgroupsanduserConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "MS Graph connector error: '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/Office365UsersFunctions.cs b/DirectConnector/Office365UsersFunctions.cs index d6d4d41..c9ad1ec 100644 --- a/DirectConnector/Office365UsersFunctions.cs +++ b/DirectConnector/Office365UsersFunctions.cs @@ -3,7 +3,7 @@ //------------------------------------------------------------ using System.Net; -using Microsoft.Azure.Connectors.DirectClient.Office365users; +using Microsoft.Azure.Connectors.Sdk.Office365users; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -48,7 +48,7 @@ await response return response; } - catch (Office365usersConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "GetMyProfile failed with status '{StatusCode}'.", ex.StatusCode); @@ -97,7 +97,7 @@ await response return response; } - catch (Office365usersConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "GetUserProfile failed with status '{StatusCode}'.", ex.StatusCode); @@ -146,7 +146,7 @@ await response return response; } - catch (Office365usersConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "GetManager failed with status '{StatusCode}'.", ex.StatusCode); @@ -195,7 +195,7 @@ await response return response; } - catch (Office365usersConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "GetDirectReports failed with status '{StatusCode}'.", ex.StatusCode); @@ -260,7 +260,7 @@ await response return response; } - catch (Office365usersConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SearchUsers failed with status '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/OneDriveFunctions.cs b/DirectConnector/OneDriveFunctions.cs index f46dbdc..c61e9ac 100644 --- a/DirectConnector/OneDriveFunctions.cs +++ b/DirectConnector/OneDriveFunctions.cs @@ -5,12 +5,12 @@ using System.Net; using System.Text; using System.Text.Json; -using Microsoft.Azure.Connectors.DirectClient.Onedriveforbusiness; +using Microsoft.Azure.Connectors.Sdk.Onedriveforbusiness; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; using Microsoft.Extensions.Logging; -using OneDriveBlobMetadata = Microsoft.Azure.Connectors.DirectClient.Onedriveforbusiness.BlobMetadata; +using OneDriveBlobMetadata = Microsoft.Azure.Connectors.Sdk.Onedriveforbusiness.BlobMetadata; namespace DirectConnector; @@ -103,7 +103,7 @@ await response return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); @@ -194,7 +194,7 @@ await response return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); @@ -272,7 +272,7 @@ await response.Body return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); @@ -391,7 +391,7 @@ await response return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); @@ -477,7 +477,7 @@ await response return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); @@ -577,7 +577,7 @@ await response return response; } - catch (OnedriveforbusinessConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "OneDrive connector error: '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/Program.cs b/DirectConnector/Program.cs index e88984c..c21e19b 100644 --- a/DirectConnector/Program.cs +++ b/DirectConnector/Program.cs @@ -3,16 +3,17 @@ //------------------------------------------------------------ using DirectConnector.Configuration; -using Microsoft.Azure.Connectors.DirectClient.Azureblob; -using Microsoft.Azure.Connectors.DirectClient.Azureloganalytics; -using Microsoft.Azure.Connectors.DirectClient.Mq; -using Microsoft.Azure.Connectors.DirectClient.Msgraphgroupsanduser; -using Microsoft.Azure.Connectors.DirectClient.Office365; -using Microsoft.Azure.Connectors.DirectClient.Office365users; -using Microsoft.Azure.Connectors.DirectClient.Onedriveforbusiness; -using Microsoft.Azure.Connectors.DirectClient.Sharepointonline; -using Microsoft.Azure.Connectors.DirectClient.Smtp; -using Microsoft.Azure.Connectors.DirectClient.Teams; +using Microsoft.Azure.Connectors.Sdk.Arm; +using Microsoft.Azure.Connectors.Sdk.Azureblob; +using Microsoft.Azure.Connectors.Sdk.Azuremonitorlogs; +using Microsoft.Azure.Connectors.Sdk.Mq; +using Microsoft.Azure.Connectors.Sdk.Msgraphgroupsanduser; +using Microsoft.Azure.Connectors.Sdk.Office365; +using Microsoft.Azure.Connectors.Sdk.Office365users; +using Microsoft.Azure.Connectors.Sdk.Onedriveforbusiness; +using Microsoft.Azure.Connectors.Sdk.Sharepointonline; +using Microsoft.Azure.Connectors.Sdk.Smtp; +using Microsoft.Azure.Connectors.Sdk.Teams; using Microsoft.Azure.Functions.Worker; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -146,15 +147,26 @@ : new Office365usersClient(options.Office365Users.ConnectionRuntimeUrl); }); - services.AddSingleton(serviceProvider => + services.AddSingleton(serviceProvider => { var options = serviceProvider.GetRequiredService>().Value; return options.AzureLogAnalytics.ManagedIdentityClientId != null - ? new AzureloganalyticsClient( + ? new AzuremonitorlogsClient( options.AzureLogAnalytics.ConnectionRuntimeUrl, options.AzureLogAnalytics.ManagedIdentityClientId) - : new AzureloganalyticsClient(options.AzureLogAnalytics.ConnectionRuntimeUrl); + : new AzuremonitorlogsClient(options.AzureLogAnalytics.ConnectionRuntimeUrl); + }); + + services.AddSingleton(serviceProvider => + { + var options = serviceProvider.GetRequiredService>().Value; + + return options.Arm.ManagedIdentityClientId != null + ? new ArmClient( + options.Arm.ConnectionRuntimeUrl, + options.Arm.ManagedIdentityClientId) + : new ArmClient(options.Arm.ConnectionRuntimeUrl); }); }) .Build(); diff --git a/DirectConnector/SmtpFunctions.cs b/DirectConnector/SmtpFunctions.cs index d84a1ce..9acc5ec 100644 --- a/DirectConnector/SmtpFunctions.cs +++ b/DirectConnector/SmtpFunctions.cs @@ -4,7 +4,7 @@ using System.Net; using System.Text.Json; -using Microsoft.Azure.Connectors.DirectClient.Smtp; +using Microsoft.Azure.Connectors.Sdk.Smtp; using Microsoft.Azure.Connectors.Sdk; using Microsoft.Azure.Functions.Worker; using Microsoft.Azure.Functions.Worker.Http; @@ -91,7 +91,7 @@ await response return response; } - catch (SmtpConnectorException ex) + catch (ConnectorException ex) { this._logger.LogError(ex, "SMTP connector error: '{StatusCode}'.", ex.StatusCode); diff --git a/DirectConnector/local.settings.json.template b/DirectConnector/local.settings.json.template index e068f83..404f0f7 100644 --- a/DirectConnector/local.settings.json.template +++ b/DirectConnector/local.settings.json.template @@ -42,6 +42,10 @@ "Connectors:AzureLogAnalytics:ConnectionRuntimeUrl": "https://YOUR-INSTANCE.azure-apihub.net/apim/azureloganalytics/YOUR-CONNECTION-ID", "__comment_AzureLogAnalytics_MSI": "To use managed identity, remove the __ prefix from the key below. Use empty string for system-assigned MSI, or a client ID GUID for user-assigned MSI.", - "__Connectors:AzureLogAnalytics:ManagedIdentityClientId": "" + "__Connectors:AzureLogAnalytics:ManagedIdentityClientId": "", + + "Connectors:Arm:ConnectionRuntimeUrl": "https://YOUR-INSTANCE.azure-apihub.net/apim/arm/YOUR-CONNECTION-ID", + "__comment_Arm_MSI": "To use managed identity, remove the __ prefix from the key below. Use empty string for system-assigned MSI, or a client ID GUID for user-assigned MSI.", + "__Connectors:Arm:ManagedIdentityClientId": "" } } diff --git a/NuGet.config b/NuGet.config index 765346e..1eae719 100644 --- a/NuGet.config +++ b/NuGet.config @@ -2,6 +2,7 @@ +