ultradns-sdk 0.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/.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
|