dnsapp 0.0.1 → 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.
data/Manifest CHANGED
@@ -1,3 +1,13 @@
1
+ Manifest
2
+ README.rdoc
1
3
  Rakefile
4
+ dnsapp.gemspec
2
5
  lib/dnsapp.rb
3
- Manifest
6
+ lib/dnsapp/auth_check_parser.rb
7
+ lib/dnsapp/credentials.rb
8
+ lib/dnsapp/domain.rb
9
+ lib/dnsapp/object.rb
10
+ lib/dnsapp/record.rb
11
+ spec/credentials.yml
12
+ spec/domain_spec.rb
13
+ spec/record_spec.rb
data/README.rdoc ADDED
@@ -0,0 +1,73 @@
1
+ == DNSApp.net
2
+
3
+ This gem allows easy access to the DNSApp.net API.
4
+
5
+ You will need a DNSApp.net account.
6
+
7
+ * https://www.dnsapp.net
8
+ * https://www.dnsapp.net/api
9
+
10
+ == Installation
11
+
12
+ [sudo] gem install httparty
13
+ [sudo] gem install dnsapp
14
+
15
+ +sudo+ is optional depending on your setup.
16
+
17
+ In your Ruby script you can now.
18
+
19
+ require 'rubygems'
20
+ require 'dnsapp'
21
+
22
+ DNSApp::Credentials.username = 'mmr@dnsapp.net'
23
+ DNSApp::Credentials.password = 'p@ssw0rd'
24
+ DNSApp::Domain.all
25
+ => [#<DNSApp::Domain:0x101be6070 @auth_id=nil, @name="dnsapp.net", @handle=nil, @user_id=1, @created_at=Mon Nov 15 12:23:55 UTC 2010, @locked=nil, @authoritative=false, @id=16, @status="done", @updated_at=Fri Nov 19 11:30:00 UTC 2010>]
26
+
27
+
28
+ == Example
29
+
30
+ require 'rubygems'
31
+ require 'dnsapp'
32
+
33
+ DNSApp::Credentials.username = 'mmr@dnsapp.net'
34
+ DNSApp::Credentials.password = 'p@ssw0rd'
35
+
36
+ DNSApp::Domain.all.each do |domain|
37
+ records = domain.records.all.length
38
+ puts "#{domain.name} has #{records} records."
39
+ end
40
+
41
+ new_domain = DNSApp::Domain.create("example.org")
42
+ new_domain.records.create :name => '%d', :content => '1.2.3.4', :type => 'A', :ttl => 3600
43
+ new_domain.records.create :name => '%d', :content => 'mailserver.somewhere.com', :type => 'MX', :ttl => 3600, :prio => "10"
44
+
45
+ new_domain.records.all.last.destroy
46
+
47
+ another_domain = DNSApp::Domain.find("another-domain.com") # could also specify numeric ID
48
+ another_domain.records.find(240).destroy # 240 is the numeric ID for the record
49
+
50
+ third_domain = DNSApp::Domain.find(42)
51
+ third_domain.delete
52
+
53
+ == Testing / RSpec
54
+
55
+ In order to run the test suite you have to have a DNSApp.net account (a trial account is not sufficient).
56
+
57
+ You must create the file <tt>spec/credentials.yml</tt>.
58
+ spec/credentials.yml
59
+
60
+ username: <your username>
61
+ password: <your password>
62
+
63
+ The specs all depend on an active internet connection and access to https://dnsapp.net.
64
+
65
+ == Known issues
66
+
67
+ On Debian/Ubuntu systems <tt>httparty</tt> sometimes gives a:
68
+
69
+ no such file to load net/https
70
+
71
+ To solve this
72
+
73
+ apt-get install libopenssl-ruby
data/Rakefile CHANGED
@@ -3,7 +3,7 @@ require 'rake'
3
3
  require 'echoe'
4
4
  require 'rspec/core/rake_task'
5
5
 
6
- Echoe.new('dnsapp', '0.0.1') do |p|
6
+ Echoe.new('dnsapp', '0.0.2') do |p|
7
7
  p.description = "Gem to interact with DNSapp.net Managed DNS service"
8
8
  p.url = "http://github.com/mmriis/dnsapp"
9
9
  p.author = "Morten Møller Riis"
data/dnsapp.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{dnsapp}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Morten M\303\270ller Riis"]
@@ -10,8 +10,8 @@ Gem::Specification.new do |s|
10
10
  s.date = %q{2011-01-15}
11
11
  s.description = %q{Gem to interact with DNSapp.net Managed DNS service}
12
12
  s.email = %q{m _AT_ justabout.it}
13
- s.extra_rdoc_files = ["lib/dnsapp.rb"]
14
- s.files = ["Rakefile", "lib/dnsapp.rb", "Manifest", "dnsapp.gemspec"]
13
+ s.extra_rdoc_files = ["README.rdoc", "lib/dnsapp.rb", "lib/dnsapp/auth_check_parser.rb", "lib/dnsapp/credentials.rb", "lib/dnsapp/domain.rb", "lib/dnsapp/object.rb", "lib/dnsapp/record.rb"]
14
+ s.files = ["Manifest", "README.rdoc", "Rakefile", "dnsapp.gemspec", "lib/dnsapp.rb", "lib/dnsapp/auth_check_parser.rb", "lib/dnsapp/credentials.rb", "lib/dnsapp/domain.rb", "lib/dnsapp/object.rb", "lib/dnsapp/record.rb", "spec/credentials.yml", "spec/domain_spec.rb", "spec/record_spec.rb"]
15
15
  s.homepage = %q{http://github.com/mmriis/dnsapp}
16
16
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Dnsapp", "--main", "README.rdoc"]
17
17
  s.require_paths = ["lib"]
@@ -0,0 +1,15 @@
1
+ require 'httparty'
2
+
3
+ module DNSApp
4
+
5
+ class Unauthorized < Exception #:nodoc:
6
+ end
7
+
8
+ class AuthCheckParser < HTTParty::Parser #:nodoc:
9
+ def parse
10
+ raise DNSApp::Unauthorized, "Access Denied. Maybe you supplied wrong credentials?" if body =~ /HTTP Basic: Access denied./i
11
+ super
12
+ end
13
+ end
14
+
15
+ end
@@ -0,0 +1,36 @@
1
+ module DNSApp
2
+
3
+ class Credentials
4
+ class << self
5
+
6
+ # Set DNSApp username.
7
+ # This must be done before connecting.
8
+ # == Example
9
+ # DNSApp::Credentials.username = 'mmr@dnsapp.net'
10
+ # DNSApp::Credentials.password = 'p@ssw0rd'
11
+ # DNSApp::Domain.all
12
+ def username=(username)
13
+ @username = username
14
+ end
15
+
16
+ def username #:nodoc:
17
+ @username
18
+ end
19
+
20
+ # Set DNSApp password.
21
+ # This must be done before connecting.
22
+ # == Example
23
+ # DNSApp::Credentials.username = 'mmr@dnsapp.net'
24
+ # DNSApp::Credentials.password = 'p@ssw0rd'
25
+ # DNSApp::Domain.all
26
+ def password=(password)
27
+ @password = password
28
+ end
29
+
30
+ def password #:nodoc:
31
+ @password
32
+ end
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,102 @@
1
+ require 'dnsapp/object'
2
+
3
+ module DNSApp
4
+
5
+ class Domain < DNSApp::Object
6
+
7
+ # id for the domain
8
+ attr_accessor :id
9
+ # The domain name
10
+ attr_accessor :name
11
+ # When the domain was created
12
+ attr_accessor :created_at
13
+ # The domain handle
14
+ attr_accessor :handle
15
+ # When the domain was updated
16
+ attr_accessor :updated_at
17
+ # Whether DNSApp.net is authoritative for the domain
18
+ # If +false+ the domain doesn't point to the DNSApp.net nameservers
19
+ attr_accessor :authoritative
20
+ # The user_id for the domain
21
+ attr_accessor :user_id
22
+ # The AUTHID for the domain. Used for transfers.
23
+ attr_accessor :auth_id
24
+ # The status of the domain
25
+ attr_accessor :status
26
+ # Whether the domain is locked. Must be false if you wish to transfer.
27
+ attr_accessor :locked
28
+
29
+ class << self
30
+ # Retrives all domains
31
+ def all
32
+ response = get("/domains")["domains"]
33
+ response.collect { |attributes| Domain.new attributes }
34
+ end
35
+
36
+ # Find domain by +id+ or +name+
37
+ # == Example
38
+ # DNSApp::Domain.find(10)
39
+ # DNSApp::Domain.find("example.org")
40
+ def find(id_or_name)
41
+ if id_or_name.is_a?(Integer)
42
+ find_by_id(id_or_name)
43
+ else
44
+ find_by_name(id_or_name)
45
+ end
46
+ end
47
+
48
+ # Find domain by +id+
49
+ def find_by_id(id)
50
+ response = get("/domains/#{id}")["domain"]
51
+ response or return nil
52
+ Domain.new response
53
+ end
54
+
55
+ # Find domain by +name+
56
+ def find_by_name(name)
57
+ domain = self.all.select { |d| d.name == name }
58
+ return domain.blank? ? nil : domain.first
59
+ end
60
+
61
+ # Creates a new domain
62
+ # +name+ must be without www or similar.
63
+ # == Example
64
+ # DNSApp::Domain.create("example.org")
65
+ def create(name)
66
+ name.is_a? String or raise TypeError, "name must be string"
67
+ r = post("/domains", :query => {"domain[name]" => name})
68
+ r["errors"] and raise StandardError, r["errors"]["error"].to_a.join(", ")
69
+ if r.code == 201
70
+ Domain.new r["domain"]
71
+ else
72
+ raise StandardError, 'Could not create the domain'
73
+ end
74
+ end
75
+
76
+ end
77
+
78
+ # Deletes the domain. This cannot be undone.
79
+ # Returns the deleted domain object.
80
+ # == Example
81
+ # DNSApp::Domain.find(10).destroy
82
+ def destroy
83
+ r = self.class.delete("/domains/#{self.id}")
84
+ if r.code == 200
85
+ self
86
+ else
87
+ raise StandardError, 'Could not delete the domain'
88
+ end
89
+ end
90
+
91
+ # Get records on the domain.
92
+ # == Example
93
+ # DNSApp::Domain.find(10).records.all
94
+ # DNSApp::Domain.find(10).records.create(:name => '%d', :content => '1.2.3.4', :type => 'A', :ttl => 3600)
95
+ def records
96
+ @@parent_id = self.id
97
+ DNSApp::Record
98
+ end
99
+
100
+ end
101
+
102
+ end
@@ -0,0 +1,59 @@
1
+ require 'dnsapp/credentials'
2
+ require 'dnsapp/auth_check_parser'
3
+
4
+ module DNSApp
5
+ class Object #:nodoc: all
6
+
7
+ @@parent_id = nil
8
+ def parent_id
9
+ @@parent_id
10
+ end
11
+
12
+ def parent_id=(id)
13
+ @@parent_id = id
14
+ end
15
+
16
+ include HTTParty
17
+ format :xml
18
+ headers 'Accept' => 'application/xml', 'Content-Type' => 'application/xml'
19
+ base_uri "https://dnsapp.net"
20
+ parser DNSApp::AuthCheckParser
21
+
22
+ class << self
23
+ def get(*args)
24
+ basic_auth DNSApp::Credentials.username, DNSApp::Credentials.password
25
+ super
26
+ end
27
+
28
+ def post(*args)
29
+ basic_auth DNSApp::Credentials.username, DNSApp::Credentials.password
30
+ super
31
+ end
32
+
33
+ def delete(*args)
34
+ basic_auth DNSApp::Credentials.username, DNSApp::Credentials.password
35
+ super
36
+ end
37
+
38
+ def put(*args)
39
+ basic_auth DNSApp::Credentials.username, DNSApp::Credentials.password
40
+ super
41
+ end
42
+
43
+ end
44
+
45
+ def initialize(attributes=nil)
46
+ attributes and attributes.each do |key, value|
47
+ setter_method = "#{key}=".to_sym
48
+ if self.respond_to?(setter_method)
49
+ self.send(setter_method, value)
50
+ end
51
+ end
52
+ end
53
+
54
+ def self.check_required_keys(hash, *keys)
55
+ hash.is_a? Hash or raise "Options must be given as a Hash"
56
+ keys.each { |key| raise "Missing required option #{key}" if hash[key].nil? }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,107 @@
1
+ require 'dnsapp/object'
2
+
3
+ module DNSApp
4
+
5
+ class Record < DNSApp::Object
6
+
7
+ # id for the record
8
+ attr_accessor :id
9
+ # name for the record
10
+ attr_accessor :name
11
+ # When the record was created
12
+ attr_accessor :created_at
13
+ # When the record was last updated
14
+ attr_accessor :updated_at
15
+ # time-to-live for the record
16
+ attr_accessor :ttl
17
+ # domain_id for the record
18
+ attr_accessor :domain_id
19
+ # content for the record
20
+ attr_accessor :content
21
+ # priority for the record.
22
+ # Only needed for MX and SRV records.
23
+ attr_accessor :prio
24
+ # type for the record
25
+ # Must be one of the following A AAAA NS SOA CNAME TXT SPF SRV MX PTR
26
+ attr_accessor :type
27
+
28
+ class << self
29
+
30
+ # Get all the records
31
+ def all
32
+ response = get("/domains/#{@@parent_id}/records")["records"]
33
+ response.collect { |attributes| Record.new attributes }
34
+ end
35
+
36
+ # Find a specific record by +id+
37
+ # == Example
38
+ # DNSApp::Domain.all.first.find(243)
39
+ # => #<DNSApp::Record:0x101ad5e88 @name="%d", @domain_id=131, @ttl=3600, @created_at=Mon Jan 10 15:48:02 UTC 2011, @content="1.2.3.4", @type="A", @id=1821, @prio=nil, @updated_at=Mon Jan 10 15:55:29 UTC 2011>
40
+ def find(id)
41
+ response = get("/domains/#{@@parent_id}/records/#{id}")["record"]
42
+ response or return nil
43
+ Record.new response
44
+ end
45
+
46
+ # Creates a new record. +options+ must contain at least the following:
47
+ # :name, :content, :type, :tll
48
+ # For SRV and MX records :prio can also be specified.
49
+ # == Valid types
50
+ # A AAAA NS SOA CNAME TXT SPF SRV MX PTR
51
+ # == Example
52
+ # DNSApp::Domain.all.first.records.create :name => '%d', :content => '1.2.3.4', :type => 'A', :ttl => 3600
53
+ def create(options={})
54
+ check_required_keys options, :name, :content, :type, :ttl
55
+
56
+ r = post("/domains/#{@@parent_id}/records", :query => { "record[name]" => options[:name],
57
+ "record[ttl]" => options[:ttl],
58
+ "record[content]" => options[:content],
59
+ "record[prio]" => options[:prio],
60
+ "record[type]" => options[:type] })
61
+ r["errors"] and raise StandardError, r["errors"]["error"].to_a.join(", ")
62
+ if r.code == 201
63
+ Record.new r["record"]
64
+ else
65
+ raise StandardError, 'Could not create the record'
66
+ end
67
+ end
68
+
69
+ end
70
+
71
+ # Saves the record.
72
+ # == Example
73
+ # r = DNSApp::Domain.all.first.record.first
74
+ # => #<DNSApp::Record:0x101ad5e88 @name="%d", @domain_id=131, @ttl=3600, @created_at=Mon Jan 10 15:48:02 UTC 2011, @content="1.2.3.4", @type="A", @id=1821, @prio=nil, @updated_at=Mon Jan 10 15:55:29 UTC 2011>
75
+ # r.content = '9.9.9.9'
76
+ # => #<DNSApp::Record:0x101ad5e88 @name="%d", @domain_id=131, @ttl=3600, @created_at=Mon Jan 10 15:48:02 UTC 2011, @content="9.9.9.9", @type="A", @id=1821, @prio=nil, @updated_at=Mon Jan 10 17:52:09 UTC 2011>
77
+ def save
78
+ r = self.class.put("/domains/#{@@parent_id}/records/#{self.id}", :query => { "record[name]" => self.name,
79
+ "record[ttl]" => self.ttl,
80
+ "record[content]" => self.content,
81
+ "record[prio]" => self.prio,
82
+ "record[type]" => self.type })
83
+ r["errors"] and raise StandardError, r["errors"]["error"].to_a.join(", ")
84
+ if r.code == 200
85
+ self.class.find(self.id)
86
+ else
87
+ raise StandardError, 'Could not update the record'
88
+ end
89
+ end
90
+
91
+ # Deletes the record.
92
+ # Returns the deleted record.
93
+ # == Example
94
+ # r = DNSApp::Domain.all.first.record.first.destroy
95
+ # => #<DNSApp::Record:0x101ad5e88 @name="%d", @domain_id=131, @ttl=3600, @created_at=Mon Jan 10 15:48:02 UTC 2011, @content="1.2.3.4", @type="A", @id=1821, @prio=nil, @updated_at=Mon Jan 10 15:55:29 UTC 2011>
96
+ def destroy
97
+ r = self.class.delete("/domains/#{@@parent_id}/records/#{self.id}")
98
+ if r.code == 200
99
+ self
100
+ else
101
+ raise StandardError, 'Could not delete the record'
102
+ end
103
+ end
104
+ alias_method :delete, :destroy
105
+ end
106
+
107
+ end
File without changes
@@ -0,0 +1,71 @@
1
+ require 'lib/dnsapp'
2
+ require 'yaml'
3
+ require 'rspec'
4
+
5
+ describe DNSApp::Domain do
6
+
7
+ before(:all) do
8
+ yml = YAML::load(File.open("spec/credentials.yml"))
9
+ DNSApp::Credentials.username = yml["username"]
10
+ DNSApp::Credentials.password = yml["password"]
11
+
12
+ @domain1 = DNSApp::Domain.create("test-example-1.com")
13
+ @domain2 = DNSApp::Domain.create("test-example-2.com")
14
+ end
15
+
16
+ after(:all) do
17
+ DNSApp::Domain.find("test-example-1.com").destroy
18
+ DNSApp::Domain.find("test-example-2.com").destroy
19
+ end
20
+
21
+ describe '#all' do
22
+ it 'should return a list of domains' do
23
+ domains = DNSApp::Domain.all.collect(&:name)
24
+ domains.should include("test-example-1.com")
25
+ domains.should include("test-example-2.com")
26
+ end
27
+ end
28
+
29
+ describe '#find' do
30
+ it 'should return the domain with id' do
31
+ DNSApp::Domain.find(@domain1.id).name.should == "test-example-1.com"
32
+ end
33
+
34
+ it 'should return the domain with name' do
35
+ DNSApp::Domain.find(@domain2.name).name.should == "test-example-2.com"
36
+ end
37
+ end
38
+
39
+ describe '#create' do
40
+ before(:all) do
41
+ @example_domain = DNSApp::Domain.create('some-example-domain.com')
42
+ end
43
+
44
+ after(:all) do
45
+ @example_domain.destroy
46
+ end
47
+
48
+ it 'should create a domain with the specified name' do
49
+ DNSApp::Domain.find(@example_domain.name).name.should == @example_domain.name
50
+ end
51
+
52
+ it 'should not be possible to create duplicate domains' do
53
+ lambda { DNSApp::Domain.create(@example_domain.name) }.should raise_error
54
+ end
55
+ end
56
+
57
+ describe '#destroy' do
58
+ it 'should destroy the domain' do
59
+ domain = DNSApp::Domain.create('some-example-domain-to-be-destroyed.com')
60
+ domain.destroy
61
+ DNSApp::Domain.find('some-example-domain-to-be-destroyed.com').should be_nil
62
+ end
63
+ end
64
+
65
+ describe '#records' do
66
+ it 'should return the record object' do
67
+ @domain1.records.should == DNSApp::Record
68
+ end
69
+ end
70
+
71
+ end
@@ -0,0 +1,73 @@
1
+ require 'lib/dnsapp'
2
+ require 'yaml'
3
+ require 'rspec'
4
+
5
+ describe DNSApp::Record do
6
+
7
+ before(:all) do
8
+ yml = YAML::load(File.open("spec/credentials.yml"))
9
+ DNSApp::Credentials.username = yml["username"]
10
+ DNSApp::Credentials.password = yml["password"]
11
+
12
+ @domain = DNSApp::Domain.create("test-example-1.com")
13
+ end
14
+
15
+ after(:all) do
16
+ DNSApp::Domain.find("test-example-1.com").destroy
17
+ end
18
+
19
+ describe '#all' do
20
+ it 'should return a list of records' do
21
+ records = @domain.records.all.collect(&:type)
22
+ records.should =~ %w(SOA NS NS NS NS NS)
23
+ end
24
+ end
25
+
26
+ describe '#find' do
27
+ it 'should return the record with id' do
28
+ record = @domain.records.find(@domain.records.all.first.id)
29
+ record.should_not be_nil
30
+ record.id.should == @domain.records.all.first.id
31
+ end
32
+ end
33
+
34
+ describe '#create' do
35
+ it 'should create a record with the specified attributes' do
36
+ @domain.records.create :name => '%d', :content => '1.2.3.4', :type => 'A', :ttl => 300
37
+ record = @domain.records.all.last
38
+ record.name.should == '%d'
39
+ record.content.should == '1.2.3.4'
40
+ record.type.should == 'A'
41
+ record.ttl.should == 300
42
+ record.prio.should be_nil
43
+ end
44
+ end
45
+
46
+ describe '#save' do
47
+ it 'should update a record with the new attributes' do
48
+ record = @domain.records.all.first
49
+ record.name = 'test1.%d'
50
+ record.content = 'test2'
51
+ record.type = 'CNAME'
52
+ record.ttl = 5000
53
+ record.prio = 10
54
+ record.save
55
+
56
+ record = @domain.records.find(record.id) # reload the record
57
+ record.name.should == 'test1.%d'
58
+ record.content.should == 'test2'
59
+ record.type.should == 'CNAME'
60
+ record.ttl.should == 5000
61
+ record.prio.should == 10
62
+ end
63
+ end
64
+
65
+ describe '#destroy' do
66
+ it 'should destroy the record' do
67
+ number_of_records = @domain.records.all.length
68
+ @domain.records.all.last.destroy
69
+ @domain.records.all.length.should == number_of_records - 1
70
+ end
71
+ end
72
+
73
+ end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dnsapp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Morten M\xC3\xB8ller Riis"
@@ -60,12 +60,27 @@ executables: []
60
60
  extensions: []
61
61
 
62
62
  extra_rdoc_files:
63
+ - README.rdoc
63
64
  - lib/dnsapp.rb
65
+ - lib/dnsapp/auth_check_parser.rb
66
+ - lib/dnsapp/credentials.rb
67
+ - lib/dnsapp/domain.rb
68
+ - lib/dnsapp/object.rb
69
+ - lib/dnsapp/record.rb
64
70
  files:
65
- - Rakefile
66
- - lib/dnsapp.rb
67
71
  - Manifest
72
+ - README.rdoc
73
+ - Rakefile
68
74
  - dnsapp.gemspec
75
+ - lib/dnsapp.rb
76
+ - lib/dnsapp/auth_check_parser.rb
77
+ - lib/dnsapp/credentials.rb
78
+ - lib/dnsapp/domain.rb
79
+ - lib/dnsapp/object.rb
80
+ - lib/dnsapp/record.rb
81
+ - spec/credentials.yml
82
+ - spec/domain_spec.rb
83
+ - spec/record_spec.rb
69
84
  has_rdoc: true
70
85
  homepage: http://github.com/mmriis/dnsapp
71
86
  licenses: []
metadata.gz.sig CHANGED
Binary file