Browse Source

remove duplicated commands

pull/36/head
Ryan Nowak 6 years ago
parent
commit
76b595c5cb
  1. 137
      src/opulence/dotnet-opulence/DeployCommand.cs
  2. 193
      src/opulence/dotnet-opulence/InitCommand.cs
  3. 79
      src/opulence/dotnet-opulence/Program.cs
  4. 4
      src/tye/Program.DeployCommand.cs
  5. 1
      src/tye/Program.cs

137
src/opulence/dotnet-opulence/DeployCommand.cs

@ -1,137 +0,0 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Tye;
namespace Opulence
{
internal static class DeployCommand
{
public static Command Create()
{
var command = new Command("deploy", "Deploy the application to Kubernetes")
{
StandardOptions.Project,
StandardOptions.Verbosity,
StandardOptions.Environment,
};
command.Handler = CommandHandler.Create<IConsole, FileInfo, string, Verbosity>((console, project, environment, verbosity) =>
{
return ExecuteAsync(new OutputContext(console, verbosity), project, environment);
});
return command;
}
private static async Task ExecuteAsync(OutputContext output, FileInfo projectFile, string environment)
{
output.WriteBanner();
var application = await ApplicationFactory.CreateApplicationAsync(output, projectFile);
if (application.Globals.Registry?.Hostname == null)
{
throw new CommandException("A registry is required for deploy operations. run 'dotnet-opulence init'.");
}
var steps = new List<ServiceExecutor.Step>()
{
new CombineStep() { Environment = environment, },
new BuildDockerImageStep() { Environment = environment, },
new PushDockerImageStep() { Environment = environment, },
};
if (application.Globals.DeploymentKind == DeploymentKind.None)
{
// No extra steps
}
else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes)
{
steps.Add(new GenerateKubernetesManifestStep() { Environment = environment, });
}
else if (application.Globals.DeploymentKind == DeploymentKind.Oam)
{
steps.Add(new GenerateOamComponentStep() { Environment = environment, });
}
else
{
throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind);
}
// If this is command is for a project, then deploy the component manifest
// for just the project. We won't run the "application deploy" part.
if (!string.Equals(".sln", projectFile.Extension, StringComparison.Ordinal))
{
steps.Add(new DeployServiceYamlStep() { Environment = environment, });
}
var executor = new ServiceExecutor(output, application, steps);
foreach (var service in application.Services)
{
if (service.IsMatchForProject(application, projectFile))
{
await executor.ExecuteAsync(service);
}
}
if (string.Equals(".sln", projectFile.Extension, StringComparison.Ordinal))
{
await PackageApplicationAsync(output, application, Path.GetFileNameWithoutExtension(projectFile.Name), environment);
}
}
private static async Task PackageApplicationAsync(OutputContext output, Application application, string applicationName, string environment)
{
using var step = output.BeginStep("Deploying Application Manifests...");
using var tempFile = TempFile.Create();
output.WriteInfoLine($"Writing output to '{tempFile.FilePath}'.");
{
using var stream = File.OpenWrite(tempFile.FilePath);
using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);
if (application.Globals.DeploymentKind == DeploymentKind.None)
{
// No extra steps
}
else if (application.Globals.DeploymentKind == DeploymentKind.Kubernetes)
{
await ApplicationYamlWriter.WriteAsync(output, writer, application);
}
else if (application.Globals.DeploymentKind == DeploymentKind.Oam)
{
await OamApplicationGenerator.WriteOamApplicationAsync(writer, output, application, applicationName, environment);
}
else
{
throw new InvalidOperationException($"Unknown DeploymentKind: " + application.Globals.DeploymentKind);
}
}
output.WriteDebugLine("Running 'kubectl apply'.");
output.WriteCommandLine("kubectl", $"apply -f \"{tempFile.FilePath}\"");
var capture = output.Capture();
var exitCode = await Process.ExecuteAsync(
$"kubectl",
$"apply -f \"{tempFile.FilePath}\"",
System.Environment.CurrentDirectory,
stdOut: capture.StdOut,
stdErr: capture.StdErr);
output.WriteDebugLine($"Done running 'kubectl apply' exit code: {exitCode}");
if (exitCode != 0)
{
throw new CommandException("'kubectl apply' failed.");
}
output.WriteInfoLine($"Deployed application '{applicationName}'.");
step.MarkComplete();
}
}
}

193
src/opulence/dotnet-opulence/InitCommand.cs

@ -1,193 +0,0 @@
using System;
using System.Collections.Generic;
using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Invocation;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Build.Construction;
namespace Opulence
{
internal static class InitCommand
{
public static Command Create()
{
var command = new Command("init", "Initialize repo")
{
StandardOptions.Verbosity,
new Option(new[] { "-d", "--directory", }, "Directory to Initialize")
{
Argument = new Argument<DirectoryInfo>(() =>
{
return new DirectoryInfo(Environment.CurrentDirectory);
}).ExistingOnly(),
},
};
command.Handler = CommandHandler.Create<IConsole, Verbosity, DirectoryInfo>((console, verbosity, directory) =>
{
var output = new OutputContext(console, verbosity);
return ExecuteAsync(output, directory);
});
return command;
}
private static async Task ExecuteAsync(OutputContext output, DirectoryInfo directory)
{
output.WriteBanner();
string? solutionFilePath = null;
string? opulenceFilePath = null;
using (var step = output.BeginStep("Looking For Existing Config..."))
{
opulenceFilePath = DirectorySearch.AscendingSearch(directory.FullName, "Opulence.csx");
if (opulenceFilePath != null)
{
output.WriteInfoLine($"Found 'Opulence.csx' at '{opulenceFilePath}'");
step.MarkComplete();
return;
}
else
{
output.WriteInfoLine("Not Found");
step.MarkComplete();
}
}
using (var step = output.BeginStep("Looking For .sln File..."))
{
solutionFilePath = DirectorySearch.AscendingWildcardSearch(directory.FullName, "*.sln").FirstOrDefault()?.FullName;
if (opulenceFilePath == null &&
solutionFilePath != null &&
output.Confirm($"Use '{Path.GetDirectoryName(solutionFilePath)}' as Root?"))
{
opulenceFilePath = Path.Combine(Path.GetDirectoryName(solutionFilePath)!, "Opulence.csx");
step.MarkComplete();
}
else
{
output.WriteInfoLine("Not Found.");
step.MarkComplete();
}
}
if (opulenceFilePath == null &&
Path.GetFullPath(directory.FullName) != Path.GetFullPath(Environment.CurrentDirectory))
{
// User specified a directory other than the current one
using (var step = output.BeginStep("Trying Project Directory..."))
{
if (output.Confirm("Use Project Directory as Root?"))
{
opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx");
}
step.MarkComplete();
}
}
if (opulenceFilePath == null)
{
using (var step = output.BeginStep("Trying Current Directory..."))
{
if (output.Confirm("Use Current Directory as Root?"))
{
opulenceFilePath = Path.Combine(directory.FullName, "Opulence.csx");
}
step.MarkComplete();
}
}
if (opulenceFilePath == null)
{
throw new CommandException("Cannot Determine Root Directory.");
}
using (var step = output.BeginStep("Writing Opulence.csx ..."))
{
var hostname = output.Prompt("Enter the Container Registry (ex: 'example.azurecr.io' for Azure or 'example' for dockerhub)");
var services = new List<(string, string)>();
if (solutionFilePath != null && output.Confirm($"Use solution file '{solutionFilePath}' to initialize services?"))
{
services.AddRange(ReadServicesFromSolution(solutionFilePath));
services.Sort((a, b) => a.Item1.CompareTo(b.Item1));
}
using var stream = File.OpenWrite(opulenceFilePath);
using var writer = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);
await WriteOpulenceConfigAsync(writer, hostname, services);
output.WriteInfoLine($"Initialized Opulence Config at '{opulenceFilePath}'.");
step.MarkComplete();
}
}
private static IEnumerable<(string, string)> ReadServicesFromSolution(string solutionFilePath)
{
SolutionFile solution;
try
{
solution = SolutionFile.Parse(solutionFilePath);
}
catch (Exception ex)
{
throw new CommandException($"Parsing solution file '{solutionFilePath}' failed.", ex);
}
for (var i = 0; i < solution.ProjectsInOrder.Count; i++)
{
var project = solution.ProjectsInOrder[i];
if (string.Equals(Path.GetExtension(project.RelativePath), ".csproj", StringComparison.Ordinal))
{
var fileName = Path.GetFileNameWithoutExtension(project.RelativePath.Replace('\\', Path.DirectorySeparatorChar));
yield return (Names.NormalizeToFriendly(fileName), Names.NormalizeToDns(fileName));
}
}
}
private static async Task WriteOpulenceConfigAsync(TextWriter writer, string hostname, List<(string, string)> services)
{
await writer.WriteLineAsync("#r \"Opulence\"");
await writer.WriteLineAsync();
await writer.WriteLineAsync($"using Opulence;");
await writer.WriteLineAsync();
await writer.WriteLineAsync($"public class Application");
await writer.WriteLineAsync($"{{");
await writer.WriteLineAsync($" public ApplicationGlobals Globals {{ get; }} = new ApplicationGlobals()");
await writer.WriteLineAsync($" {{");
await writer.WriteLineAsync($" Registry = new ContainerRegistry(\"{hostname}\"),");
await writer.WriteLineAsync($" }};");
await writer.WriteLineAsync();
await writer.WriteLineAsync($" // Define more services and dependencies here as your application grows.");
for (var i = 0; i < services.Count; i++)
{
await writer.WriteLineAsync($" public Service {services[i].Item1} {{ get; }} = new Service(\"{services[i].Item2}\");");
if (i + 1 < services.Count)
{
await writer.WriteLineAsync();
}
}
await writer.WriteLineAsync($"}}");
await writer.WriteLineAsync();
await writer.WriteLineAsync($"Pipeline.Configure<Application>(app =>");
await writer.WriteLineAsync($"{{");
await writer.WriteLineAsync($" // Configure your service bindings here with code.");
await writer.WriteLineAsync($"}});");
}
}
}

79
src/opulence/dotnet-opulence/Program.cs

@ -1,82 +1,9 @@
using System;
using System.CommandLine;
using System.CommandLine.Builder;
using System.CommandLine.Help;
using System.CommandLine.Invocation;
using System.CommandLine.IO;
using System.CommandLine.Parsing;
using System.CommandLine.Rendering;
using System.Threading.Tasks;
namespace Opulence
{
class Program
static class Program
{
static async Task<int> Main(string[] args)
public static void Main()
{
var command = new RootCommand();
command.AddCommand(InitCommand.Create());
command.AddCommand(GenerateCommand.Create());
command.AddCommand(PackageCommand.Create());
command.AddCommand(PushCommand.Create());
command.AddCommand(DeployCommand.Create());
command.Description = "White-Glove Service for .NET and Kubernetes";
command.Handler = CommandHandler.Create<IHelpBuilder>(help =>
{
help.Write(command);
return 1;
});
var builder = new CommandLineBuilder(command);
// Parsing behavior
builder.UseHelp();
builder.UseVersionOption();
builder.UseDebugDirective();
builder.UseParseErrorReporting();
builder.ParseResponseFileAs(ResponseFileHandling.ParseArgsAsSpaceSeparated);
builder.UsePrefixes(new[] { "-", "--", }); // disable garbage windows conventions
builder.CancelOnProcessTermination();
builder.UseExceptionHandler(HandleException);
// Allow fancy drawing.
builder.UseAnsiTerminalWhenAvailable();
var parser = builder.Build();
return await parser.InvokeAsync(args);
}
private static void HandleException(Exception exception, InvocationContext context)
{
context.Console.ResetTerminalForegroundColor();
context.Console.SetTerminalForegroundColor(ConsoleColor.Red);
if (exception is OperationCanceledException)
{
context.Console.Error.WriteLine("Oh dear! Operation canceled.");
}
else if (exception is CommandException command)
{
context.Console.Error.WriteLine($"Drats! '{context.ParseResult.CommandResult.Command.Name}' failed:");
context.Console.Error.WriteLine($"\t{command.Message}");
if (command.InnerException != null)
{
context.Console.Error.WriteLine();
context.Console.Error.WriteLine(command.InnerException.ToString());
}
}
else
{
context.Console.Error.WriteLine("An unhandled exception has occurred, how unseemly: ");
context.Console.Error.WriteLine(exception.ToString());
}
context.Console.ResetTerminalForegroundColor();
context.ResultCode = 1;
}
}
}
}

4
src/tye/Program.DeployCommand.cs

@ -99,10 +99,10 @@ namespace Tye
await executor.ExecuteAsync(service);
}
await PackageApplicationAsync(output, opulenceApplication, application.Source.Directory.Name, environment);
await DeployApplicationManifestAsync(output, opulenceApplication, application.Source.Directory.Name, environment);
}
private static async Task PackageApplicationAsync(OutputContext output, Opulence.Application application, string applicationName, string environment)
private static async Task DeployApplicationManifestAsync(OutputContext output, Opulence.Application application, string applicationName, string environment)
{
using var step = output.BeginStep("Deploying Application Manifests...");

1
src/tye/Program.cs

@ -20,6 +20,7 @@ namespace Tye
};
command.AddCommand(CreateInitCommand());
command.AddCommand(CreateGenerateCommand());
command.AddCommand(CreateRunCommand(args));
command.AddCommand(CreateDeployCommand());

Loading…
Cancel
Save