-
Notifications
You must be signed in to change notification settings - Fork 510
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
Update Azure.Provisioning to latest #6390
Changes from 11 commits
2738bc9
d06321c
88c15fb
4912749
5c9f739
44ee80e
b1b7194
aeba560
94ffd45
184a67a
100cb4a
0adc809
2add4c1
5e94eca
b1760c1
9d32d30
ccb1355
5ffb437
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,6 @@ | |
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Globalization; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
using Aspire.Hosting.ApplicationModel; | ||
using Aspire.Hosting.Lifecycle; | ||
|
@@ -143,7 +142,7 @@ public void BuildContainerApp(AzureResourceInfrastructure c) | |
containerImageParam = AllocateContainerImageParameter(); | ||
} | ||
|
||
var containerAppResource = new ContainerApp(Infrastructure.NormalizeIdentifierName(resource.Name)) | ||
var containerAppResource = new ContainerApp(Infrastructure.NormalizeBicepIdentifier(resource.Name)) | ||
{ | ||
Name = resource.Name.ToLowerInvariant() | ||
}; | ||
|
@@ -180,7 +179,7 @@ public void BuildContainerApp(AzureResourceInfrastructure c) | |
var containerAppContainer = new ContainerAppContainer(); | ||
template.Containers = [containerAppContainer]; | ||
|
||
containerAppContainer.Image = containerImageParam is null ? containerImageName : containerImageParam; | ||
containerAppContainer.Image = containerImageParam is null ? containerImageName! : containerImageParam; | ||
containerAppContainer.Name = resource.Name; | ||
|
||
AddEnvironmentVariablesAndCommandLineArgs(containerAppContainer); | ||
|
@@ -484,7 +483,8 @@ private async Task ProcessEnvironmentAsync(DistributedApplicationExecutionContex | |
{ | ||
var managedIdentityParameter = AllocateManagedIdentityIdParameter(); | ||
secret.Identity = managedIdentityParameter; | ||
secret.KeyVaultUri = new BicepValue<Uri>(argValue.Expression!); | ||
// TODO: this should be able to use ToUri(), but it hit an issue | ||
secret.KeyVaultUri = new BicepValue<Uri>(((BicepExpression?)argValue)!); | ||
} | ||
else | ||
{ | ||
|
@@ -518,7 +518,6 @@ private static BicepValue<string> ResolveValue(object val) | |
{ | ||
BicepValue<string> s => s, | ||
string s => s, | ||
BicepValueFormattableString fs => Interpolate(fs), | ||
ProvisioningParameter p => p, | ||
_ => throw new NotSupportedException("Unsupported value type " + val.GetType()) | ||
}; | ||
|
@@ -685,7 +684,7 @@ BicepValue<string> GetHostValue(string? prefix = null, string? suffix = null) | |
args[index++] = val; | ||
} | ||
|
||
return (new BicepValueFormattableString(expr.Format, args), finalSecretType); | ||
return (Interpolate(expr.Format, args), finalSecretType); | ||
|
||
} | ||
|
||
|
@@ -701,7 +700,7 @@ private BicepValue<string> AllocateKeyVaultSecretUriReference(BicepSecretOutputR | |
{ | ||
// We resolve the keyvault that represents the storage for secret outputs | ||
var parameter = AllocateParameter(SecretOutputExpression.GetSecretOutputKeyVault(secretOutputReference.Resource)); | ||
kv = KeyVaultService.FromExisting($"{parameter.IdentifierName}_kv"); | ||
kv = KeyVaultService.FromExisting($"{parameter.BicepIdentifier}_kv"); | ||
kv.Name = parameter; | ||
|
||
KeyVaultRefs[secretOutputReference.Resource.Name] = kv; | ||
|
@@ -710,19 +709,15 @@ private BicepValue<string> AllocateKeyVaultSecretUriReference(BicepSecretOutputR | |
if (!KeyVaultSecretRefs.TryGetValue(secretOutputReference.ValueExpression, out var secret)) | ||
{ | ||
// Now we resolve the secret | ||
var secretIdentifierName = Infrastructure.NormalizeIdentifierName($"{kv.IdentifierName}_{secretOutputReference.Name}"); | ||
secret = KeyVaultSecret.FromExisting(secretIdentifierName); | ||
var secretBicepIdentifier = Infrastructure.NormalizeBicepIdentifier($"{kv.BicepIdentifier}_{secretOutputReference.Name}"); | ||
secret = KeyVaultSecret.FromExisting(secretBicepIdentifier); | ||
secret.Name = secretOutputReference.Name; | ||
secret.Parent = kv; | ||
|
||
KeyVaultSecretRefs[secretOutputReference.ValueExpression] = secret; | ||
} | ||
|
||
// TODO: There should be a better way to do this? | ||
return new MemberExpression( | ||
new MemberExpression( | ||
new IdentifierExpression(secret.IdentifierName), "properties"), | ||
"secretUri"); | ||
return secret.Properties.SecretUri; | ||
} | ||
|
||
private ProvisioningParameter AllocateContainerImageParameter() | ||
|
@@ -882,81 +877,45 @@ private void AddContainerRegistryParameters(ContainerAppConfiguration app) | |
} | ||
} | ||
|
||
// REVIEW: BicepFunction.Interpolate is buggy and doesn't handle nested formattable strings correctly | ||
// This is a workaround to handle nested formattable strings until the bug is fixed. | ||
private static BicepValue<string> Interpolate(BicepValueFormattableString text) | ||
private static BicepValue<string> Interpolate(string format, object[] args) | ||
{ | ||
var formatStringBuilder = new StringBuilder(); | ||
var arguments = new List<BicepValue<string>>(); | ||
var bicepStringBuilder = new BicepStringBuilder(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FYI - @davidfowl. We aren't able to get rid of our There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was able to simplify the BicepValueFormattableString class. No need for it to inherit from FormattableString. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should be able to if you move this logic into the caller right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can build up the BicepStringBuilder earlier and not have the BicepValueFormattableString at all. But we will still need to parse the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yea, ok. |
||
|
||
void ProcessFormattableString(BicepValueFormattableString formattableString, int argumentIndex) | ||
{ | ||
var span = formattableString.Format.AsSpan(); | ||
var skip = 0; | ||
|
||
foreach (var match in Regex.EnumerateMatches(span, @"{\d+}")) | ||
{ | ||
formatStringBuilder.Append(span[..(match.Index - skip)]); | ||
var span = format.AsSpan(); | ||
var skip = 0; | ||
var argumentIndex = 0; | ||
|
||
var argument = formattableString.GetArgument(argumentIndex); | ||
foreach (var match in Regex.EnumerateMatches(span, @"{\d+}")) | ||
{ | ||
bicepStringBuilder.Append(span[..(match.Index - skip)].ToString()); | ||
|
||
if (argument is BicepValueFormattableString nested) | ||
{ | ||
// Inline the nested formattable string | ||
ProcessFormattableString(nested, 0); | ||
} | ||
else | ||
{ | ||
formatStringBuilder.Append(CultureInfo.InvariantCulture, $"{{{arguments.Count}}}"); | ||
if (argument is BicepValue<string> bicepValue) | ||
{ | ||
arguments.Add(bicepValue); | ||
} | ||
else if (argument is string s) | ||
{ | ||
arguments.Add(s); | ||
} | ||
else if (argument is ProvisioningParameter provisioningParameter) | ||
{ | ||
arguments.Add(provisioningParameter); | ||
} | ||
else | ||
{ | ||
throw new NotSupportedException($"{argument} is not supported"); | ||
} | ||
} | ||
var argument = args[argumentIndex]; | ||
|
||
argumentIndex++; | ||
span = span[(match.Index + match.Length - skip)..]; | ||
skip = match.Index + match.Length; | ||
if (argument is BicepValue<string> bicepValue) | ||
{ | ||
bicepStringBuilder.Append($"{bicepValue}"); | ||
} | ||
else if (argument is string s) | ||
{ | ||
bicepStringBuilder.Append(s); | ||
} | ||
else if (argument is ProvisioningParameter provisioningParameter) | ||
{ | ||
bicepStringBuilder.Append($"{provisioningParameter}"); | ||
} | ||
else | ||
{ | ||
throw new NotSupportedException($"{argument} is not supported"); | ||
} | ||
|
||
formatStringBuilder.Append(span); | ||
} | ||
|
||
ProcessFormattableString(text, 0); | ||
|
||
var formatString = formatStringBuilder.ToString(); | ||
|
||
if (formatString == "{0}") | ||
{ | ||
return arguments[0]; | ||
argumentIndex++; | ||
span = span[(match.Index + match.Length - skip)..]; | ||
skip = match.Index + match.Length; | ||
} | ||
|
||
return BicepFunction.Interpolate(new BicepValueFormattableString(formatString, [.. arguments])); | ||
} | ||
bicepStringBuilder.Append(span.ToString()); | ||
|
||
/// <summary> | ||
/// A custom FormattableString implementation that allows us to inline nested formattable strings. | ||
/// </summary> | ||
private sealed class BicepValueFormattableString(string formatString, object[] values) : FormattableString | ||
{ | ||
public override int ArgumentCount => values.Length; | ||
public override string Format => formatString; | ||
public override object? GetArgument(int index) => values[index]; | ||
public override object?[] GetArguments() => values; | ||
public override string ToString(IFormatProvider? formatProvider) => Format; | ||
public override string ToString() => formatString; | ||
return bicepStringBuilder.Build(); | ||
} | ||
|
||
/// <summary> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These NuGet.config changes won't be merged. We won't merge this PR until the
1.0.0
versions are on nuget.org.