Skip to content

Commit b035c8a

Browse files
authored
Migrate GandiProvider to new LiveDns api (#639)
1 parent 81b5236 commit b035c8a

File tree

4 files changed

+166
-0
lines changed

4 files changed

+166
-0
lines changed

KeyVault.Acmebot/Options/AcmebotOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ public class AcmebotOptions
4343

4444
public GandiOptions Gandi { get; set; }
4545

46+
public GandiLiveDnsOptions GandiLiveDns { get; set; }
47+
4648
public GoDaddyOptions GoDaddy { get; set; }
4749

4850
public GoogleDnsOptions GoogleDns { get; set; }
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace KeyVault.Acmebot.Options;
2+
3+
public class GandiLiveDnsOptions
4+
{
5+
public string ApiKey { get; set; }
6+
7+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Net;
5+
using System.Net.Http;
6+
using System.Net.Http.Headers;
7+
using System.Threading.Tasks;
8+
9+
using KeyVault.Acmebot.Internal;
10+
using KeyVault.Acmebot.Options;
11+
12+
using Newtonsoft.Json;
13+
14+
namespace KeyVault.Acmebot.Providers;
15+
16+
public class GandiLiveDnsProvider : IDnsProvider
17+
{
18+
public GandiLiveDnsProvider(GandiLiveDnsOptions options)
19+
{
20+
_client = new GandiLiveDnsClient(options.ApiKey);
21+
}
22+
23+
private readonly GandiLiveDnsClient _client;
24+
25+
public string Name => "Gandi LiveDNS";
26+
27+
public int PropagationSeconds => 300;
28+
29+
public async Task<IReadOnlyList<DnsZone>> ListZonesAsync()
30+
{
31+
var zones = await _client.ListZonesAsync();
32+
33+
return zones.Select(x => new DnsZone(this) { Id = x.Fqdn, Name = x.FqdnUnicode }).ToArray();
34+
}
35+
36+
public Task CreateTxtRecordAsync(DnsZone zone, string relativeRecordName, IEnumerable<string> values)
37+
{
38+
return _client.AddRecordAsync(zone.Name, relativeRecordName, values);
39+
}
40+
41+
public Task DeleteTxtRecordAsync(DnsZone zone, string relativeRecordName)
42+
{
43+
return _client.DeleteRecordAsync(zone.Name, relativeRecordName);
44+
}
45+
46+
private class GandiLiveDnsClient
47+
{
48+
public GandiLiveDnsClient(string apiKey)
49+
{
50+
ArgumentNullException.ThrowIfNull(apiKey);
51+
52+
_httpClient = new HttpClient
53+
{
54+
BaseAddress = new Uri("https://api.gandi.net/v5/")
55+
};
56+
57+
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
58+
_httpClient.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", "Bearer " + apiKey);
59+
}
60+
61+
private readonly HttpClient _httpClient;
62+
63+
public async Task<IReadOnlyList<Domain>> ListZonesAsync()
64+
{
65+
var response = await _httpClient.GetAsync("domain/domains");
66+
67+
response.EnsureSuccessStatusCode();
68+
var domains = await response.Content.ReadAsAsync<Domain[]>();
69+
70+
return domains.Where(x => x.Nameserver.Current == "livedns").ToArray();
71+
}
72+
73+
public async Task DeleteRecordAsync(string zoneName, string relativeRecordName)
74+
{
75+
var response = await _httpClient.DeleteAsync($"livedns/domains/{zoneName}/records/{relativeRecordName}/TXT");
76+
77+
if (response.StatusCode != HttpStatusCode.NotFound)
78+
{
79+
response.EnsureSuccessStatusCode();
80+
}
81+
}
82+
83+
public async Task AddRecordAsync(string zoneName, string relativeRecordName, IEnumerable<string> values)
84+
{
85+
var response = await _httpClient.PostAsync($"livedns/domains/{zoneName}/records/{relativeRecordName}/TXT", new
86+
{
87+
rrset_values = values.ToArray(),
88+
rrset_ttl = 300 //300 is the minimal value
89+
});
90+
91+
response.EnsureSuccessStatusCode();
92+
}
93+
}
94+
public class Domain
95+
{
96+
[JsonProperty("fqdn")]
97+
public string Fqdn { get; set; }
98+
99+
[JsonProperty("tld")]
100+
public string Tld { get; set; }
101+
102+
[JsonProperty("status")]
103+
public List<string> Status { get; set; }
104+
105+
[JsonProperty("dates")]
106+
public Dates Dates { get; set; }
107+
108+
[JsonProperty("nameserver")]
109+
public Nameserver Nameserver { get; set; }
110+
111+
[JsonProperty("autorenew")]
112+
public bool Autorenew { get; set; }
113+
114+
[JsonProperty("domain_owner")]
115+
public string DomainOwner { get; set; }
116+
117+
[JsonProperty("orga_owner")]
118+
public string OrgaOwner { get; set; }
119+
120+
[JsonProperty("owner")]
121+
public string Owner { get; set; }
122+
123+
[JsonProperty("id")]
124+
public string Id { get; set; }
125+
126+
[JsonProperty("tags")]
127+
public List<string> Tags { get; set; }
128+
129+
[JsonProperty("href")]
130+
public string Href { get; set; }
131+
132+
[JsonProperty("fqdn_unicode")]
133+
public string FqdnUnicode { get; set; }
134+
}
135+
136+
public class Dates
137+
{
138+
[JsonProperty("created_at")]
139+
public DateTime CreatedAt { get; set; }
140+
141+
[JsonProperty("registry_created_at")]
142+
public DateTime RegistryCreatedAt { get; set; }
143+
144+
[JsonProperty("registry_ends_at")]
145+
public DateTime RegistryEndsAt { get; set; }
146+
147+
[JsonProperty("updated_at")]
148+
public DateTime UpdatedAt { get; set; }
149+
}
150+
151+
public class Nameserver
152+
{
153+
[JsonProperty("current")]
154+
public string Current { get; set; }
155+
}
156+
}

KeyVault.Acmebot/Startup.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ public override void Configure(IFunctionsHostBuilder builder)
120120
dnsProviders.TryAdd(options.CustomDns, o => new CustomDnsProvider(o));
121121
dnsProviders.TryAdd(options.DnsMadeEasy, o => new DnsMadeEasyProvider(o));
122122
dnsProviders.TryAdd(options.Gandi, o => new GandiProvider(o));
123+
dnsProviders.TryAdd(options.GandiLiveDns, o => new GandiLiveDnsProvider(o));
123124
dnsProviders.TryAdd(options.GoDaddy, o => new GoDaddyProvider(o));
124125
dnsProviders.TryAdd(options.GoogleDns, o => new GoogleDnsProvider(o));
125126
dnsProviders.TryAdd(options.Route53, o => new Route53Provider(o));

0 commit comments

Comments
 (0)