ibm-cloud-sdk 0.1.10 → 0.1.11

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3846f53417aa653151063dfd91b59ea43b1ba3a9d2d53fdb085c8dc7f28bb2ea
4
- data.tar.gz: 903b21299da1b4d57953b4af2a98d27bc99e34298781b7936deae237641d34c6
3
+ metadata.gz: 336ae42302a72e720775cd6d0c6e193e4a6c9c2b2c4e2858b0c02e5d85e96380
4
+ data.tar.gz: 937ccbcf0d347b0bfaf06f959cf0e96a0aa9ea3816880795da47bfa60d0da3f5
5
5
  SHA512:
6
- metadata.gz: 9a1284cd63ae075ed1786f5045cb3951e328fb5edfcc95e1d981dd63c72a6ec85ff116102e07fe1317333dcc77305dad3287f312e184a31eb44bc3889303c521
7
- data.tar.gz: 507dde2d35874cdee345b14c785d941b0b2a40014251ad8262f684f8f0966b050f57bb03e407332c006204344061c4963f4759895ab040d1ed24e5af73acc65d
6
+ metadata.gz: 511b9535c80328b92c3e9645a46058f26fda766444ecaf76fd71f8f64ebeea490aaec3284544df68b0cb84bec69dd50f1298dc20d48af17351db6abb60e858bd
7
+ data.tar.gz: 3f1ac1719230d2a8c2ed9e2645d8311c61e7b697dfc36960df9019224392facd5aab3e815ad5fd486ef9a863c935a019e41672c83881c0650a8144901334a8ad
@@ -1,6 +1,9 @@
1
1
  # Changelog
2
2
  All notable changes to the gem ibm-cloud-sdk-ruby will be documented here.
3
3
 
4
+ ## v0.1.11 - 2020-10-28
5
+ - Add start, stop, and reboot actions on VPC instances
6
+
4
7
  ## v0.1.10 - 2020-10-08
5
8
  - Change VPC http provider to HTTParty
6
9
  - Add Tags API and clean up VPC
@@ -1,7 +1,7 @@
1
1
  module IBM
2
2
  module Cloud
3
3
  module SDK
4
- VERSION = "0.1.10"
4
+ VERSION = "0.1.11"
5
5
  end
6
6
  end
7
7
  end
@@ -11,16 +11,15 @@ module IBM
11
11
  module VpcHTTP
12
12
  include SDKHTTP::BaseHTTPMixin
13
13
 
14
- def metadata(query = nil, payload = nil)
15
- @params ||= {}
16
- @params.merge!(query) if query
17
-
18
- payload ||= {}
19
- {
20
- query: { version: '2020-08-01', generation: 2 }.merge(@params),
21
- body: payload,
22
- headers: { "Authorization": @token.authorization_header }
23
- }
14
+ # Preprocess request parameters, add required version and generation parameters to query.
15
+ # @param query [Hash] A hash of query parameters.
16
+ # @param payload [Hash] A hash to send as the body.
17
+ # @param payload_type [Hash] If json then convert to json string, else send as form data.
18
+ # @return [Hash]
19
+ def metadata(query = nil, payload = nil, payload_type = 'json')
20
+ default_params = { version: '2020-08-01', generation: 2 }
21
+ default_params.merge!(query) if query
22
+ super(default_params, payload, payload_type)
24
23
  end
25
24
  end
26
25
  end
@@ -1,6 +1,9 @@
1
1
  # typed: true
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'date'
5
+ require 'forwardable'
6
+
4
7
  module IBM
5
8
  module Cloud
6
9
  module SDK
@@ -11,6 +14,78 @@ module IBM
11
14
  def initialize(parent)
12
15
  super(parent, 'actions')
13
16
  end
17
+
18
+ # Send an action request to start the instance.
19
+ def start
20
+ create('start')
21
+ end
22
+
23
+ # Send an action request to stop the instance.
24
+ # @param force [Boolean] Clear the queue and run this action.
25
+ def stop(force: false)
26
+ create('stop', force: force)
27
+ end
28
+
29
+ # Send an action request to reboot the instance.
30
+ # @param force [Boolean] Clear the queue and run this action.
31
+ def reboot(force: false)
32
+ create('reboot', force: force)
33
+ end
34
+
35
+ # Send a custom action request.
36
+ # @param action [String] The type of action. Allowable values: [reboot, start, stop]
37
+ # @param force [Boolean] If set to true, the action will be forced immediately, and all queued actions deleted. Ignored for the start action.
38
+ def create(action, force: false)
39
+ @logger.info("Sending action request for #{action} with force #{force}.")
40
+ payload = { type: action }
41
+ payload[:force] = force if force
42
+ response = post(payload: payload)
43
+ Action.new(response)
44
+ end
45
+ end
46
+
47
+ # A base class that wraps the action response.
48
+ class Action
49
+ def initialize(response)
50
+ @response = response
51
+ @data = response.json
52
+ @keys = %i[type force created_at]
53
+ @deprecated = %i[completed_at started_at status id href]
54
+
55
+ clear_deprecated
56
+ add_inst_vars(@keys)
57
+ end
58
+
59
+ # Return the DateTime the action was created.
60
+ # @return [DateTime]
61
+ def created_at
62
+ return DateTime.parse(@created_at) if @created_at
63
+
64
+ @created_at
65
+ end
66
+
67
+ # The HTTP response object.
68
+ attr_accessor :response, :data
69
+
70
+ extend Forwardable
71
+ def_delegators :@data, :[], :dig, :each_pair, :each, :fetch, :has_key?, :has_value?, :include?, :index, :inspect, :key?, :keys, :length, :merge, :merge!, :clear, :to_h, :value?, :values, :pretty_print
72
+
73
+ private
74
+
75
+ # Iterate through an array of symbols. Set the instance variable and attr_accessor for each.
76
+ def add_inst_vars(keys)
77
+ keys.each do |k|
78
+ instance_variable_set "@#{k}", @data[k]
79
+ self.class.attr_accessor k unless respond_to?(k)
80
+ end
81
+ end
82
+
83
+ # Remove deprecated keys from hash.
84
+ def clear_deprecated
85
+ @data.each do |k, _v|
86
+ @data.delete(k) if @deprecated.include?(k)
87
+ end
88
+ end
14
89
  end
15
90
  end
16
91
  end
@@ -38,21 +38,118 @@ module IBM
38
38
 
39
39
  # Work with a single instance.
40
40
  class Instance < VPCInstance
41
+ TRANSITIONAL_STATES = %w[pausing pending restarting resuming starting stopping].freeze
42
+ ERROR_STATE = 'failed'
43
+ RUNNING_STATE = 'running'
44
+ STOPPED_STATES = %w[stopped paused].freeze
45
+
46
+ # The id of this VM.
47
+ def id
48
+ @data[:id]
49
+ end
50
+
51
+ # The name of this VM.
52
+ def name
53
+ @data[:name]
54
+ end
55
+
56
+ # The status of the virtual server instance. Possible values: [failed,paused,pausing,pending,restarting,resuming,running,starting,stopped,stopping]
57
+ def status
58
+ @data[:status]
59
+ end
60
+
61
+ # Whether the state of the VM is in failed state.
62
+ # @return [Boolean]
63
+ def failed?
64
+ status == ERROR_STATE
65
+ end
66
+
67
+ # Whether the state of the VM is in the started state.
68
+ # @return [Boolean]
69
+ def started?
70
+ status == RUNNING_STATE
71
+ end
72
+
73
+ # Whether the state of the VM is in a stopped or paused state.
74
+ # @return [Boolean]
75
+ def stopped?
76
+ STOPPED_STATES.include?(status)
77
+ end
78
+
79
+ # Whether the state of the VM is in a transitional state.
80
+ # @return [Boolean]
81
+ def transitional?
82
+ TRANSITIONAL_STATES.include?(status)
83
+ end
84
+
85
+ # Interact with instance actions.
86
+ # @return [INSTANCE::Actions]
41
87
  def actions
42
88
  INSTANCE::Actions.new(self)
43
89
  end
44
90
 
91
+ # Interact with instance network interfaces.
92
+ # @return [INSTANCE::NetworkInterfaces]
45
93
  def network_interfaces
46
94
  INSTANCE::NetworkInterfaces.new(self)
47
95
  end
48
96
 
97
+ # Interact with instance volume attachements.
98
+ # @return [INSTANCE::VolumeAttachments]
49
99
  def volume_attachments
50
100
  INSTANCE::VolumeAttachments.new(self)
51
101
  end
52
102
 
103
+ # Return the data used for initializing this VM.
53
104
  def initialization
54
105
  adhoc(method: 'get', path: 'initialization').json
55
106
  end
107
+
108
+ # Wait for the VM instance to be in a stable state.
109
+ # @param sleep_time [Integer] The time to sleep between refreshes.
110
+ # @param timeout [Integer] The number of seconds before raising an error.
111
+ # @param block [Proc] A block to test against. Must return a boolean.
112
+ # @raise [RuntimeError] Instance goes into failed state.
113
+ # @raise [RuntimeError] Timeout has been reached.
114
+ def wait_for!(sleep_time: 5, timeout: 600, &block)
115
+ @logger.info("Starting wait for instance #{id}. Starts in state #{status}.")
116
+ loop do
117
+ refresh
118
+ raise "VM #{id} is in a failed state." if failed?
119
+ break if block.call(self)
120
+
121
+ timeout = sleep_counter(sleep_time, timeout)
122
+ raise "Time out while waiting #{id} to be stable." if timeout <= 0
123
+ end
124
+ @logger.info("Finished wait for instance #{id}. Ends in state #{status}.")
125
+ end
126
+
127
+ # Wait for the VM instance to be have a started status.
128
+ # @param sleep_time [Integer] The time to sleep between refreshes.
129
+ # @param timeout [Integer] The number of seconds before raising an error.
130
+ # @raise [RuntimeError] Instance goes into failed state.
131
+ # @raise [RuntimeError] Timeout has been reached.
132
+ def wait_for_started!(sleep_time: 5, timeout: 600)
133
+ wait_for!(sleep_time: sleep_time, timeout: timeout, &:started?)
134
+ end
135
+
136
+ # Wait for the VM instance to be have a stopped status.
137
+ # @param sleep_time [Integer] The time to sleep between refreshes.
138
+ # @param timeout [Integer] The number of seconds before raising an error.
139
+ # @raise [RuntimeError] Instance goes into failed state.
140
+ # @raise [RuntimeError] Timeout has been reached.
141
+ def wait_for_stopped!(sleep_time: 5, timeout: 600)
142
+ wait_for!(sleep_time: sleep_time, timeout: timeout, &:stopped?)
143
+ end
144
+
145
+ private
146
+
147
+ # Sleep for the specificed time and decrement timout by that number.
148
+ # @return [Integer] The current timeout.
149
+ def sleep_counter(sleep_time, timeout)
150
+ sleep sleep_time
151
+ timeout - sleep_time
152
+ end
56
153
  end
57
154
  end
58
155
  end
@@ -22,7 +22,7 @@ module IBM
22
22
  # A single Connection
23
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
@@ -22,7 +22,7 @@ module IBM
22
22
  # A single Connection
23
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
@@ -10,47 +10,104 @@ module IBM
10
10
  module BaseHTTPMixin
11
11
  @connection = nil
12
12
 
13
- def adhoc(method: 'get', path: nil, params: {}, payload: {})
14
- unchecked_response(method: method, path: path, params: params, payload: payload).raise_for_status!
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!
15
23
  end
16
24
 
17
- def unchecked_response(method: 'get', path: nil, params: {}, payload: {})
18
- @connection.request(method.to_sym, url(path), metadata(params, payload))
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))
19
33
  end
20
34
 
21
- def get(path: nil, params: {})
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)
22
43
  adhoc(method: 'get', path: path, params: params)
23
44
  end
24
45
 
25
- attr_reader :endpoint
26
-
27
- def post(payload = {}, path: nil, params: {})
28
- adhoc(method: 'post', path: path, params: params, payload: payload)
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)
29
55
  end
30
56
 
31
- def put(payload = {}, path: nil, params: {})
32
- adhoc(method: 'put', path: path, params: params, payload: payload)
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)
33
66
  end
34
67
 
35
- def patch(payload = {}, path: nil, params: {})
36
- adhoc(method: 'patch', path: path, params: params, payload: payload)
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)
37
77
  end
38
78
 
39
- def delete(path: nil, params: {})
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)
40
85
  adhoc(method: 'delete', path: path, params: params)
41
86
  end
42
87
 
43
- def metadata(query = nil, payload = nil)
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')
44
94
  @params ||= {}
45
- query ||= {}
46
- payload ||= {}
47
- {
48
- query: @params.merge(query),
49
- body: payload,
95
+ @params.merge!(query) if query
96
+
97
+ send_parameters = {
98
+ query: @params,
50
99
  headers: { "Authorization": @token.authorization_header }
51
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
52
108
  end
53
109
 
110
+ # Merge path with current class's endpoint.
54
111
  def url(path = nil)
55
112
  return endpoint unless path
56
113
  return path if URI.parse(path).relative? == false
@@ -39,7 +39,7 @@ module IBM
39
39
 
40
40
  # Send an update to the server for this resource.
41
41
  def update(payload)
42
- patch(payload)
42
+ patch(payload: payload)
43
43
  end
44
44
 
45
45
  # Send a delete request to the server for this resource.
@@ -11,7 +11,13 @@ module IBM
11
11
  include HTTParty
12
12
 
13
13
  def initialize(logger)
14
- self.class.logger(logger, :debug, :curl)
14
+ @logger = logger
15
+ self.class.logger(logger, :debug, :apache)
16
+ end
17
+
18
+ # Set the logger type to curl which has more information.
19
+ def verbose_logger=(verbosity)
20
+ default_options[:log_format] = verbosity ? :curl : :apache
15
21
  end
16
22
 
17
23
  def default_options
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ibm-cloud-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - IBM Cloud Developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-10-08 00:00:00.000000000 Z
11
+ date: 2020-10-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rest-client
@@ -121,7 +121,7 @@ licenses:
121
121
  - '"Apache-2.0"'
122
122
  metadata:
123
123
  homepage_uri: https://github.com/IBM-Cloud/ibm-cloud-sdk-ruby
124
- changelog_uri: https://github.com/IBM-Cloud/ibm-cloud-sdk-ruby/blob/v0.1.10/CHANGELOG.md
124
+ changelog_uri: https://github.com/IBM-Cloud/ibm-cloud-sdk-ruby/blob/v0.1.11/CHANGELOG.md
125
125
  post_install_message:
126
126
  rdoc_options: []
127
127
  require_paths: