dyn-rb 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|