idcf-dns 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 68baeccea7effe030408dc1ad51a675f778979f5
4
+ data.tar.gz: 8a6863b8098f8a54d95374ed3b3d1fb9250f8058
5
+ SHA512:
6
+ metadata.gz: e000d440c35b0abdb1fe6d3430e0d283f5d176aa526633df82e73c44a77c807273e9b336e4490f524523b1dfee2fed853018b4748095f38a5166585a66e840bc
7
+ data.tar.gz: 106b2809bec9a87613013a2cabb9f821d67ea4b1b3f4638a2e8ac6e5111b96f4371b0c94a90ae2fb35c51416323817dc97f8ab3c87ffe40582246047fd0dc5ae
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0
4
+ - 2.1
5
+ - 2.2
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in idcf-dns.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 nownabe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,136 @@
1
+ # Idcf::Dns
2
+
3
+ A Ruby client for IDCF Cloud DNS service.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'idcf-dns'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install idcf-dns
20
+
21
+ ## Usage
22
+ ### Basic usage
23
+ #### Client
24
+ ```ruby
25
+ require "idcf/dns"
26
+
27
+ client =
28
+ Idcf::Dns::Client.new(
29
+ api_key: ENV["IDCF_API_KEY"],
30
+ secret_key: ENV["IDCF_SECRET_KEY"]
31
+ )
32
+
33
+ response = client.get("zones")
34
+ response.success? #=> true
35
+ response.body #=> [zone1, zone2, ...]
36
+ response.body[0] #=> zone1
37
+ response[0] #=> zone1
38
+ response.status #=> 200
39
+ ```
40
+
41
+ #### Zones
42
+ ##### Create new zone
43
+ ```ruby
44
+ response =
45
+ client.create_zone(
46
+ name: "foobar.example.com",
47
+ email: "foobar@example.com",
48
+ description: "description",
49
+ default_ttl: 600
50
+ )
51
+
52
+ response.uuid #=> UUID of new zone
53
+ ```
54
+
55
+ ##### Get zones
56
+ ```ruby
57
+ # Get all zones
58
+ zones = client.list_zones.body
59
+ zones[0]["name"] #=> "foobar.example.com"
60
+
61
+ # Get a zone
62
+ zone = client.get_zone(zone_uuid).body
63
+ zone["name"] #=> "foobar.example.com"
64
+ zone["records"].size #=> 3
65
+ ```
66
+
67
+ ##### Update zone
68
+ ```ruby
69
+ client.update_zone(zone_uuid, description: "Updated")
70
+ ```
71
+
72
+ ##### Delete zone
73
+ ```ruby
74
+ client.delete_zone(zone_uuid)
75
+ ```
76
+
77
+ #### Records
78
+ ##### Create new record
79
+ ```ruby
80
+ response =
81
+ client.create_record(
82
+ zone_uuid,
83
+ name: "baz.foobar.example.com",
84
+ type: "A",
85
+ content: "8.8.8.8",
86
+ ttl: 600
87
+ )
88
+
89
+ response.uuid #=> UUID of new record
90
+ ```
91
+
92
+ ##### Get records
93
+ ```ruby
94
+ # Get all records of a zone
95
+ records = client.list_records(zone_uuid).body
96
+ records[0]["name"] #=> "baz.foobar.example.com"
97
+
98
+ # Get a record
99
+ record = client.get_record(record_uuid, zone_uuid).body
100
+ record["name"] #=> "baz.foobar.example.com"
101
+ ```
102
+
103
+ ##### Update record
104
+ ```ruby
105
+ client.update_record(record_uuid, zone_uuid, content: "210.140.158.1")
106
+ ```
107
+
108
+ ##### Delete record
109
+ ```ruby
110
+ client.delete_record(record_uuid, zone_uuid)
111
+ ```
112
+
113
+ ### Advanced usage
114
+ #### Custom expiration of requests
115
+ ```ruby
116
+ expiration = Time.now.to_i + 10
117
+
118
+ client.list_zones("X-IDCF-Expires": expiration).success?
119
+ #=> true
120
+
121
+ # wait for 10 seconds ...
122
+
123
+ client.list_zones("X-IDCF-Expires": expiration)
124
+ #=> Idcf::Dns::ApiError: HTTP status code: 403, Error message: This api request is expired., Reference: http://docs.idcf.jp/cloud/dns
125
+ ```
126
+
127
+ ### API reference
128
+ URL
129
+
130
+ ## Contributing
131
+
132
+ 1. Fork it ( https://github.com/[my-github-username]/idcf-dns/fork )
133
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
134
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
135
+ 4. Push to the branch (`git push origin my-new-feature`)
136
+ 5. Create a new Pull Request
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ task default: :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "idcf/dns"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'idcf/dns/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "idcf-dns"
8
+ spec.version = Idcf::Dns::VERSION
9
+ spec.authors = ["nownabe"]
10
+ spec.email = ["nownabe@gmail.com"]
11
+
12
+ spec.summary = %q{A Ruby client for IDCF Cloud DNS Service.}
13
+ spec.homepage = "https://github.com/idcf/idcf-dns-ruby"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = "exe"
17
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler", "~> 1.9"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "rspec"
23
+ spec.add_development_dependency "simplecov"
24
+
25
+ spec.add_dependency "activesupport", "~> 4.2.3"
26
+ spec.add_dependency "faraday", "~> 0.9.1"
27
+ spec.add_dependency "faraday_middleware", "~> 0.10.0"
28
+ end
@@ -0,0 +1,14 @@
1
+ require "idcf/dns/errors"
2
+
3
+ # IDCF Cloud SDK
4
+ module Idcf
5
+ # @author nownabe
6
+ module Dns
7
+ autoload :Client , "idcf/dns/client"
8
+ autoload :ClientExtensions, "idcf/dns/client_extensions"
9
+ autoload :Request , "idcf/dns/request"
10
+ autoload :Resources , "idcf/dns/resources"
11
+ autoload :Response , "idcf/dns/response"
12
+ autoload :Validators , "idcf/dns/validators"
13
+ end
14
+ end
@@ -0,0 +1,149 @@
1
+ require "faraday"
2
+ require "faraday_middleware"
3
+
4
+ module Idcf
5
+ module Dns
6
+ # Client for IDCF DNS service
7
+ class Client
8
+ include ClientExtensions::Record
9
+ include ClientExtensions::Zone
10
+
11
+ attr_reader :api_key, :secret_key, :host, :endpoint
12
+
13
+ # The constructor of Dns::Client uses keyword arguments.
14
+ #
15
+ # @param [String] api_key API key for IDCF Cloud
16
+ # @param [String] secret_key Secret key for IDCF Cloud
17
+ def initialize(api_key:,
18
+ secret_key:,
19
+ host: "dns.idcfcloud.com",
20
+ endpoint: "/api/v1",
21
+ verify_ssl: true
22
+ )
23
+
24
+ @api_key = api_key
25
+ @secret_key = secret_key
26
+ @host = host
27
+ @endpoint = endpoint
28
+ @verify_ssl = verify_ssl
29
+ end
30
+
31
+ # @private
32
+ def connection
33
+ @connection ||=
34
+ Faraday.new(url: url_prefix, ssl: ssl_options) do |connection|
35
+ connection.request :json
36
+ connection.response :json
37
+ connection.adapter Faraday.default_adapter
38
+ end
39
+ end
40
+
41
+ # Send DELETE request.
42
+ #
43
+ # @param resource [String] resource name
44
+ # @param parameters [Hash] request parameters
45
+ # @param headers [Hash] HTTP request headers
46
+ # @return [Response] Response object
47
+ def delete(resource, parameters = {}, headers = {})
48
+ send(:delete, resource, parameters, headers)
49
+ end
50
+
51
+ # Send DELETE request with handling error
52
+ #
53
+ # @param resource [String] resource name
54
+ # @param parameters [Hash] request parameters
55
+ # @param headers [Hash] HTTP request headers
56
+ # @return [Response] Response object
57
+ def delete!(resource, parameters = {}, headers = {})
58
+ send_with_handling_error(:delete, resource, parameters, headers)
59
+ end
60
+
61
+ # Send GET request
62
+ #
63
+ # @param resource [String] Resource name
64
+ # @param parameters [Hash] Parameters
65
+ # @param headers [Hash] HTTP request headers
66
+ # @return [Response] Response object
67
+ def get(resource, parameters = {}, headers = {})
68
+ send(:get, resource, parameters, headers)
69
+ end
70
+
71
+ # Send GET request with handling error
72
+ #
73
+ # @param resource [String] resource name
74
+ # @param parameters [Hash] request parameters
75
+ # @param headers [Hash] HTTP request headers
76
+ # @return [Response] Response object
77
+ def get!(resource, parameters = {}, headers = {})
78
+ send_with_handling_error(:get, resource, parameters, headers)
79
+ end
80
+
81
+ # Send POST request
82
+ #
83
+ # @param resource [String] resource name
84
+ # @param parameters [Hash] request parameters
85
+ # @param headers [Hash] HTTP request headers
86
+ # @return [Response] Response object
87
+ def post(resource, parameters = {}, headers = {})
88
+ send(:post, resource, parameters, headers)
89
+ end
90
+
91
+ # Send POST request with handling error
92
+ #
93
+ # @param resource [String] resource name
94
+ # @param parameters [Hash] request parameters
95
+ # @param headers [Hash] HTTP request headers
96
+ # @return [Response] Response object
97
+ def post!(resource, parameters = {}, headers = {})
98
+ send_with_handling_error(:post, resource, parameters, headers)
99
+ end
100
+
101
+ # Send PUT request
102
+ #
103
+ # @param resource [String] resource name
104
+ # @param parameters [Hash] request parameters
105
+ # @param headers [Hash] HTTP request headers
106
+ # @return [Response] Response object
107
+ def put(resource, parameters = {}, headers = {})
108
+ send(:put, resource, parameters, headers)
109
+ end
110
+
111
+ # Send PUT request with handling error
112
+ #
113
+ # @param resource [String] resource name
114
+ # @param parameters [Hash] request parameters
115
+ # @param headers [Hash] HTTP request headers
116
+ # @return [Response] Response object
117
+ def put!(resource, parameters = {}, headers = {})
118
+ send_with_handling_error(:put, resource, parameters, headers)
119
+ end
120
+
121
+ private
122
+
123
+ def send(method, resource, parameters = {}, headers = {})
124
+ Request.new(self, method, resource, parameters, headers).send
125
+ end
126
+
127
+ def send_with_handling_error(method, resource, parameters = {}, headers = {})
128
+ response = send(method, resource, parameters, headers)
129
+ unless response.success?
130
+ fail(
131
+ ApiError,
132
+ "HTTP status code: #{response.status}, " \
133
+ "Error message: #{response.message}, " \
134
+ "Reference: #{response.reference}"
135
+ )
136
+ end
137
+ response
138
+ end
139
+
140
+ def ssl_options
141
+ { verify: @verify_ssl }
142
+ end
143
+
144
+ def url_prefix
145
+ "https://#{host}"
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,11 @@
1
+ module Idcf
2
+ module Dns
3
+ # This module includes SDK API methods for Client.
4
+ module ClientExtensions
5
+ end
6
+ end
7
+ end
8
+
9
+ require "idcf/dns/client_extensions/record"
10
+ require "idcf/dns/client_extensions/template"
11
+ require "idcf/dns/client_extensions/zone"
@@ -0,0 +1,90 @@
1
+ module Idcf
2
+ module Dns
3
+ module ClientExtensions
4
+ # SDK APIs for record resource
5
+ module Record
6
+ # Create a new record.
7
+ #
8
+ # @param zone_uuid [String] UUID of zone
9
+ # @param attributes [Hash] request attributes
10
+ # @option attributes [String] :name name of record
11
+ # @option attributes [String] :type type of record
12
+ # (A, AAAA, CNAME, MX, TXT or SRV)
13
+ # @option attributes [String] :content content of record
14
+ # @option attributes [Integer] :ttl TTL
15
+ # @option attributes [Integer] :priority priority of record
16
+ # @param headers [Hash] HTTP request headers
17
+ # @return [Response] HTTP response object
18
+ def create_record(zone_uuid, attributes, headers = {})
19
+ Validators::Record.validate_attributes!(attributes, :create)
20
+ post!("zones/#{zone_uuid}/records", attributes, headers)
21
+ end
22
+
23
+ # Delete a record.
24
+ #
25
+ # @param uuid [String] UUID of record
26
+ # @param zone_uuid [String] UUID of zone
27
+ # @param headers [Hash] HTTP request headers
28
+ # @return [Response] HTTP response object
29
+ def delete_record(uuid, zone_uuid, headers = {})
30
+ delete!("zones/#{zone_uuid}/records/#{uuid}", {}, headers)
31
+ end
32
+
33
+ # Get a record.
34
+ #
35
+ # @param uuid [String] UUID of record
36
+ # @param zone_uuid [String] UUID of zone
37
+ # @param headers [Hash] HTTP request headers
38
+ # @return [Response] HTTP response object
39
+ def get_record(uuid, zone_uuid, headers = {})
40
+ get!("zones/#{zone_uuid}/records/#{uuid}", {}, headers)
41
+ end
42
+
43
+ # Get list of records.
44
+ #
45
+ # @param zone_uuid [String] UUID of zone
46
+ # @return [Response] HTTP response object
47
+ def list_records(zone_uuid, headers = {})
48
+ get!("zones/#{zone_uuid}/records", {}, headers)
49
+ end
50
+
51
+ # Update a record.
52
+ #
53
+ # @param uuid [String] UUID of record
54
+ # @param zone_uuid [String] UUID of zone
55
+ # @param attributes [Hash] request attributes
56
+ # @option attributes [String] :name name of record
57
+ # @option attributes [String] :type type of record
58
+ # (A, AAAA, CNAME, MX, TXT or SRV)
59
+ # @option attributes [String] :content content of record
60
+ # @option attributes [Integer] :ttl TTL
61
+ # @option attributes [Integer] :priority priority of record
62
+ # @param headers [Hash] HTTP request headers
63
+ # @return [Response] HTTP response object
64
+ def update_record(uuid, zone_uuid, attributes, headers = {})
65
+ Validators::Record.validate_attributes!(attributes, :update)
66
+ put!("zones/#{zone_uuid}/records/#{uuid}", attributes, headers)
67
+ end
68
+
69
+ # Get a record object.
70
+ #
71
+ # @param uuid [String] UUID of record
72
+ # @param zone_uuid [String] UUID of zone
73
+ # @param headers [Hash] HTTP request headers
74
+ # @return [Resources::Record] a record object
75
+ def record(uuid, zone_uuid, headers = {})
76
+ Resources::Record.new(self, get_record(uuid, zone_uuid, headers).body)
77
+ end
78
+
79
+ # Get an array of existing record objects.
80
+ #
81
+ # @param zone_uuid [String] UUID of zone
82
+ # @param headers [Hash] HTTP request headers
83
+ # @return [Array<Resource::Record>] an array of record objects
84
+ def records(zone_uuid, headers = {})
85
+ zone(zone_uuid).records
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,59 @@
1
+ module Idcf
2
+ module Dns
3
+ module ClientExtensions
4
+ # SDK APIs for template resource
5
+ module Template
6
+ # Create a new template.
7
+ #
8
+ # @param attributes [Hash] request attributes
9
+ # @option attributes [String] :name unique name of template (required)
10
+ # @option attributes [String] :description description
11
+ # @option attributes [Integer] :default_ttl default TTL (required)
12
+ # @param headers [Hash] HTTP request headers
13
+ # @return [Response] HTTP response object
14
+ def create_template(attributes, headers = {})
15
+ Validators::Template.validate_attributes!(attributes, :create)
16
+ post!("templates", attributes, headers)
17
+ end
18
+
19
+ # Delete a template.
20
+ #
21
+ # @param uuid [String] UUID of the target template
22
+ # @param headers [Hash] HTTP request headers
23
+ # @return [Response] HTTP response object
24
+ def delete_template(uuid, headers = {})
25
+ delete!("templates/#{uuid}", {}, headers)
26
+ end
27
+
28
+ # Get a template.
29
+ #
30
+ # @param uuid [String] UUID of the target template
31
+ # @param headers [Hash] HTTP request headers
32
+ # @return [Response] HTTP response object
33
+ def get_template(uuid, headers = {})
34
+ get!("templates/#{uuid}", {}, headers)
35
+ end
36
+
37
+ # Get list of existing templates.
38
+ #
39
+ # @param headers [Hash] HTTP request headers
40
+ # @return [Response] HTTP response object
41
+ def list_templates(headers = {})
42
+ get!("templates", {}, headers)
43
+ end
44
+
45
+ # Update a template.
46
+ #
47
+ # @param uuid [String] UUID of the target template
48
+ # @param attributes [Hash] request attributes
49
+ # @option attributes [String] :description
50
+ # @option attributes [Integer] :default_ttl default TTL
51
+ # @return [Reponse] HTTP response object
52
+ def update_template(uuid, attributes, headers = {})
53
+ Validators::Template.validate_attributes!(attributes, :update)
54
+ put!("templates/#{uuid}", attributes, headers)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,80 @@
1
+ module Idcf
2
+ module Dns
3
+ module ClientExtensions
4
+ # SDK APIs for zone resource
5
+ module Zone
6
+ # Create a new zone.
7
+ #
8
+ # @param attributes [Hash] request attributes
9
+ # @option attributes [String] :name unique name of zone (required)
10
+ # @option attributes [String] :email e-mail address (required)
11
+ # @option attributes [String] :description description
12
+ # @option attributes [Integer] :default_ttl default TTL (required)
13
+ # @param headers [Hash] HTTP request headers
14
+ # @return [Response] HTTP response object
15
+ def create_zone(attributes, headers = {})
16
+ Validators::Zone.validate_attributes!(attributes, :create)
17
+ post!("zones", attributes, headers)
18
+ end
19
+
20
+ # Delete a zone.
21
+ #
22
+ # @param uuid [String] UUID of target zone
23
+ # @param headers [Hash] HTTP request headers
24
+ # @return [Response] HTTP response object
25
+ def delete_zone(uuid, headers = {})
26
+ delete!("zones/#{uuid}", {}, headers)
27
+ end
28
+
29
+ # Get a zone.
30
+ #
31
+ # @param uuid [String] UUID of target zone
32
+ # @param headers [Hash] HTTP request headers
33
+ # @return [Response] HTTP response object
34
+ def get_zone(uuid, headers = {})
35
+ get!("zones/#{uuid}", {}, headers)
36
+ end
37
+
38
+ # Get list of existing zones
39
+ #
40
+ # @param headers [Hash] HTTP request headers
41
+ # @return [Response] HTTP response object
42
+ def list_zones(headers = {})
43
+ get!("zones", {}, headers)
44
+ end
45
+
46
+ # Update a zone.
47
+ #
48
+ # @param uuid [String] UUID of target zone
49
+ # @param attributes [Hash] request attributes
50
+ # @option attributes [String] :email e-mail address
51
+ # @option attributes [String] :description description
52
+ # @option attributes [Integer] :default_ttl default TTL
53
+ # @return [Response] HTTP response object
54
+ def update_zone(uuid, attributes, headers = {})
55
+ Validators::Zone.validate_attributes!(attributes, :update)
56
+ put!("zones/#{uuid}", attributes, headers)
57
+ end
58
+
59
+ # Get a zone object.
60
+ #
61
+ # @param uuid [String] UUID of target zone
62
+ # @param headers [Hash] HTTP request headers
63
+ # @return [Resources::Zone] a zone object
64
+ def zone(uuid, headers = {})
65
+ Resources::Zone.new(self, get_zone(uuid, headers).body)
66
+ end
67
+
68
+ # Get an array of existing zone objects.
69
+ #
70
+ # @param headers [Hash] HTTP request headers
71
+ # @return [Array<Resources::Zone>] An array of zone objects
72
+ def zones(headers = {})
73
+ list_zones(headers).resources.map do |zone|
74
+ Resources::Zone.new(self, zone)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,10 @@
1
+ module Idcf
2
+ module Dns
3
+ Error = Class.new(StandardError)
4
+ ApiError = Class.new(Error)
5
+ InvalidAttributeName = Class.new(Error)
6
+ InvalidAttributeType = Class.new(Error)
7
+ MissingAttribute = Class.new(Error)
8
+ UnnecessaryAttribute = Class.new(Error)
9
+ end
10
+ end
@@ -0,0 +1,97 @@
1
+ require "base64"
2
+ require "openssl"
3
+
4
+ module Idcf
5
+ module Dns
6
+ # - Send HTTP request
7
+ # - Generate signatures
8
+ # - Set default expires
9
+ class Request
10
+ attr_reader :client, :method, :resource
11
+ attr_reader :parameters
12
+
13
+ # @private
14
+ def initialize(client, method, resource, parameters, headers)
15
+ @client = client
16
+ @method = method
17
+ @resource = resource
18
+ @parameters = parameters
19
+ @headers = headers
20
+ end
21
+
22
+ # @private
23
+ def send
24
+ Response.new(
25
+ client.connection.send(
26
+ method,
27
+ path,
28
+ parameters,
29
+ headers
30
+ )
31
+ )
32
+ end
33
+
34
+ # @private
35
+ def headers
36
+ auth_headers.merge(
37
+ @headers.reject { |key, _| key.to_s == "X-IDCF-Expires" }
38
+ )
39
+ end
40
+
41
+ private
42
+
43
+ def api_key
44
+ client.api_key
45
+ end
46
+
47
+ def auth_headers
48
+ {
49
+ "X-IDCF-Signature" => signature,
50
+ "X-IDCF-APIKEY" => api_key,
51
+ "X-IDCF-Expires" => expires
52
+ }
53
+ end
54
+
55
+ def body
56
+ if method == :post || method == :put
57
+ parameters.to_json
58
+ else
59
+ ""
60
+ end
61
+ end
62
+
63
+ def expires
64
+ @expires ||=
65
+ (@headers["X-IDCF-Expires"] || @headers[:"X-IDCF-Expires"] || Time.now.to_i + 600).to_s
66
+ end
67
+
68
+ def path
69
+ "#{client.endpoint}/#{resource}"
70
+ end
71
+
72
+ def secret_key
73
+ client.secret_key
74
+ end
75
+
76
+ def signature
77
+ Base64.encode64(
78
+ OpenSSL::HMAC.digest(
79
+ OpenSSL::Digest::SHA256.new,
80
+ secret_key,
81
+ signature_seed
82
+ )
83
+ ).chomp
84
+ end
85
+
86
+ def signature_seed
87
+ [
88
+ method.to_s.upcase,
89
+ path,
90
+ api_key,
91
+ expires,
92
+ ""
93
+ ].join("\n")
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,11 @@
1
+ module Idcf
2
+ module Dns
3
+ # DNS resources module
4
+ module Resources
5
+ end
6
+ end
7
+ end
8
+
9
+ require "idcf/dns/resources/base"
10
+ require "idcf/dns/resources/record"
11
+ require "idcf/dns/resources/zone"
@@ -0,0 +1,60 @@
1
+ require "active_support/core_ext/string/inflections"
2
+
3
+ module Idcf
4
+ module Dns
5
+ module Resources
6
+ # Base resource class
7
+ class Base
8
+ attr_reader :client
9
+
10
+ class << self
11
+ # @private
12
+ def inherited(subclass)
13
+ subclass.send(:generate_readers)
14
+ end
15
+
16
+ # @private
17
+ def class_name
18
+ to_s.gsub(/^#<Class|>$/, "").split(/::/).last
19
+ end
20
+
21
+ # @private
22
+ def generate_readers
23
+ validator_class.valid_attributes.each do |name, properties|
24
+ next if properties[:reader] == false
25
+ attr_reader name
26
+ end
27
+ end
28
+
29
+ # @private
30
+ def validator_class
31
+ "Idcf::Dns::Validators::#{class_name}".constantize
32
+ end
33
+ end
34
+
35
+ # Constructor
36
+ #
37
+ # @param client [Client] client object
38
+ # @param attributes [Hash] attributes for resource
39
+ def initialize(client, attributes = {})
40
+ @client = client
41
+ self.attributes = attributes
42
+ end
43
+
44
+ # Inspect this class
45
+ def inspect
46
+ "#<#{self.class}:0x%014x @name=#{name} @uuid=#{uuid}>" % [object_id]
47
+ end
48
+
49
+ private
50
+
51
+ def attributes=(attributes)
52
+ self.class.validator_class.validate_attributes!(attributes)
53
+ attributes.each do |name, value|
54
+ instance_variable_set(:"@#{name}", value)
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ module Idcf
2
+ module Dns
3
+ module Resources
4
+ # Record resource class
5
+ class Record < Base
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ module Idcf
2
+ module Dns
3
+ module Resources
4
+ # Zone resource class
5
+ class Zone < Base
6
+ # @return [Array<Record>] an array of records
7
+ def records
8
+ return @record_objects if @record_objects
9
+ refresh
10
+ @record_objects = @records.map { |record| Record.new(client, record) }
11
+ end
12
+
13
+ # Refresh this zone
14
+ #
15
+ # @return [Zone] self object
16
+ def refresh
17
+ self.attributes = client.get_zone(uuid).body
18
+ self
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,88 @@
1
+ require "forwardable"
2
+
3
+ module Idcf
4
+ module Dns
5
+ # HTTP response
6
+ class Response
7
+ extend Forwardable
8
+
9
+ # @!attribute [r] body
10
+ # @return [Hash, Array, nil] response body as a hash,
11
+ # an array of hashes or nil.
12
+ # @!attribute [r] headers
13
+ # @return [Hash] HTTP response headers
14
+ # @!attribute [r] status
15
+ # @return [Integer] HTTP status code
16
+ attr_reader :body, :headers, :status
17
+
18
+ # @param faraday_response [Faraday::Response]
19
+ def initialize(faraday_response)
20
+ @body = faraday_response.body
21
+ @headers = faraday_response.headers
22
+ @status = faraday_response.status
23
+ end
24
+
25
+ def_delegator :@body, :[]
26
+
27
+ # Returns the number of resources.
28
+ #
29
+ # @return [Fixnum] count of resources.
30
+ def count
31
+ case body
32
+ when Array
33
+ body.size
34
+ when Hash
35
+ if body.key?("uuid")
36
+ 1
37
+ else
38
+ 0
39
+ end
40
+ else
41
+ 0
42
+ end
43
+ end
44
+ alias_method :size, :count
45
+
46
+ # Returns error message.
47
+ # When request succeed, this returns nil.
48
+ #
49
+ # @return [String] API error message
50
+ def message
51
+ if success?
52
+ nil
53
+ else
54
+ body ? self["message"] : "Resource not found."
55
+ end
56
+ end
57
+
58
+ # Returns error reference.
59
+ # When request succeed, this returns nil.
60
+ #
61
+ # @return [String] API error reference
62
+ def reference
63
+ if success?
64
+ nil
65
+ else
66
+ body ? self["reference"] : "No reference"
67
+ end
68
+ end
69
+
70
+ # Returns an array of resource hashes.
71
+ #
72
+ # @return [Array<Hash>] an array of resource hashes
73
+ def resources
74
+ body && [*body]
75
+ end
76
+
77
+ # @return [Boolean] request success?
78
+ def success?
79
+ status < 400
80
+ end
81
+
82
+ # @return [String] UUID of a resource
83
+ def uuid
84
+ body.is_a?(Hash) && body.key?("uuid") ? self["uuid"] : nil
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,12 @@
1
+ module Idcf
2
+ module Dns
3
+ # Validators for request attributes.
4
+ module Validators
5
+ end
6
+ end
7
+ end
8
+
9
+ require "idcf/dns/validators/base"
10
+ require "idcf/dns/validators/record"
11
+ require "idcf/dns/validators/template"
12
+ require "idcf/dns/validators/zone"
@@ -0,0 +1,82 @@
1
+ require "active_support/core_ext/class/attribute"
2
+
3
+ module Idcf
4
+ module Dns
5
+ module Validators
6
+ # Base validator class
7
+ class Base
8
+ class_attribute :valid_attributes
9
+
10
+ class << self
11
+ # Validate requeste attributes.
12
+ # If there are invalid attributes, error occurs.
13
+ #
14
+ # @param attributes [Hash] request attributes
15
+ # @param action [Symbol] request method
16
+ def validate_attributes!(attributes, action = nil)
17
+ required_attributes(action).each do |name|
18
+ unless attributes.key?(name)
19
+ fail(
20
+ MissingAttribute,
21
+ "`#{name}` is required in #{action} action"
22
+ )
23
+ end
24
+ end
25
+ attributes.each do |name, value|
26
+ if action &&
27
+ (!valid_attributes[name] || !valid_attributes[name][action])
28
+ fail(
29
+ UnnecessaryAttribute,
30
+ "`#{name}` is unnecessary in #{action} action"
31
+ )
32
+ end
33
+ validate_attribute_name!(name)
34
+ validate_attribute_type!(name, value)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def required_attributes(action)
41
+ return [] unless action
42
+ valid_attributes.select do |_, validator|
43
+ validator[action] == :required
44
+ end.keys
45
+ end
46
+
47
+ def valid_attribute?(value, valid_type)
48
+ case valid_type
49
+ when Array
50
+ valid_type.any? { |t| valid_attribute?(value, t) }
51
+ when Regexp
52
+ if value.is_a?(String)
53
+ valid_type =~ value
54
+ else
55
+ false
56
+ end
57
+ else
58
+ value.is_a?(valid_type)
59
+ end
60
+ end
61
+
62
+ def validate_attribute_name!(name)
63
+ return true if valid_attributes.key?(name.to_sym)
64
+ fail(
65
+ InvalidAttributeName,
66
+ "`#{name}` is invalid attribute name"
67
+ )
68
+ end
69
+
70
+ def validate_attribute_type!(name, value)
71
+ valid_type = valid_attributes[name.to_sym][:type]
72
+ return true if valid_attribute?(value, valid_type)
73
+ fail(
74
+ InvalidAttributeType,
75
+ "`#{name}` is required to be a #{valid_type}"
76
+ )
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ module Idcf
2
+ module Dns
3
+ module Validators
4
+ # Record validator class
5
+ class Record < Base
6
+ self.valid_attributes = {
7
+ uuid: { type: String },
8
+ name: { type: String, create: :required, update: :optional },
9
+ type: { type: /^(A|CNAME|AAAA|MX|TXT|SRV|NS|SOA)$/, create: :required, update: :optional },
10
+ content: { type: [String, Hash], create: :required, update: :optional },
11
+ ttl: { type: Integer, create: :required, update: :optional },
12
+ priority: { type: [Integer, NilClass], create: :optional },
13
+ created_at: { type: String },
14
+ updated_at: { type: String }
15
+ }
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,18 @@
1
+ module Idcf
2
+ module Dns
3
+ module Validators
4
+ # Template validator class
5
+ class Template < Base
6
+ self.valid_attributes = {
7
+ uuid: { type: String },
8
+ name: { type: String, create: :required },
9
+ description: { type: String, create: :optional, update: :optional },
10
+ default_ttl: { type: Integer, create: :required, update: :optional },
11
+ created_at: { type: String },
12
+ updated_at: { type: String },
13
+ records: { type: Array, reader: false }
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ module Idcf
2
+ module Dns
3
+ module Validators
4
+ # Zone validator class
5
+ class Zone < Base
6
+ self.valid_attributes = {
7
+ uuid: { type: String },
8
+ name: { type: String, create: :required },
9
+ email: { type: String, create: :required, update: :optional },
10
+ description: { type: String, create: :optional, update: :optional },
11
+ default_ttl: { type: Integer, create: :required, update: :optional },
12
+ template_uuid: { type: String, create: :optional },
13
+ created_at: { type: String },
14
+ updated_at: { type: String },
15
+ records: { type: Array, reader: false }
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module Idcf
2
+ module Dns
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,170 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: idcf-dns
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - nownabe
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-08-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.9'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: activesupport
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 4.2.3
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 4.2.3
83
+ - !ruby/object:Gem::Dependency
84
+ name: faraday
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.9.1
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.9.1
97
+ - !ruby/object:Gem::Dependency
98
+ name: faraday_middleware
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.10.0
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.10.0
111
+ description:
112
+ email:
113
+ - nownabe@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - ".travis.yml"
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - bin/console
126
+ - bin/setup
127
+ - idcf-dns.gemspec
128
+ - lib/idcf/dns.rb
129
+ - lib/idcf/dns/client.rb
130
+ - lib/idcf/dns/client_extensions.rb
131
+ - lib/idcf/dns/client_extensions/record.rb
132
+ - lib/idcf/dns/client_extensions/template.rb
133
+ - lib/idcf/dns/client_extensions/zone.rb
134
+ - lib/idcf/dns/errors.rb
135
+ - lib/idcf/dns/request.rb
136
+ - lib/idcf/dns/resources.rb
137
+ - lib/idcf/dns/resources/base.rb
138
+ - lib/idcf/dns/resources/record.rb
139
+ - lib/idcf/dns/resources/zone.rb
140
+ - lib/idcf/dns/response.rb
141
+ - lib/idcf/dns/validators.rb
142
+ - lib/idcf/dns/validators/base.rb
143
+ - lib/idcf/dns/validators/record.rb
144
+ - lib/idcf/dns/validators/template.rb
145
+ - lib/idcf/dns/validators/zone.rb
146
+ - lib/idcf/dns/version.rb
147
+ homepage: https://github.com/idcf/idcf-dns-ruby
148
+ licenses: []
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 2.4.5
167
+ signing_key:
168
+ specification_version: 4
169
+ summary: A Ruby client for IDCF Cloud DNS Service.
170
+ test_files: []