dyn-rb 1.0.2
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 +7 -0
- data/LICENSE +202 -0
- data/lib/dyn-rb.rb +19 -0
- data/lib/dyn/exceptions.rb +36 -0
- data/lib/dyn/http/curb.rb +79 -0
- data/lib/dyn/http/http_client.rb +90 -0
- data/lib/dyn/http/net_http.rb +50 -0
- data/lib/dyn/http/patron.rb +52 -0
- data/lib/dyn/messaging.rb +156 -0
- data/lib/dyn/messaging/accounts.rb +53 -0
- data/lib/dyn/messaging/bounces.rb +41 -0
- data/lib/dyn/messaging/clicks.rb +49 -0
- data/lib/dyn/messaging/complaints.rb +41 -0
- data/lib/dyn/messaging/delivery.rb +41 -0
- data/lib/dyn/messaging/issues.rb +41 -0
- data/lib/dyn/messaging/opens.rb +49 -0
- data/lib/dyn/messaging/recipients.rb +41 -0
- data/lib/dyn/messaging/send_mail.rb +37 -0
- data/lib/dyn/messaging/senders.rb +61 -0
- data/lib/dyn/messaging/sent_mail.rb +41 -0
- data/lib/dyn/messaging/suppressions.rb +49 -0
- data/lib/dyn/traffic.rb +238 -0
- data/lib/dyn/traffic/base.rb +57 -0
- data/lib/dyn/traffic/gslb.rb +169 -0
- data/lib/dyn/traffic/http_redirect.rb +83 -0
- data/lib/dyn/traffic/qps_report.rb +30 -0
- data/lib/dyn/traffic/resource.rb +150 -0
- data/lib/dyn/traffic/secondary_zone.rb +87 -0
- data/lib/dyn/traffic/session.rb +37 -0
- data/lib/dyn/traffic/zone.rb +51 -0
- data/lib/dyn/version.rb +3 -0
- metadata +76 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sunny Gleason (<sunny@thesunnycloud.com>)
|
3
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013 Dyn, Inc.
|
5
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
6
|
+
# License:: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Dyn
|
22
|
+
module Traffic
|
23
|
+
class Base
|
24
|
+
attr_accessor :zone
|
25
|
+
|
26
|
+
# Publish any pending changes to the zone - required to make any alterations permanent.
|
27
|
+
#
|
28
|
+
# See: https://manage.dynect.net/help/docs/api2/rest/resources/Zone.html
|
29
|
+
#
|
30
|
+
# @param [String] The zone to publish - if one is provided when instantiated, we use that.
|
31
|
+
# @return [Hash] The dynect API response
|
32
|
+
def publish
|
33
|
+
@dyn.put("Zone/#{@zone}", { "publish" => true })
|
34
|
+
end
|
35
|
+
|
36
|
+
# Freeze the zone.
|
37
|
+
#
|
38
|
+
# See: https://manage.dynect.net/help/docs/api2/rest/resources/Zone.html
|
39
|
+
#
|
40
|
+
# @param [String] The zone to freeze - if one is provided when instantiated, we use that.
|
41
|
+
# @return [Hash] The dynect API response
|
42
|
+
def freeze
|
43
|
+
@dyn.put("Zone/#{@zone}", { "freeze" => true })
|
44
|
+
end
|
45
|
+
|
46
|
+
# Thaw the zone.
|
47
|
+
#
|
48
|
+
# See: https://manage.dynect.net/help/docs/api2/rest/resources/Zone.html
|
49
|
+
#
|
50
|
+
# @param [String] The zone to thaw - if one is provided when instantiated, we use that.
|
51
|
+
# @return [Hash] The dynect API response
|
52
|
+
def thaw
|
53
|
+
@dyn.put("Zone/#{@zone}", { "thaw" => true })
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sunny Gleason (<sunny@thesunnycloud.com>)
|
3
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
4
|
+
# Author:: Evan (<evan@pagerduty.com>)
|
5
|
+
# Copyright:: Copyright (c) 2013 Dyn, Inc.
|
6
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
7
|
+
# Copyright:: Copyright (c) 2013 PagerDuty, Inc.
|
8
|
+
# License:: Apache License, Version 2.0
|
9
|
+
#
|
10
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
11
|
+
# you may not use this file except in compliance with the License.
|
12
|
+
# You may obtain a copy of the License at
|
13
|
+
#
|
14
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
15
|
+
#
|
16
|
+
# Unless required by applicable law or agreed to in writing, software
|
17
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
18
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
19
|
+
# See the License for the specific language governing permissions and
|
20
|
+
# limitations under the License.
|
21
|
+
#
|
22
|
+
|
23
|
+
module Dyn
|
24
|
+
module Traffic
|
25
|
+
class GSLB < Base
|
26
|
+
def initialize(dyn, zone, options)
|
27
|
+
@dyn = dyn
|
28
|
+
@zone = zone
|
29
|
+
@resource_path = "GSLB/#{@zone}"
|
30
|
+
|
31
|
+
@fqdn = options[:fqdn]
|
32
|
+
@ttl = options[:ttl] || 30
|
33
|
+
@host_list = options[:host_list] || {}
|
34
|
+
@contact_nick = options[:contact_nick] || 'owner'
|
35
|
+
|
36
|
+
@region_code = options[:region_code] || 'global'
|
37
|
+
@monitor = options[:monitor] || {}
|
38
|
+
@serve_count = options[:serve_count] || 1
|
39
|
+
@min_healthy = options[:min_healthy] || 1
|
40
|
+
end
|
41
|
+
|
42
|
+
def [](host_list_key)
|
43
|
+
@host_list[host_list_key]
|
44
|
+
end
|
45
|
+
|
46
|
+
def fqdn(value=nil)
|
47
|
+
value ? (@fqdn = value; self) : @fqdn
|
48
|
+
end
|
49
|
+
|
50
|
+
def contact_nick(value=nil)
|
51
|
+
value ? (@contact_nick = value; self) : @contact_nick
|
52
|
+
end
|
53
|
+
|
54
|
+
def ttl(value=nil)
|
55
|
+
value ? (@ttl = value; self) : @ttl
|
56
|
+
end
|
57
|
+
|
58
|
+
def min_healthy(value=nil)
|
59
|
+
value ? (@min_healthy = value; self) : @min_healthy
|
60
|
+
end
|
61
|
+
|
62
|
+
def serve_count(value=nil)
|
63
|
+
value ? (@serve_count = value; self) : @serve_count
|
64
|
+
end
|
65
|
+
|
66
|
+
def region_code(value=nil)
|
67
|
+
# US West, US Central, US East, EU West, EU Central, EU East, Asia, global
|
68
|
+
value ? (@region_code = value; self) : @region_code
|
69
|
+
end
|
70
|
+
|
71
|
+
def host_list(value=nil)
|
72
|
+
value ? (@host_list = value; self) : @host_list
|
73
|
+
end
|
74
|
+
|
75
|
+
def monitor(value=nil)
|
76
|
+
# :protocol => 'HTTP', :interval => 1, :retries => 2, :timeout => 10, :port => 8000,
|
77
|
+
# :path => '/healthcheck', :host => 'example.com', :header => 'X-User-Agent: DynECT Health\n', :expected => 'passed'
|
78
|
+
if value
|
79
|
+
@monitor = {}
|
80
|
+
value.each do |k,v|
|
81
|
+
@monitor[k] = v
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@monitor
|
85
|
+
end
|
86
|
+
|
87
|
+
def add_host(value)
|
88
|
+
# :address => 'x.x.x.x', :label => 'friendly-name', :weight => 10, :serve_mode => 'obey'
|
89
|
+
@host_list[value[:address]] = value
|
90
|
+
self
|
91
|
+
end
|
92
|
+
|
93
|
+
def resource_path
|
94
|
+
"GSLB/#{@zone}"
|
95
|
+
end
|
96
|
+
|
97
|
+
def get(fqdn=nil, region_code='global')
|
98
|
+
if fqdn
|
99
|
+
results = @dyn.get("#{@resource_path}/#{fqdn}")
|
100
|
+
region = {}
|
101
|
+
results["region"].each {|r| region = r if r["region_code"] == region_code}
|
102
|
+
raise Dyn::Exceptions::RequestFailed, "Cannot find #{region_code} GSLB pool for #{fqdn}" if region.empty?
|
103
|
+
|
104
|
+
# Default monitor timeout is 0, but specifying timeout 0 on a put or post results in an exception
|
105
|
+
results["monitor"].delete("timeout") if results["monitor"]["timeout"] == 0
|
106
|
+
|
107
|
+
host_list = {}
|
108
|
+
region["pool"].each do |h|
|
109
|
+
host_list[h["address"]] = {
|
110
|
+
:address => h["address"],
|
111
|
+
:label => h["label"],
|
112
|
+
:weight => h["weight"],
|
113
|
+
:serve_mode => h["serve_mode"]
|
114
|
+
}
|
115
|
+
end
|
116
|
+
Dyn::Traffic::GSLB.new(@dyn, results["zone"], {
|
117
|
+
:fqdn => results["fqdn"],
|
118
|
+
:ttl => results["ttl"],
|
119
|
+
:host_list => host_list,
|
120
|
+
:contact_nick => results["contact_nickname"],
|
121
|
+
:region_code => region["region_code"],
|
122
|
+
:monitor => results["monitor"],
|
123
|
+
:serve_count => region["serve_count"],
|
124
|
+
:min_healthy => region["min_healthy"]
|
125
|
+
})
|
126
|
+
else
|
127
|
+
@dyn.get(resource_path)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def find(fqdn, query_hash)
|
132
|
+
results = []
|
133
|
+
get(fqdn).each do |rr|
|
134
|
+
query_hash.each do |key, value|
|
135
|
+
results << rr if rr[key.to_s] == value
|
136
|
+
end
|
137
|
+
end
|
138
|
+
results
|
139
|
+
end
|
140
|
+
|
141
|
+
def save(replace=false)
|
142
|
+
if replace == true || replace == :replace
|
143
|
+
@dyn.put("#{@resource_path}/#{@fqdn}", self)
|
144
|
+
else
|
145
|
+
@dyn.post("#{@resource_path}/#{@fqdn}", self)
|
146
|
+
end
|
147
|
+
self
|
148
|
+
end
|
149
|
+
|
150
|
+
def delete
|
151
|
+
@dyn.delete("#{@resource_path}/#{fqdn}")
|
152
|
+
end
|
153
|
+
|
154
|
+
def to_json
|
155
|
+
{
|
156
|
+
"ttl" => @ttl,
|
157
|
+
"monitor" => @monitor,
|
158
|
+
"region" => {
|
159
|
+
"region_code" => @region_code,
|
160
|
+
"serve_count" => @serve_count,
|
161
|
+
"min_healthy" => @min_healthy,
|
162
|
+
"pool" => @host_list.values
|
163
|
+
},
|
164
|
+
"contact_nickname" => @contact_nick
|
165
|
+
}.to_json
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sunny Gleason (<sunny@thesunnycloud.com>)
|
3
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013 Dyn, Inc.
|
5
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
6
|
+
# License:: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Dyn
|
22
|
+
module Traffic
|
23
|
+
class HTTPRedirect
|
24
|
+
attr_accessor :fqdn, :code, :keep_uri, :url
|
25
|
+
|
26
|
+
def initialize(dyn, zone, fqdn=nil)
|
27
|
+
@dyn = dyn
|
28
|
+
@zone = zone
|
29
|
+
@fqdn = fqdn
|
30
|
+
@code = nil
|
31
|
+
@keep_uri = nil
|
32
|
+
@url = nil
|
33
|
+
end
|
34
|
+
|
35
|
+
def fqdn(value=nil)
|
36
|
+
value ? (@fqdn = value; self) : @fqdn
|
37
|
+
end
|
38
|
+
|
39
|
+
def code(value=nil)
|
40
|
+
value ? (@code = value; self) : @code
|
41
|
+
end
|
42
|
+
|
43
|
+
def keep_uri(value=nil)
|
44
|
+
value ? (@keep_uri = value; self) : @keep_uri
|
45
|
+
end
|
46
|
+
|
47
|
+
def url(value=nil)
|
48
|
+
value ? (@url = value; self) : @url
|
49
|
+
end
|
50
|
+
|
51
|
+
def resource_path
|
52
|
+
"HTTPRedirect"
|
53
|
+
end
|
54
|
+
|
55
|
+
def get(fqdn = nil, record_id=nil)
|
56
|
+
@dyn.get("#{resource_path}/#{zone}/#{fqdn}/")
|
57
|
+
end
|
58
|
+
|
59
|
+
def save(replace=false)
|
60
|
+
if replace == true || replace == :replace
|
61
|
+
@dyn.put("#{resource_path}/#{@zone}/#{@fqdn}/", self)
|
62
|
+
else
|
63
|
+
@dyn.post("#{resource_path}/#{@zone}/#{@fqdn}/", self)
|
64
|
+
end
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def delete
|
69
|
+
@dyn.delete("#{resource_path}/#{@zone}/#{@fqdn}/")
|
70
|
+
end
|
71
|
+
|
72
|
+
def to_json
|
73
|
+
{
|
74
|
+
"zone" => @zone,
|
75
|
+
"fqdn" => @fqdn,
|
76
|
+
"code" => @code,
|
77
|
+
"keep_uri" => @keep_uri,
|
78
|
+
"url" => @url
|
79
|
+
}.to_json
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Dyn
|
2
|
+
module Traffic
|
3
|
+
class QPSReport
|
4
|
+
attr_accessor :csv
|
5
|
+
|
6
|
+
def initialize(dyn, csv)
|
7
|
+
@dyn = dyn
|
8
|
+
@csv = csv
|
9
|
+
end
|
10
|
+
|
11
|
+
def csv()
|
12
|
+
value ? (@csv = value; self) : @csv
|
13
|
+
end
|
14
|
+
|
15
|
+
def resource_path
|
16
|
+
"QPSReport"
|
17
|
+
end
|
18
|
+
|
19
|
+
def create(csv)
|
20
|
+
@dyn.create("#{resource_path}")
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_json
|
24
|
+
{
|
25
|
+
"csv" => @csv,
|
26
|
+
}.to_json
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sunny Gleason (<sunny@thesunnycloud.com>)
|
3
|
+
# Author:: Adam Jacob (<adam@opscode.com>)
|
4
|
+
# Copyright:: Copyright (c) 2013 Dyn, Inc.
|
5
|
+
# Copyright:: Copyright (c) 2010 Opscode, Inc.
|
6
|
+
# License:: Apache License, Version 2.0
|
7
|
+
#
|
8
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
9
|
+
# you may not use this file except in compliance with the License.
|
10
|
+
# You may obtain a copy of the License at
|
11
|
+
#
|
12
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
13
|
+
#
|
14
|
+
# Unless required by applicable law or agreed to in writing, software
|
15
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
16
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
17
|
+
# See the License for the specific language governing permissions and
|
18
|
+
# limitations under the License.
|
19
|
+
#
|
20
|
+
|
21
|
+
module Dyn
|
22
|
+
module Traffic
|
23
|
+
class Resource
|
24
|
+
attr_accessor :fqdn, :record_type, :record_id, :ttl, :zone, :rdata
|
25
|
+
|
26
|
+
def initialize(dyn, zone, record_type, fqdn=nil, record_id=nil, ttl=nil, rdata={})
|
27
|
+
@dyn = dyn
|
28
|
+
@fqdn = fqdn
|
29
|
+
@record_type = record_type
|
30
|
+
@record_id = record_id
|
31
|
+
@ttl = ttl
|
32
|
+
@zone = zone
|
33
|
+
@rdata = rdata
|
34
|
+
end
|
35
|
+
|
36
|
+
def [](rdata_key)
|
37
|
+
@rdata[rdata_key]
|
38
|
+
end
|
39
|
+
|
40
|
+
def []=(rdata_key, rdata_value)
|
41
|
+
@rdata[rdata_key] = rdata_value
|
42
|
+
end
|
43
|
+
|
44
|
+
def fqdn(value=nil)
|
45
|
+
value ? (@fqdn = value; self) : @fqdn
|
46
|
+
end
|
47
|
+
|
48
|
+
def record_id(value=nil)
|
49
|
+
value ? (@record_id = value; self) : @record_id
|
50
|
+
end
|
51
|
+
|
52
|
+
def ttl(value=nil)
|
53
|
+
value ? (@ttl = value; self) : @ttl
|
54
|
+
end
|
55
|
+
|
56
|
+
def resource_path(full=false)
|
57
|
+
@record_type << "Record" unless @record_type[-6,6] == "Record"
|
58
|
+
if (full == true || full == :full)
|
59
|
+
"/REST/#{@record_type}/#{@zone}"
|
60
|
+
else
|
61
|
+
"#{@record_type}/#{@zone}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def get(fqdn = nil, record_id=nil)
|
66
|
+
if record_id && fqdn
|
67
|
+
raw_rr = @dynect.get("#{resource_path}/#{fqdn}/#{record_id}")
|
68
|
+
Dyn::Traffic::Resource.new(@dyn,
|
69
|
+
raw_rr["record_type"],
|
70
|
+
raw_rr["zone"],
|
71
|
+
raw_rr["fqdn"],
|
72
|
+
raw_rr["record_id"],
|
73
|
+
raw_rr["ttl"],
|
74
|
+
raw_rr["rdata"])
|
75
|
+
elsif fqdn
|
76
|
+
results = @dyn.get("#{resource_path}/#{fqdn}")
|
77
|
+
raw_rr_list = results.map do |record|
|
78
|
+
if (record =~ /^#{resource_path(:full)}\/#{Regexp.escape(fqdn)}\/(\d+)$/)
|
79
|
+
self.get(fqdn, $1)
|
80
|
+
else
|
81
|
+
record
|
82
|
+
end
|
83
|
+
end
|
84
|
+
case raw_rr_list.length
|
85
|
+
when 0
|
86
|
+
raise Dyn::Exceptions::RequestFailed, "Cannot find #{record_type} record for #{fqdn}"
|
87
|
+
when 1
|
88
|
+
raw_rr_list[0]
|
89
|
+
else
|
90
|
+
raw_rr_list
|
91
|
+
end
|
92
|
+
else
|
93
|
+
@dyn.get(resource_path)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def find(fqdn, query_hash)
|
98
|
+
results = []
|
99
|
+
@dyn.get(fqdn).each do |rr|
|
100
|
+
query_hash.each do |key, value|
|
101
|
+
results << rr if rr[key.to_s] == value
|
102
|
+
end
|
103
|
+
end
|
104
|
+
results
|
105
|
+
end
|
106
|
+
|
107
|
+
def save(replace=false)
|
108
|
+
if record_id
|
109
|
+
@dyn.put("#{resource_path}/#{@fqdn}/#{record_id}", self)
|
110
|
+
else
|
111
|
+
if replace == true || replace == :replace
|
112
|
+
@dyn.put("#{resource_path}/#{@fqdn}", self)
|
113
|
+
else
|
114
|
+
@dyn.post("#{resource_path}/#{@fqdn}", self)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
self
|
118
|
+
end
|
119
|
+
|
120
|
+
def delete
|
121
|
+
url = if record_id
|
122
|
+
"#{resource_path}/#{fqdn}/#{record_id}"
|
123
|
+
else
|
124
|
+
"#{resource_path}/#{fqdn}"
|
125
|
+
end
|
126
|
+
@dyn.delete(url)
|
127
|
+
end
|
128
|
+
|
129
|
+
def to_json
|
130
|
+
{
|
131
|
+
"rdata" => @rdata,
|
132
|
+
"ttl" => @ttl
|
133
|
+
}.to_json
|
134
|
+
end
|
135
|
+
|
136
|
+
def method_missing(method_symbol, *args, &block)
|
137
|
+
method_string = method_symbol.to_s
|
138
|
+
if (args.length > 0 && method_string !~ /=$/)
|
139
|
+
@rdata[method_string] = args.length == 1 ? args[0] : args
|
140
|
+
self
|
141
|
+
elsif @rdata.has_key?(method_string)
|
142
|
+
@rdata[method_string]
|
143
|
+
else
|
144
|
+
raise NoMethodError, "undefined method `#{method_symbol.to_s}' for #{self.class.to_s}"
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|