From fc4dc9281665f3274cc8cec3ae9bc572d163e08c Mon Sep 17 00:00:00 2001 From: Justin Kotalik Date: Thu, 28 May 2020 15:23:42 -0700 Subject: [PATCH] Fix dapr and environment variable injection (#510) --- src/Microsoft.Tye.Core/CombineStep.cs | 7 +- .../Dapr/DaprExtension.cs | 8 ++ .../Model/Application.cs | 46 +++++----- test/E2ETest/ApplicationTests.cs | 5 +- .../generate/apps-with-ingress.yaml | 14 ++- test/E2ETest/testassets/generate/dapr.yaml | 8 +- .../testassets/generate/dockerfile.yaml | 14 ++- .../testassets/generate/frontend-backend.yaml | 14 ++- .../generate-connectionstring-dependency.yaml | 6 ++ .../generate/generate-named-binding.yaml | 6 ++ .../generate/generate-uri-dependency.yaml | 6 ++ .../testassets/generate/health-checks.yaml | 90 ++++++++++--------- .../testassets/generate/multi-project.yaml | 14 ++- .../testassets/generate/multirepo.yaml | 14 ++- .../generate/single-project-noregistry.yaml | 8 +- .../testassets/generate/single-project.yaml | 8 +- 16 files changed, 194 insertions(+), 74 deletions(-) diff --git a/src/Microsoft.Tye.Core/CombineStep.cs b/src/Microsoft.Tye.Core/CombineStep.cs index a6095fc3..56745841 100644 --- a/src/Microsoft.Tye.Core/CombineStep.cs +++ b/src/Microsoft.Tye.Core/CombineStep.cs @@ -46,15 +46,18 @@ namespace Microsoft.Tye } } + var services = new List() { service.Name }; + services.AddRange(service.Dependencies); + // Process bindings and turn them into environment variables and secrets. There's // some duplication with the code in m8s (Application.cs) for populating environments. // // service.Service.Bindings is the bindings OUT - this step computes bindings IN. - service.Outputs.Add(ComputeBindings(application, service.Dependencies)); + service.Outputs.Add(ComputeBindings(application, services)); foreach (var sidecar in project.Sidecars) { - sidecar.Outputs.Add(ComputeBindings(application, sidecar.Dependencies)); + sidecar.Outputs.Add(ComputeBindings(application, services)); } return Task.CompletedTask; diff --git a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs index c3feb060..eccc1707 100644 --- a/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs +++ b/src/Microsoft.Tye.Extensions/Dapr/DaprExtension.cs @@ -71,6 +71,14 @@ namespace Microsoft.Tye.Extensions.Dapr proxy.Args += $" -log-level {logLevel}"; } + // Add dapr proxy as a service available to everyone. + proxy.Dependencies.UnionWith(context.Application.Services.Select(s => s.Name)); + + foreach (var s in context.Application.Services) + { + s.Dependencies.Add(proxy.Name); + } + context.Application.Services.Add(proxy); // Listen for grpc on an auto-assigned port diff --git a/src/Microsoft.Tye.Hosting/Model/Application.cs b/src/Microsoft.Tye.Hosting/Model/Application.cs index ac2a7fe0..04713c19 100644 --- a/src/Microsoft.Tye.Hosting/Model/Application.cs +++ b/src/Microsoft.Tye.Hosting/Model/Application.cs @@ -132,33 +132,39 @@ namespace Microsoft.Tye.Hosting.Model { var bindings = new List(); + var isDockerRunInfo = service.Description.RunInfo is DockerRunInfo; + GetEffectiveBindings(isDockerRunInfo, defaultHost, bindings, service); + foreach (var serv in service.Description.Dependencies) { - var s = Services[serv]; + GetEffectiveBindings(isDockerRunInfo, defaultHost, bindings, Services[serv]); + } - foreach (var b in s.Description.Bindings) - { - var protocol = b.Protocol; - var host = b.Host ?? (service.Description.RunInfo is DockerRunInfo ? s.Description.Name : defaultHost); + return bindings; + } - var port = b.Port; - if (b.Port is object && service.Description.RunInfo is DockerRunInfo) - { - port = b.ContainerPort ?? b.Port.Value; - } + private static void GetEffectiveBindings(bool isDockerRunInfo, string defaultHost, List bindings, Service service) + { + foreach (var b in service.Description.Bindings) + { + var protocol = b.Protocol; + var host = b.Host ?? (isDockerRunInfo ? service.Description.Name : defaultHost); - bindings.Add(new EffectiveBinding( - s.Description.Name, - b.Name, - protocol, - host, - port, - b.ConnectionString, - s.Description.Configuration)); + var port = b.Port; + if (b.Port is object && isDockerRunInfo) + { + port = b.ContainerPort ?? b.Port.Value; } - } - return bindings; + bindings.Add(new EffectiveBinding( + service.Description.Name, + b.Name, + protocol, + host, + port, + b.ConnectionString, + service.Description.Configuration)); + } } } } diff --git a/test/E2ETest/ApplicationTests.cs b/test/E2ETest/ApplicationTests.cs index b4dc11cf..b5332279 100644 --- a/test/E2ETest/ApplicationTests.cs +++ b/test/E2ETest/ApplicationTests.cs @@ -31,10 +31,11 @@ namespace E2ETest var dictionary = new Dictionary(); app.PopulateEnvironment(app.Services["results"], (s1, s2) => dictionary[s1] = s2); - // Just the WORKER is defined. - Assert.Equal(8, dictionary.Count); + // Just the worker and results are defined. + Assert.Equal(16, dictionary.Count); Assert.Equal("http", dictionary["SERVICE__WORKER__PROTOCOL"]); + Assert.Equal("http", dictionary["SERVICE__RESULTS__PROTOCOL"]); // No POSTGRES or REDIS Assert.False(dictionary.ContainsKey("SERVICE__POSTGRES__PROTOCOL")); Assert.False(dictionary.ContainsKey("SERVICE__REDIS__PROTOCOL")); diff --git a/test/E2ETest/testassets/generate/apps-with-ingress.yaml b/test/E2ETest/testassets/generate/apps-with-ingress.yaml index c01452ba..2907ea24 100644 --- a/test/E2ETest/testassets/generate/apps-with-ingress.yaml +++ b/test/E2ETest/testassets/generate/apps-with-ingress.yaml @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__APPA__PROTOCOL + value: 'http' + - name: SERVICE__APPA__PORT + value: '80' + - name: SERVICE__APPA__HOST + value: 'appa' - name: SERVICE__APPB__PROTOCOL value: 'http' - name: SERVICE__APPB__PORT @@ -80,6 +86,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__APPB__PROTOCOL + value: 'http' + - name: SERVICE__APPB__PORT + value: '80' + - name: SERVICE__APPB__HOST + value: 'appb' - name: SERVICE__APPA__PROTOCOL value: 'http' - name: SERVICE__APPA__PORT @@ -143,4 +155,4 @@ spec: serviceName: appb servicePort: 80 path: /()(.*) -... \ No newline at end of file +... diff --git a/test/E2ETest/testassets/generate/dapr.yaml b/test/E2ETest/testassets/generate/dapr.yaml index bf175b4a..4772cc06 100644 --- a/test/E2ETest/testassets/generate/dapr.yaml +++ b/test/E2ETest/testassets/generate/dapr.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: dapr-test-project @@ -37,6 +37,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__DAPR-TEST-PROJECT__PROTOCOL + value: 'http' + - name: SERVICE__DAPR-TEST-PROJECT__PORT + value: '80' + - name: SERVICE__DAPR-TEST-PROJECT__HOST + value: 'dapr-test-project' ports: - containerPort: 80 ... diff --git a/test/E2ETest/testassets/generate/dockerfile.yaml b/test/E2ETest/testassets/generate/dockerfile.yaml index a8f197ad..f781a3ff 100644 --- a/test/E2ETest/testassets/generate/dockerfile.yaml +++ b/test/E2ETest/testassets/generate/dockerfile.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: backend @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__BACKEND__PROTOCOL + value: 'http' + - name: SERVICE__BACKEND__PORT + value: '80' + - name: SERVICE__BACKEND__HOST + value: 'backend' - name: SERVICE__FRONTEND__PROTOCOL value: 'http' - name: SERVICE__FRONTEND__PORT @@ -80,6 +86,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '80' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: SERVICE__BACKEND__PROTOCOL value: 'http' - name: SERVICE__BACKEND__PORT diff --git a/test/E2ETest/testassets/generate/frontend-backend.yaml b/test/E2ETest/testassets/generate/frontend-backend.yaml index b8c66948..7b4d009e 100644 --- a/test/E2ETest/testassets/generate/frontend-backend.yaml +++ b/test/E2ETest/testassets/generate/frontend-backend.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: backend @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__BACKEND__PROTOCOL + value: 'http' + - name: SERVICE__BACKEND__PORT + value: '80' + - name: SERVICE__BACKEND__HOST + value: 'backend' - name: SERVICE__FRONTEND__PROTOCOL value: 'http' - name: SERVICE__FRONTEND__PORT @@ -80,6 +86,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '80' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: SERVICE__BACKEND__PROTOCOL value: 'http' - name: SERVICE__BACKEND__PORT diff --git a/test/E2ETest/testassets/generate/generate-connectionstring-dependency.yaml b/test/E2ETest/testassets/generate/generate-connectionstring-dependency.yaml index 3552b04d..be66e4f9 100644 --- a/test/E2ETest/testassets/generate/generate-connectionstring-dependency.yaml +++ b/test/E2ETest/testassets/generate/generate-connectionstring-dependency.yaml @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '80' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: CONNECTIONSTRINGS__DEPENDENCY valueFrom: secretKeyRef: diff --git a/test/E2ETest/testassets/generate/generate-named-binding.yaml b/test/E2ETest/testassets/generate/generate-named-binding.yaml index 549b11d0..f572187a 100644 --- a/test/E2ETest/testassets/generate/generate-named-binding.yaml +++ b/test/E2ETest/testassets/generate/generate-named-binding.yaml @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '80' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: SERVICE__DEPENDENCY__MYBINDING__PROTOCOL valueFrom: secretKeyRef: diff --git a/test/E2ETest/testassets/generate/generate-uri-dependency.yaml b/test/E2ETest/testassets/generate/generate-uri-dependency.yaml index 31da78fb..81ebb60b 100644 --- a/test/E2ETest/testassets/generate/generate-uri-dependency.yaml +++ b/test/E2ETest/testassets/generate/generate-uri-dependency.yaml @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '80' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: SERVICE__DEPENDENCY__PROTOCOL valueFrom: secretKeyRef: diff --git a/test/E2ETest/testassets/generate/health-checks.yaml b/test/E2ETest/testassets/generate/health-checks.yaml index f04fe00c..3e881dbf 100644 --- a/test/E2ETest/testassets/generate/health-checks.yaml +++ b/test/E2ETest/testassets/generate/health-checks.yaml @@ -17,44 +17,50 @@ spec: app.kubernetes.io/part-of: 'health-checks' spec: containers: - - name: health-all - image: health-all:1.0.0 - imagePullPolicy: Always - env: - - name: ASPNETCORE_URLS - value: 'http://*:8004' - - name: PORT - value: '8004' - ports: - - containerPort: 8004 - livenessProbe: - httpGet: - path: /healthy - port: 8004 - scheme: HTTP - httpHeaders: - - name: name1 - value: value1 - - name: name2 - value: value2 - initialDelaySeconds: 5 - periodSeconds: 1 - successThreshold: 1 - failureThreshold: 1 - readinessProbe: - httpGet: - path: /ready - port: 8004 - scheme: HTTP - httpHeaders: - - name: name3 - value: value3 - - name: name4 - value: value4 - initialDelaySeconds: 5 - periodSeconds: 1 - successThreshold: 1 - failureThreshold: 1 + - name: health-all + image: health-all:1.0.0 + imagePullPolicy: Always + env: + - name: ASPNETCORE_URLS + value: 'http://*:8004' + - name: PORT + value: '8004' + - name: SERVICE__HEALTH-ALL__PROTOCOL + value: 'http' + - name: SERVICE__HEALTH-ALL__PORT + value: '8004' + - name: SERVICE__HEALTH-ALL__HOST + value: 'health-all' + ports: + - containerPort: 8004 + livenessProbe: + httpGet: + path: /healthy + port: 8004 + scheme: HTTP + httpHeaders: + - name: name1 + value: value1 + - name: name2 + value: value2 + initialDelaySeconds: 5 + periodSeconds: 1 + successThreshold: 1 + failureThreshold: 1 + readinessProbe: + httpGet: + path: /ready + port: 8004 + scheme: HTTP + httpHeaders: + - name: name3 + value: value3 + - name: name4 + value: value4 + initialDelaySeconds: 5 + periodSeconds: 1 + successThreshold: 1 + failureThreshold: 1 ... --- kind: Service @@ -69,8 +75,8 @@ spec: app.kubernetes.io/name: health-all type: ClusterIP ports: - - name: http - protocol: TCP - port: 8004 - targetPort: 8004 + - name: http + protocol: TCP + port: 8004 + targetPort: 8004 ... diff --git a/test/E2ETest/testassets/generate/multi-project.yaml b/test/E2ETest/testassets/generate/multi-project.yaml index 880aa36d..d32bbc0b 100644 --- a/test/E2ETest/testassets/generate/multi-project.yaml +++ b/test/E2ETest/testassets/generate/multi-project.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: backend @@ -25,6 +25,12 @@ spec: value: 'http://*:7000' - name: PORT value: '7000' + - name: SERVICE__BACKEND__PROTOCOL + value: 'http' + - name: SERVICE__BACKEND__PORT + value: '7000' + - name: SERVICE__BACKEND__HOST + value: 'backend' - name: SERVICE__FRONTEND__PROTOCOL value: 'http' - name: SERVICE__FRONTEND__PORT @@ -95,6 +101,12 @@ spec: value: 'http://*:8000' - name: PORT value: '8000' + - name: SERVICE__FRONTEND__PROTOCOL + value: 'http' + - name: SERVICE__FRONTEND__PORT + value: '8000' + - name: SERVICE__FRONTEND__HOST + value: 'frontend' - name: SERVICE__BACKEND__PROTOCOL value: 'http' - name: SERVICE__BACKEND__PORT diff --git a/test/E2ETest/testassets/generate/multirepo.yaml b/test/E2ETest/testassets/generate/multirepo.yaml index dce6a2a6..a724f7fa 100644 --- a/test/E2ETest/testassets/generate/multirepo.yaml +++ b/test/E2ETest/testassets/generate/multirepo.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: results @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__RESULTS__PROTOCOL + value: 'http' + - name: SERVICE__RESULTS__PORT + value: '80' + - name: SERVICE__RESULTS__HOST + value: 'results' - name: SERVICE__WORKER__PROTOCOL value: 'http' - name: SERVICE__WORKER__PORT @@ -80,6 +86,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__WORKER__PROTOCOL + value: 'http' + - name: SERVICE__WORKER__PORT + value: '80' + - name: SERVICE__WORKER__HOST + value: 'worker' - name: CONNECTIONSTRINGS__REDIS valueFrom: secretKeyRef: diff --git a/test/E2ETest/testassets/generate/single-project-noregistry.yaml b/test/E2ETest/testassets/generate/single-project-noregistry.yaml index d7a2f47d..d084c22d 100644 --- a/test/E2ETest/testassets/generate/single-project-noregistry.yaml +++ b/test/E2ETest/testassets/generate/single-project-noregistry.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: test-project @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__TEST-PROJECT__PROTOCOL + value: 'http' + - name: SERVICE__TEST-PROJECT__PORT + value: '80' + - name: SERVICE__TEST-PROJECT__HOST + value: 'test-project' ports: - containerPort: 80 ... diff --git a/test/E2ETest/testassets/generate/single-project.yaml b/test/E2ETest/testassets/generate/single-project.yaml index 4354f9f1..6996fd03 100644 --- a/test/E2ETest/testassets/generate/single-project.yaml +++ b/test/E2ETest/testassets/generate/single-project.yaml @@ -1,4 +1,4 @@ -kind: Deployment +kind: Deployment apiVersion: apps/v1 metadata: name: test-project @@ -25,6 +25,12 @@ spec: value: 'http://*' - name: PORT value: '80' + - name: SERVICE__TEST-PROJECT__PROTOCOL + value: 'http' + - name: SERVICE__TEST-PROJECT__PORT + value: '80' + - name: SERVICE__TEST-PROJECT__HOST + value: 'test-project' ports: - containerPort: 80 ...