nurego 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +3 -0
- data/Gemfile.lock +59 -0
- data/LICENSE +32 -0
- data/README.md +25 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/examples/enumerate_plans.rb +17 -0
- data/lib/data/ca-certificates.crt +53 -0
- data/lib/nurego.rb +287 -0
- data/lib/nurego/api_operations/create.rb +16 -0
- data/lib/nurego/api_operations/delete.rb +11 -0
- data/lib/nurego/api_operations/list.rb +16 -0
- data/lib/nurego/api_operations/update.rb +37 -0
- data/lib/nurego/api_resource.rb +33 -0
- data/lib/nurego/auth.rb +112 -0
- data/lib/nurego/bill.rb +6 -0
- data/lib/nurego/connector.rb +7 -0
- data/lib/nurego/customer.rb +29 -0
- data/lib/nurego/entitlement.rb +27 -0
- data/lib/nurego/errors/api_connection_error.rb +4 -0
- data/lib/nurego/errors/api_error.rb +4 -0
- data/lib/nurego/errors/authentication_error.rb +4 -0
- data/lib/nurego/errors/card_error.rb +10 -0
- data/lib/nurego/errors/invalid_request_error.rb +10 -0
- data/lib/nurego/errors/nurego_error.rb +24 -0
- data/lib/nurego/errors/user_not_found_error.rb +4 -0
- data/lib/nurego/feature.rb +5 -0
- data/lib/nurego/instance.rb +9 -0
- data/lib/nurego/json.rb +21 -0
- data/lib/nurego/list_object.rb +35 -0
- data/lib/nurego/nurego_object.rb +167 -0
- data/lib/nurego/offering.rb +17 -0
- data/lib/nurego/organization.rb +23 -0
- data/lib/nurego/password_reset.rb +14 -0
- data/lib/nurego/payment_method.rb +16 -0
- data/lib/nurego/plan.rb +9 -0
- data/lib/nurego/registration.rb +18 -0
- data/lib/nurego/util.rb +109 -0
- data/lib/nurego/version.rb +3 -0
- data/nurego.gemspec +31 -0
- data/spec/unit/nurego/api_resource_spec.rb +326 -0
- data/spec/unit/nurego/customer_spec.rb +75 -0
- data/spec/unit/nurego/list_object_spec.rb +14 -0
- data/spec/unit/nurego/util_spec.rb +27 -0
- data/spec/unit/test_helper.rb +94 -0
- metadata +279 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
nurego (1.0.0)
|
5
|
+
cf-uaa-lib (= 1.3.10)
|
6
|
+
mime-types (~> 1.25)
|
7
|
+
multi_json (>= 1.0.4, < 2)
|
8
|
+
rest-client (~> 1.4)
|
9
|
+
|
10
|
+
GEM
|
11
|
+
remote: https://rubygems.org/
|
12
|
+
specs:
|
13
|
+
builder (3.2.2)
|
14
|
+
cf-uaa-lib (1.3.10)
|
15
|
+
multi_json
|
16
|
+
ci_reporter (1.9.2)
|
17
|
+
builder (>= 2.1.2)
|
18
|
+
diff-lcs (1.2.5)
|
19
|
+
docile (1.1.3)
|
20
|
+
mime-types (1.25.1)
|
21
|
+
multi_json (1.10.0)
|
22
|
+
rack (1.5.2)
|
23
|
+
rack-test (0.6.2)
|
24
|
+
rack (>= 1.0)
|
25
|
+
rake (10.3.1)
|
26
|
+
rest-client (1.6.7)
|
27
|
+
mime-types (>= 1.16)
|
28
|
+
rspec (2.14.1)
|
29
|
+
rspec-core (~> 2.14.0)
|
30
|
+
rspec-expectations (~> 2.14.0)
|
31
|
+
rspec-mocks (~> 2.14.0)
|
32
|
+
rspec-core (2.14.8)
|
33
|
+
rspec-expectations (2.14.5)
|
34
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
35
|
+
rspec-mocks (2.14.6)
|
36
|
+
simplecov (0.8.2)
|
37
|
+
docile (~> 1.1.0)
|
38
|
+
multi_json
|
39
|
+
simplecov-html (~> 0.8.0)
|
40
|
+
simplecov-csv (0.1.3)
|
41
|
+
simplecov
|
42
|
+
simplecov-html (0.8.0)
|
43
|
+
simplecov-rcov (0.2.3)
|
44
|
+
simplecov (>= 0.4.1)
|
45
|
+
uuidtools (2.1.4)
|
46
|
+
|
47
|
+
PLATFORMS
|
48
|
+
ruby
|
49
|
+
|
50
|
+
DEPENDENCIES
|
51
|
+
ci_reporter
|
52
|
+
nurego!
|
53
|
+
rack-test
|
54
|
+
rake
|
55
|
+
rspec
|
56
|
+
simplecov
|
57
|
+
simplecov-csv
|
58
|
+
simplecov-rcov
|
59
|
+
uuidtools
|
data/LICENSE
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2013- Nurego, Inc. (http://www.nurego.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
22
|
+
|
23
|
+
|
24
|
+
Copyright (c) 2011- Stripe, Inc. (https://stripe.com)
|
25
|
+
|
26
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
27
|
+
of this software and associated documentation files (the "Software"), to deal
|
28
|
+
in the Software without restriction, including without limitation the rights
|
29
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
30
|
+
copies of the Software, and to permit persons to whom the Software is
|
31
|
+
furnished to do so, subject to the following conditions:
|
32
|
+
|
data/README.md
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
nurego-ruby
|
2
|
+
===========
|
3
|
+
|
4
|
+
Ruby bindings for Nurego API
|
5
|
+
|
6
|
+
== Installation
|
7
|
+
|
8
|
+
You don't need this source code unless you want to modify the gem. If
|
9
|
+
you just want to use the Nurego Ruby bindings, you should run:
|
10
|
+
|
11
|
+
gem install nurego
|
12
|
+
|
13
|
+
If you want to build the gem from source:
|
14
|
+
|
15
|
+
gem build nurego.gemspec
|
16
|
+
|
17
|
+
== Requirements
|
18
|
+
|
19
|
+
* Ruby 1.8.7 or above.
|
20
|
+
|
21
|
+
== Development
|
22
|
+
|
23
|
+
Test cases can be run with: `bundle exec rake spec:unit`
|
24
|
+
|
25
|
+
Examples can be run with: `bundle install; ruby -I./lib examples/<example_name>.rb`
|
data/Rakefile
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'rspec'
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require "rack/test"
|
4
|
+
require "ci/reporter/rake/rspec"
|
5
|
+
|
6
|
+
|
7
|
+
namespace "spec" do
|
8
|
+
RSpec::Core::RakeTask.new("unit") do |t|
|
9
|
+
t.rspec_opts = ["--format", "documentation", "--colour"]
|
10
|
+
t.pattern = "**/unit/**/*_spec.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
RSpec::Core::RakeTask.new("integration") do |t|
|
14
|
+
t.rspec_opts = ["--format", "documentation", "--colour"]
|
15
|
+
t.pattern = "**/integration/**/*_spec.rb"
|
16
|
+
end
|
17
|
+
|
18
|
+
desc "Run specs with code coverage"
|
19
|
+
task :rcov => ["ci:setup:rspec"] do
|
20
|
+
require 'simplecov'
|
21
|
+
require 'simplecov-rcov'
|
22
|
+
require 'simplecov-csv'
|
23
|
+
|
24
|
+
FileUtils.rm_rf File.join('.', "coverage")
|
25
|
+
|
26
|
+
SimpleCov.start do
|
27
|
+
formatter SimpleCov::Formatter::CSVFormatter
|
28
|
+
coverage_dir ENV["COVERAGE_REPORTS"]
|
29
|
+
root '.'
|
30
|
+
|
31
|
+
add_filter "/spec/"
|
32
|
+
|
33
|
+
RSpec::Core::Runner.disable_autorun!
|
34
|
+
exit 1 unless RSpec::Core::Runner.run(['spec/unit'], STDERR, STDOUT) == 0
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => [:spec]
|
41
|
+
task :spec => ['spec:unit']
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0.1
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require "nurego"
|
2
|
+
|
3
|
+
Nurego.api_base = "https://api.nurego.com"
|
4
|
+
Nurego.api_key = "YOUR INSTANCE KEY" #login to nurego.com and check Settings/Organization for api keys
|
5
|
+
|
6
|
+
begin
|
7
|
+
offering = Nurego::Offering.current
|
8
|
+
offering.plans.each do |plan|
|
9
|
+
puts plan.inspect
|
10
|
+
plan.features.each do |feature|
|
11
|
+
puts feature.inspect
|
12
|
+
end
|
13
|
+
end
|
14
|
+
rescue Nurego::NuregoError => e
|
15
|
+
puts "ERROR #{e.error_code}"
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
|
3
|
+
ITAfBgNVBAoTGFRoZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28g
|
4
|
+
RGFkZHkgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjExMTYw
|
5
|
+
MTU0MzdaFw0yNjExMTYwMTU0MzdaMIHKMQswCQYDVQQGEwJVUzEQMA4GA1UECBMH
|
6
|
+
QXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5j
|
7
|
+
b20sIEluYy4xMzAxBgNVBAsTKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5j
|
8
|
+
b20vcmVwb3NpdG9yeTEwMC4GA1UEAxMnR28gRGFkZHkgU2VjdXJlIENlcnRpZmlj
|
9
|
+
YXRpb24gQXV0aG9yaXR5MREwDwYDVQQFEwgwNzk2OTI4NzCCASIwDQYJKoZIhvcN
|
10
|
+
AQEBBQADggEPADCCAQoCggEBAMQt1RWMnCZM7DI161+4WQFapmGBWTtwY6vj3D3H
|
11
|
+
KrjJM9N55DrtPDAjhI6zMBS2sofDPZVUBJ7fmd0LJR4h3mUpfjWoqVTr9vcyOdQm
|
12
|
+
VZWt7/v+WIbXnvQAjYwqDL1CBM6nPwT27oDyqu9SoWlm2r4arV3aLGbqGmu75RpR
|
13
|
+
SgAvSMeYddi5Kcju+GZtCpyz8/x4fKL4o/K1w/O5epHBp+YlLpyo7RJlbmr2EkRT
|
14
|
+
cDCVw5wrWCs9CHRK8r5RsL+H0EwnWGu1NcWdrxcx+AuP7q2BNgWJCJjPOq8lh8BJ
|
15
|
+
6qf9Z/dFjpfMFDniNoW1fho3/Rb2cRGadDAW/hOUoz+EDU8CAwEAAaOCATIwggEu
|
16
|
+
MB0GA1UdDgQWBBT9rGEyk2xF1uLuhV+auud2mWjM5zAfBgNVHSMEGDAWgBTSxLDS
|
17
|
+
kdRMEXGzYcs9of7dqGrU4zASBgNVHRMBAf8ECDAGAQH/AgEAMDMGCCsGAQUFBwEB
|
18
|
+
BCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuZ29kYWRkeS5jb20wRgYDVR0f
|
19
|
+
BD8wPTA7oDmgN4Y1aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBv
|
20
|
+
c2l0b3J5L2dkcm9vdC5jcmwwSwYDVR0gBEQwQjBABgRVHSAAMDgwNgYIKwYBBQUH
|
21
|
+
AgEWKmh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9yeTAO
|
22
|
+
BgNVHQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBANKGwOy9+aG2Z+5mC6IG
|
23
|
+
OgRQjhVyrEp0lVPLN8tESe8HkGsz2ZbwlFalEzAFPIUyIXvJxwqoJKSQ3kbTJSMU
|
24
|
+
A2fCENZvD117esyfxVgqwcSeIaha86ykRvOe5GPLL5CkKSkB2XIsKd83ASe8T+5o
|
25
|
+
0yGPwLPk9Qnt0hCqU7S+8MxZC9Y7lhyVJEnfzuz9p0iRFEUOOjZv2kWzRaJBydTX
|
26
|
+
RE4+uXR21aITVSzGh6O1mawGhId/dQb8vxRMDsxuxN89txJx9OjxUUAiKEngHUuH
|
27
|
+
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
|
28
|
+
U+4=
|
29
|
+
-----END CERTIFICATE-----
|
30
|
+
-----BEGIN CERTIFICATE-----
|
31
|
+
MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
|
32
|
+
MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
|
33
|
+
YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
|
34
|
+
MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
|
35
|
+
ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
|
36
|
+
MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
|
37
|
+
ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
|
38
|
+
PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
|
39
|
+
wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
|
40
|
+
EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
|
41
|
+
avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
|
42
|
+
YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
|
43
|
+
sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
|
44
|
+
/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
|
45
|
+
IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
|
46
|
+
YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
|
47
|
+
ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
|
48
|
+
OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
|
49
|
+
TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
|
50
|
+
HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
|
51
|
+
dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
|
52
|
+
ReYNnyicsbkqWletNw+vHX/bvZ8=
|
53
|
+
-----END CERTIFICATE-----
|
data/lib/nurego.rb
ADDED
@@ -0,0 +1,287 @@
|
|
1
|
+
# Nurego Ruby bindings
|
2
|
+
# API spec at http://www.nurego.com/docs/api
|
3
|
+
require 'cgi'
|
4
|
+
require 'set'
|
5
|
+
require 'openssl'
|
6
|
+
require 'rest_client'
|
7
|
+
require 'multi_json'
|
8
|
+
|
9
|
+
# Version
|
10
|
+
require 'nurego/version'
|
11
|
+
|
12
|
+
# API operations
|
13
|
+
require 'nurego/api_operations/create'
|
14
|
+
require 'nurego/api_operations/update'
|
15
|
+
require 'nurego/api_operations/delete'
|
16
|
+
require 'nurego/api_operations/list'
|
17
|
+
|
18
|
+
# Resources
|
19
|
+
require 'nurego/util'
|
20
|
+
require 'nurego/json'
|
21
|
+
require 'nurego/auth'
|
22
|
+
require 'nurego/nurego_object'
|
23
|
+
require 'nurego/api_resource'
|
24
|
+
require 'nurego/list_object'
|
25
|
+
require 'nurego/registration'
|
26
|
+
require 'nurego/customer'
|
27
|
+
require 'nurego/organization'
|
28
|
+
require 'nurego/instance'
|
29
|
+
require 'nurego/connector'
|
30
|
+
require 'nurego/password_reset'
|
31
|
+
require 'nurego/offering'
|
32
|
+
require 'nurego/plan'
|
33
|
+
require 'nurego/feature'
|
34
|
+
require 'nurego/bill'
|
35
|
+
require 'nurego/payment_method'
|
36
|
+
require 'nurego/entitlement'
|
37
|
+
|
38
|
+
|
39
|
+
# Errors
|
40
|
+
require 'nurego/errors/nurego_error'
|
41
|
+
require 'nurego/errors/api_error'
|
42
|
+
require 'nurego/errors/api_connection_error'
|
43
|
+
require 'nurego/errors/invalid_request_error'
|
44
|
+
require 'nurego/errors/card_error'
|
45
|
+
require 'nurego/errors/authentication_error'
|
46
|
+
require 'nurego/errors/user_not_found_error'
|
47
|
+
|
48
|
+
module Nurego
|
49
|
+
@api_base = 'https://api.nurego.com'
|
50
|
+
|
51
|
+
@ssl_bundle_path = File.dirname(__FILE__) + '/data/ca-certificates.crt'
|
52
|
+
@verify_ssl_certs = true
|
53
|
+
|
54
|
+
@logger = nil
|
55
|
+
|
56
|
+
class << self
|
57
|
+
attr_accessor :api_key, :api_base, :verify_ssl_certs, :api_version, :logger
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.api_url(url='')
|
61
|
+
@api_base + url
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.request(method, url, api_key, params={}, headers={})
|
65
|
+
unless api_key ||= @api_key
|
66
|
+
raise AuthenticationError.new('No API key provided. ' +
|
67
|
+
'Set your API key using "Nurego.api_key = <API-KEY>". ' +
|
68
|
+
'You can generate API keys from the Nurego web interface. ' +
|
69
|
+
'See https://www.nurego.com/api for details, or email support@nurego.com ' +
|
70
|
+
'if you have any questions.')
|
71
|
+
end
|
72
|
+
|
73
|
+
if api_key =~ /\s/
|
74
|
+
raise AuthenticationError.new('Your API key is invalid, as it contains ' +
|
75
|
+
'whitespace. (HINT: You can double-check your API key from the ' +
|
76
|
+
'Nurego web interface. See https://www.nurego.com/api for details, or ' +
|
77
|
+
'email support@nurego.com if you have any questions.)')
|
78
|
+
end
|
79
|
+
|
80
|
+
request_opts = { :verify_ssl => false }
|
81
|
+
|
82
|
+
if ssl_preflight_passed?
|
83
|
+
request_opts.update(:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
|
84
|
+
:ssl_ca_file => @ssl_bundle_path)
|
85
|
+
end
|
86
|
+
|
87
|
+
params = Util.objects_to_ids(params)
|
88
|
+
url = api_url(url)
|
89
|
+
|
90
|
+
case method.to_s.downcase.to_sym
|
91
|
+
when :get, :head, :delete
|
92
|
+
# Make params into GET parameters
|
93
|
+
url += "#{URI.parse(url).query ? '&' : '?'}#{uri_encode(params)}" if params && params.any?
|
94
|
+
payload = nil
|
95
|
+
else
|
96
|
+
payload = uri_encode(params)
|
97
|
+
end
|
98
|
+
request_opts.update(:headers => request_headers(api_key).update(headers),
|
99
|
+
:method => method, :open_timeout => 30,
|
100
|
+
:payload => payload, :url => url, :timeout => 80)
|
101
|
+
|
102
|
+
begin
|
103
|
+
response = execute_request(request_opts)
|
104
|
+
rescue SocketError => e
|
105
|
+
handle_restclient_error(e)
|
106
|
+
rescue NoMethodError => e
|
107
|
+
# Work around RestClient bug
|
108
|
+
if e.message =~ /\WRequestFailed\W/
|
109
|
+
e = APIConnectionError.new('Unexpected HTTP response code')
|
110
|
+
handle_restclient_error(e)
|
111
|
+
else
|
112
|
+
raise
|
113
|
+
end
|
114
|
+
rescue RestClient::ExceptionWithResponse => e
|
115
|
+
if rcode = e.http_code and rbody = e.http_body
|
116
|
+
handle_api_error(rcode, rbody)
|
117
|
+
else
|
118
|
+
handle_restclient_error(e)
|
119
|
+
end
|
120
|
+
rescue RestClient::Exception, Errno::ECONNREFUSED => e
|
121
|
+
handle_restclient_error(e)
|
122
|
+
end
|
123
|
+
|
124
|
+
[parse(response), api_key]
|
125
|
+
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def self.ssl_preflight_passed?
|
130
|
+
if !verify_ssl_certs && !@no_verify
|
131
|
+
$stderr.puts "WARNING: Running without SSL cert verification. " +
|
132
|
+
"Execute 'Nurego.verify_ssl_certs = true' to enable verification."
|
133
|
+
|
134
|
+
@no_verify = true
|
135
|
+
|
136
|
+
elsif !Util.file_readable(@ssl_bundle_path) && !@no_bundle
|
137
|
+
$stderr.puts "WARNING: Running without SSL cert verification " +
|
138
|
+
"because #{@ssl_bundle_path} isn't readable"
|
139
|
+
|
140
|
+
@no_bundle = true
|
141
|
+
end
|
142
|
+
|
143
|
+
!(@no_verify || @no_bundle)
|
144
|
+
end
|
145
|
+
|
146
|
+
def self.user_agent
|
147
|
+
@uname ||= get_uname
|
148
|
+
lang_version = "#{RUBY_VERSION} p#{RUBY_PATCHLEVEL} (#{RUBY_RELEASE_DATE})"
|
149
|
+
|
150
|
+
{
|
151
|
+
:bindings_version => Nurego::VERSION,
|
152
|
+
:lang => 'ruby',
|
153
|
+
:lang_version => lang_version,
|
154
|
+
:platform => RUBY_PLATFORM,
|
155
|
+
:publisher => 'nurego',
|
156
|
+
:uname => @uname
|
157
|
+
}
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.get_uname
|
162
|
+
`uname -a 2>/dev/null`.strip if RUBY_PLATFORM =~ /linux|darwin/i
|
163
|
+
rescue Errno::ENOMEM => ex # couldn't create subprocess
|
164
|
+
"uname lookup failed"
|
165
|
+
end
|
166
|
+
|
167
|
+
def self.uri_encode(params)
|
168
|
+
Util.flatten_params(params).
|
169
|
+
map { |k,v| "#{k}=#{Util.url_encode(v)}" }.join('&')
|
170
|
+
end
|
171
|
+
|
172
|
+
def self.request_headers(api_key)
|
173
|
+
headers = {
|
174
|
+
:user_agent => "Nurego/v1 RubyBindings/#{Nurego::VERSION}",
|
175
|
+
:x_nurego_authorization => "Bearer #{api_key}",
|
176
|
+
:content_type => 'application/x-www-form-urlencoded'
|
177
|
+
}
|
178
|
+
|
179
|
+
headers[:nurego_version] = api_version if api_version
|
180
|
+
headers[:authorization] = Nurego::Auth.header_token[:token] if Nurego::Auth.header_token
|
181
|
+
|
182
|
+
begin
|
183
|
+
headers.update(:x_nurego_client_user_agent => Nurego::JSON.dump(user_agent))
|
184
|
+
rescue => e
|
185
|
+
headers.update(:x_nurego_client_raw_user_agent => user_agent.inspect,
|
186
|
+
:error => "#{e} (#{e.class})")
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def self.execute_request(opts)
|
191
|
+
opts[:headers][:x_request_id] = SecureRandom.uuid
|
192
|
+
|
193
|
+
if @logger
|
194
|
+
@logger.info("nurego-ruby execute_request")
|
195
|
+
@logger.info(opts.inspect)
|
196
|
+
end
|
197
|
+
|
198
|
+
RestClient::Request.execute(opts)
|
199
|
+
end
|
200
|
+
|
201
|
+
def self.parse(response)
|
202
|
+
begin
|
203
|
+
# Would use :symbolize_names => true, but apparently there is
|
204
|
+
# some library out there that makes symbolize_names not work.
|
205
|
+
response = Nurego::JSON.load(response.body)
|
206
|
+
rescue MultiJson::DecodeError
|
207
|
+
raise general_api_error(response.code, response.body)
|
208
|
+
end
|
209
|
+
|
210
|
+
Util.symbolize_names(response)
|
211
|
+
end
|
212
|
+
|
213
|
+
def self.general_api_error(rcode, rbody)
|
214
|
+
APIError.new("Invalid response object from API: #{rbody.inspect} " +
|
215
|
+
"(HTTP response code was #{rcode})", rcode, rbody)
|
216
|
+
end
|
217
|
+
|
218
|
+
def self.handle_api_error(rcode, rbody)
|
219
|
+
begin
|
220
|
+
error_obj = Nurego::JSON.load(rbody)
|
221
|
+
error_obj = Util.symbolize_names(error_obj)
|
222
|
+
error = (error_obj && error_obj[:error]) or raise NuregoError.new # escape from parsing
|
223
|
+
|
224
|
+
rescue MultiJson::DecodeError, NuregoError
|
225
|
+
raise general_api_error(rcode, rbody)
|
226
|
+
end
|
227
|
+
|
228
|
+
case rcode
|
229
|
+
when 402
|
230
|
+
raise card_error error, rcode, rbody, error_obj
|
231
|
+
when 400, 404
|
232
|
+
raise invalid_request_error error, rcode, rbody, error_obj
|
233
|
+
when 401
|
234
|
+
raise authentication_error error, rcode, rbody, error_obj
|
235
|
+
else
|
236
|
+
raise api_error error, rcode, rbody, error_obj
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
|
242
|
+
|
243
|
+
def self.invalid_request_error(error, rcode, rbody, error_obj)
|
244
|
+
InvalidRequestError.new(error[:message], error[:param], rcode,
|
245
|
+
rbody, error_obj)
|
246
|
+
end
|
247
|
+
|
248
|
+
def self.card_error(error, rcode, rbody, error_obj)
|
249
|
+
CardError.new(error[:message], error[:param], rcode, rbody, error_obj)
|
250
|
+
end
|
251
|
+
|
252
|
+
def self.authentication_error(error, rcode, rbody, error_obj)
|
253
|
+
AuthenticationError.new(error[:message], rcode, rbody, error_obj)
|
254
|
+
end
|
255
|
+
|
256
|
+
def self.api_error(error, rcode, rbody, error_obj)
|
257
|
+
APIError.new(error[:message], rcode, rbody, error_obj)
|
258
|
+
end
|
259
|
+
|
260
|
+
def self.handle_restclient_error(e)
|
261
|
+
case e
|
262
|
+
when RestClient::ServerBrokeConnection, RestClient::RequestTimeout
|
263
|
+
message = "Could not connect to Nurego (#{@api_base}). " +
|
264
|
+
"Please check your internet connection and try again. " +
|
265
|
+
"If this problem persists, you should check Nurego's service status at " +
|
266
|
+
"https://twitter.com/nuregostatus, or let us know at support@nurego.com."
|
267
|
+
|
268
|
+
when RestClient::SSLCertificateNotVerified
|
269
|
+
message = "Could not verify Nurego's SSL certificate. " +
|
270
|
+
"Please make sure that your network is not intercepting certificates. " +
|
271
|
+
"(Try going to https://api.nurego.com/v1 in your browser.) " +
|
272
|
+
"If this problem persists, let us know at support@nurego.com."
|
273
|
+
|
274
|
+
when SocketError
|
275
|
+
message = "Unexpected error communicating when trying to connect to Nurego. " +
|
276
|
+
"You may be seeing this message because your DNS is not working. " +
|
277
|
+
"To check, try running 'host nurego.com' from the command line."
|
278
|
+
|
279
|
+
else
|
280
|
+
message = "Unexpected error communicating with Nurego. " +
|
281
|
+
"If this problem persists, let us know at support@nurego.com."
|
282
|
+
|
283
|
+
end
|
284
|
+
|
285
|
+
raise APIConnectionError.new(message + "\n\n(Network error: #{e.message})")
|
286
|
+
end
|
287
|
+
end
|