Skip to content

Commit

Permalink
Support args on container.{v0,v1}
Browse files Browse the repository at this point in the history
We were not handling the `args` property on `container.v0` or
`container.v1` resources. This adds support and a test to confirm we
don't regress.

Fixes #4220
  • Loading branch information
ellismg committed Aug 28, 2024
1 parent fda6f19 commit 07672f6
Show file tree
Hide file tree
Showing 6 changed files with 181 additions and 2 deletions.
15 changes: 13 additions & 2 deletions cli/azd/pkg/apphost/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ func Containers(manifest *Manifest) map[string]genContainer {
Inputs: comp.Inputs,
Volumes: comp.Volumes,
BindMounts: comp.BindMounts,
Args: comp.Args,
}
}
}
Expand Down Expand Up @@ -545,7 +546,7 @@ func (b *infraGenerator) LoadManifest(m *Manifest) error {
case "project.v0":
b.addProject(name, *comp.Path, comp.Env, comp.Bindings, comp.Args)
case "container.v0":
b.addContainer(name, *comp.Image, comp.Env, comp.Bindings, comp.Inputs, comp.Volumes, comp.BindMounts)
b.addContainer(name, *comp.Image, comp.Env, comp.Bindings, comp.Inputs, comp.Volumes, comp.BindMounts, comp.Args)
case "dapr.v0":
err := b.addDapr(name, comp.Dapr)
if err != nil {
Expand Down Expand Up @@ -838,7 +839,8 @@ func (b *infraGenerator) addContainer(
bindings custommaps.WithOrder[Binding],
inputs map[string]Input,
volumes []*Volume,
bindMounts []*BindMount) {
bindMounts []*BindMount,
args []string) {
b.requireCluster()

if len(volumes) > 0 {
Expand All @@ -857,6 +859,7 @@ func (b *infraGenerator) addContainer(
Inputs: inputs,
Volumes: volumes,
BindMounts: bindMounts,
Args: args,
}
}

Expand Down Expand Up @@ -1159,6 +1162,10 @@ func (b *infraGenerator) Compile() error {
return fmt.Errorf("configuring environment for resource %s: %w", resourceName, err)
}

if err := b.buildArgsBlock(container.Args, &projectTemplateCtx); err != nil {
return err
}

b.containerAppTemplateContexts[resourceName] = projectTemplateCtx
}

Expand All @@ -1182,6 +1189,10 @@ func (b *infraGenerator) Compile() error {
return fmt.Errorf("configuring environment for resource %s: %w", resourceName, err)
}

if err := b.buildArgsBlock(bc.Args, &projectTemplateCtx); err != nil {
return err
}

b.containerAppTemplateContexts[resourceName] = projectTemplateCtx
}

Expand Down
25 changes: 25 additions & 0 deletions cli/azd/pkg/apphost/generate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ var aspireBicepManifest []byte
//go:embed testdata/aspire-container.json
var aspireContainerManifest []byte

//go:embed testdata/aspire-container-args.json
var aspireContainerArgsManifest []byte

// mockPublishManifest mocks the dotnet run --publisher manifest command to return a fixed manifest.
func mockPublishManifest(mockCtx *mocks.MockContext, manifest []byte, files map[string]string) {
mockCtx.CommandRunner.When(func(args exec.RunArgs, command string) bool {
Expand Down Expand Up @@ -258,6 +261,28 @@ func TestAspireContainerGeneration(t *testing.T) {
require.NoError(t, err)
}

func TestAspireContainerArgs(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping due to EOL issues on Windows with the baselines")
}

ctx := context.Background()
mockCtx := mocks.NewMockContext(ctx)
mockPublishManifest(mockCtx, aspireContainerArgsManifest, nil)
mockCli := dotnet.NewCli(mockCtx.CommandRunner)

m, err := ManifestFromAppHost(ctx, filepath.Join("testdata", "AspireDocker.AppHost.csproj"), mockCli, "")
require.NoError(t, err)

for _, name := range []string{"container0", "container1"} {
t.Run(name, func(t *testing.T) {
tmpl, err := ContainerAppManifestTemplateForProject(m, name, AppHostOptions{})
require.NoError(t, err)
snapshot.SnapshotT(t, tmpl)
})
}
}

func TestEvaluateForOutputs(t *testing.T) {
value := "{resource.outputs.output1} and {resource.secretOutputs.output2}"

Expand Down
1 change: 1 addition & 0 deletions cli/azd/pkg/apphost/generate_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ type genContainer struct {
Inputs map[string]Input
Volumes []*Volume
BindMounts []*BindMount
Args []string
}

type genDockerfile struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
api-version: 2024-02-02-preview
location: {{ .Env.AZURE_LOCATION }}
identity:
type: UserAssigned
userAssignedIdentities:
? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}"
: {}
properties:
environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }}
configuration:
activeRevisionsMode: single
runtime:
dotnet:
autoConfigureDataProtection: true
ingress:
additionalPortMappings:
- targetPort: 3306
external: false
external: false
targetPort: {{ targetPortOrDefault 80 }}
transport: http
allowInsecure: true
registries:
- server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }}
identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}
template:
containers:
- image: {{ .Image }}
name: container0
args:
- arg1
- https://project.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
env:
- name: AZURE_CLIENT_ID
value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
scale:
minReplicas: 1
tags:
azd-service-name: container0
aspire-resource-name: container0

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
api-version: 2024-02-02-preview
location: {{ .Env.AZURE_LOCATION }}
identity:
type: UserAssigned
userAssignedIdentities:
? "{{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}"
: {}
properties:
environmentId: {{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_ID }}
configuration:
activeRevisionsMode: single
runtime:
dotnet:
autoConfigureDataProtection: true
ingress:
additionalPortMappings:
- targetPort: 3306
external: false
external: false
targetPort: {{ targetPortOrDefault 8080 }}
transport: http
allowInsecure: true
registries:
- server: {{ .Env.AZURE_CONTAINER_REGISTRY_ENDPOINT }}
identity: {{ .Env.AZURE_CONTAINER_REGISTRY_MANAGED_IDENTITY_ID }}
template:
containers:
- image: {{ .Image }}
name: container1
args:
- arg1
- https://project.internal.{{ .Env.AZURE_CONTAINER_APPS_ENVIRONMENT_DEFAULT_DOMAIN }}
env:
- name: AZURE_CLIENT_ID
value: {{ .Env.MANAGED_IDENTITY_CLIENT_ID }}
scale:
minReplicas: 1
tags:
azd-service-name: container1
aspire-resource-name: container1

60 changes: 60 additions & 0 deletions cli/azd/pkg/apphost/testdata/aspire-container-args.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"resources": {
"project" : {
"type": "project.v0",
"path": "../Test1.Web/Test1.Web.csproj",
"env": {
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
"OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true"
},
"bindings": {
"http": {
"scheme": "http",
"protocol": "tcp",
"transport": "http"
},
"https": {
"scheme": "https",
"protocol": "tcp",
"transport": "http"
}
}
},
"container0": {
"type": "container.v0",
"image": "mysql:latest",
"args": [ "arg1", "{project.bindings.https.url}" ],
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 3306
},
"http" : {
"scheme": "http",
"protocol": "http",
"transport": "http"
}
}
},
"container1": {
"type": "container.v1",
"image": "mysql:latest",
"args": [ "arg1", "{project.bindings.https.url}" ],
"bindings": {
"tcp": {
"scheme": "tcp",
"protocol": "tcp",
"transport": "tcp",
"targetPort": 3306
},
"http" : {
"scheme": "http",
"protocol": "http",
"transport": "http"
}
}
}
}
}

0 comments on commit 07672f6

Please sign in to comment.