nurego 1.0.1

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.
Files changed (46) hide show
  1. data/Gemfile +3 -0
  2. data/Gemfile.lock +59 -0
  3. data/LICENSE +32 -0
  4. data/README.md +25 -0
  5. data/Rakefile +41 -0
  6. data/VERSION +1 -0
  7. data/examples/enumerate_plans.rb +17 -0
  8. data/lib/data/ca-certificates.crt +53 -0
  9. data/lib/nurego.rb +287 -0
  10. data/lib/nurego/api_operations/create.rb +16 -0
  11. data/lib/nurego/api_operations/delete.rb +11 -0
  12. data/lib/nurego/api_operations/list.rb +16 -0
  13. data/lib/nurego/api_operations/update.rb +37 -0
  14. data/lib/nurego/api_resource.rb +33 -0
  15. data/lib/nurego/auth.rb +112 -0
  16. data/lib/nurego/bill.rb +6 -0
  17. data/lib/nurego/connector.rb +7 -0
  18. data/lib/nurego/customer.rb +29 -0
  19. data/lib/nurego/entitlement.rb +27 -0
  20. data/lib/nurego/errors/api_connection_error.rb +4 -0
  21. data/lib/nurego/errors/api_error.rb +4 -0
  22. data/lib/nurego/errors/authentication_error.rb +4 -0
  23. data/lib/nurego/errors/card_error.rb +10 -0
  24. data/lib/nurego/errors/invalid_request_error.rb +10 -0
  25. data/lib/nurego/errors/nurego_error.rb +24 -0
  26. data/lib/nurego/errors/user_not_found_error.rb +4 -0
  27. data/lib/nurego/feature.rb +5 -0
  28. data/lib/nurego/instance.rb +9 -0
  29. data/lib/nurego/json.rb +21 -0
  30. data/lib/nurego/list_object.rb +35 -0
  31. data/lib/nurego/nurego_object.rb +167 -0
  32. data/lib/nurego/offering.rb +17 -0
  33. data/lib/nurego/organization.rb +23 -0
  34. data/lib/nurego/password_reset.rb +14 -0
  35. data/lib/nurego/payment_method.rb +16 -0
  36. data/lib/nurego/plan.rb +9 -0
  37. data/lib/nurego/registration.rb +18 -0
  38. data/lib/nurego/util.rb +109 -0
  39. data/lib/nurego/version.rb +3 -0
  40. data/nurego.gemspec +31 -0
  41. data/spec/unit/nurego/api_resource_spec.rb +326 -0
  42. data/spec/unit/nurego/customer_spec.rb +75 -0
  43. data/spec/unit/nurego/list_object_spec.rb +14 -0
  44. data/spec/unit/nurego/util_spec.rb +27 -0
  45. data/spec/unit/test_helper.rb +94 -0
  46. metadata +279 -0
@@ -0,0 +1,16 @@
1
+ module Nurego
2
+ module APIOperations
3
+ module Create
4
+ module ClassMethods
5
+ def create(params={}, api_key=nil)
6
+ response, api_key = Nurego.request(:post, self.url, api_key, params)
7
+ Util.convert_to_nurego_object(response, api_key)
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ module Nurego
2
+ module APIOperations
3
+ module Delete
4
+ def delete
5
+ response, api_key = Nurego.request(:delete, url, @api_key)
6
+ refresh_from(response, api_key)
7
+ self
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ module Nurego
2
+ module APIOperations
3
+ module List
4
+ module ClassMethods
5
+ def all(filters={}, api_key=nil)
6
+ response, api_key = Nurego.request(:get, url, api_key, filters)
7
+ Util.convert_to_nurego_object(response, api_key)
8
+ end
9
+ end
10
+
11
+ def self.included(base)
12
+ base.extend(ClassMethods)
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ module Nurego
2
+ module APIOperations
3
+ module Update
4
+ def save
5
+ values = serialize_params(self)
6
+
7
+ if values.length > 0
8
+ values.delete(:id)
9
+
10
+ response, api_key = Nurego.request(:post, url, @api_key, values)
11
+ refresh_from(response, api_key)
12
+ end
13
+ self
14
+ end
15
+
16
+
17
+ def serialize_params(obj)
18
+ case obj
19
+ when nil
20
+ ''
21
+ when NuregoObject
22
+ unsaved_keys = obj.instance_variable_get(:@unsaved_values)
23
+ obj_values = obj.instance_variable_get(:@values)
24
+ update_hash = {}
25
+
26
+ unsaved_keys.each do |k|
27
+ update_hash[k] = serialize_params(obj_values[k])
28
+ end
29
+
30
+ update_hash
31
+ else
32
+ obj
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,33 @@
1
+ module Nurego
2
+ class APIResource < NuregoObject
3
+ def self.class_name
4
+ self.name.split('::')[-1]
5
+ end
6
+
7
+ def self.url()
8
+ if self == APIResource
9
+ raise NotImplementedError.new('APIResource is an abstract class. You should perform actions on its subclasses (Customer, etc.)')
10
+ end
11
+ "/v1/#{CGI.escape(class_name.downcase)}s"
12
+ end
13
+
14
+ def url
15
+ unless id = self['id']
16
+ raise InvalidRequestError.new("Could not determine which URL to request: #{self.class} instance has invalid ID: #{id.inspect}", 'id')
17
+ end
18
+ "#{self.class.url}/#{CGI.escape(id)}"
19
+ end
20
+
21
+ def refresh
22
+ response, api_key = Nurego.request(:get, url, @api_key, @retrieve_options)
23
+ refresh_from(response, api_key)
24
+ self
25
+ end
26
+
27
+ def self.retrieve(id, api_key=nil)
28
+ instance = self.new(id, api_key)
29
+ instance.refresh
30
+ instance
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,112 @@
1
+ require 'uri'
2
+ require 'uri/http'
3
+ require 'uaa'
4
+
5
+ module Nurego
6
+ module Auth
7
+
8
+ @provider_site = 'https://uaa.nurego.com'
9
+ @client_id = 'your client id'
10
+ @client_secret = 'your client secret'
11
+
12
+ @logger = nil
13
+
14
+ class << self
15
+ attr_accessor :provider_site, :client_id, :client_secret, :header_token, :logger
16
+
17
+ def login(username, password)
18
+ @header_token = fetch_header_token(username, password)
19
+ end
20
+
21
+ def logout
22
+ @header_token = nil
23
+ end
24
+
25
+ def change_password(user_id, password, current_password)
26
+ uaa_user_account.change_password(user_id, password, current_password)
27
+ rescue CF::UAA::NotFound, CF::UAA::TargetError => e
28
+ raise UserNotFoundError.new('User not found') # TODO better error message
29
+ rescue CF::UAA::AuthError, CF::UAA::BadResponse => e
30
+ raise AuthenticationError.new('OAuth authentication failed ' +
31
+ 'Make sure you set "Nurego.client_id = <client_id>". ' +
32
+ 'Please also make sure you set "Nurego.client_secret = <client secret>". ' +
33
+ 'See https://www.nurego.com/api for details, or email support@nurego.com ' +
34
+ 'if you have any questions.') if e.message == "status 401" || e.is_a?(CF::UAA::AuthError)
35
+ raise NuregoError "fetch_access_info #{e.inspect}"
36
+ end
37
+
38
+ private
39
+ def fetch_access_info(username, password)
40
+ token = token_issuer.owner_password_grant(username, password)
41
+ info = token.info
42
+ {
43
+ :access_token => info[:access_token],
44
+ :refresh_token => info[:refresh_token],
45
+ :token_type => info[:token_type],
46
+ :expires_at => Time.now.to_i + info[:expires_in],
47
+ :header_token => info[:token_type] + " " + info[:access_token]
48
+ }
49
+ rescue CF::UAA::BadResponse, CF::UAA::TargetError => e
50
+ raise AuthenticationError.new('OAuth authentication failed ' +
51
+ 'Make sure you set "Nurego.client_id = <client_id>". ' +
52
+ 'Please also make sure you set "Nurego.client_secret = <client secret>". ' +
53
+ 'See https://www.nurego.com/api for details, or email support@nurego.com ' +
54
+ 'if you have any questions.') if e.message == "status 401" || e.is_a?(CF::UAA::TargetError)
55
+ raise NuregoError "fetch_access_info #{e.inspect}"
56
+ end
57
+
58
+ def fetch_admin_access_token
59
+ token = token_issuer.client_credentials_grant
60
+ info = token.info
61
+
62
+ info[:token_type] + " " + info[:access_token]
63
+ rescue CF::UAA::BadResponse => e
64
+ #TODO check error message here
65
+ raise AuthenticationError.new('OAuth authentication failed ' +
66
+ 'Make sure you set "Nurego.client_id = <client_id>". ' +
67
+ 'Please also make sure you set "Nurego.client_secret = <client secret>". ' +
68
+ 'See https://www.nurego.com/api for details, or email support@nurego.com ' +
69
+ 'if you have any questions.') if e.message == "status 401"
70
+ raise NuregoError "fetch_access_info #{e.inspect}"
71
+ end
72
+
73
+ def fetch_access_token(username, password)
74
+ fetch_access_info(username, password)[:access_token]
75
+ end
76
+
77
+ def fetch_header_token(username, password)
78
+ access_info = fetch_access_info(username, password)
79
+
80
+ {
81
+ token: access_info[:header_token],
82
+ expires_at: access_info[:expires_at]
83
+ }
84
+ end
85
+
86
+ def admin_access_token
87
+ @admin_access_token ||= fetch_admin_access_token
88
+ end
89
+
90
+ def build_uaa_user_account
91
+ CF::UAA::Scim.new(@provider_site, admin_access_token).tap do |uaa_user_account|
92
+ uaa_user_account.logger = @logger
93
+ end
94
+ end
95
+
96
+ def build_token_issuer
97
+ CF::UAA::TokenIssuer.new(@provider_site, @client_id, @client_secret, {symbolize_keys: true}).tap do |issuer|
98
+ issuer.logger = @logger
99
+ end
100
+ end
101
+
102
+ def token_issuer
103
+ @token_issuer ||= build_token_issuer
104
+ end
105
+
106
+ def uaa_user_account
107
+ @uaa_user_account ||= build_uaa_user_account
108
+ end
109
+ end
110
+ end
111
+ end
112
+
@@ -0,0 +1,6 @@
1
+ module Nurego
2
+ class Bill < APIResource
3
+ include Nurego::APIOperations::List
4
+
5
+ end
6
+ end
@@ -0,0 +1,7 @@
1
+ module Nurego
2
+ class Connector < APIResource
3
+ include Nurego::APIOperations::Create
4
+ include Nurego::APIOperations::Update
5
+ include Nurego::APIOperations::List
6
+ end
7
+ end
@@ -0,0 +1,29 @@
1
+ module Nurego
2
+ class Customer < APIResource
3
+ include Nurego::APIOperations::List
4
+
5
+ def self.me(api_key = nil)
6
+ response, api_key = Nurego.request(:get, me_url, api_key)
7
+ Util.convert_to_nurego_object(response, api_key)
8
+ end
9
+
10
+ def organizations
11
+ Organization.all({:customer => id }, @api_key)
12
+ end
13
+
14
+ def self.me_url
15
+ '/v1/customers/me'
16
+ end
17
+
18
+ def self.update_plan(plan_guid)
19
+ response, api_key = Nurego.request(:put, "/v1/customers/plan", nil, { :plan_id => plan_guid })
20
+ Util.convert_to_nurego_object(response, api_key)
21
+ end
22
+
23
+ def self.cancel_account
24
+ response, api_key = Nurego.request(:put, "/v1/customers/cancel", nil)
25
+ Util.convert_to_nurego_object(response, api_key)
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module Nurego
2
+ class Entitlement < APIResource
3
+ include Nurego::APIOperations::List
4
+ include Nurego::APIOperations::Create
5
+
6
+
7
+ def set_usage(feature_id, amount)
8
+ payload = {
9
+ feature_id: feature_id,
10
+ organization: id,
11
+ amount: amount
12
+ }
13
+ response, api_key = Nurego.request(:put, "/v1/entitlements/usage", nil, payload)
14
+ end
15
+
16
+ def is_allowed(feature_id, requested_amount)
17
+ payload = {
18
+ :organization => id,
19
+ :feature_id => feature_id,
20
+ :requested_amount => requested_amount
21
+ }
22
+ response, api_key = Nurego.request(:get, "/v1/entitlements/allowed", nil, payload)
23
+ Util.convert_to_nurego_object(response, api_key)
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ module Nurego
2
+ class APIConnectionError < NuregoError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Nurego
2
+ class APIError < NuregoError
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Nurego
2
+ class AuthenticationError < NuregoError
3
+ end
4
+ end
@@ -0,0 +1,10 @@
1
+ module Nurego
2
+ class CardError < NuregoError
3
+ attr_accessor :param
4
+
5
+ def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
6
+ super(message, http_status, http_body, json_body)
7
+ @param = param
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ module Nurego
2
+ class InvalidRequestError < NuregoError
3
+ attr_accessor :param
4
+
5
+ def initialize(message, param, http_status=nil, http_body=nil, json_body=nil)
6
+ super(message, http_status, http_body, json_body)
7
+ @param = param
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,24 @@
1
+ module Nurego
2
+ class NuregoError < StandardError
3
+ attr_reader :message
4
+ attr_reader :http_status
5
+ attr_reader :http_body
6
+ attr_reader :json_body
7
+
8
+ def initialize(message=nil, http_status=nil, http_body=nil, json_body=nil)
9
+ @message = message
10
+ @http_status = http_status
11
+ @http_body = http_body
12
+ @json_body = json_body
13
+ end
14
+
15
+ def error_code
16
+ @json_body ? @json_body[:error][:code] : ""
17
+ end
18
+
19
+ def to_s
20
+ status_string = @http_status.nil? ? "" : "(Status #{@http_status}) "
21
+ "#{status_string}#{@message}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,4 @@
1
+ module Nurego
2
+ class UserNotFoundError < NuregoError
3
+ end
4
+ end
@@ -0,0 +1,5 @@
1
+ module Nurego
2
+ class Feature < APIResource
3
+ include Nurego::APIOperations::List
4
+ end
5
+ end
@@ -0,0 +1,9 @@
1
+ module Nurego
2
+ class Instance < APIResource
3
+ include Nurego::APIOperations::List
4
+
5
+ def connectors
6
+ Connector.all({:instance => id }, @api_key)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ module Nurego
2
+ module JSON
3
+ if MultiJson.respond_to?(:dump)
4
+ def self.dump(*args)
5
+ MultiJson.dump(*args)
6
+ end
7
+
8
+ def self.load(*args)
9
+ MultiJson.load(*args)
10
+ end
11
+ else
12
+ def self.dump(*args)
13
+ MultiJson.encode(*args)
14
+ end
15
+
16
+ def self.load(*args)
17
+ MultiJson.decode(*args)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ module Nurego
2
+ class ListObject < NuregoObject
3
+
4
+ def [](k)
5
+ case k
6
+ when String, Symbol
7
+ super
8
+ else
9
+ raise ArgumentError.new("You tried to access the #{k.inspect} index, but ListObject types only support String keys. (HINT: List calls return an object with a 'data' (which is the data array). You likely want to call #data[#{k.inspect}])")
10
+ end
11
+ end
12
+
13
+ def each(&blk)
14
+ self.data.each(&blk)
15
+ end
16
+
17
+ def retrieve(id, api_key=nil)
18
+ api_key ||= @api_key
19
+ response, api_key = Nurego.request(:get,"#{url}/#{CGI.escape(id)}", api_key)
20
+ Util.convert_to_nurego_object(response, api_key)
21
+ end
22
+
23
+ def create(params={}, api_key=nil)
24
+ api_key ||= @api_key
25
+ response, api_key = Nurego.request(:post, url, api_key, params)
26
+ Util.convert_to_nurego_object(response, api_key)
27
+ end
28
+
29
+ def all(params={}, api_key=nil)
30
+ api_key ||= @api_key
31
+ response, api_key = Nurego.request(:get, url, api_key, params)
32
+ Util.convert_to_nurego_object(response, api_key)
33
+ end
34
+ end
35
+ end