diff --git a/src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentContext.cs b/src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentContext.cs index 738fb0d2ec0..cbd4163d04c 100644 --- a/src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentContext.cs +++ b/src/Aspire.Hosting.Kubernetes/KubernetesEnvironmentContext.cs @@ -8,7 +8,7 @@ namespace Aspire.Hosting.Kubernetes; internal sealed class KubernetesEnvironmentContext(KubernetesEnvironmentResource environment, ILogger logger) { - private readonly Dictionary _kubernetesComponents = []; + private readonly Dictionary _kubernetesComponents = new(new ResourceNameComparer()); public ILogger Logger => logger; diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/KubernetesPublisherTests.cs b/tests/Aspire.Hosting.Kubernetes.Tests/KubernetesPublisherTests.cs index a3da353c498..654b8cf29b4 100644 --- a/tests/Aspire.Hosting.Kubernetes.Tests/KubernetesPublisherTests.cs +++ b/tests/Aspire.Hosting.Kubernetes.Tests/KubernetesPublisherTests.cs @@ -407,6 +407,48 @@ public async Task KubernetesWithProjectResources() await settingsTask; } + [Fact] + public async Task KubernetesMapsPortsForBaitAndSwitchResources() + { + using var tempDir = new TestTempDirectory(); + var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, tempDir.Path); + builder.AddKubernetesEnvironment("env"); + var api = builder.AddExecutable("api", "node", ".") + .PublishAsDockerFile() + .WithHttpEndpoint(env: "PORT"); + builder.AddContainer("gateway", "nginx") + .WithHttpEndpoint(targetPort: 8080) + .WithReference(api.GetEndpoint("http")); + var app = builder.Build(); + app.Run(); + // Assert + var expectedFiles = new[] + { + "Chart.yaml", + "values.yaml", + "templates/api/deployment.yaml", + "templates/api/service.yaml", + "templates/api/config.yaml", + "templates/gateway/deployment.yaml", + "templates/gateway/config.yaml" + }; + SettingsTask settingsTask = default!; + foreach (var expectedFile in expectedFiles) + { + var filePath = Path.Combine(tempDir.Path, expectedFile); + var fileExtension = Path.GetExtension(filePath)[1..]; + if (settingsTask is null) + { + settingsTask = Verify(File.ReadAllText(filePath), fileExtension); + } + else + { + settingsTask = settingsTask.AppendContentAsFile(File.ReadAllText(filePath), fileExtension); + } + } + await settingsTask; + } + private sealed class TestProject : IProjectMetadata { public string ProjectPath => "another-path"; diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#00.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#00.verified.yaml new file mode 100644 index 00000000000..e4179697054 --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#00.verified.yaml @@ -0,0 +1,11 @@ +apiVersion: "v2" +name: "aspire-hosting-tests" +version: "0.1.0" +kubeVersion: ">= 1.18.0-0" +description: "Aspire Helm Chart" +type: "application" +keywords: + - "aspire" + - "kubernetes" +appVersion: "0.1.0" +deprecated: false diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#01.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#01.verified.yaml new file mode 100644 index 00000000000..9bb8e2495d4 --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#01.verified.yaml @@ -0,0 +1,10 @@ +parameters: + api: + api_image: "api:latest" +secrets: {} +config: + api: + PORT: "8000" + gateway: + API_HTTP: "http://api-service:8000" + services__api__http__0: "http://api-service:8000" diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#02.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#02.verified.yaml new file mode 100644 index 00000000000..7c0045b550b --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#02.verified.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: "apps/v1" +kind: "Deployment" +metadata: + name: "api-deployment" + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" +spec: + template: + metadata: + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" + spec: + containers: + - image: "{{ .Values.parameters.api.api_image }}" + name: "api" + envFrom: + - configMapRef: + name: "api-config" + ports: + - name: "http" + protocol: "TCP" + containerPort: 8000 + imagePullPolicy: "IfNotPresent" + selector: + matchLabels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" + replicas: 1 + revisionHistoryLimit: 3 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: "RollingUpdate" diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#03.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#03.verified.yaml new file mode 100644 index 00000000000..a3bfbdbc5d2 --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#03.verified.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: "v1" +kind: "Service" +metadata: + name: "api-service" + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" +spec: + type: "ClusterIP" + selector: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" + ports: + - name: "http" + protocol: "TCP" + port: 8000 + targetPort: 8000 diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#04.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#04.verified.yaml new file mode 100644 index 00000000000..2b756089179 --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#04.verified.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: "v1" +kind: "ConfigMap" +metadata: + name: "api-config" + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "api" + app.kubernetes.io/instance: "{{ .Release.Name }}" +data: + PORT: "{{ .Values.config.api.PORT }}" diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#05.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#05.verified.yaml new file mode 100644 index 00000000000..7abdfd9076b --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#05.verified.yaml @@ -0,0 +1,40 @@ +--- +apiVersion: "apps/v1" +kind: "Deployment" +metadata: + name: "gateway-deployment" + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "gateway" + app.kubernetes.io/instance: "{{ .Release.Name }}" +spec: + template: + metadata: + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "gateway" + app.kubernetes.io/instance: "{{ .Release.Name }}" + spec: + containers: + - image: "nginx:latest" + name: "gateway" + envFrom: + - configMapRef: + name: "gateway-config" + ports: + - name: "http" + protocol: "TCP" + containerPort: 8080 + imagePullPolicy: "IfNotPresent" + selector: + matchLabels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "gateway" + app.kubernetes.io/instance: "{{ .Release.Name }}" + replicas: 1 + revisionHistoryLimit: 3 + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: "RollingUpdate" diff --git a/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#06.verified.yaml b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#06.verified.yaml new file mode 100644 index 00000000000..190928c781d --- /dev/null +++ b/tests/Aspire.Hosting.Kubernetes.Tests/Snapshots/KubernetesPublisherTests.KubernetesMapsPortsForBaitAndSwitchResources#06.verified.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: "v1" +kind: "ConfigMap" +metadata: + name: "gateway-config" + labels: + app.kubernetes.io/name: "aspire-hosting-tests" + app.kubernetes.io/component: "gateway" + app.kubernetes.io/instance: "{{ .Release.Name }}" +data: + API_HTTP: "{{ .Values.config.gateway.API_HTTP }}" + services__api__http__0: "{{ .Values.config.gateway.services__api__http__0 }}"