committed by
GitHub
33 changed files with 700 additions and 95 deletions
@ -0,0 +1,6 @@ |
|||||
|
# tye application configuration file |
||||
|
# read all about it at https://github.com/dotnet/tye |
||||
|
name: single-project |
||||
|
services: |
||||
|
- name: test-project |
||||
|
project: test-project/test-project.csproj |
||||
@ -0,0 +1,59 @@ |
|||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
// See the LICENSE file in the project root for more information.
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.CommandLine; |
||||
|
using System.IO; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Tye.ConfigModel; |
||||
|
|
||||
|
namespace Tye |
||||
|
{ |
||||
|
public class GenerateHost |
||||
|
{ |
||||
|
public static Task GenerateAsync(IConsole console, FileInfo path, Verbosity verbosity, bool interactive) |
||||
|
{ |
||||
|
var application = ConfigFactory.FromFile(path); |
||||
|
return ExecuteGenerateAsync(new OutputContext(console, verbosity), application, environment: "production", interactive); |
||||
|
} |
||||
|
|
||||
|
public static async Task ExecuteGenerateAsync(OutputContext output, ConfigApplication application, string environment, bool interactive) |
||||
|
{ |
||||
|
var temporaryApplication = await Program.CreateApplicationAdapterAsync(output, application, interactive); |
||||
|
var steps = new List<ServiceExecutor.Step>() |
||||
|
{ |
||||
|
new CombineStep() { Environment = environment, }, |
||||
|
new PublishProjectStep(), |
||||
|
new BuildDockerImageStep() { Environment = environment, }, // Make an image but don't push it
|
||||
|
}; |
||||
|
|
||||
|
steps.Add(new GenerateKubernetesManifestStep() { Environment = environment, }); |
||||
|
|
||||
|
var executor = new ServiceExecutor(output, temporaryApplication, steps); |
||||
|
foreach (var service in temporaryApplication.Services) |
||||
|
{ |
||||
|
await executor.ExecuteAsync(service); |
||||
|
} |
||||
|
|
||||
|
await GenerateApplicationManifestAsync(output, temporaryApplication, application.Name ?? application.Source.Directory.Name, environment); |
||||
|
} |
||||
|
|
||||
|
private static async Task GenerateApplicationManifestAsync(OutputContext output, Tye.Application application, string applicationName, string environment) |
||||
|
{ |
||||
|
using var step = output.BeginStep("Generating Application Manifests..."); |
||||
|
|
||||
|
var outputFilePath = Path.GetFullPath(Path.Combine(application.RootDirectory, $"{applicationName}-generate-{environment}.yaml")); |
||||
|
output.WriteInfoLine($"Writing output to '{outputFilePath}'."); |
||||
|
{ |
||||
|
using var stream = File.OpenWrite(outputFilePath); |
||||
|
using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true); |
||||
|
|
||||
|
await ApplicationYamlWriter.WriteAsync(output, writer, application); |
||||
|
} |
||||
|
|
||||
|
step.MarkComplete(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using System; |
||||
|
using Xunit; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] |
||||
|
[XunitTestCaseDiscoverer("E2ETest." + nameof(ConditionalFactDiscoverer), "E2ETest")] |
||||
|
public class ConditionalFactAttribute : FactAttribute |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using Xunit.Abstractions; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
// Do not change this namespace without changing the usage in ConditionalFactAttribute
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
internal class ConditionalFactDiscoverer : FactDiscoverer |
||||
|
{ |
||||
|
private readonly IMessageSink _diagnosticMessageSink; |
||||
|
|
||||
|
public ConditionalFactDiscoverer(IMessageSink diagnosticMessageSink) |
||||
|
: base(diagnosticMessageSink) |
||||
|
{ |
||||
|
_diagnosticMessageSink = diagnosticMessageSink; |
||||
|
} |
||||
|
|
||||
|
protected override IXunitTestCase CreateTestCase(ITestFrameworkDiscoveryOptions discoveryOptions, ITestMethod testMethod, IAttributeInfo factAttribute) |
||||
|
{ |
||||
|
var skipReason = testMethod.EvaluateSkipConditions(); |
||||
|
return skipReason != null |
||||
|
? new SkippedTestCase(skipReason, _diagnosticMessageSink, discoveryOptions.MethodDisplayOrDefault(), TestMethodDisplayOptions.None, testMethod) |
||||
|
: base.CreateTestCase(discoveryOptions, testMethod, factAttribute); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
namespace E2ETest |
||||
|
{ |
||||
|
public interface ITestCondition |
||||
|
{ |
||||
|
bool IsMet { get; } |
||||
|
|
||||
|
string SkipReason { get; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
// See the LICENSE file in the project root for more information.
|
||||
|
|
||||
|
using System; |
||||
|
using Tye; |
||||
|
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)] |
||||
|
internal class SkipIfDockerNotRunningAttribute : Attribute, ITestCondition |
||||
|
{ |
||||
|
public SkipIfDockerNotRunningAttribute() |
||||
|
{ |
||||
|
// TODO Check performance of this.
|
||||
|
IsMet = DockerDetector.Instance.IsDockerConnectedToDaemon.Value.GetAwaiter().GetResult(); |
||||
|
SkipReason = "Docker is not installed or running."; |
||||
|
} |
||||
|
|
||||
|
public bool IsMet { get; } |
||||
|
|
||||
|
public string SkipReason { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,46 @@ |
|||||
|
using System; |
||||
|
using Xunit.Abstractions; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
public class SkippedTestCase : XunitTestCase |
||||
|
{ |
||||
|
private string _skipReason; |
||||
|
|
||||
|
[Obsolete("Called by the de-serializer; should only be called by deriving classes for de-serialization purposes")] |
||||
|
public SkippedTestCase() : base() |
||||
|
{ |
||||
|
_skipReason = ""; |
||||
|
} |
||||
|
|
||||
|
public SkippedTestCase( |
||||
|
string skipReason, |
||||
|
IMessageSink diagnosticMessageSink, |
||||
|
TestMethodDisplay defaultMethodDisplay, |
||||
|
TestMethodDisplayOptions defaultMethodDisplayOptions, |
||||
|
ITestMethod testMethod) |
||||
|
: base(diagnosticMessageSink, defaultMethodDisplay, defaultMethodDisplayOptions, testMethod) |
||||
|
{ |
||||
|
_skipReason = skipReason; |
||||
|
} |
||||
|
|
||||
|
protected override string GetSkipReason(IAttributeInfo factAttribute) |
||||
|
=> _skipReason ?? base.GetSkipReason(factAttribute); |
||||
|
|
||||
|
public override void Deserialize(IXunitSerializationInfo data) |
||||
|
{ |
||||
|
_skipReason = data.GetValue<string>(nameof(_skipReason)); |
||||
|
|
||||
|
// We need to call base after reading our value, because Deserialize will call
|
||||
|
// into GetSkipReason.
|
||||
|
base.Deserialize(data); |
||||
|
} |
||||
|
|
||||
|
public override void Serialize(IXunitSerializationInfo data) |
||||
|
{ |
||||
|
base.Serialize(data); |
||||
|
data.AddValue(nameof(_skipReason), _skipReason); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
using System.Linq; |
||||
|
using Xunit.Abstractions; |
||||
|
using Xunit.Sdk; |
||||
|
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
public static class TestMethodExtensions |
||||
|
{ |
||||
|
public static string EvaluateSkipConditions(this ITestMethod testMethod) |
||||
|
{ |
||||
|
var testClass = testMethod.TestClass.Class; |
||||
|
var assembly = testMethod.TestClass.TestCollection.TestAssembly.Assembly; |
||||
|
var conditionAttributes = testMethod.Method |
||||
|
.GetCustomAttributes(typeof(ITestCondition)) |
||||
|
.Concat(testClass.GetCustomAttributes(typeof(ITestCondition))) |
||||
|
.Concat(assembly.GetCustomAttributes(typeof(ITestCondition))) |
||||
|
.OfType<ReflectionAttributeInfo>() |
||||
|
.Select(attributeInfo => attributeInfo.Attribute); |
||||
|
|
||||
|
foreach (ITestCondition condition in conditionAttributes) |
||||
|
{ |
||||
|
if (!condition.IsMet) |
||||
|
{ |
||||
|
return condition.SkipReason; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null!; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,20 +1,38 @@ |
|||||
using Serilog.Core; |
using System.CommandLine; |
||||
|
using System.CommandLine.IO; |
||||
|
using Serilog.Core; |
||||
using Serilog.Events; |
using Serilog.Events; |
||||
using Xunit.Abstractions; |
using Xunit.Abstractions; |
||||
|
|
||||
namespace E2ETest |
namespace E2ETest |
||||
{ |
{ |
||||
public class TestOutputLogEventSink : ILogEventSink |
public class TestOutputLogEventSink : ILogEventSink, IConsole, IStandardStreamWriter |
||||
{ |
{ |
||||
private readonly ITestOutputHelper output; |
private readonly ITestOutputHelper output; |
||||
|
|
||||
public TestOutputLogEventSink(ITestOutputHelper output) |
public TestOutputLogEventSink(ITestOutputHelper output) |
||||
{ |
{ |
||||
this.output = output; |
this.output = output; |
||||
} |
} |
||||
|
|
||||
|
public IStandardStreamWriter Out => this; |
||||
|
|
||||
|
public bool IsOutputRedirected => false; |
||||
|
|
||||
|
public IStandardStreamWriter Error => this; |
||||
|
|
||||
|
public bool IsErrorRedirected => false; |
||||
|
|
||||
|
public bool IsInputRedirected => false; |
||||
|
|
||||
public void Emit(LogEvent logEvent) |
public void Emit(LogEvent logEvent) |
||||
{ |
{ |
||||
output.WriteLine(logEvent.RenderMessage()); |
output.WriteLine(logEvent.RenderMessage()); |
||||
} |
} |
||||
|
|
||||
|
public void Write(string value) |
||||
|
{ |
||||
|
output.WriteLine(value); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,106 @@ |
|||||
|
// Licensed to the .NET Foundation under one or more agreements.
|
||||
|
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
// See the LICENSE file in the project root for more information.
|
||||
|
|
||||
|
using System.IO; |
||||
|
using System.Threading.Tasks; |
||||
|
using Tye; |
||||
|
using Tye.ConfigModel; |
||||
|
using Xunit; |
||||
|
using Xunit.Abstractions; |
||||
|
|
||||
|
namespace E2ETest |
||||
|
{ |
||||
|
public class TyeGenerateTests |
||||
|
{ |
||||
|
private readonly ITestOutputHelper output; |
||||
|
private readonly TestOutputLogEventSink sink; |
||||
|
|
||||
|
public TyeGenerateTests(ITestOutputHelper output) |
||||
|
{ |
||||
|
this.output = output; |
||||
|
sink = new TestOutputLogEventSink(output); |
||||
|
} |
||||
|
|
||||
|
[ConditionalFact] |
||||
|
[SkipIfDockerNotRunning] |
||||
|
public async Task SingleProjectGenerateTest() |
||||
|
{ |
||||
|
var projectName = "single-project"; |
||||
|
var environment = "production"; |
||||
|
|
||||
|
var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName)); |
||||
|
using var tempDirectory = TempDirectory.Create(); |
||||
|
DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath); |
||||
|
|
||||
|
var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml")); |
||||
|
|
||||
|
var application = ConfigFactory.FromFile(projectFile); |
||||
|
|
||||
|
// Need to add docker registry for generate
|
||||
|
application.Registry = "test"; |
||||
|
|
||||
|
await GenerateHost.ExecuteGenerateAsync(new OutputContext(sink, Verbosity.Debug), application, environment, interactive: false); |
||||
|
|
||||
|
// name of application is the folder
|
||||
|
var content = File.ReadAllText(Path.Combine(tempDirectory.DirectoryPath, $"{projectName}-generate-{environment}.yaml")); |
||||
|
var expectedContent = File.ReadAllText($"testassets/generate/{projectName}.yaml"); |
||||
|
|
||||
|
Assert.Equal(expectedContent, content); |
||||
|
} |
||||
|
|
||||
|
[ConditionalFact] |
||||
|
[SkipIfDockerNotRunning] |
||||
|
public async Task FrontendBackendGenerateTest() |
||||
|
{ |
||||
|
var projectName = "frontend-backend"; |
||||
|
var environment = "production"; |
||||
|
|
||||
|
var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName)); |
||||
|
using var tempDirectory = TempDirectory.Create(); |
||||
|
DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath); |
||||
|
|
||||
|
var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml")); |
||||
|
|
||||
|
var application = ConfigFactory.FromFile(projectFile); |
||||
|
|
||||
|
// Need to add docker registry for generate
|
||||
|
application.Registry = "test"; |
||||
|
|
||||
|
await GenerateHost.ExecuteGenerateAsync(new OutputContext(sink, Verbosity.Debug), application, environment, interactive: false); |
||||
|
|
||||
|
// name of application is the folder
|
||||
|
var content = File.ReadAllText(Path.Combine(tempDirectory.DirectoryPath, $"{projectName}-generate-{environment}.yaml")); |
||||
|
var expectedContent = File.ReadAllText($"testassets/generate/{projectName}.yaml"); |
||||
|
|
||||
|
Assert.Equal(expectedContent, content); |
||||
|
} |
||||
|
|
||||
|
[ConditionalFact] |
||||
|
[SkipIfDockerNotRunning] |
||||
|
public async Task MultipleProjectGenerateTest() |
||||
|
{ |
||||
|
var projectName = "multi-project"; |
||||
|
var environment = "production"; |
||||
|
|
||||
|
var projectDirectory = new DirectoryInfo(Path.Combine(TestHelpers.GetSolutionRootDirectory("tye"), "samples", projectName)); |
||||
|
using var tempDirectory = TempDirectory.Create(); |
||||
|
DirectoryCopy.Copy(projectDirectory.FullName, tempDirectory.DirectoryPath); |
||||
|
|
||||
|
var projectFile = new FileInfo(Path.Combine(tempDirectory.DirectoryPath, "tye.yaml")); |
||||
|
|
||||
|
var application = ConfigFactory.FromFile(projectFile); |
||||
|
|
||||
|
// Need to add docker registry for generate
|
||||
|
application.Registry = "test"; |
||||
|
|
||||
|
await GenerateHost.ExecuteGenerateAsync(new OutputContext(sink, Verbosity.Debug), application, environment, interactive: false); |
||||
|
|
||||
|
// name of application is the folder
|
||||
|
var content = File.ReadAllText(Path.Combine(tempDirectory.DirectoryPath, $"{projectName}-generate-{environment}.yaml")); |
||||
|
var expectedContent = File.ReadAllText($"testassets/generate/{projectName}.yaml"); |
||||
|
|
||||
|
Assert.Equal(expectedContent, content); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,101 @@ |
|||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: backend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: backend |
||||
|
image: test/backend:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: ASPNETCORE_URLS |
||||
|
value: http://*:5050 |
||||
|
- name: SERVICE__FRONTEND__PORT |
||||
|
value: '5051' |
||||
|
- name: SERVICE__FRONTEND__HOST |
||||
|
value: 'frontend' |
||||
|
ports: |
||||
|
- containerPort: 5050 |
||||
|
... |
||||
|
--- |
||||
|
kind: Service |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: backend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
selector: |
||||
|
app.kubernetes.io/name: backend |
||||
|
type: ClusterIP |
||||
|
ports: |
||||
|
- name: backend |
||||
|
protocol: TCP |
||||
|
port: 5050 |
||||
|
targetPort: 5050 |
||||
|
... |
||||
|
--- |
||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: frontend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: frontend |
||||
|
image: test/frontend:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: ASPNETCORE_URLS |
||||
|
value: http://*:5051 |
||||
|
- name: SERVICE__BACKEND__PORT |
||||
|
value: '5050' |
||||
|
- name: SERVICE__BACKEND__HOST |
||||
|
value: 'backend' |
||||
|
ports: |
||||
|
- containerPort: 5051 |
||||
|
... |
||||
|
--- |
||||
|
kind: Service |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: frontend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: frontend-backend |
||||
|
spec: |
||||
|
selector: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
type: ClusterIP |
||||
|
ports: |
||||
|
- name: frontend |
||||
|
protocol: TCP |
||||
|
port: 5051 |
||||
|
targetPort: 5051 |
||||
|
... |
||||
@ -0,0 +1,167 @@ |
|||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: backend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: backend |
||||
|
image: test/backend:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: ASPNETCORE_URLS |
||||
|
value: http://*:7000 |
||||
|
- name: SERVICE__FRONTEND__PORT |
||||
|
value: '8000' |
||||
|
- name: SERVICE__FRONTEND__HOST |
||||
|
value: 'frontend' |
||||
|
volumeMounts: |
||||
|
- name: rabbit-rabbit |
||||
|
mountPath: /var/tye/bindings/rabbit-rabbit |
||||
|
readOnly: true |
||||
|
ports: |
||||
|
- containerPort: 7000 |
||||
|
volumes: |
||||
|
- name: rabbit-rabbit |
||||
|
secret: |
||||
|
secretName: binding-production-rabbit-rabbit-secret |
||||
|
items: |
||||
|
- key: connectionstring |
||||
|
path: CONNECTIONSTRING__RABBIT |
||||
|
... |
||||
|
--- |
||||
|
kind: Service |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: backend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: backend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
selector: |
||||
|
app.kubernetes.io/name: backend |
||||
|
type: ClusterIP |
||||
|
ports: |
||||
|
- name: backend |
||||
|
protocol: TCP |
||||
|
port: 7000 |
||||
|
targetPort: 7000 |
||||
|
... |
||||
|
--- |
||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: frontend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
replicas: 2 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: frontend |
||||
|
image: test/frontend:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: ASPNETCORE_URLS |
||||
|
value: http://*:8000 |
||||
|
- name: SERVICE__BACKEND__PORT |
||||
|
value: '7000' |
||||
|
- name: SERVICE__BACKEND__HOST |
||||
|
value: 'backend' |
||||
|
volumeMounts: |
||||
|
- name: rabbit-rabbit |
||||
|
mountPath: /var/tye/bindings/rabbit-rabbit |
||||
|
readOnly: true |
||||
|
ports: |
||||
|
- containerPort: 8000 |
||||
|
volumes: |
||||
|
- name: rabbit-rabbit |
||||
|
secret: |
||||
|
secretName: binding-production-rabbit-rabbit-secret |
||||
|
items: |
||||
|
- key: connectionstring |
||||
|
path: CONNECTIONSTRING__RABBIT |
||||
|
... |
||||
|
--- |
||||
|
kind: Service |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: frontend |
||||
|
labels: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
selector: |
||||
|
app.kubernetes.io/name: frontend |
||||
|
type: ClusterIP |
||||
|
ports: |
||||
|
- name: frontend |
||||
|
protocol: TCP |
||||
|
port: 8000 |
||||
|
targetPort: 8000 |
||||
|
... |
||||
|
--- |
||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: worker |
||||
|
labels: |
||||
|
app.kubernetes.io/name: worker |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: worker |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: worker |
||||
|
app.kubernetes.io/part-of: multi-project |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: worker |
||||
|
image: test/worker:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: SERVICE__BACKEND__PORT |
||||
|
value: '7000' |
||||
|
- name: SERVICE__BACKEND__HOST |
||||
|
value: 'backend' |
||||
|
- name: SERVICE__FRONTEND__PORT |
||||
|
value: '8000' |
||||
|
- name: SERVICE__FRONTEND__HOST |
||||
|
value: 'frontend' |
||||
|
volumeMounts: |
||||
|
- name: rabbit-rabbit |
||||
|
mountPath: /var/tye/bindings/rabbit-rabbit |
||||
|
readOnly: true |
||||
|
volumes: |
||||
|
- name: rabbit-rabbit |
||||
|
secret: |
||||
|
secretName: binding-production-rabbit-rabbit-secret |
||||
|
items: |
||||
|
- key: connectionstring |
||||
|
path: CONNECTIONSTRING__RABBIT |
||||
|
... |
||||
@ -0,0 +1,51 @@ |
|||||
|
kind: Deployment |
||||
|
apiVersion: apps/v1 |
||||
|
metadata: |
||||
|
name: test-project |
||||
|
labels: |
||||
|
app.kubernetes.io/name: test-project |
||||
|
app.kubernetes.io/part-of: single-project |
||||
|
spec: |
||||
|
replicas: 1 |
||||
|
selector: |
||||
|
matchLabels: |
||||
|
app.kubernetes.io/name: test-project |
||||
|
template: |
||||
|
metadata: |
||||
|
labels: |
||||
|
app.kubernetes.io/name: test-project |
||||
|
app.kubernetes.io/part-of: single-project |
||||
|
spec: |
||||
|
containers: |
||||
|
- name: test-project |
||||
|
image: test/test-project:1.0.0 |
||||
|
imagePullPolicy: Always |
||||
|
env: |
||||
|
- name: ASPNETCORE_URLS |
||||
|
value: http://*:5000 |
||||
|
ports: |
||||
|
- containerPort: 5001 |
||||
|
- containerPort: 5000 |
||||
|
... |
||||
|
--- |
||||
|
kind: Service |
||||
|
apiVersion: v1 |
||||
|
metadata: |
||||
|
name: test-project |
||||
|
labels: |
||||
|
app.kubernetes.io/name: test-project |
||||
|
app.kubernetes.io/part-of: single-project |
||||
|
spec: |
||||
|
selector: |
||||
|
app.kubernetes.io/name: test-project |
||||
|
type: ClusterIP |
||||
|
ports: |
||||
|
- name: test-project |
||||
|
protocol: TCP |
||||
|
port: 5001 |
||||
|
targetPort: 5001 |
||||
|
- name: test-project |
||||
|
protocol: TCP |
||||
|
port: 5000 |
||||
|
targetPort: 5000 |
||||
|
... |
||||
Loading…
Reference in new issue