Skip to content

Commit c8492c9

Browse files
Implement per instance target server/item API and mgmt hub method src gen
1 parent d18d2b1 commit c8492c9

File tree

12 files changed

+262
-305
lines changed

12 files changed

+262
-305
lines changed

src/Certify.Core/Management/CertifyManager/CertifyManager.ManagementHub.cs

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,47 @@ private async Task<InstanceCommandResult> _managementServerClient_OnGetCommandRe
263263

264264
val = await PerformDeploymentTask(null, managedCertificateIdArg.Value, taskIdArg.Value, isPreviewOnly: false, skipDeferredTasks: false, forceTaskExecution: false);
265265
}
266+
else if (arg.CommandType == ManagementHubCommands.GetTargetServiceTypes)
267+
{
268+
val = await GetTargetServiceTypes();
269+
}
270+
else if (arg.CommandType == ManagementHubCommands.GetTargetServiceItems)
271+
{
272+
var args = JsonSerializer.Deserialize<KeyValuePair<string, string>[]>(arg.Value);
273+
var serviceTypeArg = args.FirstOrDefault(a => a.Key == "serviceType");
274+
275+
var serverType = MapStandardServerType(serviceTypeArg.Value);
276+
277+
val = await GetPrimaryWebSites(serverType, ignoreStoppedSites: true);
278+
}
279+
else if (arg.CommandType == ManagementHubCommands.GetTargetServiceItemIdentifiers)
280+
{
281+
var args = JsonSerializer.Deserialize<KeyValuePair<string, string>[]>(arg.Value);
282+
var serviceTypeArg = args.FirstOrDefault(a => a.Key == "serviceType");
283+
var itemArg = args.FirstOrDefault(a => a.Key == "itemId");
284+
285+
var serverType = MapStandardServerType(serviceTypeArg.Value);
286+
287+
val = await GetDomainOptionsFromSite(serverType, itemArg.Value);
288+
}
266289
else if (arg.CommandType == ManagementHubCommands.Reconnect)
267290
{
268291
await _managementServerClient.Disconnect();
269292
}
270293

271-
var result = new InstanceCommandResult { CommandId = arg.CommandId, Value = JsonSerializer.Serialize(val) };
272-
273-
result.ObjectValue = val;
294+
return new InstanceCommandResult { CommandId = arg.CommandId, Value = JsonSerializer.Serialize(val), ObjectValue = val };
295+
}
274296

275-
return result;
297+
private StandardServerTypes MapStandardServerType(string type)
298+
{
299+
if (StandardServerTypes.TryParse(type, out StandardServerTypes standardServerType))
300+
{
301+
return standardServerType;
302+
}
303+
else
304+
{
305+
return StandardServerTypes.Other;
306+
}
276307
}
277308

278309
private void ReportManagedItemUpdateToMgmtHub(ManagedCertificate item)

src/Certify.Core/Management/CertifyManager/CertifyManager.ServerType.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,22 @@ namespace Certify.Management
99
{
1010
public partial class CertifyManager
1111
{
12+
private async Task<ICollection<string>> GetTargetServiceTypes()
13+
{
14+
var list = new List<string>();
15+
16+
// TODO: make dynamic from service
17+
if (await IsServerTypeAvailable(StandardServerTypes.IIS))
18+
{
19+
list.Add(StandardServerTypes.IIS.ToString());
20+
};
21+
22+
if (await IsServerTypeAvailable(StandardServerTypes.Nginx))
23+
{
24+
list.Add(StandardServerTypes.Nginx.ToString());
25+
};
26+
return list;
27+
}
1228

1329
private ITargetWebServer GetTargetServerProvider(StandardServerTypes serverType)
1430
{

src/Certify.Core/Management/Servers/ServerProviderIIS.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ public IBindingDeploymentTarget GetDeploymentTarget()
5454

5555
public Task<bool> IsAvailable()
5656
{
57+
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
58+
{
59+
return Task.FromResult(false);
60+
}
61+
5762
if (!_isIISAvailable)
5863
{
5964
try

src/Certify.Models/Hub/ManagedCertificateSummary.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public class ManagedCertificateSummary
1111
{
1212
public string? InstanceId { get; set; } = string.Empty;
1313
public string? InstanceTitle { get; set; } = string.Empty;
14+
15+
public string? OS { get; set; } = string.Empty;
16+
public string? ClientDetails { get; set; } = string.Empty;
1417
/// <summary>
1518
/// Id for this managed item
1619
/// </summary>

src/Certify.Models/Hub/ManagementHubMessages.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public class ManagementHubCommands
4343
public const string GetDeploymentProviders = "GetDeploymentProviders";
4444
public const string ExecuteDeploymentTask = "ExecuteDeploymentTask";
4545

46+
public const string GetTargetServiceTypes = "GetTargetServiceTypes";
47+
public const string GetTargetServiceItems = "GetTargetServiceItems";
48+
public const string GetTargetServiceItemIdentifiers = "GetTargetServiceItemIdentifiers";
49+
4650
public const string Reconnect = "Reconnect";
4751

4852
/// <summary>

src/Certify.Server/Certify.Server.Api.Public.Client/Certify.API.Public.cs

Lines changed: 45 additions & 123 deletions
Large diffs are not rendered by default.

src/Certify.Server/Certify.Server.Api.Public.Client/nswag.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"runtime": "Net80",
2+
"runtime": "Net90",
33
"defaultVariables": null,
44
"documentGenerator": {
55
"fromDocument": {

src/Certify.Server/Certify.Server.Api.Public/Controllers/internal/HubController.cs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,20 +64,28 @@ public async Task<IActionResult> GetHubManagedItems(string? instanceId, string?
6464
list.AddRange(
6565
remote.Items
6666
.Where(i => string.IsNullOrWhiteSpace(keyword) || (!string.IsNullOrWhiteSpace(keyword) && i.Name?.Contains(keyword) == true))
67-
.Select(i => new ManagedCertificateSummary
67+
.Select(i =>
6868
{
69-
InstanceId = remote.InstanceId,
70-
InstanceTitle = instances.FirstOrDefault(i => i.InstanceId == remote.InstanceId)?.Title,
71-
Id = i.Id ?? "",
72-
Title = $"{i.Name}" ?? "",
73-
PrimaryIdentifier = i.GetCertificateIdentifiers().FirstOrDefault(p => p.Value == i.RequestConfig.PrimaryDomain) ?? i.GetCertificateIdentifiers().FirstOrDefault(),
74-
Identifiers = i.GetCertificateIdentifiers(),
75-
DateRenewed = i.DateRenewed,
76-
DateExpiry = i.DateExpiry,
77-
Comments = i.Comments ?? "",
78-
Status = i.LastRenewalStatus?.ToString() ?? "",
79-
HasCertificate = !string.IsNullOrEmpty(i.CertificatePath)
80-
})
69+
var instance = instances.FirstOrDefault(i => i.InstanceId == remote.InstanceId);
70+
71+
return new ManagedCertificateSummary
72+
{
73+
InstanceId = remote.InstanceId,
74+
InstanceTitle = instance?.Title,
75+
Id = i.Id ?? "",
76+
Title = $"{i.Name}" ?? "",
77+
OS = instance?.OS,
78+
ClientDetails = instance?.ClientName,
79+
PrimaryIdentifier = i.GetCertificateIdentifiers().FirstOrDefault(p => p.Value == i.RequestConfig.PrimaryDomain) ?? i.GetCertificateIdentifiers().FirstOrDefault(),
80+
Identifiers = i.GetCertificateIdentifiers(),
81+
DateRenewed = i.DateRenewed,
82+
DateExpiry = i.DateExpiry,
83+
Comments = i.Comments ?? "",
84+
Status = i.LastRenewalStatus?.ToString() ?? "",
85+
HasCertificate = !string.IsNullOrEmpty(i.CertificatePath)
86+
};
87+
}
88+
)
8189
);
8290
}
8391
}
Lines changed: 5 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using Certify.Client;
22
using Certify.Models;
3+
using Certify.Server.Api.Public.Services;
34
using Microsoft.AspNetCore.Authentication.JwtBearer;
45
using Microsoft.AspNetCore.Authorization;
56
using Microsoft.AspNetCore.Mvc;
@@ -18,42 +19,18 @@ public partial class TargetController : ApiControllerBase
1819

1920
private readonly ICertifyInternalApiClient _client;
2021

22+
private readonly ManagementAPI _mgmtAPI;
23+
2124
/// <summary>
2225
/// Constructor
2326
/// </summary>
2427
/// <param name="logger"></param>
2528
/// <param name="client"></param>
26-
public TargetController(ILogger<TargetController> logger, ICertifyInternalApiClient client)
29+
public TargetController(ILogger<TargetController> logger, ICertifyInternalApiClient client, ManagementAPI mgmtAPI)
2730
{
2831
_logger = logger;
2932
_client = client;
30-
}
31-
32-
/// <summary>
33-
/// Get list of known service items (e.g. websites etc) we may want to then check for domains etc to add to cert. May return many items (e.g. thousands of sites)
34-
/// </summary>
35-
/// <returns></returns>
36-
[HttpGet]
37-
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
38-
[Route("{serverType}/items")]
39-
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List<SiteInfo>))]
40-
41-
public async Task<IActionResult> GetTargetServiceItems(string serverType)
42-
{
43-
var knownServerType = GetServerTypeFromString(serverType);
44-
if (knownServerType == null)
45-
{
46-
return new NotFoundResult();
47-
}
48-
49-
var targetList = new List<Models.SiteInfo>();
50-
51-
if (await _client.IsServerAvailable((StandardServerTypes)knownServerType))
52-
{
53-
targetList.AddRange(await _client.GetServerSiteList((StandardServerTypes)knownServerType));
54-
}
55-
56-
return new OkObjectResult(targetList);
33+
_mgmtAPI = mgmtAPI;
5734
}
5835

5936
private static StandardServerTypes? GetServerTypeFromString(string value)
@@ -67,90 +44,5 @@ public async Task<IActionResult> GetTargetServiceItems(string serverType)
6744
return null;
6845
}
6946
}
70-
71-
/// <summary>
72-
/// Return details of single target server item (e.g. 1 site)
73-
/// </summary>
74-
/// <param name="serverType"></param>
75-
/// <param name="itemId"></param>
76-
/// <returns></returns>
77-
[HttpGet]
78-
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
79-
[Route("{serverType}/item/{itemId}")]
80-
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SiteInfo))]
81-
82-
public async Task<IActionResult> GetTargetServiceItem(string serverType, string itemId)
83-
{
84-
if (string.IsNullOrEmpty(itemId))
85-
{
86-
return new BadRequestResult();
87-
}
88-
89-
var knownServerType = GetServerTypeFromString(serverType);
90-
if (knownServerType == null)
91-
{
92-
return new NotFoundResult();
93-
}
94-
95-
var results = await _client.GetServerSiteList((StandardServerTypes)knownServerType, itemId);
96-
97-
if (results.Count == 0)
98-
{
99-
return new NotFoundResult();
100-
}
101-
else
102-
{
103-
return new OkObjectResult(results.First());
104-
}
105-
}
106-
107-
/// <summary>
108-
/// Get list of known service items (e.g. websites etc) we may want to then check for domains etc to add to cert
109-
/// </summary>
110-
/// <returns></returns>
111-
[HttpGet]
112-
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
113-
[Route("{serverType}/item/{itemId}/identifiers")]
114-
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(List<DomainOption>))]
115-
116-
public async Task<IActionResult> GetTargetServiceItemIdentifiers(string serverType, string itemId)
117-
{
118-
var targetList = new List<Models.DomainOption>();
119-
120-
var knownServerType = GetServerTypeFromString(serverType);
121-
if (knownServerType == null)
122-
{
123-
return new NotFoundResult();
124-
}
125-
126-
targetList.AddRange(await _client.GetServerSiteDomains((StandardServerTypes)knownServerType, itemId));
127-
128-
return new OkObjectResult(targetList);
129-
130-
}
131-
/// <summary>
132-
/// Get list of target services this server supports (e.g. IIS etc)
133-
/// </summary>
134-
/// <returns></returns>
135-
[HttpGet]
136-
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
137-
[Route("services")]
138-
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(string[]))]
139-
public async Task<IActionResult> GetTargetServiceTypes()
140-
{
141-
var list = new List<string>();
142-
143-
// TODO: make dynamic from service
144-
if (await _client.IsServerAvailable(StandardServerTypes.IIS))
145-
{
146-
list.Add(StandardServerTypes.IIS.ToString());
147-
};
148-
149-
if (await _client.IsServerAvailable(StandardServerTypes.Nginx))
150-
{
151-
list.Add(StandardServerTypes.Nginx.ToString());
152-
};
153-
return new OkObjectResult(list);
154-
}
15547
}
15648
}

src/Certify.SourceGenerators/ApiMethods.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,48 @@ public static List<GeneratedAPI> GetApiDefinitions()
309309
{ "instanceId", "string" }
310310
}
311311
},
312+
new GeneratedAPI {
313+
OperationName = "GetTargetServiceTypes",
314+
OperationMethod = HttpGet,
315+
Comment = "Get Service Types present on instance (IIS, nginx etc)",
316+
UseManagementAPI = true,
317+
ManagementHubCommandType = Models.Hub.ManagementHubCommands.GetTargetServiceTypes,
318+
PublicAPIController = "Target",
319+
PublicAPIRoute = "{instanceId}/types",
320+
ReturnType = "ICollection<string>",
321+
Params =new Dictionary<string, string>{
322+
{ "instanceId", "string" }
323+
}
324+
},
325+
new GeneratedAPI {
326+
OperationName = "GetTargetServiceItems",
327+
OperationMethod = HttpGet,
328+
Comment = "Get Service items (sites) present on instance (IIS, nginx etc).",
329+
UseManagementAPI = true,
330+
ManagementHubCommandType = Models.Hub.ManagementHubCommands.GetTargetServiceItems,
331+
PublicAPIController = "Target",
332+
PublicAPIRoute = "{instanceId}/{serviceType}/items",
333+
ReturnType = "ICollection<SiteInfo>",
334+
Params =new Dictionary<string, string>{
335+
{ "instanceId", "string" },
336+
{ "serviceType", "string" }
337+
}
338+
},
339+
new GeneratedAPI {
340+
OperationName = "GetTargetServiceItemIdentifiers",
341+
OperationMethod = HttpGet,
342+
Comment = "Get Service item identifiers (domains on a website etc) present on instance (IIS, nginx etc)",
343+
UseManagementAPI = true,
344+
ManagementHubCommandType = Models.Hub.ManagementHubCommands.GetTargetServiceItemIdentifiers,
345+
PublicAPIController = "Target",
346+
PublicAPIRoute = "{instanceId}/{serviceType}/item/{itemId}/identifiers",
347+
ReturnType = "ICollection<DomainOption>",
348+
Params =new Dictionary<string, string>{
349+
{ "instanceId", "string" },
350+
{ "serviceType", "string" },
351+
{ "itemId", "string" }
352+
}
353+
},
312354
new GeneratedAPI {
313355
OperationName = "GetChallengeProviders",
314356
OperationMethod = HttpGet,

0 commit comments

Comments
 (0)