public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var azureCredentials = await ReadAzureCredentials(syntax); var resourceGroup = syntax.GetOption <string>(AzureResourceGroupOption, true); var appName = syntax.GetParameter <string>(AppNameParam, true); var appSlot = syntax.GetOption <string>(SlotOption, false); var privKey = await syntax.ReadKey(PrivateKeyOption, "CERTES_CERT_KEY", File, environment, true); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var order = await orderCtx.Resource(); if (order.Certificate == null) { throw new CertesCliException(string.Format(Strings.ErrorOrderIncompleted, orderCtx.Location)); } var cert = await orderCtx.Download(); var x509Cert = new X509Certificate2(cert.Certificate.ToDer()); var thumbprint = x509Cert.Thumbprint; using (var client = clientFactory.Invoke(azureCredentials)) { client.SubscriptionId = azureCredentials.DefaultSubscriptionId; var certUploaded = await FindCertificate(client, resourceGroup, thumbprint); if (certUploaded == null) { certUploaded = await UploadCertificate( client, resourceGroup, appName, appSlot, cert.ToPfx(privKey), thumbprint); } var hostNameBinding = new HostNameBindingInner { SslState = SslState.SniEnabled, Thumbprint = certUploaded.Thumbprint, }; var hostName = string.IsNullOrWhiteSpace(appSlot) ? await client.WebApps.CreateOrUpdateHostNameBindingAsync( resourceGroup, appName, domain, hostNameBinding) : await client.WebApps.CreateOrUpdateHostNameBindingSlotAsync( resourceGroup, appName, domain, hostNameBinding, appSlot); return(new { data = hostName }); } }
private async Task <IList <(string Location, string Name)> > LoadResourceGroups(RestClient restClient) { using var client = clientFactory.Invoke(restClient); client.SubscriptionId = restClient.Credentials.DefaultSubscriptionId; var resourceGroups = await client.ResourceGroups.ListAsync(); return(resourceGroups.Select(g => (g.Location, g.Name)).ToArray()); }
private async Task <IList <(string Location, string Name)> > LoadResourceGroups(AzureCredentials credentials) { using (var client = clientFactory.Invoke(credentials)) { var resourceGroups = await client.ResourceGroups.ListAsync(); return(resourceGroups.Select(g => (g.Location, g.Name)).ToArray()); } }
private async Task Execute(Args args, IConsole console) { var(orderId, domain, server, keyPath, azureOptions) = args; var(serverUri, key) = await ReadAccountKey(server, keyPath, true, false); logger.Debug("Updating account on '{0}'.", serverUri); var azureCredentials = await CreateAzureRestClient(azureOptions); var resourceGroup = azureOptions.ResourceGroup; var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderId); var authzCtx = await orderCtx.Authorization(domain) ?? throw new CertesCliException(string.Format(Strings.ErrorIdentifierNotAvailable, domain)); var challengeCtx = await authzCtx.Dns() ?? throw new CertesCliException(string.Format(Strings.ErrorChallengeNotAvailable, "dns")); var authz = await authzCtx.Resource(); var dnsValue = acme.AccountKey.DnsTxt(challengeCtx.Token); using var client = clientFactory.Invoke(azureCredentials); client.SubscriptionId = azureCredentials.Credentials.DefaultSubscriptionId; var idValue = authz.Identifier.Value; var zone = await FindDnsZone(client, idValue); var name = zone.Name.Length == idValue.Length ? "_acme-challenge" : "_acme-challenge." + idValue.Substring(0, idValue.Length - zone.Name.Length - 1); logger.Debug("Adding TXT record '{0}' for '{1}' in '{2}' zone.", dnsValue, name, zone.Name); var recordSet = await client.RecordSets.CreateOrUpdateAsync( resourceGroup, zone.Name, name, RecordType.TXT, new RecordSetInner( name : name, tTL : 300, txtRecords : new[] { new TxtRecord(new[] { dnsValue }) })); var output = new { data = recordSet }; console.WriteAsJson(output); }
public async Task <object> Execute(ArgumentSyntax syntax) { var(serverUri, key) = await ReadAccountKey(syntax, true, false); var orderUri = syntax.GetParameter <Uri>(OrderIdParam, true); var domain = syntax.GetParameter <string>(DomainParam, true); var azureCredentials = await ReadAzureCredentials(syntax); var resourceGroup = syntax.GetOption <string>(AzureResourceGroupOption, true); var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderUri); var authzCtx = await orderCtx.Authorization(domain) ?? throw new Exception(string.Format(Strings.ErrorIdentifierNotAvailable, domain)); var challengeCtx = await authzCtx.Dns() ?? throw new Exception(string.Format(Strings.ErrorChallengeNotAvailable, "dns")); var authz = await authzCtx.Resource(); var dnsValue = acme.AccountKey.DnsTxt(challengeCtx.Token); using (var client = clientFactory.Invoke(azureCredentials)) { client.SubscriptionId = azureCredentials.DefaultSubscriptionId; var idValue = authz.Identifier.Value; var zone = await FindDnsZone(client, idValue); var name = zone.Name.Length == idValue.Length ? "_acme-challenge" : "_acme-challenge." + idValue.Substring(0, idValue.Length - zone.Name.Length - 1); logger.Debug("Adding TXT record '{0}' for '{1}' in '{2}' zone.", dnsValue, name, zone.Name); var recordSet = await client.RecordSets.CreateOrUpdateAsync( resourceGroup, zone.Name, name, RecordType.TXT, new RecordSetInner( name : name, tTL : 300, txtRecords : new[] { new TxtRecord(new[] { dnsValue }) })); return(new { data = recordSet }); } }
public Command Define() { var cmd = new Command(CommandText, Strings.HelpCommandAzureApp) { new Option <string>(SlotOption, Strings.HelpSlot), new Option <string>(PrivateKeyOption, Strings.HelpPrivateKey), new Option <string>(PreferredChainOption, Strings.HelpPreferredChain), new Argument <Uri>(OrderIdParam, Strings.HelpOrderId), new Argument <string>(DomainParam, Strings.HelpDomain), new Argument <string>(AppNameParam, Strings.HelpAppName), }; AddCommonOptions(cmd); cmd.Handler = CommandHandler.Create(async(Args args, IConsole console) => { var(orderId, domain, app, slot, preferredChain, privateKey, server, keyPath, azureOptions) = args; var(serverUri, key) = await ReadAccountKey(server, keyPath, true, false); var azureCredentials = await CreateAzureRestClient(azureOptions); var privKey = await ReadKey(privateKey, "CERTES_CERT_KEY", File, environment); if (privKey == null) { throw new CertesCliException(Strings.ErrorNoPrivateKey); } var acme = ContextFactory.Invoke(serverUri, key); var orderCtx = acme.Order(orderId); var order = await orderCtx.Resource(); if (order.Certificate == null) { throw new CertesCliException(string.Format(Strings.ErrorOrderIncompleted, orderCtx.Location)); } var cert = await orderCtx.Download(preferredChain); var x509Cert = new X509Certificate2(cert.Certificate.ToDer()); var thumbprint = x509Cert.Thumbprint; using var client = clientFactory.Invoke(azureCredentials); client.SubscriptionId = azureCredentials.Credentials.DefaultSubscriptionId; var certUploaded = await FindCertificate(client, azureOptions.ResourceGroup, thumbprint); if (certUploaded == null) { certUploaded = await UploadCertificate( client, azureOptions.ResourceGroup, app, slot, cert.ToPfx(privKey), thumbprint); } var hostNameBinding = new HostNameBindingInner { SslState = SslState.SniEnabled, Thumbprint = certUploaded.Thumbprint, }; var hostName = string.IsNullOrWhiteSpace(slot) ? await client.WebApps.CreateOrUpdateHostNameBindingAsync( azureOptions.ResourceGroup, app, domain, hostNameBinding) : await client.WebApps.CreateOrUpdateHostNameBindingSlotAsync( azureOptions.ResourceGroup, app, domain, hostNameBinding, slot); var output = new { data = hostName }; console.WriteAsJson(output); }); return(cmd); }