Skip to content

Instantly share code, notes, and snippets.

@jpscharf
Created January 29, 2022 03:05
Show Gist options
  • Select an option

  • Save jpscharf/f8b5ffd7243fee39089c21afea0d1f42 to your computer and use it in GitHub Desktop.

Select an option

Save jpscharf/f8b5ffd7243fee39089c21afea0d1f42 to your computer and use it in GitHub Desktop.
PHP Class to Add and Delete DNS Made Easy Records for Let's Encrypt
class DnsMadeEastLeRecord {
// Docs: https://api-docs.dnsmadeeasy.com
protected $api_key;
protected $api_secret;
protected $endpoint = 'https://api.dnsmadeeasy.com/V2.0/dns/managed';
public $domain;
public $domain_id;
public $acme_record_name = '_acme-challenge';
public $acme_record_id;
public function __construct(iterable $options)
{
$this->api_key = $options['api_key'] ?? null;
$this->api_secret = $options['api_secret'] ?? null;
$this->domain = isset($options['domain'])
? strtolower($options['domain'])
: null;
$this->resolveDomainId();
}
protected function client()
{
$ts = now()->toRfc7231String();
$hmac = hash_hmac('SHA1', $ts, $this->api_secret);
$headers = [
'x-dnsme-apiKey' => $this->api_key,
'x-dnsme-requestDate' => $ts,
'x-dnsme-hmac' => $hmac,
];
return Http::withHeaders($headers)
->baseUrl($this->endpoint);
}
protected function resolveDomainId()
{
// Docs: https://api-docs.dnsmadeeasy.com/#bdf8838d-c722-4355-951f-b13049604d0c
// Endpoint: https://api.dnsmadeeasy.com/V2.0/dns/managed/
$response = $this->client()
->get('');
if (! $response->ok()) {
$error = implode(', ', $response->json()['error']);
throw new \RuntimeException($error);
}
$domain = collect($response->json()['data'])
->where('name', $this->domain)
->first();
$this->domain_id = $domain['id'] ?? null;
}
public function create(string $value, int $ttl = 600): ?int
{
// Docs: https://api-docs.dnsmadeeasy.com/#1f3ac624-b30a-46a4-904d-c1e7ffc24994
// Endpoint: https://api.dnsmadeeasy.com/V2.0/dns/managed/{$domain_id}/records/
$response = $this->client()
->post("{$domain_id}/records", [
'name' => $this->acme_record_name,
'type' => 'TXT',
'value' => $value,
'ttl' => $ttl,
]);
if (! $response->ok()) {
$error = implode(', ', $response->json()['error']);
throw new \RuntimeException($error);
}
return $this->acme_record_id = $response->json()['id'] ?? null;
}
public function verify(): bool
{
// Docs: https://api-docs.dnsmadeeasy.com/#9a7a80e8-0983-463f-aa92-ce8707e087c8
// Endpoint: https://api.dnsmadeeasy.com/V2.0/dns/managed/{$domain_id}/records?recordName=www
$response = $this->client()
->get("{$this->domain_id}/records?recordName={$this->acme_record_name}");
if (! $response->ok()) {
$error = implode(', ', $response->json()['error']);
throw new \RuntimeException($error);
}
if ($response->json()['totalRecords'] === 0) {
return false;
}
$this->acme_record_id = $response->json()['data'][0]['id'];
return ! empty($response->json()['data']);
}
public function destroy(int $record_id = null)
{
// Docs: https://api-docs.dnsmadeeasy.com/#7503c1cc-6a4b-4bf4-a32c-fdda1c8ee328
// Endpoint: https://api.dnsmadeeasy.com/V2.0/dns/managed/1119443/records/66814826
$record_id = $record_id ?? $this->acme_record_id;
if (is_null($record_id)) {
throw new \RuntimeException('record id is required');
}
$response = $this->client()
->delete("{$this->domain_id}/records/{$record_id}");
if (! $response->ok()) {
$error = implode(', ', $response->json()['error']);
throw new \RuntimeException($error);
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment