in src/Services/Azure/AppConfig/AppConfigService.cs [16:195]
public class AppConfigService(ISubscriptionService subscriptionService, ITenantService tenantService)
: BaseAzureService(tenantService), IAppConfigService
{
private readonly ISubscriptionService _subscriptionService = subscriptionService ?? throw new ArgumentNullException(nameof(subscriptionService));
public async Task<List<AppConfigurationAccount>> GetAppConfigAccounts(string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null)
{
ValidateRequiredParameters(subscriptionId);
var subscription = await _subscriptionService.GetSubscription(subscriptionId, tenant, retryPolicy);
var accounts = new List<AppConfigurationAccount>();
await foreach (var account in subscription.GetAppConfigurationStoresAsync())
{
ResourceIdentifier resourceId = account.Id;
if (resourceId.ToString().Length == 0)
continue;
var acc = new AppConfigurationAccount
{
Name = account.Data.Name,
Location = account.Data.Location.ToString(),
Endpoint = account.Data.Endpoint,
CreationDate = account.Data.CreatedOn?.DateTime ?? DateTime.MinValue,
PublicNetworkAccess = account.Data.PublicNetworkAccess.HasValue &&
account.Data.PublicNetworkAccess.Value.ToString().Equals("Enabled", StringComparison.OrdinalIgnoreCase),
Sku = account.Data.SkuName,
Tags = account.Data.Tags ?? new Dictionary<string, string>(),
DisableLocalAuth = account.Data.DisableLocalAuth,
SoftDeleteRetentionInDays = account.Data.SoftDeleteRetentionInDays,
EnablePurgeProtection = account.Data.EnablePurgeProtection,
CreateMode = account.Data.CreateMode?.ToString(),
// Map the new managed identity structure
ManagedIdentity = account.Data.Identity == null ? null : new ManagedIdentityInfo
{
SystemAssignedIdentity = new SystemAssignedIdentityInfo
{
Enabled = account.Data.Identity != null,
TenantId = account.Data.Identity?.TenantId?.ToString(),
PrincipalId = account.Data.Identity?.PrincipalId?.ToString()
},
UserAssignedIdentities = account.Data.Identity?.UserAssignedIdentities?
.Select(id => new UserAssignedIdentityInfo
{
ClientId = id.Value.ClientId?.ToString(),
PrincipalId = id.Value.PrincipalId?.ToString()
})
.ToArray()
},
// Full encryption properties from KeyVaultProperties
Encryption = account.Data.EncryptionKeyVaultProperties == null ? null : new EncryptionProperties
{
KeyIdentifier = account.Data.EncryptionKeyVaultProperties.KeyIdentifier,
IdentityClientId = account.Data.EncryptionKeyVaultProperties.IdentityClientId,
}
};
accounts.Add(acc);
}
return accounts;
}
public async Task<List<KeyValueSetting>> ListKeyValues(
string accountName,
string subscriptionId,
string? key = null,
string? label = null,
string? tenant = null,
RetryPolicyArguments? retryPolicy = null)
{
ValidateRequiredParameters(accountName, subscriptionId);
var client = await GetConfigurationClient(accountName, subscriptionId, tenant, retryPolicy);
var settings = new List<KeyValueSetting>();
var selector = new SettingSelector
{
KeyFilter = string.IsNullOrEmpty(key) ? null : key,
LabelFilter = string.IsNullOrEmpty(label) ? null : label
};
await foreach (var setting in client.GetConfigurationSettingsAsync(selector))
{
settings.Add(new KeyValueSetting
{
Key = setting.Key,
Value = setting.Value,
Label = setting.Label ?? string.Empty,
ContentType = setting.ContentType ?? string.Empty,
ETag = new ETag { Value = setting.ETag.ToString() },
LastModified = setting.LastModified,
Locked = setting.IsReadOnly
});
}
return settings;
}
public async Task<KeyValueSetting> GetKeyValue(string accountName, string key, string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null, string? label = null)
{
ValidateRequiredParameters(accountName, key, subscriptionId);
var client = await GetConfigurationClient(accountName, subscriptionId, tenant, retryPolicy);
var response = await client.GetConfigurationSettingAsync(key, label, cancellationToken: default);
var setting = response.Value;
return new KeyValueSetting
{
Key = setting.Key,
Value = setting.Value,
Label = setting.Label ?? string.Empty,
ContentType = setting.ContentType ?? string.Empty,
ETag = new ETag { Value = setting.ETag.ToString() },
LastModified = setting.LastModified,
Locked = setting.IsReadOnly
};
}
public async Task LockKeyValue(string accountName, string key, string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null, string? label = null)
{
await SetKeyValueReadOnlyState(accountName, key, subscriptionId, tenant, retryPolicy, label, true);
}
public async Task UnlockKeyValue(string accountName, string key, string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null, string? label = null)
{
await SetKeyValueReadOnlyState(accountName, key, subscriptionId, tenant, retryPolicy, label, false);
}
public async Task SetKeyValue(string accountName, string key, string value, string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null, string? label = null)
{
ValidateRequiredParameters(accountName, key, value, subscriptionId);
var client = await GetConfigurationClient(accountName, subscriptionId, tenant, retryPolicy);
await client.SetConfigurationSettingAsync(key, value, label, cancellationToken: default);
}
public async Task DeleteKeyValue(string accountName, string key, string subscriptionId, string? tenant = null, RetryPolicyArguments? retryPolicy = null, string? label = null)
{
ValidateRequiredParameters(accountName, key, subscriptionId);
var client = await GetConfigurationClient(accountName, subscriptionId, tenant, retryPolicy);
await client.DeleteConfigurationSettingAsync(key, label, cancellationToken: default);
}
private async Task SetKeyValueReadOnlyState(string accountName, string key, string subscriptionId, string? tenant, RetryPolicyArguments? retryPolicy, string? label, bool isReadOnly)
{
ValidateRequiredParameters(accountName, key, subscriptionId);
var client = await GetConfigurationClient(accountName, subscriptionId, tenant, retryPolicy);
await client.SetReadOnlyAsync(key, label, isReadOnly, cancellationToken: default);
}
private async Task<ConfigurationClient> GetConfigurationClient(string accountName, string subscriptionId, string? tenant, RetryPolicyArguments? retryPolicy)
{
var subscription = await _subscriptionService.GetSubscription(subscriptionId, tenant, retryPolicy);
var configStore = await FindAppConfigStore(subscription, accountName, subscriptionId);
var endpoint = configStore.Data.Endpoint;
var credential = await GetCredential(tenant);
AddDefaultPolicies(new ConfigurationClientOptions());
return new ConfigurationClient(new Uri(endpoint), credential);
}
private static async Task<AppConfigurationStoreResource> FindAppConfigStore(SubscriptionResource subscription, string accountName, string subscriptionId)
{
AppConfigurationStoreResource? configStore = null;
await foreach (var store in subscription.GetAppConfigurationStoresAsync())
{
if (store.Data.Name == accountName)
{
configStore = store;
break;
}
}
if (configStore == null)
throw new Exception($"App Configuration store '{accountName}' not found in subscription '{subscriptionId}'");
return configStore;
}
}