dnsmadeeasy 0.4.0 → 1.0.3
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 +5 -10
- data/.gitignore +2 -0
- data/.rubocop.yml +5 -4
- data/.rubocop_todo.yml +251 -143
- data/CLAUDE.md +67 -0
- data/Gemfile +9 -1
- data/README.md +854 -0
- data/Rakefile +4 -4
- data/dnsmadeeasy.gemspec +56 -32
- 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/plans/11-plan-zone-cli-arguments.md +114 -0
- data/docs/spec-zone-management.md +242 -0
- data/exe/dme +13 -2
- data/exe/dmez +6 -0
- data/lib/dme.rb +7 -2
- data/lib/dnsmadeeasy/api/client.rb +32 -26
- 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 +392 -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 +93 -0
- data/lib/dnsmadeeasy/cli/reported_error.rb +10 -0
- data/lib/dnsmadeeasy/credentials/api_keys.rb +11 -9
- data/lib/dnsmadeeasy/credentials.rb +0 -1
- data/lib/dnsmadeeasy/runner.rb +24 -24
- 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 +119 -0
- data/lib/dnsmadeeasy.rb +61 -27
- metadata +212 -39
- data/.dme-help.png +0 -0
- data/README.adoc +0 -690
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dry/struct'
|
|
4
|
+
require 'dnsmadeeasy/types'
|
|
5
|
+
require 'dnsmadeeasy/zone/provider_record'
|
|
6
|
+
require 'dnsmadeeasy/zone/record_set'
|
|
7
|
+
|
|
8
|
+
module DnsMadeEasy
|
|
9
|
+
module Zone
|
|
10
|
+
# Provider records plus non-fatal warnings from remote conversion.
|
|
11
|
+
class RemoteRecords < Dry::Struct
|
|
12
|
+
transform_keys(&:to_sym)
|
|
13
|
+
|
|
14
|
+
attribute :provider_records, Types::Array.of(ProviderRecord).default([].freeze)
|
|
15
|
+
attribute :warnings, Types::Array.of(Types::StrictString).default([].freeze)
|
|
16
|
+
|
|
17
|
+
def records
|
|
18
|
+
provider_records.map(&:record)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def record_set
|
|
22
|
+
RecordSet.new(records: records)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'dnsmadeeasy/zone/file'
|
|
4
|
+
|
|
5
|
+
module DnsMadeEasy
|
|
6
|
+
module Zone
|
|
7
|
+
# Emits deterministic, normalized zone-file text.
|
|
8
|
+
class Serializer
|
|
9
|
+
# Fixed columns: owner (30), TTL (5, blank when it matches $TTL),
|
|
10
|
+
# "IN " (3), record type (7), then the payload.
|
|
11
|
+
RECORD_FORMAT = '%-30s %5s %-3s%-7s %s'
|
|
12
|
+
|
|
13
|
+
def initialize(zone_file, omit_apex_ns: true)
|
|
14
|
+
@zone_file = zone_file
|
|
15
|
+
@omit_apex_ns = omit_apex_ns
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
lines = [
|
|
20
|
+
"$ORIGIN #{zone_file.origin}",
|
|
21
|
+
"$TTL #{zone_file.ttl}",
|
|
22
|
+
''
|
|
23
|
+
]
|
|
24
|
+
lines.concat(serialized_records)
|
|
25
|
+
"#{lines.join("\n")}\n"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
attr_reader :zone_file,
|
|
31
|
+
:omit_apex_ns
|
|
32
|
+
|
|
33
|
+
def serialized_records
|
|
34
|
+
grouped_records.flat_map.with_index do |records, index|
|
|
35
|
+
lines = records.map { |record| serialize_record(record) }
|
|
36
|
+
index.zero? ? lines : [''] + lines
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def grouped_records
|
|
41
|
+
serializable_records.chunk { |record| record_group(record) }.map(&:last)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def serializable_records
|
|
45
|
+
zone_file.records
|
|
46
|
+
.reject { |record| omit_apex_ns && record.owner == '@' && record.type == 'NS' }
|
|
47
|
+
.sort_by { |record| serializer_sort_key(record) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def record_group(record)
|
|
51
|
+
case record.type
|
|
52
|
+
when 'MX'
|
|
53
|
+
:mail
|
|
54
|
+
when 'TXT', 'SPF'
|
|
55
|
+
:text
|
|
56
|
+
else
|
|
57
|
+
:address
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def serializer_sort_key(record)
|
|
62
|
+
[
|
|
63
|
+
serializer_type_group(record),
|
|
64
|
+
normalized_owner(record.owner),
|
|
65
|
+
record.type,
|
|
66
|
+
record.priority || -1,
|
|
67
|
+
record.value,
|
|
68
|
+
record.ttl
|
|
69
|
+
]
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def serializer_type_group(record)
|
|
73
|
+
case record.type
|
|
74
|
+
when 'A', 'AAAA', 'CNAME', 'ANAME', 'NS', 'PTR'
|
|
75
|
+
0
|
|
76
|
+
when 'MX', 'SRV'
|
|
77
|
+
1
|
|
78
|
+
when 'TXT', 'SPF'
|
|
79
|
+
2
|
|
80
|
+
else
|
|
81
|
+
3
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def normalized_owner(owner)
|
|
86
|
+
owner == '@' ? '' : owner
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def serialize_record(record)
|
|
90
|
+
format(RECORD_FORMAT, record.owner, ttl_token(record), 'IN', record.type, record_payload(record))
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# A single $TTL cannot represent a real zone, so records that deviate
|
|
94
|
+
# from the zone default carry an explicit right-aligned TTL.
|
|
95
|
+
def ttl_token(record)
|
|
96
|
+
record.ttl == zone_file.ttl ? '' : record.ttl.to_s
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def record_payload(record)
|
|
100
|
+
case record.type
|
|
101
|
+
when 'MX'
|
|
102
|
+
"#{record.priority} #{record.value}"
|
|
103
|
+
when 'SRV'
|
|
104
|
+
"#{record.priority} #{record.weight} #{record.port} #{record.value}"
|
|
105
|
+
when 'TXT', 'SPF'
|
|
106
|
+
quote_text(record.value)
|
|
107
|
+
else
|
|
108
|
+
record.value
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def quote_text(value)
|
|
113
|
+
return value if value.start_with?('"') && value.end_with?('"')
|
|
114
|
+
|
|
115
|
+
%("#{value}")
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
data/lib/dnsmadeeasy.rb
CHANGED
|
@@ -6,25 +6,49 @@ module DnsMadeEasy
|
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
require 'dnsmadeeasy/version'
|
|
9
|
+
require 'dnsmadeeasy/types'
|
|
9
10
|
require 'dnsmadeeasy/credentials'
|
|
10
11
|
require 'dnsmadeeasy/api/client'
|
|
12
|
+
require 'dnsmadeeasy/cli/launcher'
|
|
13
|
+
require 'dnsmadeeasy/zone/record'
|
|
14
|
+
require 'dnsmadeeasy/zone/provider_record'
|
|
15
|
+
require 'dnsmadeeasy/zone/record_set'
|
|
16
|
+
require 'dnsmadeeasy/zone/file'
|
|
17
|
+
require 'dnsmadeeasy/zone/parser'
|
|
18
|
+
require 'dnsmadeeasy/zone/aname_flattener'
|
|
19
|
+
require 'dnsmadeeasy/zone/apply_executor'
|
|
20
|
+
require 'dnsmadeeasy/zone/apply_result'
|
|
21
|
+
require 'dnsmadeeasy/zone/diff'
|
|
22
|
+
require 'dnsmadeeasy/zone/plan'
|
|
23
|
+
require 'dnsmadeeasy/zone/plan_action'
|
|
24
|
+
require 'dnsmadeeasy/zone/plan_renderer'
|
|
25
|
+
require 'dnsmadeeasy/zone/remote_adapter'
|
|
26
|
+
require 'dnsmadeeasy/zone/remote_records'
|
|
27
|
+
require 'dnsmadeeasy/zone/serializer'
|
|
11
28
|
|
|
12
29
|
module DnsMadeEasy
|
|
13
|
-
class Error < StandardError
|
|
30
|
+
class Error < StandardError
|
|
14
31
|
end
|
|
15
|
-
|
|
32
|
+
|
|
33
|
+
class AuthenticationError < Error
|
|
16
34
|
end
|
|
17
|
-
|
|
35
|
+
|
|
36
|
+
class APIKeyAndSecretMissingError < Error
|
|
18
37
|
end
|
|
19
|
-
|
|
38
|
+
|
|
39
|
+
class InvalidCredentialKeys < Error
|
|
20
40
|
end
|
|
21
|
-
|
|
41
|
+
|
|
42
|
+
class AbstractMethodError < Error
|
|
22
43
|
end
|
|
23
|
-
|
|
44
|
+
|
|
45
|
+
class InvalidCredentialsFormatError < Error
|
|
24
46
|
end
|
|
25
|
-
|
|
47
|
+
|
|
48
|
+
class NoSuchAccountError < Error
|
|
26
49
|
end
|
|
27
|
-
|
|
50
|
+
|
|
51
|
+
class NoDomainError < Error
|
|
28
52
|
end
|
|
29
53
|
|
|
30
54
|
class << self
|
|
@@ -38,26 +62,22 @@ module DnsMadeEasy
|
|
|
38
62
|
def configure_from_file(file = nil,
|
|
39
63
|
account = nil,
|
|
40
64
|
encryption_key = nil)
|
|
41
|
-
|
|
42
65
|
credentials = ::DnsMadeEasy::Credentials.keys_from_file(
|
|
43
|
-
file: file || ::DnsMadeEasy::Credentials.default_credentials_path(user: ENV
|
|
66
|
+
file: file || ::DnsMadeEasy::Credentials.default_credentials_path(user: ENV.fetch('USER', nil)),
|
|
44
67
|
account: account,
|
|
45
68
|
encryption_key: encryption_key
|
|
46
69
|
)
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
else
|
|
53
|
-
raise APIKeyAndSecretMissingError, "Unable to load valid api keys from #{file}!"
|
|
70
|
+
raise APIKeyAndSecretMissingError, "Unable to load valid api keys from #{file}!" unless credentials
|
|
71
|
+
|
|
72
|
+
configure do |config|
|
|
73
|
+
config.api_key = credentials.api_key
|
|
74
|
+
config.api_secret = credentials.api_secret
|
|
54
75
|
end
|
|
55
76
|
end
|
|
56
77
|
|
|
57
78
|
def credentials_from_file(file: DnsMadeEasy::Credentials.default_credentials_path,
|
|
58
79
|
account: nil,
|
|
59
80
|
encryption_key: nil)
|
|
60
|
-
|
|
61
81
|
DnsMadeEasy::Credentials.keys_from_file file: file,
|
|
62
82
|
account: account,
|
|
63
83
|
encryption_key: encryption_key
|
|
@@ -67,37 +87,51 @@ module DnsMadeEasy
|
|
|
67
87
|
self.default_api_key = value
|
|
68
88
|
end
|
|
69
89
|
|
|
90
|
+
def api_key
|
|
91
|
+
default_api_key
|
|
92
|
+
end
|
|
93
|
+
|
|
70
94
|
def api_secret=(value)
|
|
71
95
|
self.default_api_secret = value
|
|
72
96
|
end
|
|
73
97
|
|
|
74
|
-
def
|
|
75
|
-
|
|
98
|
+
def api_secret
|
|
99
|
+
default_api_secret
|
|
76
100
|
end
|
|
77
101
|
|
|
78
|
-
def
|
|
79
|
-
@
|
|
102
|
+
def client(**)
|
|
103
|
+
@client ||= create_client(false, **)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def sandbox_client(**)
|
|
107
|
+
@sandbox_client ||= create_client(true, **)
|
|
80
108
|
end
|
|
81
109
|
|
|
82
110
|
def create_client(sandbox = false,
|
|
83
111
|
api_key: default_api_key,
|
|
84
112
|
api_secret: default_api_secret,
|
|
85
113
|
|
|
86
|
-
**
|
|
114
|
+
**)
|
|
87
115
|
raise APIKeyAndSecretMissingError, 'Please set #api_key and #api_secret' unless api_key && api_secret
|
|
88
116
|
|
|
89
|
-
::DnsMadeEasy::Api::Client.new(api_key, api_secret, sandbox, **
|
|
117
|
+
::DnsMadeEasy::Api::Client.new(api_key, api_secret, sandbox, **)
|
|
90
118
|
end
|
|
91
119
|
|
|
92
120
|
# Basically delegate it all to the Client instance
|
|
93
121
|
# if the method call is supported.
|
|
94
122
|
#
|
|
95
|
-
def method_missing(method,
|
|
123
|
+
def method_missing(method, ...)
|
|
96
124
|
if client.respond_to?(method)
|
|
97
|
-
client.send(method,
|
|
125
|
+
client.send(method, ...)
|
|
98
126
|
else
|
|
99
|
-
super
|
|
127
|
+
super
|
|
100
128
|
end
|
|
101
129
|
end
|
|
130
|
+
|
|
131
|
+
def respond_to_missing?(method, include_private = false)
|
|
132
|
+
client.respond_to?(method, include_private) || super
|
|
133
|
+
rescue APIKeyAndSecretMissingError
|
|
134
|
+
super
|
|
135
|
+
end
|
|
102
136
|
end
|
|
103
137
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: dnsmadeeasy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 1.0.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Konstantin Gredeskoul
|
|
@@ -10,10 +10,9 @@ authors:
|
|
|
10
10
|
- James Hart
|
|
11
11
|
- Phil Cohen
|
|
12
12
|
- Praneeth Are
|
|
13
|
-
autorequire:
|
|
14
13
|
bindir: exe
|
|
15
14
|
cert_chain: []
|
|
16
|
-
date:
|
|
15
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
17
16
|
dependencies:
|
|
18
17
|
- !ruby/object:Gem::Dependency
|
|
19
18
|
name: awesome_print
|
|
@@ -43,6 +42,76 @@ dependencies:
|
|
|
43
42
|
- - ">="
|
|
44
43
|
- !ruby/object:Gem::Version
|
|
45
44
|
version: '0'
|
|
45
|
+
- !ruby/object:Gem::Dependency
|
|
46
|
+
name: dns-zonefile
|
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
|
48
|
+
requirements:
|
|
49
|
+
- - ">="
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '0'
|
|
52
|
+
type: :runtime
|
|
53
|
+
prerelease: false
|
|
54
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '0'
|
|
59
|
+
- !ruby/object:Gem::Dependency
|
|
60
|
+
name: dry-cli
|
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '0'
|
|
66
|
+
type: :runtime
|
|
67
|
+
prerelease: false
|
|
68
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '0'
|
|
73
|
+
- !ruby/object:Gem::Dependency
|
|
74
|
+
name: dry-monads
|
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
type: :runtime
|
|
81
|
+
prerelease: false
|
|
82
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '0'
|
|
87
|
+
- !ruby/object:Gem::Dependency
|
|
88
|
+
name: dry-struct
|
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
|
90
|
+
requirements:
|
|
91
|
+
- - ">="
|
|
92
|
+
- !ruby/object:Gem::Version
|
|
93
|
+
version: '0'
|
|
94
|
+
type: :runtime
|
|
95
|
+
prerelease: false
|
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
97
|
+
requirements:
|
|
98
|
+
- - ">="
|
|
99
|
+
- !ruby/object:Gem::Version
|
|
100
|
+
version: '0'
|
|
101
|
+
- !ruby/object:Gem::Dependency
|
|
102
|
+
name: dry-types
|
|
103
|
+
requirement: !ruby/object:Gem::Requirement
|
|
104
|
+
requirements:
|
|
105
|
+
- - ">="
|
|
106
|
+
- !ruby/object:Gem::Version
|
|
107
|
+
version: '0'
|
|
108
|
+
type: :runtime
|
|
109
|
+
prerelease: false
|
|
110
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
111
|
+
requirements:
|
|
112
|
+
- - ">="
|
|
113
|
+
- !ruby/object:Gem::Version
|
|
114
|
+
version: '0'
|
|
46
115
|
- !ruby/object:Gem::Dependency
|
|
47
116
|
name: hashie
|
|
48
117
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -72,13 +141,41 @@ dependencies:
|
|
|
72
141
|
- !ruby/object:Gem::Version
|
|
73
142
|
version: '0'
|
|
74
143
|
- !ruby/object:Gem::Dependency
|
|
75
|
-
name:
|
|
144
|
+
name: tsort
|
|
76
145
|
requirement: !ruby/object:Gem::Requirement
|
|
77
146
|
requirements:
|
|
78
147
|
- - ">="
|
|
79
148
|
- !ruby/object:Gem::Version
|
|
80
149
|
version: '0'
|
|
81
|
-
type: :
|
|
150
|
+
type: :runtime
|
|
151
|
+
prerelease: false
|
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
153
|
+
requirements:
|
|
154
|
+
- - ">="
|
|
155
|
+
- !ruby/object:Gem::Version
|
|
156
|
+
version: '0'
|
|
157
|
+
- !ruby/object:Gem::Dependency
|
|
158
|
+
name: tty-box
|
|
159
|
+
requirement: !ruby/object:Gem::Requirement
|
|
160
|
+
requirements:
|
|
161
|
+
- - ">="
|
|
162
|
+
- !ruby/object:Gem::Version
|
|
163
|
+
version: '0'
|
|
164
|
+
type: :runtime
|
|
165
|
+
prerelease: false
|
|
166
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
167
|
+
requirements:
|
|
168
|
+
- - ">="
|
|
169
|
+
- !ruby/object:Gem::Version
|
|
170
|
+
version: '0'
|
|
171
|
+
- !ruby/object:Gem::Dependency
|
|
172
|
+
name: tty-spinner
|
|
173
|
+
requirement: !ruby/object:Gem::Requirement
|
|
174
|
+
requirements:
|
|
175
|
+
- - ">="
|
|
176
|
+
- !ruby/object:Gem::Version
|
|
177
|
+
version: '0'
|
|
178
|
+
type: :runtime
|
|
82
179
|
prerelease: false
|
|
83
180
|
version_requirements: !ruby/object:Gem::Requirement
|
|
84
181
|
requirements:
|
|
@@ -197,16 +294,39 @@ dependencies:
|
|
|
197
294
|
- - ">="
|
|
198
295
|
- !ruby/object:Gem::Version
|
|
199
296
|
version: '0'
|
|
297
|
+
- !ruby/object:Gem::Dependency
|
|
298
|
+
name: aruba
|
|
299
|
+
requirement: !ruby/object:Gem::Requirement
|
|
300
|
+
requirements:
|
|
301
|
+
- - ">="
|
|
302
|
+
- !ruby/object:Gem::Version
|
|
303
|
+
version: '0'
|
|
304
|
+
type: :development
|
|
305
|
+
prerelease: false
|
|
306
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
307
|
+
requirements:
|
|
308
|
+
- - ">="
|
|
309
|
+
- !ruby/object:Gem::Version
|
|
310
|
+
version: '0'
|
|
200
311
|
description: |
|
|
201
|
-
This
|
|
312
|
+
This gem ships "dmez" — a Terraform-style command line tool for the
|
|
313
|
+
DNS provider DnsMadeEasy.com — together with an authoritative,
|
|
314
|
+
fully-featured Ruby client for their REST API v2.0.
|
|
202
315
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
316
|
+
The dmez CLI manages your zones as standard DNS zone files with the
|
|
317
|
+
familiar read -> plan -> apply loop: "dmez zone export" writes a
|
|
318
|
+
canonical, TTL-lossless zone file with fixed aligned columns;
|
|
319
|
+
"dmez zone plan" diffs it against the live records (conservatively:
|
|
320
|
+
deletes are skipped by default and ambiguous record groups are
|
|
321
|
+
flagged for manual review); "dmez zone apply" executes the plan in
|
|
322
|
+
merge, add-only, or delete-only mode. Zone files can also be
|
|
323
|
+
validated and formatted, ANAME records are preserved as first-class
|
|
324
|
+
citizens (with optional --strict-rfc flattening on export), and
|
|
325
|
+
every account API operation is available under "dmez account".
|
|
207
326
|
|
|
208
|
-
|
|
209
|
-
|
|
327
|
+
The Ruby API supports storing credentials in
|
|
328
|
+
~/.dnsmadeeasy/credentials.yml, including multiple accounts and
|
|
329
|
+
sym-encrypted values.
|
|
210
330
|
|
|
211
331
|
ACKNOWLEDGEMENTS:
|
|
212
332
|
|
|
@@ -216,82 +336,135 @@ description: |
|
|
|
216
336
|
2. We also wish to thank the gem author Phil Cohen who
|
|
217
337
|
kindly yielded the "dnsmadeeasy" RubyGems namespace to this gem.
|
|
218
338
|
|
|
219
|
-
3. We also thank Praneeth Are for contributing the support for
|
|
339
|
+
3. We also thank Praneeth Are for contributing the support for
|
|
340
|
+
secondary domains in 0.3.5.
|
|
220
341
|
email:
|
|
221
342
|
- kigster@gmail.com
|
|
222
343
|
- letuboy@gmail.com
|
|
223
344
|
- hjhart@gmail.com
|
|
224
345
|
executables:
|
|
225
346
|
- dme
|
|
347
|
+
- dmez
|
|
226
348
|
extensions: []
|
|
227
349
|
extra_rdoc_files: []
|
|
228
350
|
files:
|
|
229
351
|
- ".codeclimate.yml"
|
|
230
|
-
- ".dme-help.png"
|
|
231
352
|
- ".github/workflows/ruby.yml"
|
|
232
353
|
- ".gitignore"
|
|
233
354
|
- ".rspec"
|
|
234
355
|
- ".rubocop.yml"
|
|
235
356
|
- ".rubocop_todo.yml"
|
|
236
357
|
- ".travis.yml"
|
|
358
|
+
- CLAUDE.md
|
|
237
359
|
- Gemfile
|
|
238
360
|
- LICENSE.txt
|
|
239
|
-
- README.
|
|
361
|
+
- README.md
|
|
240
362
|
- Rakefile
|
|
241
363
|
- bin/console
|
|
242
364
|
- bin/setup
|
|
243
365
|
- dnsmadeeasy.gemspec
|
|
366
|
+
- docs/badges/coverage_badge.svg
|
|
367
|
+
- docs/dry-cli-based-tools.webloc
|
|
368
|
+
- docs/plan-zone-management.md
|
|
369
|
+
- docs/plans/01-plan-ruby4-baseline.md
|
|
370
|
+
- docs/plans/02-plan-dry-cli-launcher.md
|
|
371
|
+
- docs/plans/03-plan-account-command.md
|
|
372
|
+
- docs/plans/04-plan-zone-record-model.md
|
|
373
|
+
- docs/plans/05-plan-zone-parser.md
|
|
374
|
+
- docs/plans/06-plan-zone-formatter.md
|
|
375
|
+
- docs/plans/07-plan-zone-export.md
|
|
376
|
+
- docs/plans/08-plan-zone-diff.md
|
|
377
|
+
- docs/plans/09-plan-zone-apply.md
|
|
378
|
+
- docs/plans/10-plan-docs-cleanup.md
|
|
379
|
+
- docs/plans/11-plan-zone-cli-arguments.md
|
|
380
|
+
- docs/spec-zone-management.md
|
|
244
381
|
- exe/dme
|
|
382
|
+
- exe/dmez
|
|
245
383
|
- lib/dme.rb
|
|
246
384
|
- lib/dnsmadeeasy.rb
|
|
247
385
|
- lib/dnsmadeeasy/api/client.rb
|
|
386
|
+
- lib/dnsmadeeasy/cli/box_output.rb
|
|
387
|
+
- lib/dnsmadeeasy/cli/commands.rb
|
|
388
|
+
- lib/dnsmadeeasy/cli/commands/account.rb
|
|
389
|
+
- lib/dnsmadeeasy/cli/commands/base.rb
|
|
390
|
+
- lib/dnsmadeeasy/cli/commands/legacy_operation.rb
|
|
391
|
+
- lib/dnsmadeeasy/cli/commands/version.rb
|
|
392
|
+
- lib/dnsmadeeasy/cli/commands/zone.rb
|
|
393
|
+
- lib/dnsmadeeasy/cli/input.rb
|
|
394
|
+
- lib/dnsmadeeasy/cli/launcher.rb
|
|
395
|
+
- lib/dnsmadeeasy/cli/message_helpers.rb
|
|
396
|
+
- lib/dnsmadeeasy/cli/reported_error.rb
|
|
248
397
|
- lib/dnsmadeeasy/credentials.rb
|
|
249
398
|
- lib/dnsmadeeasy/credentials/api_keys.rb
|
|
250
399
|
- lib/dnsmadeeasy/credentials/yaml_file.rb
|
|
251
400
|
- lib/dnsmadeeasy/dme.rb
|
|
252
401
|
- lib/dnsmadeeasy/runner.rb
|
|
402
|
+
- lib/dnsmadeeasy/types.rb
|
|
253
403
|
- lib/dnsmadeeasy/version.rb
|
|
404
|
+
- lib/dnsmadeeasy/zone/aname_flattener.rb
|
|
405
|
+
- lib/dnsmadeeasy/zone/apply_executor.rb
|
|
406
|
+
- lib/dnsmadeeasy/zone/apply_result.rb
|
|
407
|
+
- lib/dnsmadeeasy/zone/diff.rb
|
|
408
|
+
- lib/dnsmadeeasy/zone/file.rb
|
|
409
|
+
- lib/dnsmadeeasy/zone/parser.rb
|
|
410
|
+
- lib/dnsmadeeasy/zone/plan.rb
|
|
411
|
+
- lib/dnsmadeeasy/zone/plan_action.rb
|
|
412
|
+
- lib/dnsmadeeasy/zone/plan_renderer.rb
|
|
413
|
+
- lib/dnsmadeeasy/zone/provider_record.rb
|
|
414
|
+
- lib/dnsmadeeasy/zone/record.rb
|
|
415
|
+
- lib/dnsmadeeasy/zone/record_set.rb
|
|
416
|
+
- lib/dnsmadeeasy/zone/remote_adapter.rb
|
|
417
|
+
- lib/dnsmadeeasy/zone/remote_records.rb
|
|
418
|
+
- lib/dnsmadeeasy/zone/serializer.rb
|
|
254
419
|
homepage: https://github.com/kigster/dnsmadeeasy
|
|
255
420
|
licenses:
|
|
256
421
|
- MIT
|
|
257
|
-
metadata:
|
|
422
|
+
metadata:
|
|
423
|
+
rubygems_mfa_required: 'true'
|
|
258
424
|
post_install_message: |
|
|
259
|
-
Thank you for
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
instead of the ruby API if you prefer. Run `dme` with no
|
|
263
|
-
arguments to see the help message.
|
|
425
|
+
Thank you for installing the DnsMadeEasy ruby gem, which ships
|
|
426
|
+
the 'dmez' CLI — manage your DNS zones as plain zone files with
|
|
427
|
+
a Terraform-style workflow:
|
|
264
428
|
|
|
265
|
-
|
|
266
|
-
|
|
429
|
+
dmez zone export yourdomain.com --output=yourdomain.com.zone
|
|
430
|
+
dmez zone plan yourdomain.com yourdomain.com.zone
|
|
431
|
+
dmez zone apply yourdomain.com yourdomain.com.zone
|
|
432
|
+
|
|
433
|
+
Run `dmez --help` to see all commands (the old 'dme' executable
|
|
434
|
+
is deprecated). A full Ruby API client is included as well, with
|
|
435
|
+
(multi-account) credentials support via a YAML file in your home
|
|
436
|
+
directory. For more information, please see the README at:
|
|
267
437
|
https://github.com/kigster/dnsmadeeasy
|
|
268
438
|
rdoc_options: []
|
|
269
439
|
require_paths:
|
|
270
440
|
- lib
|
|
271
441
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
272
442
|
requirements:
|
|
273
|
-
- - "
|
|
443
|
+
- - "~>"
|
|
274
444
|
- !ruby/object:Gem::Version
|
|
275
|
-
version: '0'
|
|
445
|
+
version: '4.0'
|
|
276
446
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
277
447
|
requirements:
|
|
278
448
|
- - ">="
|
|
279
449
|
- !ruby/object:Gem::Version
|
|
280
450
|
version: '0'
|
|
281
451
|
requirements: []
|
|
282
|
-
rubygems_version:
|
|
283
|
-
signing_key:
|
|
452
|
+
rubygems_version: 4.0.16
|
|
284
453
|
specification_version: 4
|
|
285
|
-
summary: 'This
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
454
|
+
summary: 'This gem ships "dmez" — a Terraform-style command line tool for the DNS
|
|
455
|
+
provider DnsMadeEasy.com — together with an authoritative, fully-featured Ruby client
|
|
456
|
+
for their REST API v2.0. The dmez CLI manages your zones as standard DNS zone files
|
|
457
|
+
with the familiar read -> plan -> apply loop: "dmez zone export" writes a canonical,
|
|
458
|
+
TTL-lossless zone file with fixed aligned columns; "dmez zone plan" diffs it against
|
|
459
|
+
the live records (conservatively: deletes are skipped by default and ambiguous record
|
|
460
|
+
groups are flagged for manual review); "dmez zone apply" executes the plan in merge,
|
|
461
|
+
add-only, or delete-only mode. Zone files can also be validated and formatted, ANAME
|
|
462
|
+
records are preserved as first-class citizens (with optional --strict-rfc flattening
|
|
463
|
+
on export), and every account API operation is available under "dmez account". The
|
|
464
|
+
Ruby API supports storing credentials in ~/.dnsmadeeasy/credentials.yml, including
|
|
465
|
+
multiple accounts and sym-encrypted values. ACKNOWLEDGEMENTS: 1. This gem is based
|
|
466
|
+
on the original work contributed by Wanelo.com to the now abandonded "dnsmadeeasy-rest-api"
|
|
467
|
+
client. 2. We also wish to thank the gem author Phil Cohen who kindly yielded the
|
|
468
|
+
"dnsmadeeasy" RubyGems namespace to this gem. 3. We also thank Praneeth Are for
|
|
469
|
+
contributing the support for secondary domains in 0.3.5.'
|
|
297
470
|
test_files: []
|
data/.dme-help.png
DELETED
|
Binary file
|