Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
8 changes: 7 additions & 1 deletion src/Cli.Tests/EnvironmentTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ public class EnvironmentTests
[TestInitialize]
public void TestInitialize()
{
StringJsonConverterFactory converterFactory = new(EnvironmentVariableReplacementFailureMode.Throw);
DeserializationVariableReplacementSettings replacementSettings = new(
azureKeyVaultOptions: null,
doReplaceEnvVar: true,
doReplaceAkvVar: false,
envFailureMode: EnvironmentVariableReplacementFailureMode.Throw);

StringJsonConverterFactory converterFactory = new(replacementSettings);
_options = new()
{
PropertyNameCaseInsensitive = true
Expand Down
1 change: 1 addition & 0 deletions src/Config/Azure.DataApiBuilder.Config.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<ItemGroup>
<PackageReference Include="Azure.Identity" />
<PackageReference Include="Azure.Security.KeyVault.Secrets" />
<PackageReference Include="Microsoft.AspNetCore.Authorization" />
<PackageReference Include="Microsoft.IdentityModel.Protocols" />
<PackageReference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect" />
Expand Down
32 changes: 16 additions & 16 deletions src/Config/Converters/AKVRetryPolicyOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ namespace Azure.DataApiBuilder.Config.Converters;
/// </summary>
internal class AKVRetryPolicyOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
// Currently allows for Azure Key Vault and Environment Variable replacement.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
Expand All @@ -25,27 +25,27 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AKVRetryPolicyOptionsConverter(_replaceEnvVar);
return new AKVRetryPolicyOptionsConverter(_replacementSettings);
}

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AKVRetryPolicyOptionsConverterFactory(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AKVRetryPolicyOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

private class AKVRetryPolicyOptionsConverter : JsonConverter<AKVRetryPolicyOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
// Currently allows for Azure Key Vault and Environment Variable replacement.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AKVRetryPolicyOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public AKVRetryPolicyOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand Down Expand Up @@ -82,7 +82,7 @@ public AKVRetryPolicyOptionsConverter(bool replaceEnvVar)
}
else
{
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replaceEnvVar)!);
mode = EnumExtensions.Deserialize<AKVRetryPolicyMode>(reader.DeserializeString(_replacementSettings)!);
}

break;
Expand Down
113 changes: 113 additions & 0 deletions src/Config/Converters/AzureKeyVaultOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

using System.Text.Json;
using System.Text.Json.Serialization;
using Azure.DataApiBuilder.Config.ObjectModel;

namespace Azure.DataApiBuilder.Config.Converters;

/// <summary>
/// Converter factory for AzureKeyVaultOptions that can optionally perform variable replacement.
/// </summary>
internal class AzureKeyVaultOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AzureKeyVaultOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replacementSettings = replacementSettings;
}

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
{
return typeToConvert.IsAssignableTo(typeof(AzureKeyVaultOptions));
}

/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AzureKeyVaultOptionsConverter(_replacementSettings);
}

private class AzureKeyVaultOptionsConverter : JsonConverter<AzureKeyVaultOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AzureKeyVaultOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replacementSettings = replacementSettings;
}

/// <summary>
/// Reads AzureKeyVaultOptions with optional variable replacement.
/// </summary>
public override AzureKeyVaultOptions? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType is JsonTokenType.Null)
{
return null;
}

if (reader.TokenType is JsonTokenType.StartObject)
{
string? endpoint = null;
AKVRetryPolicyOptions? retryPolicy = null;

while (reader.Read())
{
if (reader.TokenType is JsonTokenType.EndObject)
{
return new AzureKeyVaultOptions
{
Endpoint = endpoint,
RetryPolicy = retryPolicy
};
}

string? property = reader.GetString();
reader.Read();

switch (property)
{
case "endpoint":
if (reader.TokenType is JsonTokenType.String)
{
endpoint = reader.DeserializeString(_replacementSettings);
}

break;

case "retry-policy":
if (reader.TokenType is JsonTokenType.StartObject)
{
// Pass the replaceEnvVar setting to the retry policy converter
retryPolicy = JsonSerializer.Deserialize<AKVRetryPolicyOptions>(ref reader, options);
}

break;

default:
throw new JsonException($"Unexpected property {property}");
}
}
}

throw new JsonException("Invalid AzureKeyVaultOptions format");
}

public override void Write(Utf8JsonWriter writer, AzureKeyVaultOptions value, JsonSerializerOptions options)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What changed in this file?

{
JsonSerializer.Serialize(writer, value, options);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we always want to write the options back into the config? I would expect to only write values if the user wants to do it in the first place.

}
}
}
19 changes: 9 additions & 10 deletions src/Config/Converters/AzureLogAnalyticsAuthOptionsConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,14 @@ namespace Azure.DataApiBuilder.Config.Converters;

internal class AzureLogAnalyticsAuthOptionsConverter : JsonConverter<AzureLogAnalyticsAuthOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public AzureLogAnalyticsAuthOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public AzureLogAnalyticsAuthOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand Down Expand Up @@ -48,23 +47,23 @@ public AzureLogAnalyticsAuthOptionsConverter(bool replaceEnvVar)
case "custom-table-name":
if (reader.TokenType is not JsonTokenType.Null)
{
customTableName = reader.DeserializeString(_replaceEnvVar);
customTableName = reader.DeserializeString(_replacementSettings);
}

break;

case "dcr-immutable-id":
if (reader.TokenType is not JsonTokenType.Null)
{
dcrImmutableId = reader.DeserializeString(_replaceEnvVar);
dcrImmutableId = reader.DeserializeString(_replacementSettings);
}

break;

case "dce-endpoint":
if (reader.TokenType is not JsonTokenType.Null)
{
dceEndpoint = reader.DeserializeString(_replaceEnvVar);
dceEndpoint = reader.DeserializeString(_replacementSettings);
}

break;
Expand Down
32 changes: 15 additions & 17 deletions src/Config/Converters/AzureLogAnalyticsOptionsConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ namespace Azure.DataApiBuilder.Config.Converters;
/// </summary>
internal class AzureLogAnalyticsOptionsConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
Expand All @@ -25,27 +24,26 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new AzureLogAnalyticsOptionsConverter(_replaceEnvVar);
return new AzureLogAnalyticsOptionsConverter(_replacementSettings);
}

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AzureLogAnalyticsOptionsConverterFactory(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AzureLogAnalyticsOptionsConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

private class AzureLogAnalyticsOptionsConverter : JsonConverter<AzureLogAnalyticsOptions>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal AzureLogAnalyticsOptionsConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

/// <summary>
Expand All @@ -57,7 +55,7 @@ internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
{
if (reader.TokenType is JsonTokenType.StartObject)
{
AzureLogAnalyticsAuthOptionsConverter authOptionsConverter = new(_replaceEnvVar);
AzureLogAnalyticsAuthOptionsConverter authOptionsConverter = new(_replacementSettings);

bool? enabled = null;
AzureLogAnalyticsAuthOptions? auth = null;
Expand Down Expand Up @@ -91,7 +89,7 @@ internal AzureLogAnalyticsOptionsConverter(bool replaceEnvVar)
case "dab-identifier":
if (reader.TokenType is not JsonTokenType.Null)
{
logType = reader.DeserializeString(_replaceEnvVar);
logType = reader.DeserializeString(_replacementSettings);
}

break;
Expand Down
34 changes: 16 additions & 18 deletions src/Config/Converters/DataSourceConverterFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@ namespace Azure.DataApiBuilder.Config.Converters;

internal class DataSourceConverterFactory : JsonConverterFactory
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <inheritdoc/>
public override bool CanConvert(Type typeToConvert)
Expand All @@ -22,27 +21,26 @@ public override bool CanConvert(Type typeToConvert)
/// <inheritdoc/>
public override JsonConverter? CreateConverter(Type typeToConvert, JsonSerializerOptions options)
{
return new DataSourceConverter(_replaceEnvVar);
return new DataSourceConverter(_replacementSettings);
}

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
internal DataSourceConverterFactory(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
internal DataSourceConverterFactory(DeserializationVariableReplacementSettings? replacementSettings = null)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

private class DataSourceConverter : JsonConverter<DataSource>
{
// Determines whether to replace environment variable with its
// value or not while deserializing.
private bool _replaceEnvVar;
// Settings for variable replacement during deserialization.
private readonly DeserializationVariableReplacementSettings? _replacementSettings;

/// <param name="replaceEnvVar">Whether to replace environment variable with its
/// value or not while deserializing.</param>
public DataSourceConverter(bool replaceEnvVar)
/// <param name="replacementSettings">Settings for variable replacement during deserialization.
/// If null, no variable replacement will be performed.</param>
public DataSourceConverter(DeserializationVariableReplacementSettings? replacementSettings)
{
_replaceEnvVar = replaceEnvVar;
_replacementSettings = replacementSettings;
}

public override DataSource? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
Expand All @@ -69,11 +67,11 @@ public DataSourceConverter(bool replaceEnvVar)
switch (propertyName)
{
case "database-type":
databaseType = EnumExtensions.Deserialize<DatabaseType>(reader.DeserializeString(_replaceEnvVar)!);
databaseType = EnumExtensions.Deserialize<DatabaseType>(reader.DeserializeString(_replacementSettings)!);
break;

case "connection-string":
connectionString = reader.DeserializeString(replaceEnvVar: _replaceEnvVar)!;
connectionString = reader.DeserializeString(_replacementSettings)!;
break;

case "health":
Expand Down Expand Up @@ -106,7 +104,7 @@ public DataSourceConverter(bool replaceEnvVar)
if (reader.TokenType is JsonTokenType.String)
{
// Determine whether to resolve the environment variable or keep as-is.
string stringValue = reader.DeserializeString(replaceEnvVar: _replaceEnvVar)!;
string stringValue = reader.DeserializeString(_replacementSettings)!;

if (bool.TryParse(stringValue, out bool boolValue))
{
Expand Down
Loading
Loading