ibm-cloud-sdk 0.1.6 → 0.1.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +20 -0
  3. data/Gemfile +2 -0
  4. data/ibm-cloud-sdk.gemspec +1 -1
  5. data/lib/ibm/cloud/sdk.rb +3 -1
  6. data/lib/ibm/cloud/sdk/iam.rb +5 -0
  7. data/lib/ibm/cloud/sdk/logging.rb +21 -0
  8. data/lib/ibm/cloud/sdk/null_logger.rb +19 -0
  9. data/lib/ibm/cloud/sdk/power_iaas.rb +117 -9
  10. data/lib/ibm/cloud/sdk/resource_controller.rb +4 -0
  11. data/lib/ibm/cloud/sdk/tags.rb +28 -0
  12. data/lib/ibm/cloud/sdk/tags/http.rb +5 -0
  13. data/lib/ibm/cloud/sdk/tags/http/tag_collection.rb +99 -0
  14. data/lib/ibm/cloud/sdk/version.rb +1 -1
  15. data/lib/ibm/cloud/sdk/vpc.rb +8 -6
  16. data/lib/ibm/cloud/sdk/vpc/floatingips.rb +2 -2
  17. data/lib/ibm/cloud/sdk/vpc/flowlogcollectors.rb +2 -2
  18. data/lib/ibm/cloud/sdk/vpc/http.rb +7 -0
  19. data/lib/ibm/cloud/sdk/vpc/http/vpc_collection.rb +82 -0
  20. data/lib/ibm/cloud/sdk/vpc/http/vpc_http.rb +28 -0
  21. data/lib/ibm/cloud/sdk/vpc/http/vpc_instance.rb +30 -0
  22. data/lib/ibm/cloud/sdk/vpc/ike_policies.rb +2 -2
  23. data/lib/ibm/cloud/sdk/vpc/images.rb +2 -2
  24. data/lib/ibm/cloud/sdk/vpc/instance/actions.rb +77 -2
  25. data/lib/ibm/cloud/sdk/vpc/instance/floating_ips.rb +3 -3
  26. data/lib/ibm/cloud/sdk/vpc/instance/network_interfaces.rb +3 -3
  27. data/lib/ibm/cloud/sdk/vpc/instance/volume_attachments.rb +3 -3
  28. data/lib/ibm/cloud/sdk/vpc/instance_profiles.rb +3 -3
  29. data/lib/ibm/cloud/sdk/vpc/instances.rb +99 -6
  30. data/lib/ibm/cloud/sdk/vpc/ipsec_policies.rb +2 -2
  31. data/lib/ibm/cloud/sdk/vpc/keys.rb +2 -24
  32. data/lib/ibm/cloud/sdk/vpc/load_balancer.rb +1 -1
  33. data/lib/ibm/cloud/sdk/vpc/load_balancer/listeners.rb +2 -2
  34. data/lib/ibm/cloud/sdk/vpc/load_balancer/members.rb +2 -2
  35. data/lib/ibm/cloud/sdk/vpc/load_balancer/policies.rb +2 -2
  36. data/lib/ibm/cloud/sdk/vpc/load_balancer/pools.rb +2 -2
  37. data/lib/ibm/cloud/sdk/vpc/load_balancer/rules.rb +2 -2
  38. data/lib/ibm/cloud/sdk/vpc/load_balancers.rb +1 -1
  39. data/lib/ibm/cloud/sdk/vpc/network_acls.rb +4 -4
  40. data/lib/ibm/cloud/sdk/vpc/operating_systems.rb +2 -2
  41. data/lib/ibm/cloud/sdk/vpc/public_gateways.rb +2 -2
  42. data/lib/ibm/cloud/sdk/vpc/regions.rb +4 -4
  43. data/lib/ibm/cloud/sdk/vpc/security_groups.rb +6 -6
  44. data/lib/ibm/cloud/sdk/vpc/subnets.rb +2 -2
  45. data/lib/ibm/cloud/sdk/vpc/volume_profiles.rb +2 -2
  46. data/lib/ibm/cloud/sdk/vpc/volumes.rb +2 -2
  47. data/lib/ibm/cloud/sdk/vpc/vpcs.rb +6 -6
  48. data/lib/ibm/cloud/sdk/vpc/vpn_gateway/connections.rb +2 -2
  49. data/lib/ibm/cloud/sdk/vpc/vpn_gateway/local_cidrs.rb +3 -3
  50. data/lib/ibm/cloud/sdk/vpc/vpn_gateway/peer_cidrs.rb +3 -3
  51. data/lib/ibm/cloud/sdk/vpc/vpn_gateways.rb +2 -2
  52. data/lib/ibm/cloud/sdk_http.rb +16 -0
  53. data/lib/ibm/cloud/sdk_http/base_collection.rb +121 -0
  54. data/lib/ibm/cloud/sdk_http/base_http_mixin.rb +120 -0
  55. data/lib/ibm/cloud/sdk_http/base_instance.rb +55 -0
  56. data/lib/ibm/cloud/sdk_http/connection.rb +38 -0
  57. data/lib/ibm/cloud/sdk_http/exceptions.rb +31 -0
  58. data/lib/ibm/cloud/sdk_http/has_child.rb +23 -0
  59. data/lib/ibm/cloud/sdk_http/iam_token.rb +53 -0
  60. data/lib/ibm/cloud/sdk_http/sdk_response.rb +132 -0
  61. data/lib/ibm/cloud_sdk.rb +39 -0
  62. metadata +23 -10
  63. data/lib/ibm/cloud/sdk/vpc/base_collection.rb +0 -108
  64. data/lib/ibm/cloud/sdk/vpc/base_instance.rb +0 -23
  65. data/lib/ibm/cloud/sdk/vpc/base_vpc.rb +0 -61
  66. data/lib/ibm/cloud/sdk/vpc/cloud_sdk.rb +0 -33
  67. data/lib/ibm/cloud/sdk/vpc/helpers/connection.rb +0 -66
  68. data/lib/ibm/cloud/sdk/vpc/helpers/response.rb +0 -92
@@ -6,28 +6,28 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # Work with VPC reqions
9
- class Regions < BaseCollection
9
+ class Regions < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'regions', child_class: Region)
12
12
  end
13
13
  end
14
14
 
15
15
  # Work with a single region
16
- class Region < BaseInstance
16
+ class Region < VPCInstance
17
17
  def zones
18
18
  Zones.new(self)
19
19
  end
20
20
  end
21
21
 
22
22
  # Zones are included within a region.
23
- class Zones < BaseCollection
23
+ class Zones < VPCCollection
24
24
  def initialize(parent)
25
25
  super(parent, 'zones', child_class: Zone)
26
26
  end
27
27
  end
28
28
 
29
29
  # A single zone.
30
- class Zone < BaseInstance
30
+ class Zone < VPCInstance
31
31
  end
32
32
  end
33
33
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # Work with VPC reqions
9
- class SecurityGroups < BaseCollection
9
+ class SecurityGroups < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'security_groups', child_class: SecurityGroup)
12
12
  end
13
13
  end
14
14
 
15
15
  # Work with VPC reqions
16
- class SecurityGroup < BaseCollection
16
+ class SecurityGroup < VPCInstance
17
17
  def network_interfaces
18
18
  SECURITYGROUP::NetworkInterfaces.new(self)
19
19
  end
@@ -21,25 +21,25 @@ module IBM
21
21
 
22
22
  module SECURITYGROUP
23
23
  # Work with interfaces associated with parent group.
24
- class NetworkInterfaces < BaseCollection
24
+ class NetworkInterfaces < VPCCollection
25
25
  def initialize(parent)
26
26
  super(parent, 'network_interfaces', child_class: NetworkInterface)
27
27
  end
28
28
  end
29
29
 
30
30
  # Work with a single rule.
31
- class NetworkInterface < BaseInstance
31
+ class NetworkInterface < VPCInstance
32
32
  end
33
33
 
34
34
  # Work with rules associated with parent group.
35
- class Rules < BaseCollection
35
+ class Rules < VPCCollection
36
36
  def initialize(parent)
37
37
  super(parent, 'rules', child_class: Rule)
38
38
  end
39
39
  end
40
40
 
41
41
  # Work with a single rule.
42
- class Rule < BaseInstance
42
+ class Rule < VPCInstance
43
43
  end
44
44
  end
45
45
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # A list of submetes
9
- class Subnets < BaseCollection
9
+ class Subnets < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'subnets', child_class: Subnet)
12
12
  end
13
13
  end
14
14
 
15
15
  # A single subnet
16
- class Subnet < BaseInstance
16
+ class Subnet < VPCInstance
17
17
  end
18
18
  end
19
19
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # Work with Volume Profiles.
9
- class VolumeProfiles < BaseCollection
9
+ class VolumeProfiles < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'volume/profiles', child_class: VolumeProfile, array_key: 'profiles')
12
12
  end
13
13
  end
14
14
 
15
15
  # Work with a single volume profile.
16
- class VolumeProfile < BaseInstance
16
+ class VolumeProfile < VPCInstance
17
17
  end
18
18
  end
19
19
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # Work with a collection of volumes.
9
- class Volumes < BaseCollection
9
+ class Volumes < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'volumes', child_class: Volume)
12
12
  end
13
13
  end
14
14
 
15
15
  # Work with a single volume.
16
- class Volume < BaseInstance
16
+ class Volume < VPCInstance
17
17
  end
18
18
  end
19
19
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # A list of Vpc
9
- class Vpcs < BaseCollection
9
+ class Vpcs < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'vpcs', child_class: VpcInstance)
12
12
  end
13
13
  end
14
14
 
15
15
  # A single Vpc
16
- class VpcInstance < BaseInstance
16
+ class VpcInstance < VPCInstance
17
17
  def default_network_acl
18
18
  get('default_network_acl')
19
19
  end
@@ -33,25 +33,25 @@ module IBM
33
33
 
34
34
  module VPCS
35
35
  # A list of Vpc
36
- class AddressPrefixes < BaseCollection
36
+ class AddressPrefixes < VPCCollection
37
37
  def initialize(parent)
38
38
  super(parent, 'address_prefixes', child_class: AddressPrefix)
39
39
  end
40
40
  end
41
41
 
42
42
  # A single Vpc
43
- class AddressPrefix < BaseInstance
43
+ class AddressPrefix < VPCInstance
44
44
  end
45
45
 
46
46
  # A list of Vpc
47
- class Routes < BaseCollection
47
+ class Routes < VPCCollection
48
48
  def initialize(parent)
49
49
  super(parent, 'routes', child_class: Route)
50
50
  end
51
51
  end
52
52
 
53
53
  # A single Vpc
54
- class Route < BaseInstance
54
+ class Route < VPCInstance
55
55
  end
56
56
  end
57
57
  end
@@ -10,7 +10,7 @@ module IBM
10
10
  module VPC
11
11
  module VPNGATEWAY
12
12
  # A list of Connection
13
- class Connections < BaseCollection
13
+ class Connections < VPCCollection
14
14
  def initialize(parent)
15
15
  @array_key = 'connections'
16
16
  @instance = Connection
@@ -19,7 +19,7 @@ module IBM
19
19
  end
20
20
 
21
21
  # A single Connection
22
- class Connection < BaseInstance
22
+ class Connection < VPCInstance
23
23
  def local_cidrs
24
24
  LocalCIDRs.new(self)
25
25
  end
@@ -7,7 +7,7 @@ module IBM
7
7
  module VPC
8
8
  module VPNGATEWAY
9
9
  # A list of Connection
10
- class LocalCIDRs < BaseCollection
10
+ class LocalCIDRs < VPCCollection
11
11
  def initialize(parent)
12
12
  @array_key = 'local_cidrs'
13
13
  @instance = Connection
@@ -20,9 +20,9 @@ module IBM
20
20
  end
21
21
 
22
22
  # A single Connection
23
- class LocalCIDR < BaseInstance
23
+ class LocalCIDR < VPCInstance
24
24
  def update(payload)
25
- put(payload)
25
+ put(payload: payload)
26
26
  end
27
27
  end
28
28
  end
@@ -7,7 +7,7 @@ module IBM
7
7
  module VPC
8
8
  module VPNGATEWAY
9
9
  # A list of Connection
10
- class PeerCIDRs < BaseCollection
10
+ class PeerCIDRs < VPCCollection
11
11
  def initialize(parent)
12
12
  @array_key = 'peer_cidrs'
13
13
  @instance = Connection
@@ -20,9 +20,9 @@ module IBM
20
20
  end
21
21
 
22
22
  # A single Connection
23
- class PeerCIDR < BaseInstance
23
+ class PeerCIDR < VPCInstance
24
24
  def update(payload)
25
- put(payload)
25
+ put(payload: payload)
26
26
  end
27
27
  end
28
28
  end
@@ -6,14 +6,14 @@ module IBM
6
6
  module SDK
7
7
  module VPC
8
8
  # A list of VPNGateway
9
- class VPNGateways < BaseCollection
9
+ class VPNGateways < VPCCollection
10
10
  def initialize(parent)
11
11
  super(parent, 'vpn_gateways', child_class: VPNGateway)
12
12
  end
13
13
  end
14
14
 
15
15
  # A single VPNGateway
16
- class VPNGateway < BaseInstance
16
+ class VPNGateway < VPCInstance
17
17
  # Get a lisst of connections asssociated with this gateway.
18
18
  def connections
19
19
  VPNGATEWAY::Connections.new(self)
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sdk_http/connection'
4
+ require_relative 'sdk_http/exceptions'
5
+ require_relative 'sdk_http/base_collection'
6
+ require_relative 'sdk_http/base_instance'
7
+ require_relative 'sdk_http/sdk_response'
8
+ require_relative 'sdk_http/iam_token'
9
+
10
+ module IBM
11
+ module Cloud
12
+ # Module holds basic HTTP functionality.
13
+ module SDKHTTP
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,121 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require_relative 'base_http_mixin'
5
+ require_relative 'has_child'
6
+
7
+ module IBM
8
+ module Cloud
9
+ module SDKHTTP
10
+ # Container that encapsulates the VPC API.
11
+ # This class is used as a base for collection APIs.
12
+ # @param parent [Object] The parent instance in the API chain.
13
+ # @param endpoint [string] A path from the parent to the desired endpoint. In most cases is should be 1 word.
14
+ # @param array_key [string] The key that the API response holds the endpoint data. When nil the endpoint will be used.
15
+ # @param child_class [Object] The Object to be used when instanciating the single instance for this class.
16
+ class BaseCollection
17
+ include BaseHTTPMixin
18
+
19
+ def initialize(parent, endpoint, array_key: nil, child_class: nil, child_id: 'id')
20
+ # Setup empty base instance variables.
21
+ @params = {}
22
+ @token = parent.token
23
+ array_key ||= endpoint
24
+
25
+ # Set the array key and child class.
26
+ @array_key ||= array_key
27
+
28
+ @instance ||= child_class
29
+ @instance_id ||= child_id
30
+
31
+ @connection = parent.connection
32
+
33
+ (class << self; include ChildMixin; end) if child_class
34
+
35
+ @endpoint = parent.url(endpoint)
36
+ @logger = parent.logger
37
+ end
38
+
39
+ attr_reader :logger, :endpoint, :token, :connection
40
+
41
+ # In a Child base class add the possible query parameters for the API and return self to make it chainable.
42
+ # When implemented usage would be Collection.params(limit: 2).get
43
+ # @return [BaseCollection] The instanticated class.
44
+ def params(limit: nil)
45
+ raise NotImplementedError('Sample only. The params method needs to be customized in child class.')
46
+ # rubocop:disable Lint/UnreachableCode
47
+ @params[:limit] = limit if limit
48
+ self
49
+ # rubocop:enable Lint/UnreachableCode
50
+ end
51
+
52
+ def reset_params
53
+ @params.clear
54
+ end
55
+
56
+ # Retrieve the collection from the cloud.
57
+ # @return [IBM::Cloud::SDK::VPC::Response] The http response object.
58
+ def fetch
59
+ @data ||= get
60
+ end
61
+
62
+ # Get an iterable for the resource collection.
63
+ # @return [Enumerator] Use standard each, next idioms.
64
+ def all
65
+ each_resource(url)
66
+ end
67
+
68
+ # Fetch all data and return in an array.
69
+ # @return [Array] Hashes of the returned data.
70
+ def data
71
+ all.to_a
72
+ end
73
+
74
+ # A generic post method to create a resource on the collection.
75
+ # @param payload [Hash] A hash of parameters to send to the server.
76
+ # @param payload_type [String] One of the following options json, form, or body.
77
+ # @return [IBM::Cloud::SDK::VPC::Response] The http response object.
78
+ def create(payload, payload_type = 'json')
79
+ adhoc(method: 'post', payload_type: payload_type, payload: payload)
80
+ end
81
+
82
+ private
83
+
84
+ # Return a wrapped instance if set.
85
+ # @param value [Hash] The hash returned from server.
86
+ def hash_instance(value)
87
+ return @instance.new(self, data: value, id_key: @instance_id) if @instance
88
+
89
+ value
90
+ end
91
+
92
+ # Create a generator that removes the need for pagination.
93
+ # @param url [String] Full URL to send to server.
94
+ # @return [Enumerator] Object to page through results.
95
+ # @yield [BaseInstance] An instance of the instance class.
96
+ # @yield [Hash] When no BaseInstance set.
97
+ def each_resource(url, &block)
98
+ raise NotImplementedError('Sample only. The each_resource method needs to be customized in child class.')
99
+ # rubocop:disable Lint/UnreachableCode
100
+ # Sample implementation based on VPC.
101
+ return enum_for(:each_resource, url) unless block_given?
102
+ return unless url
103
+
104
+ response = get(path: url)
105
+ resources = response.fetch(@array_key.to_sym)
106
+
107
+ resources&.each { |value| yield hash_instance(value) }
108
+ # VPC has a next key that holds the next URL.
109
+ return unless response.key?(:next)
110
+
111
+ # The next data structure is a hash with a href member.
112
+ next_url = response.dig(:next, :href)
113
+ return unless next_url
114
+
115
+ each_resource(next_url, &block)
116
+ # rubocop:enable Lint/UnreachableCode
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'sdk_response'
4
+
5
+ module IBM
6
+ module Cloud
7
+ # Module holds basic HTTP functionality.
8
+ module SDKHTTP
9
+ # Generic methods for accessing VPC.
10
+ module BaseHTTPMixin
11
+ @connection = nil
12
+
13
+ # Run a custom query and verify response is 2xx or 404.
14
+ # @param method [String] The HTTP method to use.
15
+ # @param path [String] The relative path from the current object location.
16
+ # @param params [Hash] A hash of query parameters.
17
+ # @param payload [Hash] A hash to send as the body.
18
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
19
+ # @return [SDKResponse]
20
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
21
+ def adhoc(method: 'get', path: nil, params: nil, payload: nil, payload_type: 'json')
22
+ unchecked_response(method: method, path: path, params: params, payload: payload, payload_type: payload_type).raise_for_status!
23
+ end
24
+
25
+ # Run a custom query do not verify the response.
26
+ # @param method [String] The HTTP method to use.
27
+ # @param path [String] The relative path from the current object location.
28
+ # @param params [Hash] A hash of query parameters.
29
+ # @param payload [Hash] A hash to send as the body.
30
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
31
+ def unchecked_response(method: 'get', path: nil, params: nil, payload: nil, payload_type: 'json')
32
+ @connection.request(method.to_sym, url(path), metadata(params, payload, payload_type))
33
+ end
34
+
35
+ attr_reader :endpoint
36
+
37
+ # Perform a GET request and verify response is 2xx or 404.
38
+ # @param path [String] The relative path from the current object location.
39
+ # @param params [Hash] A hash of query parameters.
40
+ # @return [SDKResponse]
41
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
42
+ def get(path: nil, params: nil)
43
+ adhoc(method: 'get', path: path, params: params)
44
+ end
45
+
46
+ # Send a POST request and verify response is 2xx or 404.
47
+ # @param path [String] The relative path from the current object location.
48
+ # @param params [Hash] A hash of query parameters.
49
+ # @param payload [Hash] A hash to send as the body.
50
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
51
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
52
+ # @return [SDKResponse]
53
+ def post(payload: nil, path: nil, params: nil, payload_type: 'json')
54
+ adhoc(method: 'post', path: path, params: params, payload: payload, payload_type: payload_type)
55
+ end
56
+
57
+ # Send a PUT request and verify response is 2xx or 404.
58
+ # @param path [String] The relative path from the current object location.
59
+ # @param params [Hash] A hash of query parameters.
60
+ # @param payload [Hash] A hash to send as the body.
61
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
62
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
63
+ # @return [SDKResponse]
64
+ def put(payload: nil, path: nil, params: nil, payload_type: 'json')
65
+ adhoc(method: 'put', path: path, params: params, payload: payload, payload_type: payload_type)
66
+ end
67
+
68
+ # Send a PATCH request and verify response is 2xx or 404.
69
+ # @param path [String] The relative path from the current object location.
70
+ # @param params [Hash] A hash of query parameters.
71
+ # @param payload [Hash] A hash to send as the body.
72
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
73
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
74
+ # @return [SDKResponse]
75
+ def patch(payload: nil, path: nil, params: nil, payload_type: 'json')
76
+ adhoc(method: 'patch', path: path, params: params, payload: payload, payload_type: payload_type)
77
+ end
78
+
79
+ # Send a DELETE request and verify response is 2xx or 404.
80
+ # @param path [String] The relative path from the current object location.
81
+ # @param params [Hash] A hash of query parameters.
82
+ # @raise [Exceptions::HttpStatusError] Raise if status checks failed.
83
+ # @return [SDKResponse]
84
+ def delete(path: nil, params: nil)
85
+ adhoc(method: 'delete', path: path, params: params)
86
+ end
87
+
88
+ # Preprocess request parameters with any additional data.
89
+ # @param query [Hash] A hash of query parameters.
90
+ # @param payload [Hash] A hash to send as the body.
91
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
92
+ # @return [Hash]
93
+ def metadata(query = nil, payload = nil, payload_type = 'json')
94
+ @params ||= {}
95
+ @params.merge!(query) if query
96
+
97
+ send_parameters = {
98
+ query: @params,
99
+ headers: { "Authorization": @token.authorization_header }
100
+ }
101
+
102
+ # Add payload if it is not nil.
103
+ if payload && payload.empty? == false
104
+ payload = payload.to_json if payload_type == 'json'
105
+ send_parameters[:body] = payload
106
+ end
107
+ send_parameters
108
+ end
109
+
110
+ # Merge path with current class's endpoint.
111
+ def url(path = nil)
112
+ return endpoint unless path
113
+ return path if URI.parse(path).relative? == false
114
+
115
+ "#{endpoint}/#{path}"
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end