ultradns-sdk 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/README.md +44 -0
- data/Rakefile +11 -0
- data/lib/ultradns.rb +11 -0
- data/lib/ultradns/api/account.rb +52 -0
- data/lib/ultradns/api/authentication.rb +107 -0
- data/lib/ultradns/api/client_accessor.rb +23 -0
- data/lib/ultradns/api/rrset.rb +112 -0
- data/lib/ultradns/api/zone.rb +137 -0
- data/lib/ultradns/client.rb +185 -0
- data/lib/ultradns/version.rb +9 -0
- data/test/fixtures/vcr_cassettes/test_account_related_apis.yml +166 -0
- data/test/fixtures/vcr_cassettes/test_auth.yml +166 -0
- data/test/fixtures/vcr_cassettes/test_auth_failure.yml +163 -0
- data/test/fixtures/vcr_cassettes/test_basic_client_apis.yml +124 -0
- data/test/fixtures/vcr_cassettes/test_tasks_list.yml +83 -0
- data/test/fixtures/vcr_cassettes/test_zone_apis.yml +124 -0
- data/test/fixtures/vcr_cassettes/test_zone_rrsets_apis.yml +546 -0
- data/test/test_authentication.rb +39 -0
- data/test/test_client_api.rb +131 -0
- data/test/test_helper.rb +54 -0
- data/ultradns-sdk.gemspec +32 -0
- metadata +191 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
|
2
|
+
class Ultradns::Api::ClientAccessor
|
3
|
+
|
4
|
+
def initialize(client)
|
5
|
+
@client = client
|
6
|
+
if client.kind_of?(Ultradns::Api::ClientAccessor)
|
7
|
+
@client = client.client
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
#########
|
13
|
+
|
14
|
+
def client
|
15
|
+
@client
|
16
|
+
end
|
17
|
+
|
18
|
+
def request_options(params = {})
|
19
|
+
@client.send :request_options, params
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright 2000-2014 NeuStar, Inc. All rights reserved.
|
2
|
+
# NeuStar, the Neustar logo and related names and logos are registered
|
3
|
+
# trademarks, service marks or tradenames of NeuStar, Inc. All other
|
4
|
+
# product names, company names, marks, logos and symbols may be trademarks
|
5
|
+
# of their respective owners.
|
6
|
+
|
7
|
+
require_relative 'client_accessor'
|
8
|
+
|
9
|
+
class Ultradns::Api::Rrset < Ultradns::Api::ClientAccessor
|
10
|
+
|
11
|
+
attr_reader :rtype, :owner_name
|
12
|
+
|
13
|
+
def initialize(zone, rtype, owner_name)
|
14
|
+
super(zone)
|
15
|
+
@zone_name = zone.zone_name
|
16
|
+
@rtype = rtype
|
17
|
+
@owner_name = owner_name
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
# Creates a new RRSet in the specified zone.
|
22
|
+
#
|
23
|
+
# === Required Parameters
|
24
|
+
#
|
25
|
+
# * +zone_name+ - The zone that contains the RRSet.The trailing dot is optional.
|
26
|
+
# * +rtype+ - The type of the RRSet.This can be numeric (1) or
|
27
|
+
# if a well-known name is defined for the type (A), you can use it instead.
|
28
|
+
# * +owner_name+ - The owner name for the RRSet.
|
29
|
+
# If no trailing dot is supplied, the owner_name is assumed to be relative (foo).
|
30
|
+
# If a trailing dot is supplied, the owner name is assumed to be absolute (foo.zonename.com.)
|
31
|
+
# * +ttl+ - The updated TTL value for the RRSet.
|
32
|
+
# * +rdata+ - The updated BIND data for the RRSet as a string.
|
33
|
+
# If there is a single resource record in the RRSet, you can pass in the single string or an array with a single element.
|
34
|
+
# If there are multiple resource records in this RRSet, pass in a list of strings.
|
35
|
+
#
|
36
|
+
# === Examples
|
37
|
+
#
|
38
|
+
# c.zone('zone.invalid.').rrset('A', 'foo').create(300, '1.2.3.4')
|
39
|
+
def create(ttl, rdata)
|
40
|
+
rrset = {:ttl => ttl, :rdata => rdata}
|
41
|
+
rrset[:rdata] = [rdata] unless rdata.kind_of? Array
|
42
|
+
client.with_auth_retry {|c| c.post rrset_path, request_options({body: rrset.to_json}) }
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
# List all RRSets for this rtype and owner_name
|
47
|
+
def list
|
48
|
+
client.with_auth_retry {|c| c.get rrset_path, request_options }
|
49
|
+
end
|
50
|
+
|
51
|
+
# (Partially) Updates an existing RRSet for this rtype and owner_name in this zone
|
52
|
+
#
|
53
|
+
# === Required Parameters
|
54
|
+
#
|
55
|
+
# * +ttl+ - The updated TTL value for the RRSet.
|
56
|
+
# * +rdata+ - The updated BIND data for the RRSet as a string.
|
57
|
+
# If there is a single resource record in the RRSet, you can pass in the single string or an array with a single element.
|
58
|
+
# If there are multiple resource records in this RRSet, pass in a list of strings.
|
59
|
+
# #
|
60
|
+
# === Examples
|
61
|
+
#
|
62
|
+
# c.update('zone.invalid.', "A", "foo", 100, ["10.20.30.40"])
|
63
|
+
def update(ttl, rdata = nil)
|
64
|
+
rrset = {}
|
65
|
+
rrset[:ttl] = ttl if ttl != nil
|
66
|
+
rrset[:rdata] = (rdata.kind_of?(Array) ? rdata : [rdata]) if rdata != nil
|
67
|
+
|
68
|
+
client.with_auth_retry {|c| c.patch rrset_path, request_options({body: rrset.to_json}) }
|
69
|
+
end
|
70
|
+
|
71
|
+
# Updates (by replacing) an existing RRSet for this rtype and owner_name in this zone
|
72
|
+
def replace()
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# Delete an rrset
|
77
|
+
#
|
78
|
+
# === Required Parameters
|
79
|
+
# * +zone_name+ - The zone containing the RRSet to be deleted. The trailing dot is optional.
|
80
|
+
# * +rtype+ - The type of the RRSet.This can be numeric (1) or if a well-known name
|
81
|
+
# is defined for the type (A), you can use it instead.
|
82
|
+
# * +owner_name+ - The owner name for the RRSet.
|
83
|
+
# If no trailing dot is supplied, the owner_name is assumed to be relative (foo).
|
84
|
+
# If a trailing dot is supplied, the owner name is assumed to be absolute (foo.zonename.com.)
|
85
|
+
#
|
86
|
+
# === Examples
|
87
|
+
#
|
88
|
+
# c.delete_rrset(first_zone_name, 'A', 'foo')
|
89
|
+
def delete
|
90
|
+
client.with_auth_retry {|c| c.delete rrset_path, request_options }
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# def profiles
|
95
|
+
# list()
|
96
|
+
# end
|
97
|
+
|
98
|
+
# Set the profile for the matching rrsets
|
99
|
+
#
|
100
|
+
def profile(options)
|
101
|
+
client.with_auth_retry {|c| c.patch rrset_path, request_options({body: {profile: options}.to_json}) }
|
102
|
+
end
|
103
|
+
|
104
|
+
|
105
|
+
protected
|
106
|
+
#########
|
107
|
+
|
108
|
+
def rrset_path()
|
109
|
+
"/zones/#{@zone_name}/rrsets/#{@rtype}/#{@owner_name}"
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# Copyright 2000-2014 NeuStar, Inc. All rights reserved.
|
2
|
+
# NeuStar, the Neustar logo and related names and logos are registered
|
3
|
+
# trademarks, service marks or tradenames of NeuStar, Inc. All other
|
4
|
+
# product names, company names, marks, logos and symbols may be trademarks
|
5
|
+
# of their respective owners.
|
6
|
+
|
7
|
+
require_relative 'client_accessor'
|
8
|
+
|
9
|
+
class Ultradns::Api::Zone < Ultradns::Api::ClientAccessor
|
10
|
+
|
11
|
+
attr_reader :zone_name
|
12
|
+
|
13
|
+
def initialize(client, zone_name)
|
14
|
+
super(client)
|
15
|
+
@zone_name = zone_name
|
16
|
+
end
|
17
|
+
|
18
|
+
# Get zone metadata
|
19
|
+
#
|
20
|
+
# === Examples
|
21
|
+
#
|
22
|
+
# c.zone('foo.invalid.').metadata
|
23
|
+
def metadata
|
24
|
+
client.with_auth_retry {|c| c.get "/zones/#{@zone_name}", request_options }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Create a zone
|
28
|
+
#
|
29
|
+
# === Required Parameters
|
30
|
+
#
|
31
|
+
# * +account_name+ - The account that the zone will be created under. The user must have write access for zones in that account.
|
32
|
+
#
|
33
|
+
# === Optional Parameters
|
34
|
+
#
|
35
|
+
# * +type+ - The type of zone to be created, one of three possible values: PRIMARY, SECONDARY, or ALIAS.
|
36
|
+
#
|
37
|
+
# See documentation section: Primary Zone DTO or Secondary Zone DTO for further options.
|
38
|
+
# === Examples
|
39
|
+
#
|
40
|
+
# c.create('my_account')
|
41
|
+
def create(account_name, options = {})
|
42
|
+
zone_properties = {name: @zone_name, accountName: account_name, type: 'PRIMARY'}
|
43
|
+
|
44
|
+
primary_zone_info = {}
|
45
|
+
if options[:properties][:type] == 'PRIMARY' || options[:properties][:type] == nil
|
46
|
+
primary_zone_info = {forceImport: true, createType: 'NEW'}
|
47
|
+
end
|
48
|
+
|
49
|
+
zone_data = {properties: zone_properties,
|
50
|
+
primaryCreateInfo: primary_zone_info}.merge(options)
|
51
|
+
|
52
|
+
with_auth_retry {|c| c.post '/zones', request_options({body: zone_data.to_json}) }
|
53
|
+
end
|
54
|
+
|
55
|
+
# Delete a zone
|
56
|
+
#
|
57
|
+
# === Examples
|
58
|
+
#
|
59
|
+
# c.zone('foo.invalid.').delete
|
60
|
+
def delete
|
61
|
+
client.with_auth_retry {|c| c.delete "/zones/#{@zone_name}", request_options }
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
|
66
|
+
# Returns the list of RRSets in the specified zone of the (optional) specified type.
|
67
|
+
#
|
68
|
+
# === Optional Parameters
|
69
|
+
#
|
70
|
+
# * +rtype+ - The type of the RRSets. This can be numeric (1) or
|
71
|
+
# if a well-known name is defined for the type (A), you can use it instead.
|
72
|
+
#
|
73
|
+
# === Optional Parameters
|
74
|
+
#
|
75
|
+
# * +:q+ - The search parameters, in a hash. Valid keys are:
|
76
|
+
# ttl - must match the TTL for the rrset
|
77
|
+
# owner - substring match of the owner name
|
78
|
+
# value - substring match of the first BIND field value
|
79
|
+
# * +:sort+ - The sort column used to order the list. Valid values for the sort field are:
|
80
|
+
# OWNER
|
81
|
+
# TTL
|
82
|
+
# TYPE
|
83
|
+
# * +:reverse+ - Whether the list is ascending(false) or descending(true). Defaults to true
|
84
|
+
# * +:offset+ - The position in the list for the first returned element(0 based)
|
85
|
+
# * +:limit+ - The maximum number of zones to be returned.
|
86
|
+
#
|
87
|
+
# === Examples
|
88
|
+
#
|
89
|
+
# c.zone('foo.invalid.').rrsets() # all types returned
|
90
|
+
# c.zone('foo.invalid.').rrsets('A')
|
91
|
+
# c.zone('foo.invalid.').rrsets('TXT', q: {value: 'cheese', ttl:300}, offset:5, limit:10)
|
92
|
+
def rrsets(rtype = nil, options={})
|
93
|
+
rrsets_path = "/zones/#{@zone_name}/rrsets"
|
94
|
+
rrsets_path += "/#{rtype}" if rtype != nil
|
95
|
+
|
96
|
+
client.with_auth_retry {|c| c.get(rrsets_path, request_options(options)) }
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# === Required Parameters
|
101
|
+
# * +rtype+ - The type of the RRSet.This can be numeric (1) or if a well-known name
|
102
|
+
# is defined for the type (A), you can use it instead.
|
103
|
+
# * +owner_name+ - The owner name for the RRSet.
|
104
|
+
# If no trailing dot is supplied, the owner_name is assumed to be relative (foo).
|
105
|
+
# If a trailing dot is supplied, the owner name is assumed to be absolute (foo.zonename.com.)
|
106
|
+
#
|
107
|
+
# === Examples
|
108
|
+
#
|
109
|
+
# c.rrset('A', 'foo')
|
110
|
+
def rrset(rtype, owner_name)
|
111
|
+
Ultradns::Api::Rrset.new(self, rtype, owner_name)
|
112
|
+
end
|
113
|
+
|
114
|
+
# Creates a new RRSet in the specified zone.
|
115
|
+
#
|
116
|
+
# === Required Parameters
|
117
|
+
#
|
118
|
+
# * +zone_name+ - The zone that contains the RRSet.The trailing dot is optional.
|
119
|
+
# * +rtype+ - The type of the RRSet.This can be numeric (1) or
|
120
|
+
# if a well-known name is defined for the type (A), you can use it instead.
|
121
|
+
# * +owner_name+ - The owner name for the RRSet.
|
122
|
+
# If no trailing dot is supplied, the owner_name is assumed to be relative (foo).
|
123
|
+
# If a trailing dot is supplied, the owner name is assumed to be absolute (foo.zonename.com.)
|
124
|
+
# * +ttl+ - The updated TTL value for the RRSet.
|
125
|
+
# * +rdata+ - The updated BIND data for the RRSet as a string.
|
126
|
+
# If there is a single resource record in the RRSet, you can pass in the single string or an array with a single element.
|
127
|
+
# If there are multiple resource records in this RRSet, pass in a list of strings.
|
128
|
+
#
|
129
|
+
# === Examples
|
130
|
+
#
|
131
|
+
# c.zone('zone.invalid.').create_rrset('A', 'foo', 300, '1.2.3.4')
|
132
|
+
def create_rrset(rtype, owner_name, ttl, rdata)
|
133
|
+
rrset(rtype, owner_name).create(ttl, rdata)
|
134
|
+
end
|
135
|
+
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
# Copyright 2000-2014 NeuStar, Inc. All rights reserved.
|
2
|
+
# NeuStar, the Neustar logo and related names and logos are registered
|
3
|
+
# trademarks, service marks or tradenames of NeuStar, Inc. All other
|
4
|
+
# product names, company names, marks, logos and symbols may be trademarks
|
5
|
+
# of their respective owners.
|
6
|
+
|
7
|
+
require 'httparty'
|
8
|
+
require 'logger'
|
9
|
+
|
10
|
+
require_relative 'api/authentication'
|
11
|
+
require_relative 'api/account'
|
12
|
+
require_relative 'api/client_accessor'
|
13
|
+
require_relative 'api/rrset'
|
14
|
+
require_relative 'api/zone'
|
15
|
+
|
16
|
+
class Ultradns::Client
|
17
|
+
include HTTParty
|
18
|
+
include Ultradns::Api::Authentication
|
19
|
+
|
20
|
+
disable_rails_query_string_format
|
21
|
+
default_timeout 30
|
22
|
+
open_timeout 10
|
23
|
+
read_timeout 10
|
24
|
+
headers({'Accept' => 'application/json', 'Content-Type' => 'application/json'})
|
25
|
+
format :json # force the format to json
|
26
|
+
|
27
|
+
# base uri for the service
|
28
|
+
base_uri 'https://restapi.ultradns.com/v1'
|
29
|
+
|
30
|
+
debug_output $stdout if ENV['DEBUG']
|
31
|
+
|
32
|
+
|
33
|
+
# Initialize an Ultra REST API client
|
34
|
+
#
|
35
|
+
# === Required Parameters
|
36
|
+
#
|
37
|
+
# * +username+ - The user name
|
38
|
+
# * +password+ - The user's password
|
39
|
+
#
|
40
|
+
# === Optional Parameters
|
41
|
+
#
|
42
|
+
# * +:use_http+ - Use http instead of https. Defaults to false, set to true only in test environments. Will not work in production.
|
43
|
+
# * +:host+ - host and port of the remote server. Defaults to restapi.ultradns.com.
|
44
|
+
#
|
45
|
+
# === Examples
|
46
|
+
#
|
47
|
+
# c = RestClient.new("myUname", "myPwd")
|
48
|
+
# c = RestClient.new("myUname", "myPwd", host: 'restapi-useast1b01-01.ct.ultradns.net:8080')
|
49
|
+
def initialize(username, password, options = {})
|
50
|
+
@logger ||= ::Logger.new($stdout)
|
51
|
+
|
52
|
+
auth(username, password)
|
53
|
+
|
54
|
+
@options = {}
|
55
|
+
# override or ignored if nil
|
56
|
+
@options[:base_uri] = HTTParty.normalize_base_uri(options[:host]) if options[:host]
|
57
|
+
|
58
|
+
logger.debug "Initializing UltraDNS Client using #{@options.inspect}"
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
# Get version of REST API server
|
64
|
+
#
|
65
|
+
# === Examples
|
66
|
+
#
|
67
|
+
# c.version
|
68
|
+
def version
|
69
|
+
with_auth_retry {|c| c.get '/version', request_options }
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
# Get status of REST API server
|
74
|
+
#
|
75
|
+
# === Examples
|
76
|
+
#
|
77
|
+
# c.status
|
78
|
+
def status
|
79
|
+
with_auth_retry {|c| c.get '/status', request_options }
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
# Access Account Level Resources for the given account_name
|
84
|
+
#
|
85
|
+
# === Required Parameters
|
86
|
+
#
|
87
|
+
# * +account_name+ - One of the user's accounts. The user must have read access for zones in that account.
|
88
|
+
#
|
89
|
+
def account(account_name)
|
90
|
+
Ultradns::Api::Account.new(self, account_name)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Get account details for user
|
94
|
+
#
|
95
|
+
# === Examples
|
96
|
+
#
|
97
|
+
# c.accounts
|
98
|
+
def accounts
|
99
|
+
with_auth_retry {|c| c.get '/accounts', request_options }
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# === Required Parameters
|
104
|
+
#
|
105
|
+
# * +zone_name+ - The name of the zone.
|
106
|
+
#
|
107
|
+
def zone(zone_name)
|
108
|
+
Ultradns::Api::Zone.new(self, zone_name)
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# Create a primary zone
|
113
|
+
#
|
114
|
+
# === Required Parameters
|
115
|
+
#
|
116
|
+
# * +account_name+ - The account that the zone will be created under. The user must have write access for zones in that account.
|
117
|
+
# * +zone_name+ - The name of the zone. The trailing . is optional. The zone name must not be in use by anyone.
|
118
|
+
#
|
119
|
+
# === Examples
|
120
|
+
#
|
121
|
+
# c.create_primary_zone('my_account', 'zone.invalid.')
|
122
|
+
def create_primary_zone(account_name, zone_name)
|
123
|
+
zone_properties = {:name => zone_name, :accountName => account_name, :type => 'PRIMARY'}
|
124
|
+
primary_zone_info = {:forceImport => true, :createType => 'NEW'}
|
125
|
+
|
126
|
+
zone_data = {:properties => zone_properties, :primaryCreateInfo => primary_zone_info}
|
127
|
+
|
128
|
+
with_auth_retry {|c| c.post '/zones', request_options({:body => zone_data.to_json}) }
|
129
|
+
end
|
130
|
+
|
131
|
+
# List the background tasks (jobs) running. Some APIs will return a Task Id
|
132
|
+
# which can used to determine the state of those jobs.
|
133
|
+
#
|
134
|
+
# === Optional Parameters
|
135
|
+
#
|
136
|
+
# * +:q+ - The search parameters, in a hash. The query used to construct the list.
|
137
|
+
# Valid keys are:
|
138
|
+
# code - valid values for 'code' are PENDING, IN_PROCESS, COMPLETE, and ERROR.
|
139
|
+
# hasData - valid values for 'hasData' are true and false.
|
140
|
+
#
|
141
|
+
# * +offset+ - The position in the list for the first returned element (0 based). The
|
142
|
+
# default value is 0.
|
143
|
+
#
|
144
|
+
# * +limit+ - The maximum number of rows requested. The default value is 100.
|
145
|
+
#
|
146
|
+
# * +sort+ - The sort column used to order the list. Valid sort fields are CODE, CONTENT_TYPE, EXTENSIONS,
|
147
|
+
# HAS_DATA, and DATE. The default value is CODE.
|
148
|
+
#
|
149
|
+
# * +reverse+ - Whether the list is ascending (false) or descending (true). The default
|
150
|
+
# value is false.
|
151
|
+
#
|
152
|
+
def tasks(options = {})
|
153
|
+
with_auth_retry {|c| c.get("/tasks", request_options(options)) }
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
|
158
|
+
protected
|
159
|
+
#########
|
160
|
+
def request_options(params = {})
|
161
|
+
add_auth_header!(params)
|
162
|
+
@options.merge(build_params(params))
|
163
|
+
end
|
164
|
+
|
165
|
+
|
166
|
+
def logger
|
167
|
+
@logger
|
168
|
+
end
|
169
|
+
|
170
|
+
def build_params(args)
|
171
|
+
params = {}
|
172
|
+
if args[:q]
|
173
|
+
q = args[:q]
|
174
|
+
q_str = ''
|
175
|
+
q.each { |k, v| q_str += "#{k}:#{v} " }
|
176
|
+
if q_str.length > 0
|
177
|
+
params[:q] = q_str
|
178
|
+
end
|
179
|
+
args.delete :q
|
180
|
+
end
|
181
|
+
params.update(args)
|
182
|
+
params
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|