prom3theu5 / aspirational-manifests

Handle deployments of .NET Aspire AppHost Projects
MIT License
702 stars 36 forks source link

Nested expressions sometimes can be unresolved #217

Closed badnickname closed 5 months ago

badnickname commented 5 months ago

🔥 Bug Description

I has field order.ConnectionStrings__OrderDb in manifest.json with expression that consumed field OrderDb.connectionString with another expression:

"order": {
    "type": "project.v0",
    "path": "../Order/Order.csproj",
    "env": {
        "ConnectionStrings__OrderDb": "{OrderDb.connectionString}"
    }
},
"OrderDb": {
    "type": "value.v0",
    "connectionString": "{postgres.connectionString};Database=OrderDb"
}

After perform aspirate generate I get config with unresolved expression postgres.connectionString:

services:
  // ...
  order:
    container_name: "order"
    environment:
      ConnectionStrings__OrderDb: "{postgres.connectionString};Database=OrderDb"
      // ...

🔍 Steps to Reproduce the Bug

  1. Configure composition:
    
    var builder = DistributedApplication.CreateBuilder(args);
    var postgres = builder
    .AddPostgres("postgres")
    .WithPgAdmin();
    builder
    .AddProject<Order>("order")
    .WithHttpEndpoint(name: "order", port: 5100)
    .WithReference(postgres.AddDatabase("OrderDb"));

builder .Build() .Run();


<details><summary>manifest</summary>

```json
{
  "resources": {
    "postgres": {
      "type": "container.v0",
      "connectionString": "Host={postgres.bindings.tcp.host};Port={postgres.bindings.tcp.port};Username=postgres;Password={postgres-password.value}",
      "image": "docker.io/library/postgres:16.2",
      "env": {
        "POSTGRES_HOST_AUTH_METHOD": "scram-sha-256",
        "POSTGRES_INITDB_ARGS": "--auth-host=scram-sha-256 --auth-local=scram-sha-256",
        "POSTGRES_USER": "postgres",
        "POSTGRES_PASSWORD": "{postgres-password.value}"
      },
      "bindings": {
        "tcp": {
          "scheme": "tcp",
          "protocol": "tcp",
          "transport": "tcp",
          "targetPort": 5432
        }
      }
    },
    "order": {
      "type": "project.v0",
      "path": "../Order/Order.csproj",
      "env": {
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EXCEPTION_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_EMIT_EVENT_LOG_ATTRIBUTES": "true",
        "OTEL_DOTNET_EXPERIMENTAL_OTLP_RETRY": "in_memory",
        "ASPNETCORE_FORWARDEDHEADERS_ENABLED": "true",
        "ConnectionStrings__OrderDb": "{OrderDb.connectionString}"
      },
      "bindings": {
        "order": {
          "scheme": "http",
          "protocol": "tcp",
          "transport": "http",
          "port": 5100
        }
      }
    },
    "OrderDb": {
      "type": "value.v0",
      "connectionString": "{postgres.connectionString};Database=OrderDb"
    },
    "postgres-password": {
      "type": "parameter.v0",
      "value": "{postgres-password.inputs.value}",
      "inputs": {
        "value": {
          "type": "string",
          "secret": true,
          "default": {
            "generate": {
              "minLength": 22
            }
          }
        }
      }
    }
  }
}

  1. Run
    aspirate generate --skip-build --output-format compose --disable-secrets
  2. Get config with incorrect connection string for postgres

🧯 Possible Solution

I think Aspirate.Processors.Transformation.Json.JsonExpressionProcessor should check if nodes after resolving still has expressions and perform processing for them again

prom3theu5 commented 5 months ago

218 Merged in your PR - thanks for the contribution