ripe-db 1.0.0

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: 113aa555dbe99a0ec69d2df303a3a4b9bb3c476a
4
+ data.tar.gz: d55623b8cd7bb5da0cb7492c2da6314639dfb075
5
+ SHA512:
6
+ metadata.gz: 57b009a09ec3b2165f9097d6f51e79bc7caa490b98f82709e4187cbdb8705ec05afaebff25200b1e6a273b590dc699ed6644d1c3446243b808c450c687246b20
7
+ data.tar.gz: 51def3fe9368369d5aa4f9feb966ebb244e5230ba794e3bc77c312dc4a94b18bb4de8d0aceb35293e4f309684d6bf1a2468a53f5542086919cb23596bd7a0113
@@ -0,0 +1 @@
1
+ require 'ripe/client'
@@ -0,0 +1,34 @@
1
+ module RIPE
2
+ class Attribute
3
+
4
+ def initialize(client, attribute)
5
+ @client = client
6
+ @attribute = attribute
7
+ end
8
+
9
+ def name
10
+ @attribute['name']
11
+ end
12
+
13
+ def value
14
+ @attribute['value']
15
+ end
16
+
17
+ def referenced_type
18
+ @attribute['referenced-type']
19
+ end
20
+
21
+ def referenced_object
22
+ @referenced_object ||= referenced_type ? @client.find(self.referenced_type, self.value) : nil
23
+ end
24
+ alias_method :object, :referenced_object
25
+
26
+ def to_api_hash
27
+ {
28
+ 'name' => @attribute['name'],
29
+ 'value' => @attribute['value']
30
+ }
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ module RIPE
2
+ class AttributeSet < Array
3
+
4
+ def initialize(client, name)
5
+ @client = client
6
+ @name = name
7
+ super([])
8
+ end
9
+
10
+ def name
11
+ @name
12
+ end
13
+
14
+ def add(value)
15
+ self << Attribute.new(@client, 'name' => @name, 'value' => value)
16
+ end
17
+
18
+ def update(values)
19
+ clear
20
+ values = [values] unless values.is_a?(Array)
21
+ values.each { |value| add(value) }
22
+ end
23
+
24
+ def to_api_hash
25
+ map(&:to_api_hash)
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ require 'ripe/object'
2
+
3
+ module RIPE
4
+ class Client
5
+
6
+ def initialize(mode, password = nil)
7
+ @mode = mode
8
+ @password = password
9
+ end
10
+
11
+ def mode
12
+ @mode
13
+ end
14
+
15
+ def password
16
+ @password
17
+ end
18
+
19
+ def find(key, value)
20
+ Object.find(self, key, value)
21
+ end
22
+
23
+ def new(key)
24
+ Object.new(self, key)
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,31 @@
1
+ require 'ripe/object_error'
2
+
3
+ module RIPE
4
+
5
+ class Error < StandardError
6
+ end
7
+
8
+ class NotFound < Error
9
+ end
10
+
11
+ class BadRequest < Error
12
+ end
13
+
14
+ class AccessDenied < Error
15
+ end
16
+
17
+ class ValidationError < Error
18
+ def initialize(errors)
19
+ @errors = errors.map { |r| ObjectError.new(r) }
20
+ end
21
+
22
+ def errors
23
+ @errors
24
+ end
25
+
26
+ def to_s
27
+ @errors.map(&:text).join(', ')
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,77 @@
1
+ require 'uri'
2
+ require 'net/https'
3
+ require 'json'
4
+ require 'ripe/errors'
5
+
6
+ module RIPE
7
+ class HTTPRequest
8
+
9
+ def initialize(client, object_type)
10
+ @client = client
11
+ @object_type = object_type
12
+ end
13
+
14
+ def lookup(key)
15
+ json = request(Net::HTTP::Get, "/#{key}")
16
+ json.dig('objects', 'object').first
17
+ end
18
+
19
+ def create(password, object_hash)
20
+ json = request(Net::HTTP::Post, '', :query => {:password => password}, :json => object_hash.to_json)
21
+ json.dig('objects', 'object').first
22
+ end
23
+
24
+ def update(password, key, object_hash)
25
+ json = request(Net::HTTP::Put, "/#{key}", :query => {:password => password}, :json => object_hash.to_json)
26
+ json.dig('objects', 'object').first
27
+ end
28
+
29
+ def delete(password, key, reason = nil)
30
+ request(Net::HTTP::Delete, "/#{key}", :query => {:password => password, :reason => reason})
31
+ end
32
+
33
+ private
34
+
35
+ def request(request_type, path, options = {})
36
+ http = Net::HTTP.new(@client.mode == :test ? 'rest-test.db.ripe.net' : 'rest.db.ripe.net', 443)
37
+ http.use_ssl = true
38
+ path = "/#{@client.mode == :test ? 'test' : 'ripe'}/#{@object_type}#{path}"
39
+
40
+ if options[:query]
41
+ path << "?"
42
+ path << URI.encode_www_form(options[:query])
43
+ end
44
+
45
+ request = request_type.new(path)
46
+ request['Accept'] = 'application/json'
47
+
48
+ if options[:json]
49
+ request.add_field 'Content-Type', 'application/json'
50
+ request.body = options[:json]
51
+ end
52
+
53
+ response = http.request(request)
54
+ case response
55
+ when Net::HTTPOK
56
+ JSON.parse(response.body)
57
+ when Net::HTTPNotFound
58
+ raise RIPE::NotFound, "No resource found at #{path}"
59
+ when Net::HTTPUnauthorized
60
+ raise RIPE::AccessDenied, "Access denied to #{path}"
61
+ when Net::HTTPBadRequest
62
+ if response['Content-Type'] == 'application/json'
63
+ body = JSON.parse(response.body)
64
+ errors = body.dig('errormessages', 'errormessage')
65
+ raise ValidationError.new(errors)
66
+ else
67
+ puts response.body
68
+ raise RIPE::BadRequest, "Invalid request to API #{path}"
69
+ end
70
+ else
71
+ puts response.inspect
72
+ false
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,112 @@
1
+ require 'ripe/http_request'
2
+ require 'ripe/attribute'
3
+ require 'ripe/attribute_set'
4
+
5
+ module RIPE
6
+ class Object
7
+
8
+ def self.find(client, type, key)
9
+ request = HTTPRequest.new(client, type).lookup(key)
10
+ self.new(client, type, request)
11
+ end
12
+
13
+ def initialize(client, type, data = nil)
14
+ @client = client
15
+ @type = type
16
+ @data = data
17
+ end
18
+
19
+ def new?
20
+ @data.nil?
21
+ end
22
+
23
+ def deleted?
24
+ !!@deleted
25
+ end
26
+
27
+ def source
28
+ @data['source']['id']
29
+ end
30
+
31
+ def link
32
+ if @data['link'] && @data['link']['type'] == 'locator'
33
+ @data['link']['href']
34
+ end
35
+ end
36
+
37
+ def [](key)
38
+ attributes[key]
39
+ end
40
+
41
+ def []=(key, value)
42
+ attributes[key] = AttributeSet.new(key) if attributes[key].nil?
43
+ attributes[key].update(value)
44
+ end
45
+
46
+ def primary_key
47
+ if key = @data.dig('primary-key', 'attribute')&.first
48
+ attributes[key['name']].first
49
+ end
50
+ end
51
+
52
+ def to_api_hash
53
+ {
54
+ 'objects' => {
55
+ 'object' => [
56
+ {
57
+ 'source' => {
58
+ 'id' => @client.mode == :test ? 'test' : 'ripe'
59
+ },
60
+ 'attributes' => {
61
+ 'attribute' => attributes.values.map(&:to_api_hash).flatten
62
+ }
63
+ }
64
+ ]
65
+ }
66
+ }
67
+ end
68
+
69
+ def create
70
+ if !new?
71
+ raise RIPE::Error, "This object has already been created, it cannot be created again"
72
+ end
73
+
74
+ request = HTTPRequest.new(@client, @type).create(@client.password, self.to_api_hash)
75
+ @data = request
76
+ self
77
+ end
78
+
79
+ def update
80
+ if new?
81
+ raise RIPE::Error, "This object has not been created yet, it cannot be updated until it exists"
82
+ end
83
+
84
+ if key = primary_key&.value
85
+ request = HTTPRequest.new(@client, @type).update(@client.password, key, self.to_api_hash)
86
+ @data = request
87
+ self
88
+ else
89
+ raise RIPE::Error, "Object does not have a primary key therefore cannot be updated"
90
+ end
91
+ end
92
+
93
+ def delete(reason = nil)
94
+ if key = primary_key&.value
95
+ request = HTTPRequest.new(@client, @type).delete(@client.password, key, reason)
96
+ @deleted = true
97
+ else
98
+ raise RIPE::Error, "Object does not have a primary key therefore cannot be deleted"
99
+ end
100
+ end
101
+
102
+ private
103
+
104
+ def attributes
105
+ @attributes ||= new? ? {} : @data['attributes']['attribute'].each_with_object({}) do |attr, hash|
106
+ hash[attr['name']] ||= AttributeSet.new(@client, attr['name'])
107
+ hash[attr['name']] << Attribute.new(@client, attr)
108
+ end
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,25 @@
1
+ module RIPE
2
+ class ObjectError
3
+
4
+ def initialize(hash)
5
+ @hash = hash
6
+ end
7
+
8
+ def text
9
+ @hash['text'] % args
10
+ end
11
+
12
+ def severity
13
+ @hash['severity']
14
+ end
15
+
16
+ def attribute
17
+ @hash['attribute']
18
+ end
19
+
20
+ def args
21
+ @hash['args'].map { |a| a['value'] }
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module RIPE
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ripe-db
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Adam Cooke
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-02-07 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: A Ruby library for inteacting with the RIPE database
14
+ email:
15
+ - me@adamcooke.io
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/ripe-db.rb
21
+ - lib/ripe/attribute.rb
22
+ - lib/ripe/attribute_set.rb
23
+ - lib/ripe/client.rb
24
+ - lib/ripe/errors.rb
25
+ - lib/ripe/http_request.rb
26
+ - lib/ripe/object.rb
27
+ - lib/ripe/object_error.rb
28
+ - lib/ripe/version.rb
29
+ homepage: https://github.com/adamcooke/ripe-db
30
+ licenses:
31
+ - MIT
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.5.1
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: A Ruby library for inteacting with the RIPE database
53
+ test_files: []