record_store 2.1.0 → 3.0.0

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.
@@ -2,157 +2,147 @@ require 'fog/dnsimple'
2
2
 
3
3
  module RecordStore
4
4
  class Provider::DNSimple < Provider
5
- def self.supports_alias?
6
- true
7
- end
8
-
9
- def add(record)
10
- record_hash = api_hash(record)
11
- res = session.create_record(
12
- @zone_name,
13
- record_hash.fetch(:name),
14
- record.type,
15
- record_hash.fetch(:content),
16
- ttl: record_hash.fetch(:ttl),
17
- priority: record_hash.fetch(:prio, nil)
18
- )
19
-
20
- if record.type == 'ALIAS'
21
- txt_alias = retrieve_current_records.detect do |rr|
22
- rr.type == 'TXT' && rr.fqdn == record.fqdn && rr.txtdata == "ALIAS for #{record.alias.chomp('.')}"
23
- end
24
- remove(txt_alias)
5
+ class << self
6
+ def supports_alias?
7
+ true
25
8
  end
26
9
 
27
- res
28
- end
29
-
30
- def remove(record)
31
- session.delete_record(@zone_name, record.id)
32
- end
33
-
34
- def update(id, record)
35
- record_hash = api_hash(record)
36
- session.update_record(@zone_name, id, api_hash(record))
37
- end
38
-
39
- # returns an array of Record objects that match the records which exist in the provider
40
- def retrieve_current_records(stdout = $stdout)
41
- session.list_records(@zone_name).body.map do |record|
42
- record_body = record.fetch('record')
10
+ def add(record, zone)
11
+ record_hash = api_hash(record, zone)
12
+ res = session.create_record(
13
+ zone,
14
+ record_hash.fetch(:name),
15
+ record.type,
16
+ record_hash.fetch(:content),
17
+ ttl: record_hash.fetch(:ttl),
18
+ priority: record_hash.fetch(:prio, nil)
19
+ )
43
20
 
44
- begin
45
- build_from_api(record_body)
46
- rescue StandardError
47
- stdout.puts "Cannot build record: #{record_body}"
48
- raise
21
+ if record.type == 'ALIAS'
22
+ txt_alias = retrieve_current_records(zone: zone).detect do |rr|
23
+ rr.type == 'TXT' && rr.fqdn == record.fqdn && rr.txtdata == "ALIAS for #{record.alias.chomp('.')}"
24
+ end
25
+ remove(txt_alias, zone)
49
26
  end
50
- end.select(&:present?)
51
- end
52
27
 
53
- # Returns an array of the zones managed by provider as strings
54
- def zones
55
- session.zones.map(&:domain)
56
- end
28
+ res
29
+ end
57
30
 
58
- private
31
+ def remove(record, zone)
32
+ session.delete_record(zone, record.id)
33
+ end
59
34
 
60
- def discard_change_set
61
- session.request(expects: 200, method: :delete, path: "ZoneChanges/#{@zone_name}")
62
- end
35
+ def update(id, record, zone)
36
+ record_hash = api_hash(record, zone)
37
+ session.update_record(zone, id, api_hash(record, zone))
38
+ end
63
39
 
64
- def session
65
- @dns ||= Fog::DNS.new(session_params)
66
- end
40
+ # returns an array of Record objects that match the records which exist in the provider
41
+ def retrieve_current_records(zone:, stdout: $stdout)
42
+ session.list_records(zone).body.map do |record|
43
+ record_body = record.fetch('record')
44
+
45
+ begin
46
+ build_from_api(record_body, zone)
47
+ rescue StandardError
48
+ stdout.puts "Cannot build record: #{record_body}"
49
+ raise
50
+ end
51
+ end.select(&:present?)
52
+ end
67
53
 
68
- def session_params
69
- {
70
- provider: 'DNSimple',
71
- dnsimple_email: secrets.fetch('email'),
72
- dnsimple_token: secrets.fetch('api_token'),
73
- }
74
- end
54
+ # Returns an array of the zones managed by provider as strings
55
+ def zones
56
+ session.zones.map(&:domain)
57
+ end
75
58
 
76
- def secrets
77
- super.fetch('dnsimple')
78
- end
59
+ private
79
60
 
80
- def build_from_api(api_record)
81
- record_type = api_record.fetch('record_type')
82
- record = {
83
- record_id: api_record.fetch('id'),
84
- ttl: api_record.fetch('ttl'),
85
- fqdn: api_record.fetch('name').present? ? "#{api_record.fetch('name')}.#{@zone_name}" : @zone_name,
86
- }
87
-
88
- return if record_type == 'SOA'
89
-
90
- case record_type
91
- when 'A'
92
- record.merge!(address: api_record.fetch('content'))
93
- when 'AAAA'
94
- record.merge!(address: api_record.fetch('content'))
95
- when 'ALIAS'
96
- record.merge!(alias: api_record.fetch('content'))
97
- when 'CNAME'
98
- record.merge!(cname: api_record.fetch('content'))
99
- when 'MX'
100
- record.merge!(preference: api_record.fetch('prio'), exchange: api_record.fetch('content'))
101
- when 'NS'
102
- record.merge!(nsdname: api_record.fetch('content'))
103
- when 'SPF'
104
- record.merge!(txtdata: api_record.fetch('content'))
105
- when 'SRV'
106
- weight, port, host = api_record.fetch('content').split(' ')
107
-
108
- record.merge!(
109
- priority: api_record.fetch('prio'),
110
- weight: weight,
111
- port: port,
112
- target: Record.ensure_ends_with_dot(host),
113
- )
114
- when 'TXT'
115
- record.merge!(txtdata: api_record.fetch('content'))
61
+ def session
62
+ @dns ||= Fog::DNS.new(session_params)
116
63
  end
117
64
 
118
- unless record.fetch(:fqdn).ends_with?('.')
119
- record[:fqdn] += '.'
65
+ def session_params
66
+ {
67
+ provider: 'DNSimple',
68
+ dnsimple_email: secrets.fetch('email'),
69
+ dnsimple_token: secrets.fetch('api_token'),
70
+ }
120
71
  end
121
72
 
122
- Record.const_get(record_type).new(record)
123
- end
73
+ def secrets
74
+ super.fetch('dnsimple')
75
+ end
124
76
 
125
- def api_hash(record)
126
- record_hash = {
127
- name: record.fqdn.gsub("#{Record.ensure_ends_with_dot(@zone_name)}", '').chomp('.'),
128
- ttl: record.ttl,
129
- type: record.type,
130
- }
131
-
132
- case record.type
133
- when 'A'
134
- record_hash[:content] = record.address
135
- when 'AAAA'
136
- record_hash[:content] = record.address
137
- when 'ALIAS'
138
- record_hash[:content] = record.alias.chomp('.')
139
- when 'CNAME'
140
- record_hash[:content] = record.cname.chomp('.')
141
- when 'MX'
142
- record_hash[:prio] = record.preference
143
- record_hash[:content] = record.exchange.chomp('.')
144
- when 'NS'
145
- record_hash[:content] = record.nsdname.chomp('.')
146
- when 'SPF'
147
- record_hash[:content] = record.txtdata
148
- when 'SRV'
149
- record_hash[:content] = "#{record.weight} #{record.port} #{record.target.chomp('.')}"
150
- record_hash[:prio] = record.priority
151
- when 'TXT'
152
- record_hash[:content] = record.txtdata
77
+ def build_from_api(api_record, zone)
78
+ record_type = api_record.fetch('record_type')
79
+ record = {
80
+ record_id: api_record.fetch('id'),
81
+ ttl: api_record.fetch('ttl'),
82
+ fqdn: api_record.fetch('name').present? ? "#{api_record.fetch('name')}.#{zone}" : zone,
83
+ }
84
+
85
+ return if record_type == 'SOA'
86
+
87
+ case record_type
88
+ when 'A', 'AAAA'
89
+ record.merge!(address: api_record.fetch('content'))
90
+ when 'ALIAS'
91
+ record.merge!(alias: api_record.fetch('content'))
92
+ when 'CNAME'
93
+ record.merge!(cname: api_record.fetch('content'))
94
+ when 'MX'
95
+ record.merge!(preference: api_record.fetch('prio'), exchange: api_record.fetch('content'))
96
+ when 'NS'
97
+ record.merge!(nsdname: api_record.fetch('content'))
98
+ when 'SPF', 'TXT'
99
+ record.merge!(txtdata: api_record.fetch('content'))
100
+ when 'SRV'
101
+ weight, port, host = api_record.fetch('content').split(' ')
102
+
103
+ record.merge!(
104
+ priority: api_record.fetch('prio'),
105
+ weight: weight,
106
+ port: port,
107
+ target: Record.ensure_ends_with_dot(host),
108
+ )
109
+ end
110
+
111
+ unless record.fetch(:fqdn).ends_with?('.')
112
+ record[:fqdn] += '.'
113
+ end
114
+
115
+ Record.const_get(record_type).new(record)
153
116
  end
154
117
 
155
- record_hash
118
+ def api_hash(record, zone)
119
+ record_hash = {
120
+ name: record.fqdn.gsub("#{Record.ensure_ends_with_dot(zone)}", '').chomp('.'),
121
+ ttl: record.ttl,
122
+ type: record.type,
123
+ }
124
+
125
+ case record.type
126
+ when 'A', 'AAAA'
127
+ record_hash[:content] = record.address
128
+ when 'ALIAS'
129
+ record_hash[:content] = record.alias.chomp('.')
130
+ when 'CNAME'
131
+ record_hash[:content] = record.cname.chomp('.')
132
+ when 'MX'
133
+ record_hash[:prio] = record.preference
134
+ record_hash[:content] = record.exchange.chomp('.')
135
+ when 'NS'
136
+ record_hash[:content] = record.nsdname.chomp('.')
137
+ when 'SPF', 'TXT'
138
+ record_hash[:content] = record.txtdata
139
+ when 'SRV'
140
+ record_hash[:content] = "#{record.weight} #{record.port} #{record.target.chomp('.')}"
141
+ record_hash[:prio] = record.priority
142
+ end
143
+
144
+ record_hash
145
+ end
156
146
  end
157
147
  end
158
148
  end
@@ -2,96 +2,98 @@ require 'fog/dynect'
2
2
 
3
3
  module RecordStore
4
4
  class Provider::DynECT < Provider
5
- def freeze_zone
6
- session.put_zone(@zone_name, freeze: true)
7
- end
5
+ class << self
6
+ def freeze_zone(zone)
7
+ session.put_zone(zone, freeze: true)
8
+ end
8
9
 
9
- def thaw
10
- session.put_zone(@zone_name, thaw: true)
11
- end
10
+ def thaw_zone(zone)
11
+ session.put_zone(zone, thaw: true)
12
+ end
12
13
 
13
- def add(record)
14
- session.post_record(record.type, @zone_name, record.fqdn, record.rdata, ttl: record.ttl)
15
- end
14
+ def add(record, zone)
15
+ session.post_record(record.type, zone, record.fqdn, record.rdata, ttl: record.ttl)
16
+ end
16
17
 
17
- def remove(record)
18
- session.delete_record(record.type, @zone_name, record.fqdn, record.id)
19
- end
18
+ def remove(record, zone)
19
+ session.delete_record(record.type, zone, record.fqdn, record.id)
20
+ end
20
21
 
21
- def update(id, record)
22
- session.put_record(record.type, @zone_name, record.fqdn, record.rdata, ttl: record.ttl, record_id: id)
23
- end
22
+ def update(id, record, zone)
23
+ session.put_record(record.type, zone, record.fqdn, record.rdata, ttl: record.ttl, record_id: id)
24
+ end
24
25
 
25
- def publish
26
- session.put_zone(@zone_name, publish: true)
27
- end
26
+ def publish(zone)
27
+ session.put_zone(zone, publish: true)
28
+ end
28
29
 
29
- # Applies changeset to provider
30
- def apply_changeset(changeset, stdout = $stdout)
31
- begin
32
- thaw
33
- super
34
- publish
35
- rescue StandardError
36
- puts "An exception occurred while applying DNS changes, deleting changeset"
37
- discard_change_set
38
- raise
39
- ensure
40
- freeze_zone
30
+ # Applies changeset to provider
31
+ def apply_changeset(changeset, stdout = $stdout)
32
+ begin
33
+ thaw_zone(changeset.zone)
34
+ super
35
+ publish(changeset.zone)
36
+ rescue StandardError
37
+ puts "An exception occurred while applying DNS changes, deleting changeset"
38
+ discard_change_set(changeset.zone)
39
+ raise
40
+ ensure
41
+ freeze_zone(changeset.zone)
42
+ end
41
43
  end
42
- end
43
44
 
44
- # returns an array of Record objects that match the records which exist in the provider
45
- def retrieve_current_records(stdout = $stdout)
46
- session.get_all_records(@zone_name).body.fetch('data').flat_map do |type, records|
47
- records.map do |record_body|
48
- begin
49
- build_from_api(record_body)
50
- rescue StandardError => e
51
- stdout.puts "Cannot build record: #{record_body}"
45
+ # returns an array of Record objects that match the records which exist in the provider
46
+ def retrieve_current_records(zone:, stdout: $stdout)
47
+ session.get_all_records(zone).body.fetch('data').flat_map do |type, records|
48
+ records.map do |record_body|
49
+ begin
50
+ build_from_api(record_body)
51
+ rescue StandardError => e
52
+ stdout.puts "Cannot build record: #{record_body}"
53
+ end
52
54
  end
53
- end
54
- end.select(&:present?)
55
- end
55
+ end.select(&:present?)
56
+ end
56
57
 
57
- # Returns an array of the zones managed by provider as strings
58
- def zones
59
- session.zones.map(&:domain)
60
- end
58
+ # Returns an array of the zones managed by provider as strings
59
+ def zones
60
+ session.zones.map(&:domain)
61
+ end
61
62
 
62
- private
63
+ private
63
64
 
64
- def discard_change_set
65
- session.request(expects: 200, method: :delete, path: "ZoneChanges/#{@zone_name}")
66
- end
65
+ def discard_change_set(zone)
66
+ session.request(expects: 200, method: :delete, path: "ZoneChanges/#{zone}")
67
+ end
67
68
 
68
- def session
69
- @dns ||= Fog::DNS.new(session_params)
70
- end
69
+ def session
70
+ @dns ||= Fog::DNS.new(session_params)
71
+ end
71
72
 
72
- def session_params
73
- {
74
- provider: 'Dynect',
75
- dynect_customer: secrets.fetch('customer'),
76
- dynect_username: secrets.fetch('username'),
77
- dynect_password: secrets.fetch('password')
78
- }
79
- end
73
+ def session_params
74
+ {
75
+ provider: 'Dynect',
76
+ dynect_customer: secrets.fetch('customer'),
77
+ dynect_username: secrets.fetch('username'),
78
+ dynect_password: secrets.fetch('password')
79
+ }
80
+ end
80
81
 
81
- def secrets
82
- super.fetch('dynect')
83
- end
82
+ def secrets
83
+ super.fetch('dynect')
84
+ end
84
85
 
85
- def build_from_api(api_record)
86
- record = api_record.merge(api_record.fetch('rdata')).slice!('rdata').symbolize_keys
86
+ def build_from_api(api_record)
87
+ record = api_record.merge(api_record.fetch('rdata')).slice!('rdata').symbolize_keys
87
88
 
88
- return if record.fetch(:record_type) == 'SOA'
89
+ return if record.fetch(:record_type) == 'SOA'
89
90
 
90
- unless record.fetch(:fqdn).ends_with?('.')
91
- record[:fqdn] = "#{record.fetch(:fqdn)}."
92
- end
91
+ unless record.fetch(:fqdn).ends_with?('.')
92
+ record[:fqdn] = "#{record.fetch(:fqdn)}."
93
+ end
93
94
 
94
- Record.const_get(record.fetch(:record_type)).new(record)
95
+ Record.const_get(record.fetch(:record_type)).new(record)
96
+ end
95
97
  end
96
98
  end
97
99
  end
@@ -19,6 +19,7 @@ module RecordStore
19
19
 
20
20
  def self.build_from_yaml_definition(yaml_definition)
21
21
  record_type = yaml_definition.fetch(:type)
22
+
22
23
  # TODO: remove backward compatibility support for ALIAS records using cname attribute instead of alias
23
24
  # REMOVE after merging https://github.com/Shopify/record-store/pull/781
24
25
  case record_type