Class: Fog::DNS::Dynect::Real

Inherits:
Object
  • Object
show all
Defined in:
lib/fog/dynect/dns.rb,
lib/fog/dynect/requests/dns/get_zone.rb,
lib/fog/dynect/requests/dns/put_zone.rb,
lib/fog/dynect/requests/dns/post_zone.rb,
lib/fog/dynect/requests/dns/get_record.rb,
lib/fog/dynect/requests/dns/put_record.rb,
lib/fog/dynect/requests/dns/delete_zone.rb,
lib/fog/dynect/requests/dns/post_record.rb,
lib/fog/dynect/requests/dns/post_session.rb,
lib/fog/dynect/requests/dns/delete_record.rb,
lib/fog/dynect/requests/dns/get_node_list.rb,
lib/fog/dynect/requests/dns/get_all_records.rb

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Real

Returns a new instance of Real.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/fog/dynect/dns.rb', line 62

def initialize(options={})
  @dynect_customer = options[:dynect_customer]
  @dynect_username = options[:dynect_username]
  @dynect_password = options[:dynect_password]

  @connection_options = options[:connection_options] || {}
  @host               = 'api-v4.dynect.net'
  @port               = options[:port]             || 443
  @path               = options[:path]             || '/REST'
  @persistent         = options[:persistent]       || false
  @scheme             = options[:scheme]           || 'https'
  @version            = options[:version]          || '3.5.2'
  @job_poll_timeout   = options[:job_poll_timeout] || 10
  @connection = Fog::XML::Connection.new("#{@scheme}://#{@host}:#{@port}", @persistent, @connection_options)
end

Instance Method Details

#auth_tokenObject



78
79
80
# File 'lib/fog/dynect/dns.rb', line 78

def auth_token
  @auth_token ||= post_session.body['data']['token']
end

#delete_record(type, zone, fqdn, record_id) ⇒ Object

Delete a record

Parameters

  • 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’]

  • zone<~String> - zone of record

  • fqdn<~String> - fqdn of record

  • record_id<~String> - id of record



13
14
15
16
17
18
19
20
# File 'lib/fog/dynect/requests/dns/delete_record.rb', line 13

def delete_record(type, zone, fqdn, record_id)
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :delete,
    :path     => ["#{type.to_s.upcase}Record", zone, fqdn, record_id].join('/')
  )
end

#delete_zone(zone) ⇒ Object

Delete a zone

Parameters

  • zone<~String> - zone to host



10
11
12
13
14
15
16
# File 'lib/fog/dynect/requests/dns/delete_zone.rb', line 10

def delete_zone(zone)
  request(
    :expects  => 200,
    :method   => :delete,
    :path     => "Zone/#{zone}"
  )
end

#get_all_records(zone, options = {}) ⇒ Object

Get one or more node lists

Parameters

  • zone<~String> - zone to lookup node lists for

  • options<~Hash>

    • fqdn<~String> - fully qualified domain name of node to lookup



12
13
14
15
16
17
18
19
20
21
# File 'lib/fog/dynect/requests/dns/get_all_records.rb', line 12

def get_all_records(zone, options = {})
  requested_fqdn = options['fqdn'] || options[:fqdn]
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :get,
    :path     => ['AllRecord', zone, requested_fqdn].compact.join('/'),
    :query    => {'detail' => 'Y'} # return full records, instead of just resource URLs
  )
end

#get_node_list(zone, options = {}) ⇒ Object

Get one or more node lists

Parameters

  • zone<~String> - zone to lookup node lists for

  • options<~Hash>

    • fqdn<~String> - fully qualified domain name of node to lookup



12
13
14
15
16
17
18
19
20
# File 'lib/fog/dynect/requests/dns/get_node_list.rb', line 12

def get_node_list(zone, options = {})
  requested_fqdn = options['fqdn'] || options[:fqdn]
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :get,
    :path     => ['AllRecord', zone, requested_fqdn].compact.join('/')
  )
end

#get_record(type, zone, fqdn, options = {}) ⇒ Object

List records of a given type

Parameters

  • 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’]

  • zone<~String> - name of zone to lookup

  • fqdn<~String> - name of fqdn to lookup

  • options<~Hash>:

    • record_id<~String> - id of record



14
15
16
17
18
19
20
21
# File 'lib/fog/dynect/requests/dns/get_record.rb', line 14

def get_record(type, zone, fqdn, options = {})
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :get,
    :path     => ["#{type.to_s.upcase}Record", zone, fqdn, options['record_id']].compact.join('/')
  )
end

#get_zone(options = {}) ⇒ Object

Get one or more zones

Parameters

  • options<~Hash>:

    • zone<~String> - name of zone to lookup, or omit to return list of zones



11
12
13
14
15
16
17
18
# File 'lib/fog/dynect/requests/dns/get_zone.rb', line 11

def get_zone(options = {})
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :get,
    :path     => ['Zone', options['zone']].compact.join('/')
  )
end

#poll_job(response, original_expects, time_to_wait) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/fog/dynect/dns.rb', line 130

def poll_job(response, original_expects, time_to_wait)
  job_location = response.headers['Location']

  begin
    Fog.wait_for(time_to_wait) do
     response = request(
       :expects => original_expects,
       :idempotent => true,
       :method => :get,
       :path => job_location
     )
     response.body['status'] != 'incomplete'
    end

  rescue Errors::TimeoutError => error
    if response.body['status'] == 'incomplete'
      raise JobIncomplete.new("Job #{response.body['job_id']} is still incomplete")
    else
      raise error
    end
  end

  response
end

#post_record(type, zone, fqdn, rdata, options = {}) ⇒ Object

Create a record

Parameters

  • 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’]

  • zone<~String> - zone of record

  • rdata<~Hash> - rdata for record

  • options<~Hash>: (options vary by type, listing below includes common parameters)

    • ttl<~Integer> - ttl for the record, defaults to zone ttl



14
15
16
17
18
19
20
21
22
# File 'lib/fog/dynect/requests/dns/post_record.rb', line 14

def post_record(type, zone, fqdn, rdata, options = {})
  options.merge!('rdata' => rdata)
  request(
    :body     => Fog::JSON.encode(options),
    :expects  => 200,
    :method   => :post,
    :path     => ["#{type.to_s.upcase}Record", zone, fqdn].join('/')
  )
end

#post_sessionObject



5
6
7
8
9
10
11
12
13
14
15
16
17
# File 'lib/fog/dynect/requests/dns/post_session.rb', line 5

def post_session
  request(
    :expects  => 200,
    :idempotent => true,
    :method   => :post,
    :path     => "Session",
    :body     => Fog::JSON.encode({
      :customer_name  => @dynect_customer,
      :user_name      => @dynect_username,
      :password       => @dynect_password
    })
  )
end

#post_zone(rname, ttl, zone, options = {}) ⇒ Object

Create a zone

Parameters

  • rname<~String> - administrative contact

  • ttl<~Integer> - time to live (in seconds) for records in this zone

  • zone<~String> - name of zone to host

  • options<~Hash>:

    • serial_style<~String> - style of serial number, in [‘day’, ‘epoch’, ‘increment’, ‘minute’]. Defaults to increment



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/fog/dynect/requests/dns/post_zone.rb', line 14

def post_zone(rname, ttl, zone, options = {})
  body = Fog::JSON.encode({
    :rname  => rname,
    :token  => auth_token,
    :ttl    => ttl
  }.merge!(options))

  request(
    :body     => body,
    :expects  => 200,
    :method   => :post,
    :path     => 'Zone/' << zone
  )
end

#put_record(type, zone, fqdn, rdata, options = {}) ⇒ Object

Update or replace a record

Parameters

  • 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’]

  • zone<~String> - zone of record

  • rdata<~Hash> - rdata for record

  • options<~Hash>: (options vary by type, listing below includes common parameters)

    • ttl<~Integer> - ttl for the record, defaults to zone ttl



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/fog/dynect/requests/dns/put_record.rb', line 14

def put_record(type, zone, fqdn, rdata, options = {})
  options.merge!('rdata' => rdata)
  type.to_s.upcase!
  options = {"#{type}Records" => [options]} unless options['record_id']
  path = ["#{type}Record", zone, fqdn].join('/')
  path += "/#{options.delete('record_id')}" if options['record_id']
  request(
    :body       => Fog::JSON.encode(options),
    :expects    => 200,
    :idempotent => true,
    :method     => :put,
    :path       => path
  )
end

#put_zone(zone, options = {}) ⇒ Object

Update a zone

Parameters

  • zone<~String> - name or id of zone

  • options<~Hash>:

    • freeze<~Boolean> - causes zone to become frozen

    • publish<~Boolean> - causes all pending changes to be pushed to nameservers

    • thaw<~Boolean> - causes zone to cease being frozen



14
15
16
17
18
19
20
21
22
# File 'lib/fog/dynect/requests/dns/put_zone.rb', line 14

def put_zone(zone, options = {})
  request(
    :body       => Fog::JSON.encode(options),
    :expects    => 200,
    :idempotent => true,
    :method     => :put,
    :path       => 'Zone/' << zone
  )
end

#request(params) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/fog/dynect/dns.rb', line 82

def request(params)
  begin
    # any request could redirect to a job
    params[:expects] = Array(params[:expects]) | [307]

    params[:headers] ||= {}
    params[:headers]['Content-Type'] = 'application/json'
    params[:headers]['API-Version'] = @version
    params[:headers]['Auth-Token'] = auth_token unless params[:path] == 'Session'
    params[:path] = "#{@path}/#{params[:path]}" unless params[:path] =~ %r{^#{Regexp.escape(@path)}/}

    response = @connection.request(params)

    if response.body.empty?
      response.body = {}
    elsif response.headers['Content-Type'] == 'application/json'
      response.body = Fog::JSON.decode(response.body)
    end

    if response.body['status'] == 'failure'
      raise Error, response.body['msgs'].first['INFO']
    end

    if params[:path] !~ %r{^/REST/Job/}
      if response.status == 307
        response = poll_job(response, params[:expects], @job_poll_timeout)

      # Dynect intermittently returns 200 with an incomplete status.  When this
      # happens, the job should still be polled.
      elsif response.status == 200 && response.body['status'].eql?('incomplete')
        response.headers['Location'] = "/REST/Job/#{ response.body['job_id'] }"
        response = poll_job(response, params[:expects], @job_poll_timeout)
      end
    end

    response
  rescue Excon::Errors::HTTPStatusError => error
    if @auth_token && error.message =~ /login: (Bad or expired credentials|inactivity logout)/
      @auth_token = nil
      retry
    else
      raise error
    end
  end

  response
end