mystro-common 0.1.11 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +42 -4
- data/Gemfile +7 -1
- data/Rakefile +137 -1
- data/lib/{mystro/ext/fog → fog/ext}/balancer.rb +0 -0
- data/lib/fog/ext/dynect/dns.rb +140 -0
- data/lib/fog/ext/dynect/models/dns/record.rb +66 -0
- data/lib/fog/ext/dynect/models/dns/records.rb +87 -0
- data/lib/fog/ext/dynect/models/dns/zone.rb +60 -0
- data/lib/fog/ext/dynect/models/dns/zones.rb +29 -0
- data/lib/fog/ext/dynect/requests/dns/delete_record.rb +56 -0
- data/lib/fog/ext/dynect/requests/dns/delete_zone.rb +42 -0
- data/lib/fog/ext/dynect/requests/dns/get_all_records.rb +56 -0
- data/lib/fog/ext/dynect/requests/dns/get_node_list.rb +56 -0
- data/lib/fog/ext/dynect/requests/dns/get_record.rb +85 -0
- data/lib/fog/ext/dynect/requests/dns/get_zone.rb +58 -0
- data/lib/fog/ext/dynect/requests/dns/post_record.rb +72 -0
- data/lib/fog/ext/dynect/requests/dns/post_session.rb +44 -0
- data/lib/fog/ext/dynect/requests/dns/post_zone.rb +71 -0
- data/lib/fog/ext/dynect/requests/dns/put_zone.rb +76 -0
- data/lib/fog/ext/dynect.rb +26 -0
- data/lib/mystro/cloud/action.rb +22 -0
- data/lib/mystro/cloud/connect/aws/balancer.rb +55 -0
- data/lib/mystro/cloud/connect/aws/compute.rb +151 -0
- data/lib/mystro/cloud/connect/aws/listener.rb +36 -0
- data/lib/mystro/cloud/connect/aws/record.rb +58 -0
- data/lib/mystro/cloud/connect/aws/zone.rb +35 -0
- data/lib/mystro/cloud/connect/aws.rb +14 -0
- data/lib/mystro/cloud/connect/dynect/record.rb +72 -0
- data/lib/mystro/cloud/connect/dynect/zone.rb +35 -0
- data/lib/mystro/cloud/connect/dynect.rb +17 -0
- data/lib/mystro/cloud/connect/fog.rb +66 -0
- data/lib/mystro/cloud/connect.rb +64 -0
- data/lib/mystro/cloud/model/balancer.rb +15 -0
- data/lib/mystro/cloud/model/compute.rb +27 -0
- data/lib/mystro/cloud/model/listener.rb +30 -0
- data/lib/mystro/cloud/model/record.rb +20 -0
- data/lib/mystro/cloud/model/volume.rb +12 -0
- data/lib/mystro/cloud/model/zone.rb +9 -0
- data/lib/mystro/cloud/model.rb +183 -0
- data/lib/mystro/cloud.rb +32 -0
- data/lib/mystro/common/version.rb +4 -3
- data/lib/mystro/dsl/balancer.rb +18 -0
- data/lib/mystro/dsl/compute.rb +57 -0
- data/lib/mystro/dsl/health.rb +7 -0
- data/lib/mystro/dsl/listener.rb +5 -0
- data/lib/mystro/dsl/oldtemplate.rb +281 -0
- data/lib/mystro/dsl/template.rb +12 -278
- data/lib/mystro/dsl/template_file.rb +18 -0
- data/lib/mystro/dsl/volume.rb +8 -0
- data/lib/mystro/dsl.rb +40 -0
- data/lib/mystro/organization.rb +83 -0
- data/lib/mystro/plugin.rb +4 -3
- data/lib/mystro/provider.rb +40 -0
- data/lib/mystro/userdata.rb +1 -1
- data/lib/mystro-common.rb +32 -31
- data/mystro-common.gemspec +2 -1
- data/spec/cloud/aws/balancer_spec.rb +10 -0
- data/spec/cloud/aws/compute_spec.rb +10 -0
- data/spec/cloud/aws/record_spec.rb +10 -0
- data/spec/cloud/dynect/record_spec.rb +10 -0
- data/spec/model/compute_spec.rb +36 -0
- data/spec/model/model_spec.rb +89 -0
- data/spec/model/record_spec.rb +27 -0
- data/spec/spec_helper.rb +36 -0
- data/spec/support/balancer.rb +49 -0
- data/spec/support/compute.rb +65 -0
- data/spec/support/record.rb +45 -0
- data/test/config.yml +71 -0
- metadata +99 -14
- data/lib/mystro/account.rb +0 -105
- data/lib/mystro/connect/balancer.rb +0 -91
- data/lib/mystro/connect/compute.rb +0 -100
- data/lib/mystro/connect/dns.rb +0 -51
- data/lib/mystro/connect/environment.rb +0 -31
- data/lib/mystro/connect.rb +0 -124
- data/lib/mystro/job.rb +0 -0
- data/lib/mystro/model.rb +0 -71
data/.rspec
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,41 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v0.2.0:
|
4
|
+
* tests green.
|
5
|
+
* conversion work completed... still want to test things a bit
|
6
|
+
* custom create method for balancers
|
7
|
+
* conversion work nearly completed. balancers working. environment creation cleaned up
|
8
|
+
* checkin
|
9
|
+
* fix tests to properly clean up after themselves
|
10
|
+
* refactor some of the fog extension work. monkey patch fog/dynect support.
|
11
|
+
* fixes for volume support
|
12
|
+
* getting compute and records conversion completed
|
13
|
+
* disable volumes to avoid fog bug
|
14
|
+
* volume modification (changing root volume size) is working, but there's a bug in fog
|
15
|
+
* conversion work
|
16
|
+
* refactor data call to to_hash
|
17
|
+
* dsl conversion
|
18
|
+
* check in
|
19
|
+
* add access to config, allow to disable in configuration
|
20
|
+
* add raw attribute to listener
|
21
|
+
* cleanup
|
22
|
+
* add _raw to decoded object
|
23
|
+
* dynect record destroy working. refactor tests to use configuration file. add _raw attribute to models, this can contain source object (fog object). reopen fog dynect records to add find_by_name.
|
24
|
+
* working with shawncatz/fog fork
|
25
|
+
* dynect
|
26
|
+
* some refactoring, support for dynect started
|
27
|
+
* refactor to shared examples
|
28
|
+
* compute, balancers and records working. includes tests for cloud operations and models
|
29
|
+
* converted to new format, organizations now use new connect framework, started support for DNS
|
30
|
+
* balancers
|
31
|
+
* rspec integration
|
32
|
+
* add LIST to Version class. makes it easier to handle release tasks
|
33
|
+
* providers support
|
34
|
+
* orgs
|
35
|
+
|
36
|
+
## v0.1.11:
|
37
|
+
* fixes bug if disabled is not set
|
38
|
+
|
3
39
|
## v0.1.10:
|
4
40
|
* allow for disabling plugins
|
5
41
|
|
@@ -18,17 +54,19 @@
|
|
18
54
|
* changelog rake tasks
|
19
55
|
|
20
56
|
## v0.1.6:
|
21
|
-
|
22
|
-
## v0.1.5:
|
23
57
|
* update rails to 3.2.14. tweak plugins jobs output to match qujo. fix issue with getting zones through fog
|
24
58
|
* smarter errors in dns connect. add and use Account#get instead of @list attr
|
25
|
-
*
|
26
|
-
* support for templates in userdata, handled like files, but processed through erubis
|
59
|
+
* merge
|
27
60
|
* merge release v0.1.2
|
28
61
|
* new DSL framework
|
29
62
|
* ruby version file
|
30
63
|
* changelog rake tasks
|
31
64
|
|
65
|
+
## v0.1.4:
|
66
|
+
* merge
|
67
|
+
* hard code rake version in Gemfile to match mystro server
|
68
|
+
* support for templates in userdata, handled like files, but processed through erubis
|
69
|
+
|
32
70
|
## v0.1.3:
|
33
71
|
* fixes bugs with dns usage and plugin methods when no plugins are defined
|
34
72
|
* update ruby version
|
data/Gemfile
CHANGED
@@ -3,5 +3,11 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in mystro-common.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
-
gem
|
6
|
+
gem 'damsel', path: '../../damsel'
|
7
|
+
|
8
|
+
gem 'rake', '10.0.4'
|
7
9
|
gem 'awesome_print'
|
10
|
+
gem 'rspec'
|
11
|
+
gem 'terminal-table'
|
12
|
+
gem 'factory_girl', '~> 4.0'
|
13
|
+
gem 'net-dns'
|
data/Rakefile
CHANGED
@@ -1,4 +1,140 @@
|
|
1
|
-
require
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
require 'mystro-common'
|
4
|
+
require 'terminal-table'
|
5
|
+
require 'awesome_print'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
task :default => :spec
|
9
|
+
desc 'run tests and create computes and such that cost money'
|
10
|
+
task :spend do
|
11
|
+
Mystro.config.test!.spend = true
|
12
|
+
Rake::Task['spec'].invoke
|
13
|
+
end
|
14
|
+
def table(head, rows=nil)
|
15
|
+
if rows
|
16
|
+
t = Terminal::Table.new :headings => head, :rows => rows
|
17
|
+
else
|
18
|
+
t = Terminal::Table.new :rows => rows
|
19
|
+
end
|
20
|
+
t
|
21
|
+
end
|
22
|
+
|
23
|
+
def list(keys, list)
|
24
|
+
rows = []
|
25
|
+
list.each do |l|
|
26
|
+
row = []
|
27
|
+
keys.each do |k|
|
28
|
+
row << (l[k] || l[k.downcase] || l[k.to_sym] || l[k.downcase.to_sym])
|
29
|
+
end
|
30
|
+
rows << row
|
31
|
+
end
|
32
|
+
table(keys, rows)
|
33
|
+
end
|
34
|
+
|
35
|
+
def show(obj)
|
36
|
+
keys = obj.keys
|
37
|
+
rows = []
|
38
|
+
keys.each do |k|
|
39
|
+
list = [obj[k]].flatten
|
40
|
+
list.each do |v|
|
41
|
+
if v.is_a?(Hash)
|
42
|
+
v = v.inject([]) {|s, e| s << e.join(": ")}.join("\n")
|
43
|
+
end
|
44
|
+
v
|
45
|
+
rows << [k, v]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
table(%w{key value}, rows)
|
49
|
+
end
|
50
|
+
|
51
|
+
def options
|
52
|
+
{aws_access_key_id: 'AKIAIVMUCDVWWZFFLVGA', aws_secret_access_key: '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'}
|
53
|
+
end
|
54
|
+
|
55
|
+
#Mystro::Log.console_debug
|
56
|
+
#Mystro::Log.debug "logging ... "
|
57
|
+
|
58
|
+
desc 'get and show compute'
|
59
|
+
task :compute do
|
60
|
+
x = Mystro.compute
|
61
|
+
o = x.find("i-69d32404")
|
62
|
+
e = o.to_hash
|
63
|
+
e.merge!(name: o.name)
|
64
|
+
puts show(e)
|
65
|
+
end
|
66
|
+
|
67
|
+
desc 'get list of computes'
|
68
|
+
task :computes do
|
69
|
+
x = Mystro.compute
|
70
|
+
list = x.all
|
71
|
+
list.map! {|e| e.to_hash.merge(name: e.tags['Name'])}
|
72
|
+
puts list(%w{id name state ip dns}, list)
|
73
|
+
end
|
74
|
+
|
75
|
+
desc 'get and show balancer'
|
76
|
+
task :balancer do
|
77
|
+
x = Mystro.balancer
|
78
|
+
o = x.find 'RG-EVENTS-1'
|
79
|
+
e = o.to_hash
|
80
|
+
puts show(e)
|
81
|
+
end
|
82
|
+
|
83
|
+
desc 'get and show zone'
|
84
|
+
task :record do
|
85
|
+
o = Mystro::Organization.get('rg')
|
86
|
+
x = o.record
|
87
|
+
r = x.find_by_name 'mcstg1.rgops.com'
|
88
|
+
e = r.to_hash
|
89
|
+
puts show(e)
|
90
|
+
r = x.find '75069597'
|
91
|
+
e = r.to_hash
|
92
|
+
puts show(e)
|
93
|
+
end
|
94
|
+
|
95
|
+
desc 'get and show zone'
|
96
|
+
task :records do
|
97
|
+
x = Mystro.record
|
98
|
+
o = x.all
|
99
|
+
puts list(%w{name type ttl values}, o)
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
desc 'show default organization'
|
104
|
+
task :org do
|
105
|
+
puts Mystro.organization.to_hash.to_yaml
|
106
|
+
end
|
107
|
+
|
108
|
+
desc 'show configuration'
|
109
|
+
task :config do
|
110
|
+
puts Mystro.config.to_hash.to_yaml
|
111
|
+
end
|
112
|
+
|
113
|
+
desc 'template'
|
114
|
+
task :template, [:name] do |_, args|
|
115
|
+
name = args.name || 'hdp/live'
|
116
|
+
name.gsub!(/\.rb$/, '') if name =~ /\.rb$/
|
117
|
+
t = Mystro::Dsl.load("config/mystro/templates/#{name}.rb")
|
118
|
+
ap t
|
119
|
+
end
|
120
|
+
|
121
|
+
desc 'template cloud'
|
122
|
+
task :cloud, [:name] do |_, args|
|
123
|
+
name = args.name || 'hdp/live'
|
124
|
+
ap Mystro::Dsl.load("config/mystro/templates/#{name}.rb").actions
|
125
|
+
end
|
126
|
+
|
127
|
+
desc 'compute volumes'
|
128
|
+
task :volumes do
|
129
|
+
org = Mystro::Organization.get 'ops'
|
130
|
+
connect = org.compute
|
131
|
+
service = connect.service
|
132
|
+
template = Mystro::Dsl.load("config/mystro/templates/hdp/live.rb")
|
133
|
+
puts template.to_hash.to_yaml
|
134
|
+
#actions = template.actions
|
135
|
+
#options = connect.encode(actions.first.data)
|
136
|
+
#ap options
|
137
|
+
end
|
2
138
|
|
3
139
|
def changelog(last=nil, single=false)
|
4
140
|
command="git --no-pager log --format='%an::::%h::::%s'"
|
File without changes
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'fog/dynect'
|
2
|
+
require 'fog/dns'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect < Fog::Service
|
7
|
+
|
8
|
+
requires :dynect_customer, :dynect_username, :dynect_password
|
9
|
+
recognizes :timeout, :persistent
|
10
|
+
recognizes :provider # remove post deprecation
|
11
|
+
|
12
|
+
model_path 'fog/ext/dynect/models/dns'
|
13
|
+
model :record
|
14
|
+
collection :records
|
15
|
+
model :zone
|
16
|
+
collection :zones
|
17
|
+
|
18
|
+
request_path 'fog/ext/dynect/requests/dns'
|
19
|
+
request :delete_record
|
20
|
+
request :delete_zone
|
21
|
+
request :get_node_list
|
22
|
+
request :get_all_records
|
23
|
+
request :get_record
|
24
|
+
request :get_zone
|
25
|
+
request :post_record
|
26
|
+
request :post_session
|
27
|
+
request :post_zone
|
28
|
+
request :put_zone
|
29
|
+
|
30
|
+
class JobIncomplete < Error; end
|
31
|
+
|
32
|
+
class Mock
|
33
|
+
def initialize(options={})
|
34
|
+
@dynect_customer = options[:dynect_customer]
|
35
|
+
@dynect_username = options[:dynect_username]
|
36
|
+
@dynect_password = options[:dynect_password]
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.data
|
40
|
+
@data ||= {
|
41
|
+
:zones => {}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.reset
|
46
|
+
@data = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
def auth_token
|
50
|
+
@auth_token ||= Fog::Dynect::Mock.token
|
51
|
+
end
|
52
|
+
|
53
|
+
def data
|
54
|
+
self.class.data
|
55
|
+
end
|
56
|
+
|
57
|
+
def reset_data
|
58
|
+
self.class.reset
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Real
|
63
|
+
def initialize(options={})
|
64
|
+
@dynect_customer = options[:dynect_customer]
|
65
|
+
@dynect_username = options[:dynect_username]
|
66
|
+
@dynect_password = options[:dynect_password]
|
67
|
+
|
68
|
+
@connection_options = options[:connection_options] || {}
|
69
|
+
@host = 'api-v4.dynect.net'
|
70
|
+
@port = options[:port] || 443
|
71
|
+
@path = options[:path] || '/REST'
|
72
|
+
@persistent = options[:persistent] || false
|
73
|
+
@scheme = options[:scheme] || 'https'
|
74
|
+
@version = options[:version] || '3.5.2'
|
75
|
+
@connection = Fog::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
|
76
|
+
end
|
77
|
+
|
78
|
+
def auth_token
|
79
|
+
@auth_token ||= post_session.body['data']['token']
|
80
|
+
end
|
81
|
+
|
82
|
+
def request(params)
|
83
|
+
begin
|
84
|
+
# any request could redirect to a job
|
85
|
+
params[:expects] = Array(params[:expects]) | [307]
|
86
|
+
|
87
|
+
params[:headers] ||= {}
|
88
|
+
params[:headers]['Content-Type'] = 'application/json'
|
89
|
+
params[:headers]['API-Version'] = @version
|
90
|
+
params[:headers]['Auth-Token'] = auth_token unless params[:path] == 'Session'
|
91
|
+
params[:path] = "#{@path}/#{params[:path]}" unless params[:path] =~ %r{^#{Regexp.escape(@path)}/}
|
92
|
+
|
93
|
+
response = @connection.request(params.merge!({:host => @host}))
|
94
|
+
|
95
|
+
if response.body.empty?
|
96
|
+
response.body = {}
|
97
|
+
elsif response.headers['Content-Type'] == 'application/json'
|
98
|
+
response.body = Fog::JSON.decode(response.body)
|
99
|
+
end
|
100
|
+
|
101
|
+
if response.body['status'] == 'failure'
|
102
|
+
raise Error, response.body['msgs'].first['INFO']
|
103
|
+
end
|
104
|
+
|
105
|
+
if response.status == 307 && params[:path] !~ %r{^/REST/Job/}
|
106
|
+
response = poll_job(response, params[:expects])
|
107
|
+
end
|
108
|
+
|
109
|
+
response
|
110
|
+
rescue Excon::Errors::HTTPStatusError => error
|
111
|
+
if @auth_token && error.message =~ /login: (Bad or expired credentials|inactivity logout)/
|
112
|
+
@auth_token = nil
|
113
|
+
retry
|
114
|
+
else
|
115
|
+
raise error
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
response
|
120
|
+
end
|
121
|
+
|
122
|
+
def poll_job(response, original_expects, time_to_wait = 10)
|
123
|
+
job_location = response.headers['Location']
|
124
|
+
|
125
|
+
Fog.wait_for(time_to_wait) do
|
126
|
+
response = request(:expects => original_expects, :method => :get, :path => job_location)
|
127
|
+
response.body['status'] != 'incomplete'
|
128
|
+
end
|
129
|
+
|
130
|
+
if response.body['status'] == 'incomplete'
|
131
|
+
raise JobIncomplete.new("Job #{response.body['job_id']} is still incomplete")
|
132
|
+
end
|
133
|
+
|
134
|
+
response
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
|
3
|
+
module Fog
|
4
|
+
module DNS
|
5
|
+
class Dynect
|
6
|
+
|
7
|
+
class Record < Fog::Model
|
8
|
+
extend Fog::Deprecation
|
9
|
+
|
10
|
+
identity :id
|
11
|
+
attribute :name, :aliases => [:fqdn, 'fqdn']
|
12
|
+
attribute :rdata
|
13
|
+
attribute :serial_style
|
14
|
+
attribute :ttl
|
15
|
+
attribute :type, :aliases => 'record_type'
|
16
|
+
|
17
|
+
def destroy
|
18
|
+
requires :identity, :name, :type, :zone
|
19
|
+
service.delete_record(type, zone.identity, name, identity)
|
20
|
+
true
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
requires :name, :type, :rdata, :zone
|
25
|
+
|
26
|
+
options = {
|
27
|
+
:ttl => ttl
|
28
|
+
}
|
29
|
+
options.delete_if {|key, value| value.nil?}
|
30
|
+
|
31
|
+
data = service.post_record(type, zone.identity, name, rdata, options).body['data']
|
32
|
+
# avoid overwriting zone object with zone string
|
33
|
+
data = data.reject {|key, value| key == 'zone'}
|
34
|
+
merge_attributes(data)
|
35
|
+
|
36
|
+
zone.publish
|
37
|
+
records = service.get_record(type, zone.identity, name).body['data']
|
38
|
+
# data in format ['/REST/xRecord/domain/fqdn/identity]
|
39
|
+
records.map! do |record|
|
40
|
+
tokens = record.split('/')
|
41
|
+
{
|
42
|
+
:identity => tokens.last,
|
43
|
+
:type => tokens[2][0...-6] # everything before 'Record'
|
44
|
+
}
|
45
|
+
end
|
46
|
+
record = records.detect {|record| record[:type] == type}
|
47
|
+
merge_attributes(record)
|
48
|
+
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def zone
|
53
|
+
@zone
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def zone=(new_zone)
|
59
|
+
@zone = new_zone
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/ext/dynect/models/dns/record'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
|
8
|
+
class Records < Fog::Collection
|
9
|
+
|
10
|
+
attribute :zone
|
11
|
+
|
12
|
+
model Fog::DNS::Dynect::Record
|
13
|
+
|
14
|
+
def all(options = {})
|
15
|
+
requires :zone
|
16
|
+
data = []
|
17
|
+
service.get_all_records(zone.domain, options).body['data'].each do |url|
|
18
|
+
(_, _, t, _, fqdn, id) = url.split('/')
|
19
|
+
type = t.gsub(/Record$/, '')
|
20
|
+
|
21
|
+
# leave out the default, read only records
|
22
|
+
# by putting this here we don't make the secondary request for these records
|
23
|
+
next if ['NS', 'SOA'].include?(type)
|
24
|
+
record = service.get_record(type, zone.domain, fqdn, 'record_id' => id).body['data']
|
25
|
+
|
26
|
+
data << {
|
27
|
+
:identity => record['record_id'],
|
28
|
+
:fqdn => record['fqdn'],
|
29
|
+
:type => record['record_type'],
|
30
|
+
:rdata => record['rdata']
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
load(data)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(record_id)
|
38
|
+
requires :zone
|
39
|
+
|
40
|
+
list = service.get_all_records(zone.domain, {}).body['data']
|
41
|
+
url = list.detect { |e| e =~ /\/#{record_id}$/ }
|
42
|
+
return unless url
|
43
|
+
(_, _, t, _, fqdn, id) = url.split('/')
|
44
|
+
type = t.gsub(/Record$/, '')
|
45
|
+
record = service.get_record(type, zone.domain, fqdn, 'record_id' => id).body['data']
|
46
|
+
|
47
|
+
new({
|
48
|
+
:identity => record['record_id'],
|
49
|
+
:fqdn => record['fqdn'],
|
50
|
+
:type => record['record_type'],
|
51
|
+
:rdata => record['rdata']
|
52
|
+
})
|
53
|
+
end
|
54
|
+
|
55
|
+
def new(attributes = {})
|
56
|
+
requires :zone
|
57
|
+
super({:zone => zone}.merge!(attributes))
|
58
|
+
end
|
59
|
+
|
60
|
+
def find_by_name(name)
|
61
|
+
requires :zone
|
62
|
+
data = []
|
63
|
+
service.get_all_records(zone.domain, {}).body['data'].select { |url| url =~ /\/#{name}\// }.each do |url|
|
64
|
+
(_, _, t, _, fqdn, id) = url.split('/')
|
65
|
+
type = t.gsub(/Record$/, '')
|
66
|
+
|
67
|
+
# leave out the default, read only records
|
68
|
+
next if ['NS', 'SOA'].include?(type)
|
69
|
+
|
70
|
+
record = service.get_record(type, zone.domain, fqdn, 'record_id' => id).body['data']
|
71
|
+
|
72
|
+
data << {
|
73
|
+
:identity => record['record_id'],
|
74
|
+
:fqdn => record['fqdn'],
|
75
|
+
:type => record['record_type'],
|
76
|
+
:rdata => record['rdata']
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
80
|
+
load(data)
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'fog/core/model'
|
2
|
+
require 'fog/ext/dynect/models/dns/records'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
|
8
|
+
class Zone < Fog::Model
|
9
|
+
|
10
|
+
identity :domain
|
11
|
+
|
12
|
+
attribute :domain, :aliases => 'zone'
|
13
|
+
attribute :email, :aliases => 'rname'
|
14
|
+
attribute :serial
|
15
|
+
attribute :serial_style
|
16
|
+
attribute :ttl
|
17
|
+
attribute :type, :aliases => 'zone_type'
|
18
|
+
|
19
|
+
def initialize(attributes={})
|
20
|
+
super
|
21
|
+
end
|
22
|
+
|
23
|
+
def destroy
|
24
|
+
requires :domain
|
25
|
+
service.delete_zone(domain)
|
26
|
+
true
|
27
|
+
end
|
28
|
+
|
29
|
+
undef_method :domain=
|
30
|
+
def domain=(new_domain)
|
31
|
+
attributes[:domain] = new_domain.split('/').last
|
32
|
+
end
|
33
|
+
|
34
|
+
def publish
|
35
|
+
requires :identity
|
36
|
+
data = service.put_zone(identity, 'publish' => true)
|
37
|
+
true
|
38
|
+
end
|
39
|
+
|
40
|
+
def records
|
41
|
+
@records ||= Fog::DNS::Dynect::Records.new(:zone => self, :service => service)
|
42
|
+
end
|
43
|
+
|
44
|
+
def nameservers
|
45
|
+
raise 'nameservers Not Implemented'
|
46
|
+
end
|
47
|
+
|
48
|
+
def save
|
49
|
+
self.ttl ||= 3600
|
50
|
+
requires :domain, :email, :ttl
|
51
|
+
data = service.post_zone(email, ttl, domain).body['data']
|
52
|
+
merge_attributes(data)
|
53
|
+
true
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'fog/core/collection'
|
2
|
+
require 'fog/ext/dynect/models/dns/zone'
|
3
|
+
|
4
|
+
module Fog
|
5
|
+
module DNS
|
6
|
+
class Dynect
|
7
|
+
|
8
|
+
class Zones < Fog::Collection
|
9
|
+
|
10
|
+
model Fog::DNS::Dynect::Zone
|
11
|
+
|
12
|
+
def all
|
13
|
+
data = service.get_zone.body['data'].map do |zone|
|
14
|
+
{ :domain => zone }
|
15
|
+
end
|
16
|
+
load(data)
|
17
|
+
end
|
18
|
+
|
19
|
+
def get(zone_id)
|
20
|
+
new(service.get_zone('zone' => zone_id).body['data'])
|
21
|
+
rescue Excon::Errors::NotFound
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Fog
|
2
|
+
module DNS
|
3
|
+
class Dynect
|
4
|
+
class Real
|
5
|
+
|
6
|
+
# Delete a record
|
7
|
+
#
|
8
|
+
# ==== Parameters
|
9
|
+
# * type<~String> - type of record in ['AAAA', 'ANY', 'A', 'CNAME', 'DHCID', 'DNAME', 'DNSKEY', 'DS', 'KEY', 'LOC', 'MX', 'NSA', 'NS', 'PTR', 'PX', 'RP', 'SOA', 'SPF', 'SRV', 'SSHFP', 'TXT']
|
10
|
+
# * zone<~String> - zone of record
|
11
|
+
# * fqdn<~String> - fqdn of record
|
12
|
+
# * record_id<~String> - id of record
|
13
|
+
|
14
|
+
def delete_record(type, zone, fqdn, record_id)
|
15
|
+
request(
|
16
|
+
:expects => 200,
|
17
|
+
:idempotent => true,
|
18
|
+
:method => :delete,
|
19
|
+
:path => ["#{type.to_s.upcase}Record", zone, fqdn, record_id].join('/')
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Mock
|
25
|
+
def delete_record(type, zone, fqdn, record_id)
|
26
|
+
raise Fog::DNS::Dynect::NotFound unless zone = self.data[:zones][zone]
|
27
|
+
|
28
|
+
raise Fog::DNS::Dynect::NotFound unless zone[:records][type].find { |record| record[:fqdn] == fqdn && record[:record_id] == record_id.to_i }
|
29
|
+
|
30
|
+
zone[:records_to_delete] << {
|
31
|
+
:type => type,
|
32
|
+
:fqdn => fqdn,
|
33
|
+
:record_id => record_id.to_i
|
34
|
+
}
|
35
|
+
|
36
|
+
response = Excon::Response.new
|
37
|
+
response.status = 200
|
38
|
+
|
39
|
+
response.body = {
|
40
|
+
"status" => "success",
|
41
|
+
"data" => {},
|
42
|
+
"job_id" => Fog::Dynect::Mock.job_id,
|
43
|
+
"msgs" => [{
|
44
|
+
"INFO" => "delete: Record will be deleted on zone publish",
|
45
|
+
"SOURCE" => "BLL",
|
46
|
+
"ERR_CD" => nil,
|
47
|
+
"LVL" => "INFO"
|
48
|
+
}]
|
49
|
+
}
|
50
|
+
|
51
|
+
response
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|