dnsmadeeasy 0.3.5 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +31 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +272 -107
- data/.travis.yml +2 -1
- data/CLAUDE.md +67 -0
- data/Gemfile +9 -1
- data/README.md +506 -310
- data/Rakefile +4 -4
- data/dnsmadeeasy.gemspec +44 -27
- data/docs/badges/coverage_badge.svg +21 -0
- data/docs/dry-cli-based-tools.webloc +8 -0
- data/docs/plan-zone-management.md +756 -0
- data/docs/plans/01-plan-ruby4-baseline.md +38 -0
- data/docs/plans/02-plan-dry-cli-launcher.md +44 -0
- data/docs/plans/03-plan-account-command.md +43 -0
- data/docs/plans/04-plan-zone-record-model.md +48 -0
- data/docs/plans/05-plan-zone-parser.md +41 -0
- data/docs/plans/06-plan-zone-formatter.md +43 -0
- data/docs/plans/07-plan-zone-export.md +58 -0
- data/docs/plans/08-plan-zone-diff.md +42 -0
- data/docs/plans/09-plan-zone-apply.md +69 -0
- data/docs/plans/10-plan-docs-cleanup.md +55 -0
- data/docs/spec-zone-management.md +242 -0
- data/exe/dme +13 -2
- data/exe/dmez +6 -0
- data/lib/dme.rb +6 -6
- data/lib/dnsmadeeasy/api/client.rb +31 -32
- data/lib/dnsmadeeasy/cli/box_output.rb +9 -0
- data/lib/dnsmadeeasy/cli/commands/account.rb +222 -0
- data/lib/dnsmadeeasy/cli/commands/base.rb +119 -0
- data/lib/dnsmadeeasy/cli/commands/legacy_operation.rb +30 -0
- data/lib/dnsmadeeasy/cli/commands/version.rb +22 -0
- data/lib/dnsmadeeasy/cli/commands/zone.rb +326 -0
- data/lib/dnsmadeeasy/cli/commands.rb +19 -0
- data/lib/dnsmadeeasy/cli/input.rb +14 -0
- data/lib/dnsmadeeasy/cli/launcher.rb +53 -0
- data/lib/dnsmadeeasy/cli/message_helpers.rb +81 -0
- data/lib/dnsmadeeasy/cli/reported_error.rb +10 -0
- data/lib/dnsmadeeasy/credentials/api_keys.rb +11 -9
- data/lib/dnsmadeeasy/credentials/yaml_file.rb +28 -27
- data/lib/dnsmadeeasy/credentials.rb +3 -4
- data/lib/dnsmadeeasy/runner.rb +102 -98
- data/lib/dnsmadeeasy/types.rb +19 -0
- data/lib/dnsmadeeasy/version.rb +2 -1
- data/lib/dnsmadeeasy/zone/aname_flattener.rb +63 -0
- data/lib/dnsmadeeasy/zone/apply_executor.rb +189 -0
- data/lib/dnsmadeeasy/zone/apply_result.rb +22 -0
- data/lib/dnsmadeeasy/zone/diff.rb +152 -0
- data/lib/dnsmadeeasy/zone/file.rb +26 -0
- data/lib/dnsmadeeasy/zone/parser.rb +172 -0
- data/lib/dnsmadeeasy/zone/plan.rb +28 -0
- data/lib/dnsmadeeasy/zone/plan_action.rb +29 -0
- data/lib/dnsmadeeasy/zone/plan_renderer.rb +91 -0
- data/lib/dnsmadeeasy/zone/provider_record.rb +18 -0
- data/lib/dnsmadeeasy/zone/record.rb +44 -0
- data/lib/dnsmadeeasy/zone/record_set.rb +23 -0
- data/lib/dnsmadeeasy/zone/remote_adapter.rb +94 -0
- data/lib/dnsmadeeasy/zone/remote_records.rb +26 -0
- data/lib/dnsmadeeasy/zone/serializer.rb +115 -0
- data/lib/dnsmadeeasy.rb +61 -31
- metadata +184 -23
data/README.md
CHANGED
|
@@ -1,105 +1,420 @@
|
|
|
1
|
-
|
|
2
|
-
[](https://travis-ci.org/kigster/dnsmadeeasy)
|
|
3
|
-
[](https://codeclimate.com/github/kigster/dnsmadeeasy/maintainability)
|
|
4
|
-
[](https://codeclimate.com/github/kigster/dnsmadeeasy/test_coverage)
|
|
1
|
+
# DnsMadeEasy (`dmez`)
|
|
5
2
|
|
|
3
|
+
[](https://badge.fury.io/rb/dnsmadeeasy)  
|
|
6
4
|
|
|
7
|
-
# DnsMadeEasy — Ruby Client API (Supporting SDK V2.0)
|
|
8
5
|
|
|
9
|
-
|
|
6
|
+
## Ruby Client API Library Supporting Rest API SDK V2.0
|
|
10
7
|
|
|
11
|
-
|
|
8
|
+
### Gem Version 1.0 Supporting Zone Exports, Formatting, Plan, Apply
|
|
12
9
|
|
|
13
|
-
**DnsMadeEasy** allows you to fetch, create, update DNS records, as long as you know your API key and the secret.
|
|
14
10
|
|
|
15
|
-
### Setting up Credentials
|
|
16
11
|
|
|
17
|
-
|
|
12
|
+
> [!IMPORTANT]
|
|
13
|
+
>
|
|
14
|
+
> This gem is not backwards compatible with the previous version. It has been updated to work with DNS zone files and follow Terraform's pattern of the `read` → `plan` → `apply` loop. The old `dme` executable is deprecated in favor of `dmez`.
|
|
15
|
+
|
|
16
|
+
------
|
|
17
|
+
|
|
18
|
+
This gem ships two things:
|
|
19
|
+
|
|
20
|
+
1. The **`dmez` command line tool** — manage your DNS Made Easy zones as standard zone files with a Terraform-style `export` → `plan` → `apply` workflow, plus direct access to every account API operation.
|
|
21
|
+
1. A **fully featured Ruby client** for the DNS Made Easy REST API V2.0.
|
|
22
|
+
|
|
23
|
+
DME is an **excellent** provider, and is highly recommended for their ease of use, very solid API, and great customer support. They also offer free DNS failover with business accounts, which is highly recommended for the arrays of load balancers in front of your app.
|
|
24
|
+
|
|
25
|
+
## Installation
|
|
26
|
+
|
|
27
|
+
Add this line to your application's Gemfile:
|
|
28
|
+
|
|
29
|
+
```ruby
|
|
30
|
+
gem 'dnsmadeeasy'
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
And then execute `bundle`, or install it yourself:
|
|
34
|
+
|
|
35
|
+
```console
|
|
36
|
+
gem install dnsmadeeasy
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## The `dmez` CLI
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
$ dmez --help
|
|
43
|
+
Commands:
|
|
44
|
+
dmez account [ARGUMENT|SUBCOMMAND] # Execute DNS Made Easy account API operation
|
|
45
|
+
dmez version # Print version
|
|
46
|
+
dmez zone [SUBCOMMAND] # Zone file commands
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Every command exits `0` on success and `1` on failure, and **stdout carries only payload** (zone files, plan output) — all status boxes, warnings, and progress go to stderr. Piping and redirection are always safe, and every successful operation ends with a green summary box on stderr telling you what was done.
|
|
50
|
+
|
|
51
|
+
### CLI Credentials
|
|
52
|
+
|
|
53
|
+
You can find your API Key and Secret on the [Account Settings Page](https://cp.dnsmadeeasy.com/account/info) of the DME UI. The CLI resolves credentials in this order:
|
|
54
|
+
|
|
55
|
+
1. Explicit flags: `--api-key=KEY --api-secret=SECRET`
|
|
56
|
+
1. An INI file passed via `--credentials=PATH`
|
|
57
|
+
1. Environment variables `DNSMADEEASY_API_KEY` and `DNSMADEEASY_API_SECRET`
|
|
58
|
+
1. A default INI file: `~/.dnsmadeeasy/credentials.ini` (or `./.dnsmadeeasy/credential.ini`)
|
|
59
|
+
|
|
60
|
+
The INI format is two lines:
|
|
61
|
+
|
|
62
|
+
```ini
|
|
63
|
+
dns_dnsmadeeasy_api_key = 06cb6d10-63ca-013f-380b-66219a96f4e3
|
|
64
|
+
dns_dnsmadeeasy_secret_key = 14b9eb80-63ca-013f-380c-66219a96f4e3
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
(The Ruby API additionally supports multi-account YAML files with optional encryption — see [Ruby API](#ruby-api) below.)
|
|
68
|
+
|
|
69
|
+
### Zone Management: `dmez zone`
|
|
70
|
+
|
|
71
|
+
This is the flagship feature of version 1.0: your DME zones become plain text files you can diff, review, version-control, and apply — the same `read` → `plan` → `apply` loop you know from Terraform.
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
$ dmez zone --help
|
|
75
|
+
Commands:
|
|
76
|
+
dmez zone apply FILE # Apply DNS changes for a zone file
|
|
77
|
+
dmez zone export DOMAIN # Export DNS Made Easy records as a canonical zone file
|
|
78
|
+
dmez zone fmt FILE # Format a DNS zone file
|
|
79
|
+
dmez zone plan FILE # Plan DNS changes for a zone file
|
|
80
|
+
dmez zone validate FILE # Validate a DNS zone file
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### `dmez zone export`
|
|
84
|
+
|
|
85
|
+
Exports the live records of a domain as a canonical, normalized zone file:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
dmez zone export example.com --output=example.com.zone
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
A real-world export looks like this:
|
|
92
|
+
|
|
93
|
+
```dns
|
|
94
|
+
$ORIGIN example.com.
|
|
95
|
+
$TTL 60
|
|
96
|
+
|
|
97
|
+
@ 300 IN A 151.101.3.52
|
|
98
|
+
@ 300 IN A 151.101.67.52
|
|
99
|
+
@ 300 IN ANAME t.sni.global.fastly.net.
|
|
100
|
+
* 300 IN CNAME t.sni.global.fastly.net.
|
|
101
|
+
_acme-challenge IN CNAME validation-abc123.acme-validations.example.net.
|
|
102
|
+
dev IN A 127.0.0.1
|
|
103
|
+
mail._domainkey IN CNAME mail.domainkey.abc123.mailprovider.example.net.
|
|
104
|
+
ssh 300 IN A 203.0.113.22
|
|
105
|
+
|
|
106
|
+
@ IN MX 10 mail.protonmail.ch.
|
|
107
|
+
@ IN MX 20 mailsec.protonmail.ch.
|
|
108
|
+
|
|
109
|
+
_imaps._tcp 1800 IN SRV 0 1 993 imap.fastmail.com.
|
|
110
|
+
_submission._tcp 1800 IN SRV 0 1 587 smtp.fastmail.com.
|
|
111
|
+
|
|
112
|
+
@ IN TXT "v=spf1 include:_spf.protonmail.ch ~all"
|
|
113
|
+
@ IN TXT "google-site-verification=abc123def456"
|
|
114
|
+
_dmarc IN TXT "v=DMARC1; p=quarantine"
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Things to notice:
|
|
118
|
+
|
|
119
|
+
- **`$TTL` is derived from your records** — it is set to the most common record TTL, and only records that deviate carry an explicit TTL (the `300` and `1800` above). The export is TTL-lossless: re-parsing it yields exactly the TTLs the provider reported.
|
|
120
|
+
- **ANAME records are preserved as ANAME.** ANAME is not a standard DNS record type (it exists only inside providers), and DME's own zone export *flattens* ANAMEs into resolved A-record snapshots — which go stale as soon as the target rotates. `dmez` keeps them first-class so the file remains a faithful, apply-able representation of your account. If you need an RFC-portable file (for BIND, or to migrate providers), pass `--strict-rfc` to the `dmez zone export` command: ANAMEs are flattened into their currently resolved A records, and a warning is printed for each conversion — if and only if a conversion happened.
|
|
121
|
+
- **Apex NS records are omitted by default** since DME manages them; pass `--include-apex-ns` to include them.
|
|
122
|
+
- Records are sorted and grouped deterministically, so exports diff cleanly in git.
|
|
123
|
+
|
|
124
|
+
Options: `--format=rfc|json|yaml` (default `rfc`), `--output=FILE`, `--ttl=N` (default TTL for records the provider returns without one), `--include-apex-ns`, `--strict-rfc`.
|
|
125
|
+
|
|
126
|
+
#### `dmez zone validate`
|
|
127
|
+
|
|
128
|
+
Parses a zone file and reports whether it is usable, with parse errors when it is not:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
$ dmez zone validate example.com.zone
|
|
132
|
+
╔ OK ════════════════════════════════════════╗
|
|
133
|
+
║ Zone file is valid. ║
|
|
134
|
+
║ Records: 18 ║
|
|
135
|
+
╚════════════════════════════════════════════╝
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Any valid zone file parses as-is — including raw exports from DNS providers with fully-qualified owners, tab separation, per-record TTLs, and SOA records (SOA is ignored, since DME manages it). You do **not** need to run `fmt` first.
|
|
139
|
+
|
|
140
|
+
#### `dmez zone fmt`
|
|
141
|
+
|
|
142
|
+
Rewrites any valid zone file into the canonical format shown above (stdout):
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
dmez zone fmt provider-export.zone > example.com.zone
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### `dmez zone plan`
|
|
149
|
+
|
|
150
|
+
The heart of the workflow: compares a zone file (desired state) against the live records (actual state) and prints what would change — without changing anything.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
$ dmez zone plan example.com.zone --domain=example.com
|
|
154
|
+
No changes.
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
When there are differences, the plan groups them into sections:
|
|
158
|
+
|
|
159
|
+
```text
|
|
160
|
+
Create
|
|
161
|
+
- www CNAME @ (ttl=300)
|
|
162
|
+
Update
|
|
163
|
+
- send TXT v=spf1 include:example.net ~all (ttl=60) -> send TXT v=spf1 include:example.org ~all (ttl=60)
|
|
164
|
+
Skipped Creates
|
|
165
|
+
- @ NS ns0.dnsmadeeasy.com. (ttl=86400) (Apex NS records are managed by the DNS provider)
|
|
166
|
+
Skipped Deletes
|
|
167
|
+
- old CNAME retired.example.net. (ttl=300) (Delete skipped by default)
|
|
168
|
+
Manual Review
|
|
169
|
+
- @ A 151.101.131.52 (ttl=300) -> @ A 140.248.151.52 (ttl=300) (Multiple records share the same owner/type identity (desired: 5, remote: 4))
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
- **Create** — records in the file but not in the account.
|
|
173
|
+
- **Update** — records whose value changed (matched by owner and type).
|
|
174
|
+
- **Skipped Creates** — apex NS records from the file; DME manages these and the API will not create them.
|
|
175
|
+
- **Skipped Deletes** — records in the account but not in the file. Deletes never happen by default; see `apply --delete-only`.
|
|
176
|
+
- **Manual Review** — multiple records share the same owner/type identity and cannot be paired one-to-one (for example five apex `A` records in the file versus four in the account). The plan refuses to guess.
|
|
177
|
+
|
|
178
|
+
Options: `--domain=NAME` (defaults to the file's `$ORIGIN`), `--format=text|json`, `--diff-ttl`.
|
|
179
|
+
|
|
180
|
+
#### TTL Handling
|
|
181
|
+
|
|
182
|
+
`zone plan` and `zone apply` **ignore TTL-only differences by default**: a record whose only deviation from the remote is its TTL is considered unchanged, and value updates preserve the remote TTL. Pass `--diff-ttl` to treat TTLs as part of the record — TTL-only differences then become updates, and applied records take the TTL from the zone file:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
$ dmez zone plan example.com.zone --domain=example.com --diff-ttl
|
|
186
|
+
Update
|
|
187
|
+
- click CNAME links.cdn.example.net. (ttl=120) -> click CNAME links.cdn.example.net. (ttl=300)
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### `dmez zone apply`
|
|
191
|
+
|
|
192
|
+
Executes the plan against DNS Made Easy. You will be shown the number of actions and asked to confirm (skip the prompt with `--yes`):
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
$ dmez zone apply example.com.zone --domain=example.com
|
|
196
|
+
Apply 3 action(s)? Type yes to continue:
|
|
197
|
+
yes
|
|
198
|
+
╔ ✔ OK ══════════════════════════════════════╗
|
|
199
|
+
║ Zone apply complete for example.com. ║
|
|
200
|
+
║ Applied: 3 ║
|
|
201
|
+
║ Failed: 0 ║
|
|
202
|
+
║ Skipped: 2 ║
|
|
203
|
+
╚════════════════════════════════════════════╝
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Three modes control the blast radius:
|
|
207
|
+
|
|
208
|
+
| Mode | Flag | Behavior |
|
|
209
|
+
| --------------- | --------------------- | -------------------------------------------------------------------------- |
|
|
210
|
+
| Merge (default) | `--merge` | Applies creates and updates; never deletes. |
|
|
211
|
+
| Add only | `--add-only`, `-a` | Only creates missing records. |
|
|
212
|
+
| Delete only | `--delete-only`, `-d` | Only deletes records absent from the file (SOA and apex NS are protected). |
|
|
213
|
+
|
|
214
|
+
Actions run concurrently (4 workers) with progress spinners on stderr, so stdout stays clean for scripting.
|
|
215
|
+
|
|
216
|
+
#### A Complete Workflow
|
|
217
|
+
|
|
218
|
+
Setting up transactional email for a subdomain, start to finish:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# 1. Read: export current state
|
|
222
|
+
dmez zone export mail.example.com --output=mail.example.com.zone
|
|
223
|
+
|
|
224
|
+
# 2. Edit: add the records your email provider asks for
|
|
225
|
+
$EDITOR mail.example.com.zone
|
|
226
|
+
|
|
227
|
+
# 3. Validate and review the plan
|
|
228
|
+
dmez zone validate mail.example.com.zone
|
|
229
|
+
dmez zone plan mail.example.com.zone --domain=mail.example.com
|
|
230
|
+
|
|
231
|
+
# 4. Apply (add-only is the safest mode for additive changes)
|
|
232
|
+
dmez zone apply mail.example.com.zone --domain=mail.example.com --add-only --yes
|
|
233
|
+
|
|
234
|
+
# 5. Verify: re-running plan should now be a no-op
|
|
235
|
+
dmez zone plan mail.example.com.zone --domain=mail.example.com
|
|
236
|
+
# => No changes.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The edited file from step 2 might look like:
|
|
240
|
+
|
|
241
|
+
```dns
|
|
242
|
+
$ORIGIN mail.example.com.
|
|
243
|
+
$TTL 300
|
|
244
|
+
|
|
245
|
+
click IN CNAME links.mailer.example.net.
|
|
246
|
+
|
|
247
|
+
@ IN MX 10 inbound-smtp.us-east-1.amazonaws.com.
|
|
248
|
+
send IN MX 10 feedback-smtp.us-east-1.amazonses.com.
|
|
249
|
+
|
|
250
|
+
_dmarc IN TXT "v=DMARC1; p=none;"
|
|
251
|
+
mailer._domainkey IN TXT "p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC7abc123...AQAB"
|
|
252
|
+
send IN TXT "v=spf1 include:amazonses.com ~all"
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
> [!NOTE]
|
|
256
|
+
> TXT and SPF values are stored unquoted internally and quoted exactly once in zone files — regardless of whether the DME API returns them with embedded quotes. You never need to worry about double-quoting.
|
|
257
|
+
|
|
258
|
+
### Account Operations: `dmez account`
|
|
259
|
+
|
|
260
|
+
The `account` command exposes every operation of the underlying API client (the complete list of the legacy CLI):
|
|
261
|
+
|
|
262
|
+
```bash
|
|
263
|
+
❯ dmez account --list
|
|
264
|
+
all
|
|
265
|
+
base_url
|
|
266
|
+
create_a_record
|
|
267
|
+
create_aaaa_record
|
|
268
|
+
create_cname_record
|
|
269
|
+
create_domain
|
|
270
|
+
create_domains
|
|
271
|
+
create_httpred_record
|
|
272
|
+
create_mx_record
|
|
273
|
+
create_ns_record
|
|
274
|
+
create_ptr_record
|
|
275
|
+
create_record
|
|
276
|
+
create_secondary_domain
|
|
277
|
+
create_secondary_domains
|
|
278
|
+
create_secondary_ip_set
|
|
279
|
+
create_spf_record
|
|
280
|
+
create_srv_record
|
|
281
|
+
create_txt_record
|
|
282
|
+
delete_all_records
|
|
283
|
+
delete_domain
|
|
284
|
+
delete_record
|
|
285
|
+
delete_records
|
|
286
|
+
delete_secondary_domain
|
|
287
|
+
delete_secondary_ip_set
|
|
288
|
+
domain
|
|
289
|
+
domains
|
|
290
|
+
find_all
|
|
291
|
+
find_first
|
|
292
|
+
find_record_ids
|
|
293
|
+
get_id_by_domain
|
|
294
|
+
get_id_by_secondary_domain
|
|
295
|
+
records_for
|
|
296
|
+
secondary_domain
|
|
297
|
+
secondary_domains
|
|
298
|
+
secondary_ip_set
|
|
299
|
+
secondary_ip_sets
|
|
300
|
+
update_record
|
|
301
|
+
update_records
|
|
302
|
+
update_secondary_domains
|
|
303
|
+
update_secondary_ip_set
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
Run `dmez account <operation> --help` for the signature of any operation, and pass `--format=json|json_pretty|yaml|pp` to control the output format:
|
|
307
|
+
|
|
308
|
+
```bash
|
|
309
|
+
dmez account domains --format=json_pretty
|
|
310
|
+
dmez account records_for example.com
|
|
311
|
+
dmez account create_a_record example.com www 203.0.113.10
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
<a name="ruby-api"></a>
|
|
315
|
+
|
|
316
|
+
## Ruby API
|
|
317
|
+
|
|
318
|
+
**DnsMadeEasy** allows you to fetch, create, update DNS records from Ruby, as long as you know your API key and the secret.
|
|
319
|
+
|
|
320
|
+
### Setting up Credentials
|
|
18
321
|
|
|
19
322
|
Once you have the key and the secret, you have several choices:
|
|
20
323
|
|
|
21
|
-
|
|
324
|
+
#### Credentials Methods for Both: CLI and Ruby API
|
|
22
325
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
```
|
|
326
|
+
> [!NOTE]
|
|
327
|
+
>
|
|
328
|
+
> Credentials used in these examples are random UUIDs generated specifically for these examples and are not actual valid API keys and a secret.
|
|
27
329
|
|
|
28
|
-
|
|
330
|
+
- Set environment variables `DNSMADEEASY_API_KEY` and `DNSMADEEASY_API_SECRET`
|
|
29
331
|
|
|
30
|
-
|
|
31
|
-
require 'dnsmadeeasy'
|
|
332
|
+
- Put a `credentials.ini` file in the `~/.dnsmadeeasy` folder in your home, or in the current directory. The file's format is very simple:
|
|
32
333
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
334
|
+
```ini
|
|
335
|
+
dns_dnsmadeeasy_api_key = 06cb6d10-63ca-013f-380b-66219a96f4e3
|
|
336
|
+
dns_dnsmadeeasy_secret_key = 14b9eb80-63ca-013f-380c-66219a96f4e3
|
|
337
|
+
```
|
|
37
338
|
|
|
38
|
-
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
3. Configuring API keys as above is easy, and can be done using environment variables. Alternatively, it may be convenient to store credentials in a YAML file.
|
|
42
|
-
|
|
43
|
-
* If filename is not specified, there is default location where this file is searched, which is `~/.dnsmadeeasy/credentials.yml`.
|
|
44
|
-
* If filename is provided, it will be read, and must conform to the following format:
|
|
45
|
-
|
|
46
|
-
**Simple Credentials Format**
|
|
339
|
+
- If you prefer the YAML format, place the credentials into the file `~/.dnsmadeeasy/credentials.yml`:
|
|
47
340
|
|
|
48
341
|
```yaml
|
|
49
342
|
# file: ~/.dnsmadeeasy/credentials.yml
|
|
50
343
|
credentials:
|
|
51
|
-
|
|
52
|
-
|
|
344
|
+
api_key: 06cb6d10-63ca-013f-380b-66219a96f4e3
|
|
345
|
+
api_secret: 14b9eb80-63ca-013f-380c-66219a96f4e3
|
|
53
346
|
```
|
|
54
347
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Below you see two accounts, with production key and secret being encrypted. See [further below](#encryption) about encrypting your key and secrets.
|
|
348
|
+
- Or set environment variable `DNSMADEEASY_CREDENTIALS_FILE` to whatever path your credentials live. Either YAML or INI format will be supported.
|
|
58
349
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
- name: production
|
|
67
|
-
credentials:
|
|
68
|
-
api_key: "BAhTOh1TeW06OkRhdGE6OldyYXBwZXJT............"
|
|
69
|
-
api_secret: "BAhTOh1TeW06OkRhdGE6OldyYXBwZ............"
|
|
70
|
-
encryption_key: spec/fixtures/sym.key
|
|
350
|
+
#### Credentials Methods Ruby API Only
|
|
351
|
+
|
|
352
|
+
- You can directly instantiate a new instance of the `Client` class, by passing your API key and API secrets as arguments:
|
|
353
|
+
|
|
354
|
+
```ruby
|
|
355
|
+
require 'dnsmadeeasy'
|
|
356
|
+
@client = DnsMadeEasy::Api::Client.new(api_key, api_secret)
|
|
71
357
|
```
|
|
72
358
|
|
|
73
|
-
|
|
74
|
-
|
|
359
|
+
- Or, you can use the `DnsMadeEasy.configure` method to configure the key/secret pair, and then use `DnsMadeEasy` namespace to call the methods:
|
|
360
|
+
|
|
75
361
|
```ruby
|
|
76
|
-
|
|
77
|
-
DnsMadeEasy.configure_from_file(file, account = nil, encryption_key = nil)
|
|
78
|
-
|
|
79
|
-
# for example:
|
|
80
|
-
DnsMadeEasy.configure_from_file('config/dme.yaml', 'production')
|
|
81
|
-
DnsMadeEasy.domains #=> [ ... ]
|
|
82
|
-
|
|
83
|
-
# or with encrypted key passed as an argument to decrypt YAML values:
|
|
84
|
-
DnsMadeEasy.configure_from_file(
|
|
85
|
-
'config/dme.yaml',
|
|
86
|
-
'production',
|
|
87
|
-
ENV['PRODUCTION_KEY'])
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
3. Finally, you can use `DME.credentials_from_file` method that, unlike the method above, uses hash arguments:
|
|
362
|
+
require 'dnsmadeeasy'
|
|
91
363
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
364
|
+
DnsMadeEasy.configure do |config|
|
|
365
|
+
config.api_key = 'XXXX'
|
|
366
|
+
config.api_secret = 'YYYY'
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
DnsMadeEasy.domains.data.first.name #=> 'moo.gamespot.com'
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Multi-Account Credentials File Format
|
|
373
|
+
|
|
374
|
+
Below you see two accounts, with production key and secret being encrypted. See [further below](#encryption) about encrypting your key and secrets.
|
|
99
375
|
|
|
100
|
-
|
|
376
|
+
```yaml
|
|
377
|
+
accounts:
|
|
378
|
+
- name: development
|
|
379
|
+
default_account: true
|
|
380
|
+
credentials:
|
|
381
|
+
api_key: 12345678-a8f8-4466-ffff-2324aaaa9098
|
|
382
|
+
api_secret: 43009899-abcc-ffcc-eeee-09f809808098
|
|
383
|
+
- name: production
|
|
384
|
+
credentials:
|
|
385
|
+
api_key: "BAhTOh1TeW06OkRhdGE6OldyYXBwZXJT............"
|
|
386
|
+
api_secret: "BAhTOh1TeW06OkRhdGE6OldyYXBwZ............"
|
|
387
|
+
encryption_key: spec/fixtures/sym.key
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
You can use the following method to access both simple and multi-account YAML configurations:
|
|
391
|
+
|
|
392
|
+
```ruby
|
|
393
|
+
require 'dnsmadeeasy'
|
|
394
|
+
DnsMadeEasy.configure_from_file(file, account = nil, encryption_key = nil)
|
|
395
|
+
|
|
396
|
+
# for example:
|
|
397
|
+
DnsMadeEasy.configure_from_file('config/dme.yaml', 'production')
|
|
398
|
+
DnsMadeEasy.domains #=> [ ... ]
|
|
399
|
+
|
|
400
|
+
# or with encrypted key passed as an argument to decrypt YAML values:
|
|
401
|
+
DnsMadeEasy.configure_from_file(
|
|
402
|
+
'config/dme.yaml',
|
|
403
|
+
'production',
|
|
404
|
+
ENV['PRODUCTION_KEY'])
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
Finally, you can use `DME.credentials_from_file` method that, unlike the method above, uses hash arguments:
|
|
408
|
+
|
|
409
|
+
```ruby
|
|
410
|
+
@creds = DnsMadeEasy.credentials_from_file(file: 'my-creds.yml',
|
|
411
|
+
account: 'production',
|
|
412
|
+
encryption_key: 'MY_KEY')
|
|
413
|
+
@creds.api_key # => ...
|
|
414
|
+
@creds.api_secret # => ...
|
|
415
|
+
```
|
|
101
416
|
|
|
102
|
-
|
|
417
|
+
Method above simply returns the credentials instance, but does not "save" it as the default credentials like `configure_from_file`. Therefore, if you need to access multiple accounts at the same time, this method will help you maintain multiple credentials at the same time.
|
|
103
418
|
|
|
104
419
|
Once you configure the keys, you can also use the shortcut module to save you some typing:
|
|
105
420
|
|
|
@@ -108,36 +423,31 @@ require 'dnsmadeeasy/dme'
|
|
|
108
423
|
DME.domains.data.first.name #=> 'moo.gamespot.com'
|
|
109
424
|
```
|
|
110
425
|
|
|
111
|
-
This has the advantage of being much shorter, but might conflict with existing modules in your Ruby VM.
|
|
426
|
+
This has the advantage of being much shorter, but might conflict with existing modules in your Ruby VM.
|
|
112
427
|
In this case, just do not require `dnsmadeeasy/dme` and only require `dnsmadeeasy`, and you'll be fine.
|
|
113
428
|
Otherwise, using `DME` is identical to using `DnsMadeEasy`, assuming you required `dnsmadeeasy/dme` file.
|
|
114
|
-
|
|
115
429
|
|
|
116
430
|
### Which Namespace to Use? What is `DME` versus `DnsMadeEasy`?
|
|
117
431
|
|
|
118
432
|
Since `DnsMadeEasy` is a bit of a mouthful, we decided to offer (in addition to the standard `DnsMadeEasy` namespace) the abbreviated module `DME` that simply forwards all messages to the module `DnsMadeEasy`. If in your Ruby VM there is no conflicting top-level class `DME`, then you can `require 'dnsmadeeasy/dme'` to get all of the DnsMadeEasy client library functionality without having to type the full name once. You can even do `require 'dme'`.
|
|
119
433
|
|
|
120
|
-
Whenever you require `dme` you also import the `DnsMadeEasy` namespace.
|
|
434
|
+
Whenever you require `dme` you also import the `DnsMadeEasy` namespace. **The opposite is not true.**
|
|
121
435
|
|
|
122
436
|
So if you DO have a name clash with another top-level module `DME`, simply do `require 'dnsmadeeasy'` and none of the `DME` module namespace will be loaded.
|
|
123
437
|
|
|
124
438
|
In a nutshell you have three ways to access all methods provided by the [`DnsMadeEasy::Api::Client`](http://www.rubydoc.info/gems/dnsmadeeasy/DnsMadeEasy/Api/Client) class:
|
|
125
439
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
440
|
+
1. Instantiate and use the client class directly,
|
|
441
|
+
1. Use the top-level module `DnsMadeEasy` with `require 'dnsmadeeasy'`
|
|
442
|
+
1. Use the shortened top-level module `DME` with `require 'dnsmadeeasy/dme'`
|
|
443
|
+
|
|
131
444
|
### Examples
|
|
132
445
|
|
|
133
446
|
Whether or not you are accessing a single account or multiple, it is recommended that you save your credentials (the API key and the secret) encrypted in the above mentioned file `~/.dnsmadeeasy/credentials.yml` (or any file of you preference).
|
|
134
|
-
___
|
|
135
447
|
|
|
136
|
-
>
|
|
137
|
-
>
|
|
138
|
-
>
|
|
139
|
-
> * If you use encryption, do not check in your key!
|
|
140
|
-
___
|
|
448
|
+
> [!WARNING]
|
|
449
|
+
>
|
|
450
|
+
> _**DO NOT check that file into your repo! If you use encryption, do not check in your key!**_
|
|
141
451
|
|
|
142
452
|
The examples that follow assume credentials have already been configured, and so we explore the API.
|
|
143
453
|
|
|
@@ -161,7 +471,7 @@ IRB > DME.api_key
|
|
|
161
471
|
|
|
162
472
|
IRB > DME.api_secret
|
|
163
473
|
⤷ "2265bc3-e31ead-95b286312e-c215b6a0"
|
|
164
|
-
|
|
474
|
+
|
|
165
475
|
IRB > DME.domain('gamespot.live').delegateNameServers
|
|
166
476
|
⤷ #<Hashie::Array ["ns-125-c.gandi.net.", "ns-129-a.gandi.net.", "ns-94-b.gandi.net."]>
|
|
167
477
|
|
|
@@ -173,7 +483,7 @@ IRB > @client = DME.client
|
|
|
173
483
|
@options={},
|
|
174
484
|
@requests_remaining=149,
|
|
175
485
|
@request_limit=150,
|
|
176
|
-
@base_uri="https://api.dnsmadeeasy.com/V2.0">
|
|
486
|
+
@base_uri="https://api.dnsmadeeasy.com/V2.0">
|
|
177
487
|
```
|
|
178
488
|
|
|
179
489
|
Next, let's fetch a particular domain, get it's records and compute the counts for each record type, such as 'A', 'NS', etc.
|
|
@@ -186,7 +496,7 @@ IRB > records.data.select{|f| f.type == 'A' }.map(&:name)
|
|
|
186
496
|
⤷ ["www", "vpn-us-east1", "vpn-us-east2", "staging", "yourmom"]
|
|
187
497
|
IRB > types = records.data.map(&:type)
|
|
188
498
|
⤷ [....]
|
|
189
|
-
IRB > require 'awesome_print'
|
|
499
|
+
IRB > require 'awesome_print'
|
|
190
500
|
IRB > ap Hash[types.group_by {|x| x}.map {|k,v| [k,v.count]}]
|
|
191
501
|
{
|
|
192
502
|
"MX" => 2,
|
|
@@ -201,217 +511,82 @@ IRB > ap Hash[types.group_by {|x| x}.map {|k,v| [k,v.count]}]
|
|
|
201
511
|
|
|
202
512
|
All public methods of this library return a Hash-like object, that is actually an instance of the class [`Hashie::Mash`](https://github.com/intridea/hashie). `Hashie::Mash` supports the very useful ability to reach deeply nested hash values via a chain of method calls instead of using a train of square brackets. You can always convert it to a regular hash either `to_hash` or `to_h` on an instance of a `Hashie::Mash` to get a pure hash representation.
|
|
203
513
|
|
|
204
|
-
> NOTE
|
|
205
|
-
>
|
|
206
|
-
>
|
|
207
|
-
> IRB > recs.to_h['data'].last.value
|
|
208
|
-
> ⤷ "54.200.26.233"
|
|
209
|
-
> IRB > recs.to_hash['data'].last.value
|
|
210
|
-
> "NoMethodError: undefined method `value` for #<Hash:0x00007fe36fab0f68>"
|
|
211
|
-
> IRB > recs.to_hash['data'].last['value']
|
|
212
|
-
> ⤷ "54.200.26.233"
|
|
213
|
-
> ```
|
|
214
|
-
|
|
215
|
-
For more information on the actual JSON API, please refer to the [following PDF document](http://www.dnsmadeeasy.com/integration/pdf/API-Docv2.pdf).
|
|
216
|
-
|
|
217
|
-
## Available Actions
|
|
218
|
-
|
|
219
|
-
Here is the complete of all methods supported by the `DnsMadeEasy::Api::Client`:
|
|
220
|
-
|
|
221
|
-
#### Domains
|
|
222
|
-
|
|
223
|
-
* `create_domain`
|
|
224
|
-
* `create_domains`
|
|
225
|
-
* `delete_domain`
|
|
226
|
-
* `domain`
|
|
227
|
-
* `domains`
|
|
228
|
-
* `get_id_by_domain`
|
|
229
|
-
|
|
230
|
-
#### Records
|
|
231
|
-
|
|
232
|
-
* `records_for`
|
|
233
|
-
* `all`
|
|
234
|
-
* `base_uri`
|
|
235
|
-
* `create_a_record`
|
|
236
|
-
* `create_aaaa_record`
|
|
237
|
-
* `create_cname_record`
|
|
238
|
-
* `create_httpred_record`
|
|
239
|
-
* `create_mx_record`
|
|
240
|
-
* `create_ns_record`
|
|
241
|
-
* `create_ptr_record`
|
|
242
|
-
* `create_record`
|
|
243
|
-
* `create_spf_record`
|
|
244
|
-
* `create_srv_record`
|
|
245
|
-
* `create_txt_record`
|
|
246
|
-
* `delete_all_records`
|
|
247
|
-
* `delete_record`
|
|
248
|
-
* `delete_records`
|
|
249
|
-
* `find_all`
|
|
250
|
-
* `find_first`
|
|
251
|
-
* `find_record_ids`
|
|
252
|
-
|
|
253
|
-
#### Secondary Domains
|
|
254
|
-
* `secondary_domain`
|
|
255
|
-
* `secondary_domains`
|
|
256
|
-
* `get_id_by_secondary_domain`
|
|
257
|
-
* `create_secondary_domain`
|
|
258
|
-
* `create_secondary_domains`
|
|
259
|
-
* `update_secondary_domains`
|
|
260
|
-
* `delete_secondary_domain`
|
|
261
|
-
|
|
262
|
-
#### Secondary IpSets
|
|
263
|
-
* `secondary_ip_set`
|
|
264
|
-
* `secondary_ip_sets`
|
|
265
|
-
* `create_secondary_ip_set`
|
|
266
|
-
* `update_secondary_ip_set`
|
|
267
|
-
* `delete_secondary_ip_set`
|
|
268
|
-
|
|
269
|
-
<a name="encryption"></a>
|
|
270
|
-
|
|
271
|
-
### Encryption
|
|
514
|
+
> [!NOTE]
|
|
515
|
+
>
|
|
516
|
+
> `to_hash` converts the entire object to a regular hash, including the deeply nested hashes, while `to_h` only converts the primary object, but not the nested hashes. Here is an example below -- in the first instance where we call `to_h` we are still able to call `.value` on the nested object, because only the top-level `Mash` has been converted into a `Hash`. In the second example, this call fails, because this method does not exist, and the value must be accessed via the square brackets:
|
|
272
517
|
|
|
273
|
-
It was mentioned above that the credentials YAML file may contain encrypted values. This facility is provided by the encryption gem [Sym](https://github.com/kigster/sym).
|
|
274
518
|
|
|
275
|
-
In order to encrypt your values, you need to perform the following steps:
|
|
276
519
|
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
# this creates an entry in the keychain named 'my.key' that can be used later.
|
|
285
|
-
sym -g -x my.key
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
Once you have the key generated, first, **make sure to never commit this to any repo!**. You can use 1Password for it, or something like that.
|
|
289
|
-
|
|
290
|
-
Let's encrypt our actual API key:
|
|
291
|
-
|
|
292
|
-
```bash
|
|
293
|
-
api_key="12345678-a8f8-4466-ffff-2324aaaa9098"
|
|
294
|
-
api_secret="43009899-abcc-ffcc-eeee-09f809808098"
|
|
295
|
-
sym -ck my.key -e -s "${api_key}"
|
|
296
|
-
# => prints the encrypted value
|
|
297
|
-
|
|
298
|
-
# On a mac, you can copy it to clipboard:
|
|
299
|
-
sym -ck my.key -e -s "${api_secret}" | pbcopy
|
|
520
|
+
```ruby
|
|
521
|
+
IRB > recs.to_h['data'].last.value
|
|
522
|
+
⤷ "54.200.26.233"
|
|
523
|
+
IRB > recs.to_hash['data'].last.value
|
|
524
|
+
"NoMethodError: undefined method `value` for #<Hash:0x00007fe36fab0f68>"
|
|
525
|
+
IRB > recs.to_hash['data'].last['value']
|
|
526
|
+
⤷ "54.200.26.233"
|
|
300
527
|
```
|
|
301
528
|
|
|
302
|
-
|
|
529
|
+
For more information on the actual JSON API, please refer to the [following PDF document](http://www.dnsmadeeasy.com/integration/pdf/API-Docv2.pdf).
|
|
303
530
|
|
|
304
|
-
|
|
531
|
+
### Available Actions
|
|
305
532
|
|
|
306
|
-
|
|
533
|
+
Here is the complete list of all methods supported by the `DnsMadeEasy::Api::Client`:
|
|
307
534
|
|
|
308
|
-
|
|
309
|
-
❯ dme --help
|
|
310
|
-
Usage:
|
|
311
|
-
# Execute an API call:
|
|
312
|
-
dme [ --json | --yaml ] operation [ arg1 arg2 ... ]
|
|
535
|
+
#### Domains
|
|
313
536
|
|
|
314
|
-
|
|
315
|
-
|
|
537
|
+
- `create_domain`
|
|
538
|
+
- `create_domains`
|
|
539
|
+
- `delete_domain`
|
|
540
|
+
- `domain`
|
|
541
|
+
- `domains`
|
|
542
|
+
- `get_id_by_domain`
|
|
316
543
|
|
|
317
|
-
|
|
318
|
-
Store your credentials in a YAML file
|
|
319
|
-
/Users/kig/.dnsmadeeasy/credentials.yml as follows:
|
|
544
|
+
#### Records
|
|
320
545
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
546
|
+
- `records_for`
|
|
547
|
+
- `all`
|
|
548
|
+
- `base_uri`
|
|
549
|
+
- `create_a_record`
|
|
550
|
+
- `create_aaaa_record`
|
|
551
|
+
- `create_cname_record`
|
|
552
|
+
- `create_httpred_record`
|
|
553
|
+
- `create_mx_record`
|
|
554
|
+
- `create_ns_record`
|
|
555
|
+
- `create_ptr_record`
|
|
556
|
+
- `create_record`
|
|
557
|
+
- `create_spf_record`
|
|
558
|
+
- `create_srv_record`
|
|
559
|
+
- `create_txt_record`
|
|
560
|
+
- `delete_all_records`
|
|
561
|
+
- `delete_record`
|
|
562
|
+
- `delete_records`
|
|
563
|
+
- `find_all`
|
|
564
|
+
- `find_first`
|
|
565
|
+
- `find_record_ids`
|
|
324
566
|
|
|
325
|
-
|
|
326
|
-
dme domain moo.com
|
|
327
|
-
dme --json domain moo.com
|
|
328
|
-
dme find_all moo.com A www
|
|
329
|
-
dme find_first moo.com CNAME vpn-west
|
|
330
|
-
dme --yaml find_first moo.com CNAME vpn-west
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
You can run `dme operations` to see the supported list of operations:
|
|
567
|
+
#### Secondary Domains
|
|
334
568
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
Valid Operations Are:
|
|
343
|
-
all
|
|
344
|
-
base_uri
|
|
345
|
-
create_a_record
|
|
346
|
-
create_aaaa_record
|
|
347
|
-
create_cname_record
|
|
348
|
-
create_domain
|
|
349
|
-
create_domains
|
|
350
|
-
create_httpred_record
|
|
351
|
-
create_mx_record
|
|
352
|
-
create_ns_record
|
|
353
|
-
create_ptr_record
|
|
354
|
-
create_record
|
|
355
|
-
create_secondary_domain
|
|
356
|
-
create_secondary_domains
|
|
357
|
-
create_secondary_ip_set
|
|
358
|
-
create_spf_record
|
|
359
|
-
create_srv_record
|
|
360
|
-
create_txt_record
|
|
361
|
-
delete_all_records
|
|
362
|
-
delete_domain
|
|
363
|
-
delete_record
|
|
364
|
-
delete_records
|
|
365
|
-
delete_secondary_domain
|
|
366
|
-
delete_secondary_ip_set
|
|
367
|
-
domain
|
|
368
|
-
domains
|
|
369
|
-
find_all
|
|
370
|
-
find_first
|
|
371
|
-
find_record_ids
|
|
372
|
-
get_id_by_domain
|
|
373
|
-
get_id_by_secondary_domain
|
|
374
|
-
records_for
|
|
375
|
-
secondary_domain
|
|
376
|
-
secondary_domains
|
|
377
|
-
secondary_ip_set
|
|
378
|
-
secondary_ip_sets
|
|
379
|
-
update_record
|
|
380
|
-
update_records
|
|
381
|
-
update_secondary_domains
|
|
382
|
-
update_secondary_ip_set
|
|
383
|
-
```
|
|
384
|
-
|
|
385
|
-
For example:
|
|
569
|
+
- `secondary_domain`
|
|
570
|
+
- `secondary_domains`
|
|
571
|
+
- `get_id_by_secondary_domain`
|
|
572
|
+
- `create_secondary_domain`
|
|
573
|
+
- `create_secondary_domains`
|
|
574
|
+
- `update_secondary_domains`
|
|
575
|
+
- `delete_secondary_domain`
|
|
386
576
|
|
|
387
|
-
|
|
388
|
-
❯ dme domains moo.com
|
|
389
|
-
```
|
|
577
|
+
#### Secondary IpSets
|
|
390
578
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
- dynamicDns: false
|
|
397
|
-
failed: false
|
|
398
|
-
gtdLocation: DEFAULT
|
|
399
|
-
hardLink: false
|
|
400
|
-
ttl: 60
|
|
401
|
-
failover: false
|
|
402
|
-
monitor: false
|
|
403
|
-
sourceId: 5861234
|
|
404
|
-
source: 1
|
|
405
|
-
name: www
|
|
406
|
-
value: ec2-54-202-251-7.us-west-2.compute.amazonaws.com
|
|
407
|
-
id: 43509989
|
|
408
|
-
type: CNAME
|
|
409
|
-
```
|
|
579
|
+
- `secondary_ip_set`
|
|
580
|
+
- `secondary_ip_sets`
|
|
581
|
+
- `create_secondary_ip_set`
|
|
582
|
+
- `update_secondary_ip_set`
|
|
583
|
+
- `delete_secondary_ip_set`
|
|
410
584
|
|
|
411
585
|
### Managing Domains
|
|
412
586
|
|
|
413
|
-
> NOTE
|
|
414
|
-
>
|
|
587
|
+
> [!NOTE]
|
|
588
|
+
>
|
|
589
|
+
> Below we can be using `@client` instantiated with given key and secret, or `DME` or `DnsMadeEasy` module.
|
|
415
590
|
|
|
416
591
|
To retrieve all domains:
|
|
417
592
|
|
|
@@ -449,6 +624,7 @@ DME.delete_domain ('test.io')
|
|
|
449
624
|
### Managing Secondary Domains
|
|
450
625
|
|
|
451
626
|
To retrieve all secondary domains:
|
|
627
|
+
|
|
452
628
|
```ruby
|
|
453
629
|
DME.secondary_domains
|
|
454
630
|
```
|
|
@@ -478,8 +654,8 @@ DME.create_secondary_domains(%w[test.io moo.re], IP_SET_ID)
|
|
|
478
654
|
To update a secondary domain:
|
|
479
655
|
|
|
480
656
|
```ruby
|
|
481
|
-
# IP_SET_ID is id of ip_set you want to associate
|
|
482
|
-
# DOMAIN_ID is id of domain
|
|
657
|
+
# IP_SET_ID is id of ip_set you want to associate
|
|
658
|
+
# DOMAIN_ID is id of domain
|
|
483
659
|
DME.update_secondary_domains([DOMAIN_ID], IP_SET_ID)
|
|
484
660
|
```
|
|
485
661
|
|
|
@@ -492,6 +668,7 @@ DME.delete_secondary_domain('test.io')
|
|
|
492
668
|
### Managing Secondary IpSets
|
|
493
669
|
|
|
494
670
|
To retrieve all secondary IpSets:
|
|
671
|
+
|
|
495
672
|
```ruby
|
|
496
673
|
DME.secondary_ip_sets
|
|
497
674
|
```
|
|
@@ -572,7 +749,7 @@ Below are the method calls for `MX`, `SRV`, and `HTTPRED` types:
|
|
|
572
749
|
DME.create_mx_record ('test.io', 'woah', 5, '127.0.0.1', {})
|
|
573
750
|
# Arguments are: domain_name, name, priority, weight, port, value, options = {}
|
|
574
751
|
DME.create_srv_record ('test.io', 'woah', 1, 5, 80, '127.0.0.1', {})
|
|
575
|
-
# Arguments are: domain_name, name, value, redirectType,
|
|
752
|
+
# Arguments are: domain_name, name, value, redirectType,
|
|
576
753
|
DME.create_httpred_record('test.io', 'woah', '127.0.0.1', 'STANDARD - 302',
|
|
577
754
|
# description, keywords, title, options = {}
|
|
578
755
|
'a description', 'keywords', 'a title', {})
|
|
@@ -595,7 +772,6 @@ DME.update_records('test.io',
|
|
|
595
772
|
'value'=> '127.0.0.1'
|
|
596
773
|
}
|
|
597
774
|
], { 'ttl' => '60' })
|
|
598
|
-
|
|
599
775
|
```
|
|
600
776
|
|
|
601
777
|
To get the number of API requests remaining after a call:
|
|
@@ -604,59 +780,79 @@ To get the number of API requests remaining after a call:
|
|
|
604
780
|
DME.requests_remaining
|
|
605
781
|
#=> 19898
|
|
606
782
|
```
|
|
607
|
-
|
|
783
|
+
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
> [!NOTE]
|
|
787
|
+
> Information is not available until an API call has been made.
|
|
608
788
|
|
|
609
789
|
To get the API request total limit after a call:
|
|
610
790
|
|
|
611
791
|
```ruby
|
|
612
792
|
DME.request_limit
|
|
613
793
|
#=> 2342
|
|
794
|
+
|
|
614
795
|
```
|
|
615
|
-
> NOTE: Information is not available until an API call has been made
|
|
616
796
|
|
|
797
|
+
<a name="encryption"></a>
|
|
617
798
|
|
|
618
|
-
|
|
799
|
+
### Encryption
|
|
619
800
|
|
|
620
|
-
|
|
801
|
+
It was mentioned above that the credentials YAML file may contain encrypted values. This facility is provided by the encryption gem [Sym](https://github.com/kigster/sym).
|
|
621
802
|
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
803
|
+
> [!IMPORTANT]
|
|
804
|
+
>
|
|
805
|
+
> There is a much better encryption facility called `sopsy` written in Rust. We highly recommend you use `sopsy` for encrypting your secrets, as it mints private keys on a Mac inside Appple Enclave hardware chip. For more information please see [sopsy's website](https://sopsy-cli.dev) or the [Github Project](https://github.com/kigster/sopsy).
|
|
625
806
|
|
|
626
|
-
|
|
807
|
+
------
|
|
627
808
|
|
|
628
|
-
|
|
629
|
-
$ bundle
|
|
630
|
-
```
|
|
809
|
+
In order to encrypt your values, you need to perform the following steps:
|
|
631
810
|
|
|
632
|
-
|
|
811
|
+
```bash
|
|
812
|
+
gem install sym
|
|
633
813
|
|
|
814
|
+
# let's generate a new key and save it to a file:
|
|
815
|
+
sym -g -o my.key
|
|
816
|
+
|
|
817
|
+
# if you are on Mac OS-X, you can import the key into the KeyChain.
|
|
818
|
+
# this creates an entry in the keychain named 'my.key' that can be used later.
|
|
819
|
+
sym -g -x my.key
|
|
634
820
|
```
|
|
635
|
-
|
|
821
|
+
|
|
822
|
+
Once you have the key generated, first, **make sure to never commit this to any repo!**. You can use 1Password for it, or something like that.
|
|
823
|
+
|
|
824
|
+
Let's encrypt our actual API key:
|
|
825
|
+
|
|
826
|
+
```bash
|
|
827
|
+
api_key="12345678-a8f8-4466-ffff-2324aaaa9098"
|
|
828
|
+
api_secret="43009899-abcc-ffcc-eeee-09f809808098"
|
|
829
|
+
sym -ck my.key -e -s "${api_key}"
|
|
830
|
+
# => prints the encrypted value
|
|
831
|
+
|
|
832
|
+
# On a mac, you can copy it to clipboard:
|
|
833
|
+
sym -ck my.key -e -s "${api_secret}" | pbcopy
|
|
636
834
|
```
|
|
637
835
|
|
|
836
|
+
Now, you place the encrypted values in the YAML file, and you can save "my.key" as the value against `encryption_key:` at the same level as the `api_key` and `api_secret` in the YAML file. This value can either point to a file path, or be a keychain name, or even a name of an environment variable. For full details, please see [sym documentation](https://github.com/kigster/sym#using-sym-with-the-command-line).
|
|
638
837
|
|
|
639
838
|
## Development
|
|
640
839
|
|
|
641
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle
|
|
840
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
642
841
|
|
|
643
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version,
|
|
842
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
644
843
|
|
|
645
844
|
## Acknowledgements
|
|
646
845
|
|
|
647
846
|
The current maintainer [Konstantin Gredeskoul](https://github.com/kigster) wishes to thank:
|
|
648
847
|
|
|
649
|
-
*
|
|
650
|
-
*
|
|
651
|
-
*
|
|
652
|
-
|
|
848
|
+
- *Arnoud Vermeer* for the original `dnsmadeeasy-rest-api` gem
|
|
849
|
+
- *Andre Arko, Paul Henry, James Hart* formerly of [Wanelo](wanelo.com) fame, for bringing the REST API gem up to the level.
|
|
850
|
+
- *Phil Cohen*, who graciously transferred the ownership of the name of this gem on RubyGems.org to the current maintainer.
|
|
653
851
|
|
|
654
852
|
## Contributing
|
|
655
853
|
|
|
656
|
-
Bug reports and pull requests are welcome on GitHub at
|
|
854
|
+
Bug reports and pull requests are welcome on GitHub at <https://github.com/kigster/dnsmadeeasy>.
|
|
657
855
|
|
|
658
856
|
## License
|
|
659
857
|
|
|
660
858
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
661
|
-
|
|
662
|
-
|