Class: DynectRest

Inherits:
Object
  • Object
show all
Defined in:
lib/dynect_rest.rb,
lib/dynect_rest/gslb.rb,
lib/dynect_rest/version.rb,
lib/dynect_rest/resource.rb,
lib/dynect_rest/exceptions.rb

Overview

Author

Adam Jacob (<[email protected]>)

Copyright

Copyright © 2010 Opscode, Inc.

License

Apache License, Version 2.0

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Defined Under Namespace

Classes: Exceptions, GSLB, Resource

Constant Summary collapse

VERSION =
'0.4.5'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(customer_name, user_name, password, zone = nil, connect = true, verbose = false, max_redirects = 10) ⇒ DynectRest

Creates a new base object for interacting with Dynect’s REST API

Parameters:

  • Your (String)

    dynect customer name

  • Your (String)

    dnyect user name

  • Your (String)

    dynect password

  • The (String)

    zone you are going to be editing

  • Whether (Boolean)

    to connect immediately or not - runs login for you

  • Verbosity (Boolean)


37
38
39
40
41
42
43
44
45
# File 'lib/dynect_rest.rb', line 37

def initialize(customer_name, user_name, password, zone=nil, connect=true, verbose=false, max_redirects=10)
  @customer_name = customer_name
  @user_name = user_name
  @password = password
  @rest = RestClient::Resource.new('https://api2.dynect.net/REST/', :headers => { :content_type => 'application/json' }, :max_redirects=>max_redirects)
  @zone = zone
  @verbose = verbose
   if connect
end

Instance Attribute Details

#customer_nameObject

Returns the value of attribute customer_name.



27
28
29
# File 'lib/dynect_rest.rb', line 27

def customer_name
  @customer_name
end

#passwordObject

Returns the value of attribute password.



27
28
29
# File 'lib/dynect_rest.rb', line 27

def password
  @password
end

#restObject

Returns the value of attribute rest.



27
28
29
# File 'lib/dynect_rest.rb', line 27

def rest
  @rest
end

#user_nameObject

Returns the value of attribute user_name.



27
28
29
# File 'lib/dynect_rest.rb', line 27

def user_name
  @user_name
end

#zoneObject

Returns the value of attribute zone.



27
28
29
# File 'lib/dynect_rest.rb', line 27

def zone
  @zone
end

Class Method Details

.underscore(string) ⇒ Object

Convert a CamelCasedString to an under_scored_string.



147
148
149
150
151
152
153
154
155
# File 'lib/dynect_rest.rb', line 147

def self.underscore(string)
  word = string.dup
  word.gsub!(/::/, '/')
  word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
  word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
  word.tr!("-", "_")
  word.downcase!
  word
end

Instance Method Details

#all_records(zone = nil, fqdn = nil) ⇒ Object

Get all the entries in a zone

See: help.dynect.net/get-all-records-api/

Retrieves all records from the zone – api.dynect.net/REST/AllRecord/<zone> Retrieves all records from the node – api.dynect.net/REST/AllRecord/<zone>/<FQDN>/



91
92
93
94
95
96
97
# File 'lib/dynect_rest.rb', line 91

def all_records(zone=nil, fqdn=nil)
  zone ||= @zone
  resource = [zone,fqdn].compact.join("/")
  get("AllRecord/#{resource}").each do |ref|
    ref.sub!(/^\/REST\//,'')
  end
end

#api_request(&block) ⇒ Object

Handles making Dynect API requests and formatting the responses properly.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/dynect_rest.rb', line 220

def api_request(&block)
  response_body = begin
    response = block.call
    response.body
  rescue RestClient::Exception => e
    if @verbose
      puts "I have #{e.inspect} with #{e.http_code}"
    end
    if e.http_code == 307
      e.response.sub!(/^\/REST\//,'')
      get(e.response)
    end
    # Something went wrong, so escalate to caller
    raise DynectRest::Exceptions::RequestFailed, "Request failed: #{e.inspect}"
  end

  parse_response(JSON.parse(response_body || '{}'))
end

#delete(path_part, additional_headers = {}, &block) ⇒ Object

Raw DELETE request, formatted for Dyn. See list of endpoints at:

manage.dynect.net/help/docs/api2/rest/resources/

Parameters:

  • The (String)

    partial path to DELETE - for example, ‘User’ or ‘Zone’.

  • Additional (Hash)

    HTTP headers



189
190
191
# File 'lib/dynect_rest.rb', line 189

def delete(path_part, additional_headers = {}, &block)
  api_request { @rest[path_part].delete(additional_headers, &block) }
end

#freeze(zone = nil) ⇒ Hash

Parameters:

  • The (String)

    zone to freeze - if one is provided when instantiated, we use that.

Returns:

  • (Hash)

    The dynect API response



130
131
132
133
# File 'lib/dynect_rest.rb', line 130

def freeze(zone=nil)
  zone ||= @zone
  put("Zone/#{zone}", { "freeze" => true })
end

#get(path_part, additional_headers = {}, &block) ⇒ Object

Raw GET request, formatted for Dyn. See list of endpoints at:

manage.dynect.net/help/docs/api2/rest/resources/

Parameters:

  • The (String)

    partial path to GET - for example, ‘User’ or ‘Zone’.

  • Additional (Hash)

    HTTP headers



179
180
181
# File 'lib/dynect_rest.rb', line 179

def get(path_part, additional_headers = {}, &block)
  api_request { @rest[path_part].get(additional_headers, &block) }
end

#get_zone(zone = nil) ⇒ Hash

Parameters:

  • The (String)

    zone to fetch - if one is provided when instantiated, we use that.

Returns:

  • (Hash)

    The dynect API response



108
109
110
111
# File 'lib/dynect_rest.rb', line 108

def get_zone(zone=nil)
  zone ||= @zone
  get("Zone/#{zone}")
end

#gslbObject

GSLB Service



169
170
171
# File 'lib/dynect_rest.rb', line 169

def gslb
  DynectRest::GSLB.new(:dynect => self, :zone => @zone)
end

#loginHash

Login to Dynect - must be done before any other methods called.

See: manage.dynect.net/help/docs/api2/rest/resources/Session.html

Returns:

  • (Hash)

    The dynect API response



56
57
58
59
60
# File 'lib/dynect_rest.rb', line 56

def 
  response = post('Session', { 'customer_name' => @customer_name, 'user_name' => @user_name, 'password' => @password })
  @rest.headers[:auth_token] = response["token"]
  response
end

#logoutHash

Logout of Dynect - must be done before any other methods called.

See: manage.dynect.net/help/docs/api2/rest/resources/Session.html

Returns:

  • (Hash)

    The dynect API response



67
68
69
# File 'lib/dynect_rest.rb', line 67

def logout
  delete('Session')
end

#node_list(zone = nil, fqdn = nil) ⇒ Object

Get all the entries in a zone

See: help.dynect.net/get-node-list-api/

Get nodes under the FQDN – api.dynect.net/REST/NodeLIst/<zone>/<FQDN>/ Get nodes in the zone – api.dynect.net/REST/NodeList/<zone>/



77
78
79
80
81
82
83
# File 'lib/dynect_rest.rb', line 77

def node_list(zone=nil, fqdn=nil)
  zone ||= @zone
  resource = [zone,fqdn].compact.join("/")
  get("NodeList/#{resource}").each do |ref|
    ref.sub!(/^\/REST\//,'')
  end
end

#parse_response(response) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/dynect_rest.rb', line 239

def parse_response(response)
  case response["status"]
  when "success"
    response["data"]
  when "incomplete"
    # we get 'incomplete' when the API is running slow and claims the session has a previous job running
    # raise an error and return the job ID in case we want to ask the API what the job's status is
    error_messages = []
    error_messages.push( "This session may have a job _still_ running (slowly). Call /REST/Job/#{response["job_id"]} to get its status." )
    response["msgs"].each do |error_message|
      error_messages << "#{error_message["LVL"]} #{error_message["ERR_CD"]} #{error_message["SOURCE"]} - #{error_message["INFO"]}"
    end
    raise DynectRest::Exceptions::IncompleteRequest.new( "#{error_messages.join("\n")}", response["job_id"] )
  when "failure"
    error_messages = []
    response["msgs"].each do |error_message|
      error_messages << "#{error_message["LVL"]} #{error_message["ERR_CD"]} #{error_message["SOURCE"]} - #{error_message["INFO"]}"
    end
    raise DynectRest::Exceptions::RequestFailed, "Request failed: #{error_messages.join("\n")}"
  end
end

#post(path_part, payload, additional_headers = {}, &block) ⇒ Object

Raw POST request, formatted for Dyn. See list of endpoints at:

manage.dynect.net/help/docs/api2/rest/resources/

Read the API documentation, and submit the proper data structure from here.

Parameters:

  • The (String)

    partial path to POST - for example, ‘User’ or ‘Zone’.

  • The (Hash)

    data structure to submit as the body, is automatically turned to JSON.

  • Additional (Hash)

    HTTP headers



202
203
204
# File 'lib/dynect_rest.rb', line 202

def post(path_part, payload, additional_headers = {}, &block)
  api_request { @rest[path_part].post(payload.to_json, additional_headers, &block) }
end

#publish(zone = nil) ⇒ Hash

Publish any pending changes to the zone - required to make any alterations permanent.

See: manage.dynect.net/help/docs/api2/rest/resources/Zone.html

Parameters:

  • The (String)

    zone to publish - if one is provided when instantiated, we use that.

Returns:

  • (Hash)

    The dynect API response



119
120
121
122
# File 'lib/dynect_rest.rb', line 119

def publish(zone=nil)
  zone ||= @zone
  put("Zone/#{zone}", { "publish" => true })
end

#put(path_part, payload, additional_headers = {}, &block) ⇒ Object

Raw PUT request, formatted for Dyn. See list of endpoints at:

manage.dynect.net/help/docs/api2/rest/resources/

Read the API documentation, and submit the proper data structure from here.

Parameters:

  • The (String)

    partial path to PUT - for example, ‘User’ or ‘Zone’.

  • The (Hash)

    data structure to submit as the body, is automatically turned to JSON.

  • Additional (Hash)

    HTTP headers



215
216
217
# File 'lib/dynect_rest.rb', line 215

def put(path_part, payload, additional_headers = {}, &block)
  api_request { @rest[path_part].put(payload.to_json, additional_headers, &block) }
end

#record_typeObject

Resource Records



160
161
162
163
164
# File 'lib/dynect_rest.rb', line 160

%w{AAAA A CNAME DNSKEY DS KEY LOC MX NS PTR RP SOA SRV TXT}.each do |record_type|
  define_method underscore(record_type) do
    DynectRest::Resource.new(self,"#{record_type}" , @zone)
  end
end

#thaw(zone = nil) ⇒ Hash

Parameters:

  • The (String)

    zone to thaw - if one is provided when instantiated, we use that.

Returns:

  • (Hash)

    The dynect API response



141
142
143
144
# File 'lib/dynect_rest.rb', line 141

def thaw(zone=nil)
  zone ||= @zone
  put("Zone/#{zone}", { "thaw" => true })
end