This repository was archived by the owner on Mar 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathProgram.cs
More file actions
197 lines (169 loc) · 7.61 KB
/
Copy pathProgram.cs
File metadata and controls
197 lines (169 loc) · 7.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
using CommandLine;
using Microsoft.Azure.Batch.SoftwareEntitlement.Common;
using Microsoft.Extensions.Logging;
namespace Microsoft.Azure.Batch.SoftwareEntitlement
{
public static class Program
{
// Logger used for program output
private static ILogger _logger;
// Provider used for ASP.NET logging
private static ILoggerProvider _provider;
private static ICertificateStore _certificateStore = new CertificateStore();
public static async Task<int> Main(string[] args)
{
var parser = new Parser(ConfigureParser);
var parseResult = parser
.ParseArguments<GenerateCommandLine, ServerCommandLine, ListCertificatesCommandLine, FindCertificateCommandLine, VerifyCommandLine>(args);
parseResult.WithParsed((CommandLineBase options) => ConfigureLogging(options));
var exitCode = ResultCodes.Failed;
if (_logger != null)
{
// Logging is ready for use, can try other things
exitCode = await parseResult.MapResult(
(GenerateCommandLine commandLine) => RunCommand(Generate, commandLine),
(ServerCommandLine commandLine) => RunCommand(Serve, commandLine),
(ListCertificatesCommandLine commandLine) => RunCommand(ListCertificates, commandLine),
(FindCertificateCommandLine commandLine) => RunCommand(FindCertificate, commandLine),
(VerifyCommandLine commandLine) => RunCommand(Submit, commandLine),
errors => Task.FromResult(ResultCodes.Failed))
.ConfigureAwait(false);
if (Debugger.IsAttached)
{
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}
return exitCode;
}
/// <summary>
/// Generation mode - create a new token for testing
/// </summary>
/// <param name="commandLine">Options from the command line.</param>
/// <returns>Exit code to return from this process.</returns>
public static Task<int> Generate(GenerateCommandLine commandLine)
{
var command = new GenerateCommand(_logger);
return Task.FromResult(command.Execute(commandLine));
}
/// <summary>
/// Serve mode - run as a standalone web server
/// </summary>
/// <param name="commandLine">Options from the command-line.</param>
/// <returns>Exit code to return from this process.</returns>
public static async Task<int> Serve(ServerCommandLine commandLine)
{
var builder = new ServerOptionBuilder(commandLine, _certificateStore);
var resultCodeOrFailure = await builder.Build()
.Select(RunServer)
.AsTask().ConfigureAwait(false);
return resultCodeOrFailure.LogIfFailed(_logger, ResultCodes.Failed);
}
private static Task<int> RunServer(ServerOptions options)
{
var server = new SoftwareEntitlementServer(options, _provider);
server.Run();
return Task.FromResult(ResultCodes.Success);
}
/// <summary>
/// List available certificates
/// </summary>
/// <param name="commandLine">Options from the command line.</param>
/// <returns>Exit code for process.</returns>
private static async Task<int> ListCertificates(ListCertificatesCommandLine commandLine)
{
var command = new ListCertificatesCommand(_logger);
return await command.Execute(commandLine).ConfigureAwait(false);
}
/// <summary>
/// Show details of one particular certificate
/// </summary>
/// <param name="commandLine">Options from the command line.</param>
/// <returns>Exit code for process.</returns>
private static async Task<int> FindCertificate(FindCertificateCommandLine commandLine)
{
var command = new FindCertificateCommand(_logger);
return await command.Execute(commandLine).ConfigureAwait(false);
}
private static async Task<int> Submit(VerifyCommandLine commandLine)
{
var command = new VerifyCommand(_logger);
return await command.Execute(commandLine).ConfigureAwait(false);
}
/// <summary>
/// Configure our logging as requested by the user
/// </summary>
/// <param name="commandLine">Options selected by the user (if any).</param>
private static void ConfigureLogging(CommandLineBase commandLine)
{
var logSetup = new LoggerSetup();
var consoleLevel = TryParseLogLevel(commandLine.LogLevel, "console", LogLevel.Information);
var actualLevel = consoleLevel.Merge(errors => LogLevel.Information);
logSetup.SendToConsole(actualLevel);
var fileLevel = TryParseLogLevel(commandLine.LogFileLevel, "file", actualLevel);
if (!string.IsNullOrEmpty(commandLine.LogFile))
{
fileLevel.OnOk(level =>
{
var file = new FileInfo(commandLine.LogFile);
logSetup.SendToFile(file, level);
});
}
var logger = logSetup.Logger;
logger.LogHeader("Software Entitlement Service Test Utility");
consoleLevel.OnError(logger.LogErrors);
fileLevel.OnError(logger.LogErrors);
// Only share our config if there were no problems during setup.
consoleLevel.With(fileLevel).OnOk(_ =>
{
_logger = logger;
_provider = logSetup.Provider;
});
}
/// <summary>
/// Configure parsing of our command-line options
/// </summary>
/// <param name="settings">Settings instance to update.</param>
private static void ConfigureParser(ParserSettings settings)
{
settings.CaseInsensitiveEnumValues = true;
settings.CaseSensitive = false;
settings.EnableDashDash = true;
settings.IgnoreUnknownArguments = false;
settings.HelpWriter = Console.Error;
}
/// <summary>
/// Run a command with full logging
/// </summary>
/// <typeparam name="T">Type of parameters provided for this command to run</typeparam>
/// <param name="command">Actual command to run.</param>
/// <param name="commandLine">Parameters provided on the command line.</param>
/// <returns>Exit code for this command.</returns>
private static async Task<int> RunCommand<T>(Func<T, Task<int>> command, T commandLine)
where T : CommandLineBase
{
try
{
return await command(commandLine).ConfigureAwait(false);
}
catch (Exception ex)
{
_logger.LogError(0, ex, ex.Message);
return ResultCodes.InternalError;
}
}
private static Result<LogLevel, ErrorSet> TryParseLogLevel(string level, string purpose, LogLevel defaultLevel)
{
if (string.IsNullOrEmpty(level))
{
return defaultLevel;
}
return purpose.ParseEnum<LogLevel>().OnError(_ => ErrorSet.Create(
$"Failed to recognize {purpose} log level '{level}'; valid choices are: error, warning, information, and debug."));
}
}
}