oneview-sdk 4.0.0 → 4.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +26 -0
- data/README.md +34 -11
- data/Rakefile +0 -1
- data/lib/oneview-sdk.rb +6 -4
- data/lib/oneview-sdk/cli.rb +2 -2
- data/lib/oneview-sdk/client.rb +33 -8
- data/lib/oneview-sdk/exceptions.rb +52 -16
- data/lib/oneview-sdk/image-streamer/client.rb +6 -3
- data/lib/oneview-sdk/image-streamer/resource/api300/artifact_bundle.rb +215 -0
- data/lib/oneview-sdk/image-streamer/resource/api300/build_plan.rb +10 -3
- data/lib/oneview-sdk/image-streamer/resource/api300/{artifacts_bundle.rb → deployment_group.rb} +21 -6
- data/lib/oneview-sdk/image-streamer/resource/api300/deployment_plan.rb +10 -3
- data/lib/oneview-sdk/image-streamer/resource/api300/golden_image.rb +121 -3
- data/lib/oneview-sdk/resource.rb +4 -4
- data/lib/oneview-sdk/resource/api200.rb +1 -1
- data/lib/oneview-sdk/resource/api200/firmware_bundle.rb +11 -4
- data/lib/oneview-sdk/resource/api200/volume_attachment.rb +1 -1
- data/lib/oneview-sdk/resource/api300.rb +1 -1
- data/lib/oneview-sdk/resource/api300/c7000/switch.rb +4 -4
- data/lib/oneview-sdk/rest.rb +80 -16
- data/lib/oneview-sdk/version.rb +1 -1
- data/oneview-sdk.gemspec +4 -4
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33d01d70d21a357c6e0c4f9295f039d874aea7b1
|
4
|
+
data.tar.gz: f5bd6ddea83a0124bf87c034b2107b7949a1004b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81644b00704bc889c5f62fbeb98fc2ef00fd7c0ba2a66631016aa867a298207bfc109eb904a8f404768779447f34b9f40a1cc17c3fb1efea46f2be3bd64811ae
|
7
|
+
data.tar.gz: d469232c518d22bc5ec52d828b929093a5bdac8a7d8ac12bbf647d4c1ca7f6be6f60ac817638e805d2d47dad578649e3ca7d4a310e9251a2bbdb34ab2c3304eb
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,30 @@
|
|
1
1
|
# Unreleased Changes
|
2
|
+
(none)
|
3
|
+
|
4
|
+
# v4.1.0
|
5
|
+
|
6
|
+
#### New Resources:
|
7
|
+
Added full support to Image Streamer Rest API version 300:
|
8
|
+
- Artifact Bundle
|
9
|
+
- Build Plan
|
10
|
+
- Deployment Group
|
11
|
+
- Deployment Plan
|
12
|
+
- Golden Image
|
13
|
+
- OS Volume
|
14
|
+
- Plan Script
|
15
|
+
|
16
|
+
#### Bug fixes & Enhancements:
|
17
|
+
- Give custom exception classes a data attribute for more error context and default message
|
18
|
+
- [#116](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/112) VolumeAttachment::remove_extra_unmanaged_volume throw Unexpected Http Error
|
19
|
+
- [#135](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/135) Firmware Bundle timeout does not give proper instructions for user post failure
|
20
|
+
- [#146](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/146) Why is Switch the only resource that directly implements #set_scope_uris?
|
21
|
+
- [#166](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/166) I3S - Simplify login to i3s through oneview client
|
22
|
+
- [#178](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/178) Add client destroy_session method and domain attribute
|
23
|
+
- [#174](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/174) I3S - Integration test for Build Plan failing
|
24
|
+
- [#176](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/176) OneviewSDK.resource_named now finds resources that are not children of Resource
|
25
|
+
- [#183](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/183) Image Streamer Client cannot be created with the OneView environment variables
|
26
|
+
- [#184](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/184) Coveralls badge showing coverage as unknown
|
27
|
+
- [#196](https://github.com/HewlettPackard/oneview-sdk-ruby/issues/196) Missing endpoint for extract backup in Artifact Bundle
|
2
28
|
|
3
29
|
# v4.0.0
|
4
30
|
|
data/README.md
CHANGED
@@ -1,17 +1,18 @@
|
|
1
1
|
# oneview-sdk for Ruby
|
2
2
|
[](https://badge.fury.io/rb/oneview-sdk)
|
3
|
+
[](http://www.rubydoc.info/gems/oneview-sdk)
|
3
4
|
|
5
|
+
[](https://travis-ci.org/HewlettPackard/oneview-sdk-ruby)
|
6
|
+
[](https://coveralls.io/github/HewlettPackard/oneview-sdk-ruby)
|
7
|
+
[](https://codeclimate.com/github/HewlettPackard/oneview-sdk-ruby)
|
4
8
|
|
5
9
|
The OneView SDK provides a Ruby library to easily interact with HPE OneView and Image Streamer APIs. The Ruby SDK enables developers to easily build integrations and scalable solutions with HPE OneView and Image Streamer.
|
6
10
|
|
7
|
-
Note that currently the Image Streamer resources are a work in progress, so should be treated as experimental.
|
8
|
-
Many of these resources are unimplemented, and all are subject to change in ways that are incompatible with current usage & docs.
|
9
|
-
|
10
11
|
## Installation
|
11
12
|
- Require the gem in your Gemfile:
|
12
13
|
|
13
14
|
```ruby
|
14
|
-
gem 'oneview-sdk', '~> 4.
|
15
|
+
gem 'oneview-sdk', '~> 4.1'
|
15
16
|
```
|
16
17
|
|
17
18
|
Then run `$ bundle install`
|
@@ -36,6 +37,7 @@ client = OneviewSDK::Client.new(
|
|
36
37
|
ssl_enabled: true, # This is the default and strongly encouraged
|
37
38
|
logger: Logger.new(STDOUT), # This is the default
|
38
39
|
log_level: :info, # This is the default
|
40
|
+
domain: 'LOCAL', # This is the default
|
39
41
|
api_version: 200 # Defaults to minimum of 200 and appliance's max API version
|
40
42
|
)
|
41
43
|
```
|
@@ -60,6 +62,19 @@ i3s_client = OneviewSDK::ImageStreamer::Client.new(
|
|
60
62
|
)
|
61
63
|
```
|
62
64
|
|
65
|
+
You can also create the i3s client through the Oneview client instance.
|
66
|
+
```ruby
|
67
|
+
# Create an Image Streamer client object through the Oneview client object:
|
68
|
+
require 'oneview-sdk'
|
69
|
+
i3s_client = client.new_i3s_client(
|
70
|
+
url: 'https://image-streamer.example.com',
|
71
|
+
ssl_enabled: true, # This is the default and strongly encouraged
|
72
|
+
logger: Logger.new(STDOUT), # This is the default
|
73
|
+
log_level: :info, # This is the default
|
74
|
+
api_version: 300 # Defaults to minimum of 300 and appliance's max API version
|
75
|
+
)
|
76
|
+
```
|
77
|
+
|
63
78
|
##### Environment Variables
|
64
79
|
|
65
80
|
You can also set many of the client attributes using environment variables. To set these variables in bash:
|
@@ -67,6 +82,7 @@ You can also set many of the client attributes using environment variables. To s
|
|
67
82
|
```bash
|
68
83
|
# OneView client options:
|
69
84
|
export ONEVIEWSDK_URL='https://oneview.example.com'
|
85
|
+
export ONEVIEWSDK_DOMAIN='LOCAL'
|
70
86
|
# You can set the token if you know it, or set the user and password to generate one:
|
71
87
|
export ONEVIEWSDK_TOKEN='xxxx...'
|
72
88
|
export ONEVIEWSDK_USER='Administrator'
|
@@ -76,7 +92,6 @@ export ONEVIEWSDK_SSL_ENABLED=false
|
|
76
92
|
|
77
93
|
# Image Streamer (I3S) client options:
|
78
94
|
export I3S_URL='https://image-streamer.example.com'
|
79
|
-
export I3S_TOKEN='xxxx...'
|
80
95
|
export I3S_SSL_ENABLED=false
|
81
96
|
# NOTE: Disabling SSL is strongly discouraged. Please see the CLI section for import instructions.
|
82
97
|
```
|
@@ -88,7 +103,18 @@ Then you can leave out these options from your config, enabling you to just do:
|
|
88
103
|
```ruby
|
89
104
|
require 'oneview-sdk'
|
90
105
|
client = OneviewSDK::Client.new
|
91
|
-
|
106
|
+
```
|
107
|
+
|
108
|
+
You can create the i3s client with environment variables in the following ways:
|
109
|
+
```ruby
|
110
|
+
require 'oneview-sdk'
|
111
|
+
# Note: Both options require the I3S_URL environment variable to be set.
|
112
|
+
|
113
|
+
# This way uses the ONEVIEWSDK_URL, ONEVIEWSDK_USER and ONEVIEWSDK_PASSWORD environment variables to generate a token:
|
114
|
+
client = OneviewSDK::Client.new
|
115
|
+
i3s_client = client.new_i3s_client
|
116
|
+
|
117
|
+
# This way uses the ONEVIEWSDK_TOKEN environment variable directly:
|
92
118
|
i3s_client = OneviewSDK::ImageStreamer::Client.new
|
93
119
|
```
|
94
120
|
|
@@ -152,7 +178,7 @@ OneviewSDK.api_version = 300
|
|
152
178
|
OneviewSDK.api_version # 300
|
153
179
|
OneviewSDK.api_version_updated? # true
|
154
180
|
|
155
|
-
# The API200 module has
|
181
|
+
# The API200 module has no variants, but API300 has 2 (C7000 & Synergy):
|
156
182
|
OneviewSDK::API300::SUPPORTED_VARIANTS # ['C7000', 'Synergy']
|
157
183
|
OneviewSDK::API300::DEFAULT_VARIANT # 'C7000'
|
158
184
|
OneviewSDK::API300.variant # 'C7000'
|
@@ -406,7 +432,4 @@ First run `$ bundle` (requires the bundler gem), then...
|
|
406
432
|
Note: run `$ rake -T` to get a list of all the available rake tasks.
|
407
433
|
|
408
434
|
## Authors
|
409
|
-
|
410
|
-
- Henrique Diomede - [@hdiomede](https://github.com/hdiomede)
|
411
|
-
- Thiago Miotto - [@tmiotto](https://github.com/tmiotto)
|
412
|
-
- Ricardo Piantola - [@piantola](https://github.com/piantola)
|
435
|
+
See the [contributors graph](https://github.com/HewlettPackard/oneview-sdk-ruby/graphs/contributors)
|
data/Rakefile
CHANGED
data/lib/oneview-sdk.rb
CHANGED
@@ -19,9 +19,9 @@ require_relative 'oneview-sdk/image_streamer'
|
|
19
19
|
|
20
20
|
# Module for interacting with the HPE OneView API
|
21
21
|
module OneviewSDK
|
22
|
-
env_sdk = %w(ONEVIEWSDK_URL ONEVIEWSDK_USER ONEVIEWSDK_PASSWORD ONEVIEWSDK_TOKEN)
|
22
|
+
env_sdk = %w(ONEVIEWSDK_URL ONEVIEWSDK_USER ONEVIEWSDK_PASSWORD ONEVIEWSDK_TOKEN ONEVIEWSDK_DOMAIN)
|
23
23
|
env_sdk.concat %w(ONEVIEWSDK_SSL_ENABLED ONEVIEWSDK_API_VERSION ONEVIEWSDK_VARIANT)
|
24
|
-
env_i3s = %w(I3S_URL
|
24
|
+
env_i3s = %w(I3S_URL I3S_SSL_ENABLED)
|
25
25
|
ENV_VARS = env_sdk.concat(env_i3s).freeze
|
26
26
|
|
27
27
|
SUPPORTED_API_VERSIONS = [200, 300].freeze
|
@@ -37,8 +37,10 @@ module OneviewSDK
|
|
37
37
|
# Set the default API version
|
38
38
|
def self.api_version=(version)
|
39
39
|
version = version.to_i rescue version
|
40
|
-
raise "API version #{version} is not supported!"
|
41
|
-
|
40
|
+
raise UnsupportedVersion, "API version #{version} is not supported!"\
|
41
|
+
unless SUPPORTED_API_VERSIONS.include?(version)
|
42
|
+
raise UnsupportedVariant, "The module for API version #{@api_version} is undefined"\
|
43
|
+
unless constants.include?("API#{@api_version}".to_sym)
|
42
44
|
@api_version_updated = true
|
43
45
|
@api_version = version
|
44
46
|
end
|
data/lib/oneview-sdk/cli.rb
CHANGED
@@ -466,13 +466,13 @@ module OneviewSDK
|
|
466
466
|
r = OneviewSDK.resource_named(type, api_ver, variant)
|
467
467
|
# Try default API version as last resort
|
468
468
|
r ||= OneviewSDK.resource_named(type, OneviewSDK.api_version, variant) unless api_ver == OneviewSDK.api_version
|
469
|
-
return r if r
|
469
|
+
return r if r && r.respond_to?(:find_by)
|
470
470
|
valid_classes = []
|
471
471
|
api_module = OneviewSDK.const_get("API#{api_ver}")
|
472
472
|
api_module = api_module.const_get(variant.to_s) unless api_ver.to_i == 200
|
473
473
|
api_module.constants.each do |c|
|
474
474
|
klass = api_module.const_get(c)
|
475
|
-
next unless klass.is_a?(Class) && klass
|
475
|
+
next unless klass.is_a?(Class) && klass.respond_to?(:find_by)
|
476
476
|
valid_classes.push(klass.name.split('::').last)
|
477
477
|
end
|
478
478
|
vc = valid_classes.sort_by!(&:downcase).join("\n ")
|
data/lib/oneview-sdk/client.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# (
|
1
|
+
# (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
#
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
5
|
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software distributed
|
@@ -18,7 +18,7 @@ module OneviewSDK
|
|
18
18
|
# The client defines the connection to the OneView server and handles communication with it.
|
19
19
|
class Client
|
20
20
|
attr_reader :max_api_version
|
21
|
-
attr_accessor :url, :user, :token, :password, :ssl_enabled, :api_version, \
|
21
|
+
attr_accessor :url, :user, :token, :password, :domain, :ssl_enabled, :api_version, \
|
22
22
|
:logger, :log_level, :cert_store, :print_wait_dots, :timeout
|
23
23
|
|
24
24
|
include Rest
|
@@ -32,6 +32,7 @@ module OneviewSDK
|
|
32
32
|
# @option options [String] :url URL of OneView appliance
|
33
33
|
# @option options [String] :user ('Administrator') The username to use for authentication with the OneView appliance
|
34
34
|
# @option options [String] :password (ENV['ONEVIEWSDK_PASSWORD']) The password to use for authentication with OneView appliance
|
35
|
+
# @option options [String] :domain ('LOCAL') The name of the domain directory used for authentication
|
35
36
|
# @option options [String] :token (ENV['ONEVIEWSDK_TOKEN']) The token to use for authentication with OneView appliance
|
36
37
|
# Use the token or the username and password (not both). The token has precedence.
|
37
38
|
# @option options [Integer] :api_version (200) This is the API version to use by default for requests
|
@@ -65,12 +66,12 @@ module OneviewSDK
|
|
65
66
|
@timeout = options[:timeout] unless options[:timeout].nil?
|
66
67
|
@cert_store = OneviewSDK::SSLHelper.load_trusted_certs if @ssl_enabled
|
67
68
|
@token = options[:token] || ENV['ONEVIEWSDK_TOKEN']
|
68
|
-
|
69
|
-
@logger.warn 'User option not set. Using default (Administrator)' unless options[:user] || ENV['ONEVIEWSDK_USER']
|
69
|
+
@logger.warn 'User option not set. Using default (Administrator)' unless @token || options[:user] || ENV['ONEVIEWSDK_USER']
|
70
70
|
@user = options[:user] || ENV['ONEVIEWSDK_USER'] || 'Administrator'
|
71
71
|
@password = options[:password] || ENV['ONEVIEWSDK_PASSWORD']
|
72
|
-
raise InvalidClient, 'Must set user & password options or token option' unless @password
|
73
|
-
@
|
72
|
+
raise InvalidClient, 'Must set user & password options or token option' unless @token || @password
|
73
|
+
@domain = options[:domain] || ENV['ONEVIEWSDK_DOMAIN'] || 'LOCAL'
|
74
|
+
@token ||= login
|
74
75
|
end
|
75
76
|
|
76
77
|
def log_level=(level)
|
@@ -157,6 +158,30 @@ module OneviewSDK
|
|
157
158
|
self
|
158
159
|
end
|
159
160
|
|
161
|
+
# Delete the session on the appliance, invalidating the client's token.
|
162
|
+
# To generate a new token after calling this method, use the refresh_login method.
|
163
|
+
# Call this after a token expires or the user and/or password is updated on the client object.
|
164
|
+
# @return [OneviewSDK::Client] self
|
165
|
+
def destroy_session
|
166
|
+
response_handler(rest_delete('/rest/login-sessions'))
|
167
|
+
self
|
168
|
+
end
|
169
|
+
|
170
|
+
# Creates the image streamer client object.
|
171
|
+
# @param [Hash] options the options to configure the client
|
172
|
+
# @option options [Logger] :logger (Logger.new(STDOUT)) Logger object to use.
|
173
|
+
# Must implement debug(String), info(String), warn(String), error(String), & level=
|
174
|
+
# @option options [Symbol] :log_level (:info) Log level. Logger must define a constant with this name. ie Logger::INFO
|
175
|
+
# @option options [Boolean] :print_wait_dots (false) When true, prints status dots while waiting on the tasks to complete.
|
176
|
+
# @option options [String] :url URL of Image Streamer
|
177
|
+
# @option options [Integer] :api_version (300) This is the API version to use by default for requests
|
178
|
+
# @option options [Boolean] :ssl_enabled (true) Use ssl for requests? Respects ENV['I3S_SSL_ENABLED']
|
179
|
+
# @option options [Integer] :timeout (nil) Override the default request timeout value
|
180
|
+
# @return [OneviewSDK::ImageStreamer::Client] New instance of image streamer client
|
181
|
+
def new_i3s_client(options = {})
|
182
|
+
OneviewSDK::ImageStreamer::Client.new(options.merge(token: @token))
|
183
|
+
end
|
184
|
+
|
160
185
|
|
161
186
|
private
|
162
187
|
|
@@ -179,7 +204,7 @@ module OneviewSDK
|
|
179
204
|
'body' => {
|
180
205
|
'userName' => @user,
|
181
206
|
'password' => @password,
|
182
|
-
'authLoginDomain' =>
|
207
|
+
'authLoginDomain' => @domain
|
183
208
|
}
|
184
209
|
}
|
185
210
|
response = rest_post('/rest/login-sessions', options)
|
@@ -1,7 +1,7 @@
|
|
1
|
-
# (
|
1
|
+
# (c) Copyright 2016-2017 Hewlett Packard Enterprise Development LP
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
#
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
5
|
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
6
|
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software distributed
|
@@ -11,45 +11,81 @@
|
|
11
11
|
|
12
12
|
# Contains all the custom Exception classes
|
13
13
|
module OneviewSDK
|
14
|
-
|
14
|
+
# Error class allowing storage of a data attribute
|
15
|
+
class OneViewError < ::StandardError
|
16
|
+
attr_accessor :data
|
17
|
+
MESSAGE = '(No message)'.freeze
|
18
|
+
|
19
|
+
def initialize(msg = self.class::MESSAGE, data = nil)
|
20
|
+
@data = data
|
21
|
+
super(msg)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Shorthand method to raise an error.
|
25
|
+
# @example
|
26
|
+
# OneviewSDK::OneViewError.raise! 'Message', { data: 'stuff' }
|
27
|
+
def self.raise!(msg = self::MESSAGE, data = nil)
|
28
|
+
raise new(msg, data)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class ConnectionError < OneViewError # Cannot connect to client/resource
|
33
|
+
MESSAGE = 'Cannot connect to client/resource'.freeze
|
34
|
+
end
|
35
|
+
|
36
|
+
class InvalidURL < OneViewError # URL is invalid
|
37
|
+
MESSAGE = 'URL is invalid'.freeze
|
15
38
|
end
|
16
39
|
|
17
|
-
class
|
40
|
+
class InvalidClient < OneViewError # Client configuration is invalid
|
41
|
+
MESSAGE = 'Client configuration is invalid'.freeze
|
18
42
|
end
|
19
43
|
|
20
|
-
class
|
44
|
+
class InvalidResource < OneViewError # Failed resource validations
|
45
|
+
MESSAGE = 'Failed resource validations'.freeze
|
21
46
|
end
|
22
47
|
|
23
|
-
class
|
48
|
+
class IncompleteResource < OneViewError # Missing required resource data to complete action
|
49
|
+
MESSAGE = 'Missing required resource data to complete action'.freeze
|
24
50
|
end
|
25
51
|
|
26
|
-
class
|
52
|
+
class MethodUnavailable < OneViewError # Resource does not support this method
|
53
|
+
MESSAGE = 'Resource does not support this method'.freeze
|
27
54
|
end
|
28
55
|
|
29
|
-
class
|
56
|
+
class UnsupportedVariant < OneViewError # Variant is not supported
|
57
|
+
MESSAGE = 'Variant is not supported'.freeze
|
30
58
|
end
|
31
59
|
|
32
|
-
class UnsupportedVersion <
|
60
|
+
class UnsupportedVersion < OneViewError # Resource not supported on this API version
|
61
|
+
MESSAGE = 'Resource not supported on this API version'.freeze
|
33
62
|
end
|
34
63
|
|
35
|
-
class InvalidRequest <
|
64
|
+
class InvalidRequest < OneViewError # Could not make request
|
65
|
+
MESSAGE = 'Could not make request'.freeze
|
36
66
|
end
|
37
67
|
|
38
|
-
class BadRequest <
|
68
|
+
class BadRequest < OneViewError # 400
|
69
|
+
MESSAGE = '400'.freeze
|
39
70
|
end
|
40
71
|
|
41
|
-
class Unauthorized <
|
72
|
+
class Unauthorized < OneViewError # 401
|
73
|
+
MESSAGE = '401'.freeze
|
42
74
|
end
|
43
75
|
|
44
|
-
class NotFound <
|
76
|
+
class NotFound < OneViewError # 404
|
77
|
+
MESSAGE = '404'.freeze
|
45
78
|
end
|
46
79
|
|
47
|
-
class RequestError <
|
80
|
+
class RequestError < OneViewError # Other bad response codes
|
81
|
+
MESSAGE = 'Bad response code'.freeze
|
48
82
|
end
|
49
83
|
|
50
|
-
class TaskError <
|
84
|
+
class TaskError < OneViewError # Task ended in a bad state
|
85
|
+
MESSAGE = 'Task ended in a bad state'.freeze
|
51
86
|
end
|
52
87
|
|
53
|
-
class InvalidFormat <
|
88
|
+
class InvalidFormat < OneViewError # File format is invalid
|
89
|
+
MESSAGE = 'File format is invalid'.freeze
|
54
90
|
end
|
55
91
|
end
|
@@ -19,7 +19,10 @@ module OneviewSDK
|
|
19
19
|
undef :user=
|
20
20
|
undef :password
|
21
21
|
undef :password=
|
22
|
+
undef :domain
|
23
|
+
undef :domain=
|
22
24
|
undef :refresh_login
|
25
|
+
undef :destroy_session
|
23
26
|
|
24
27
|
# Creates client object, establish connection, and set up logging and api version.
|
25
28
|
# @param [Hash] options the options to configure the client
|
@@ -28,7 +31,7 @@ module OneviewSDK
|
|
28
31
|
# @option options [Symbol] :log_level (:info) Log level. Logger must define a constant with this name. ie Logger::INFO
|
29
32
|
# @option options [Boolean] :print_wait_dots (false) When true, prints status dots while waiting on the tasks to complete.
|
30
33
|
# @option options [String] :url URL of Image Streamer
|
31
|
-
# @option options [String] :token (ENV['
|
34
|
+
# @option options [String] :token (ENV['ONEVIEWSDK_TOKEN']) The token to use for authentication
|
32
35
|
# @option options [Integer] :api_version (300) This is the API version to use by default for requests
|
33
36
|
# @option options [Boolean] :ssl_enabled (true) Use ssl for requests? Respects ENV['I3S_SSL_ENABLED']
|
34
37
|
# @option options [Integer] :timeout (nil) Override the default request timeout value
|
@@ -60,8 +63,8 @@ module OneviewSDK
|
|
60
63
|
@ssl_enabled = options[:ssl_enabled] unless options[:ssl_enabled].nil?
|
61
64
|
@timeout = options[:timeout] unless options[:timeout].nil?
|
62
65
|
@cert_store = OneviewSDK::SSLHelper.load_trusted_certs if @ssl_enabled
|
63
|
-
raise InvalidClient, 'Must set token option' unless options[:token] || ENV['
|
64
|
-
@token = options[:token] || ENV['
|
66
|
+
raise InvalidClient, 'Must set token option' unless options[:token] || ENV['ONEVIEWSDK_TOKEN']
|
67
|
+
@token = options[:token] || ENV['ONEVIEWSDK_TOKEN']
|
65
68
|
end
|
66
69
|
|
67
70
|
# Get array of all resources of a specified type
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# (C) Copyright 2017 Hewlett Packard Enterprise Development LP
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# You may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software distributed
|
8
|
+
# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
9
|
+
# CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
|
10
|
+
# language governing permissions and limitations under the License.
|
11
|
+
|
12
|
+
require_relative 'resource'
|
13
|
+
|
14
|
+
module OneviewSDK
|
15
|
+
module ImageStreamer
|
16
|
+
module API300
|
17
|
+
# Artifacts Bundle resource implementation for Image Streamer
|
18
|
+
class ArtifactBundle < Resource
|
19
|
+
ACCEPTED_FORMATS = %w(.zip .ZIP).freeze # Supported upload extensions
|
20
|
+
|
21
|
+
BASE_URI = '/rest/artifact-bundles'.freeze
|
22
|
+
BACKUPS_URI = "#{BASE_URI}/backups".freeze
|
23
|
+
BACKUPS_ARCHIVE_URI = "#{BACKUPS_URI}/archive".freeze
|
24
|
+
|
25
|
+
# Create a resource object, associate it with a client, and set its properties.
|
26
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
27
|
+
# @param [Hash] params The options for this resource (key-value pairs)
|
28
|
+
# @param [Integer] api_ver The api version to use when interracting with this resource.
|
29
|
+
def initialize(client, params = {}, api_ver = nil)
|
30
|
+
super
|
31
|
+
@data['buildPlans'] ||= []
|
32
|
+
@data['planScripts'] ||= []
|
33
|
+
@data['deploymentPlans'] ||= []
|
34
|
+
@data['goldenImages'] ||= []
|
35
|
+
end
|
36
|
+
|
37
|
+
# Creates an artifact bundle resource from the file that is uploaded from admin's local drive
|
38
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
39
|
+
# @param [String] file_path The file path with file extension
|
40
|
+
# @param [String] artifact_name The name for the artifact that will be created
|
41
|
+
# @param [Integer] timeout The number of seconds to wait for completing the request. Default is 300.
|
42
|
+
# @return [OneviewSDK::ImageStreamer::API300::ArtifactBundle] if the upload was successful, return a ArtifactBundle object
|
43
|
+
def self.create_from_file(client, file_path, artifact_name, timeout = OneviewSDK::Rest::READ_TIMEOUT)
|
44
|
+
ensure_file_path_extension!(file_path)
|
45
|
+
|
46
|
+
file_name = artifact_name.dup
|
47
|
+
if file_name && !file_name.empty?
|
48
|
+
file_name += File.extname(file_path)
|
49
|
+
else
|
50
|
+
file_name = File.basename(file_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
params = { 'name' => file_name }
|
54
|
+
body = client.upload_file(file_path, BASE_URI, params, timeout)
|
55
|
+
ArtifactBundle.new(client, body)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Gets the backup bundles created
|
59
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
60
|
+
# @return [Array<ArtifactBundle>] Array of ArtifactBundle
|
61
|
+
def self.get_backups(client)
|
62
|
+
find_by(client, {}, BACKUPS_URI)
|
63
|
+
end
|
64
|
+
|
65
|
+
# Creates a backup bundle with all the artifacts present on the appliance.
|
66
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
67
|
+
# @param [DeploymentGroup] deployment_group The DeploymentGroup with name or uri
|
68
|
+
# @return [Hash] The result hash with DeploymentGroup data
|
69
|
+
def self.create_backup(client, deployment_group)
|
70
|
+
ensure_resource!(deployment_group)
|
71
|
+
response = client.rest_post(BACKUPS_URI, 'body' => { 'deploymentGroupURI' => deployment_group['uri'] })
|
72
|
+
client.response_handler(response)
|
73
|
+
end
|
74
|
+
|
75
|
+
# Creates a backup bundle from the zip file and extract all the artifacts present in the uploaded file
|
76
|
+
# If there are any artifacts existing, they will be removed before the extract operation.
|
77
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
78
|
+
# @param [String] file_path The file path with file extension
|
79
|
+
# @param [String] artifact_name The name for the artifact that will be created
|
80
|
+
# @param [Integer] timeout The number of seconds to wait for completing the request. Default is 300.
|
81
|
+
# @return [Hash] The result hash with DeploymentGroup data
|
82
|
+
def self.create_backup_from_file!(client, deployment_group, file_path, artifact_name, timeout = OneviewSDK::Rest::READ_TIMEOUT)
|
83
|
+
ensure_resource!(deployment_group)
|
84
|
+
ensure_file_path_extension!(file_path)
|
85
|
+
|
86
|
+
file_name = artifact_name.dup
|
87
|
+
if file_name && !file_name.empty?
|
88
|
+
file_name += File.extname(file_path)
|
89
|
+
else
|
90
|
+
file_name = File.basename(file_path)
|
91
|
+
end
|
92
|
+
|
93
|
+
params = { 'name' => file_name, 'deploymentGrpUri' => deployment_group['uri'] }
|
94
|
+
client.upload_file(file_path, BACKUPS_ARCHIVE_URI, params, timeout)
|
95
|
+
end
|
96
|
+
|
97
|
+
# Download the backup bundle
|
98
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
99
|
+
# @param [String] local_drive_path The path where file will be saved
|
100
|
+
# @param [ArtifactBundle] bundle_backup The backup ArtifactBundle with 'downloadURI'
|
101
|
+
# @return [Boolean] true if backup was downloaded
|
102
|
+
def self.download_backup(client, local_drive_path, bundle_backup)
|
103
|
+
raise IncompleteResource, "Missing required attribute 'downloadURI'" unless bundle_backup['downloadURI']
|
104
|
+
client.download_file(bundle_backup['downloadURI'], local_drive_path)
|
105
|
+
end
|
106
|
+
|
107
|
+
# Extracts the existing backup bundle on the appliance and creates all the artifacts.
|
108
|
+
# If there are any artifacts existing, they will be removed before the extract operation.
|
109
|
+
# @param [DeploymentGroup] deployment_group The DeploymentGroup with 'name' or 'uri'
|
110
|
+
# @param [ArtifactBundle] bundle_backup The backup ArtifactBundle with 'uri'
|
111
|
+
# @return [Boolean] true if backup bundle was extracted
|
112
|
+
# @raise [OneviewSDK::IncompleteResource] if the client or uri is not set
|
113
|
+
def self.extract_backup(client, deployment_group, bundle_backup)
|
114
|
+
ensure_resource!(deployment_group)
|
115
|
+
raise IncompleteResource, "Missing required attribute 'uri' of backup bundle" unless bundle_backup['uri']
|
116
|
+
id = bundle_backup['uri'].split('/').last
|
117
|
+
response = client.rest_put("#{BACKUPS_URI}/#{id}", 'body' => { 'deploymentGroupURI' => deployment_group['uri'] })
|
118
|
+
client.response_handler(response)
|
119
|
+
true
|
120
|
+
end
|
121
|
+
|
122
|
+
# Method is not available
|
123
|
+
# @raise [OneviewSDK::MethodUnavailable] method is not available
|
124
|
+
def update(*)
|
125
|
+
unavailable_method
|
126
|
+
end
|
127
|
+
|
128
|
+
# Update the name of Artifact Bundle
|
129
|
+
# @param [String] new_name Name to update the Artifact Bundle
|
130
|
+
# @return [Boolean] true if name was updated
|
131
|
+
# @raise [OneviewSDK::IncompleteResource] if the client or uri is not set
|
132
|
+
def update_name(new_name)
|
133
|
+
ensure_uri
|
134
|
+
response = @client.rest_put(@data['uri'], 'body' => { 'name' => new_name, 'type' => 'ArtifactsBundle' })
|
135
|
+
@client.response_handler(response)
|
136
|
+
@data['name'] = new_name
|
137
|
+
true
|
138
|
+
end
|
139
|
+
|
140
|
+
# Extracts the artifact bundle and creates the artifacts on the appliance
|
141
|
+
# @param [Boolean] force Forces the extract operation even when there are any conflicts
|
142
|
+
# @return [Boolean] true if artifact bundle was extracted
|
143
|
+
# @raise [OneviewSDK::IncompleteResource] if the client or uri is not set
|
144
|
+
def extract(force = true)
|
145
|
+
ensure_uri
|
146
|
+
options = { 'Content-Type' => 'text/plain' }
|
147
|
+
response = @client.rest_put(@data['uri'] + "?extract=true&forceImport=#{force}", options)
|
148
|
+
@client.response_handler(response)
|
149
|
+
true
|
150
|
+
end
|
151
|
+
|
152
|
+
# Downloads the content of the selected artifact bundle to the admin's local drive.
|
153
|
+
# @param [String] local_drive_path Path to save file downloaded
|
154
|
+
# @return [Boolean] true if the file was downloaded
|
155
|
+
def download(local_drive_path)
|
156
|
+
raise IncompleteResource, "Missing required attribute 'downloadURI'" unless @data['downloadURI']
|
157
|
+
client.download_file(@data['downloadURI'], local_drive_path)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Add a Build Plan to this ArtifactBundle
|
161
|
+
# @param [OneviewSDK::ImageStreamer::API300::BuildPlan] resource The BuildPlan resource with uri
|
162
|
+
# @param [TrueClass, FalseClass] read_only Indicates whether the BuildPlan will be readonly in artifact bundle package
|
163
|
+
# @raise [RuntimeError] if the BuildPlan uri is not set or it is not valid
|
164
|
+
def add_build_plan(resource, read_only = true)
|
165
|
+
add_resource(resource, 'buildPlans', read_only)
|
166
|
+
end
|
167
|
+
|
168
|
+
# Add a Plan Script to this ArtifactBundle
|
169
|
+
# @param [OneviewSDK::ImageStreamer::API300::PlanScript] resource The PlanScripts resource with uri
|
170
|
+
# @param [TrueClass, FalseClass] read_only Indicates whether the PlanScripts will be readonly in artifact bundle package
|
171
|
+
# @raise [RuntimeError] if the PlanScripts uri is not set or it is not valid
|
172
|
+
def add_plan_script(resource, read_only = true)
|
173
|
+
add_resource(resource, 'planScripts', read_only)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Add a Deployment Plan to this ArtifactBundle
|
177
|
+
# @param [OneviewSDK::ImageStreamer::API300::DeploymentPlans] resource The DeploymentPlans resource with uri
|
178
|
+
# @param [TrueClass, FalseClass] read_only Indicates whether the DeploymentPlans will be readonly in artifact bundle package
|
179
|
+
# @raise [RuntimeError] if the DeploymentPlans uri is not set or it is not valid
|
180
|
+
def add_deployment_plan(resource, read_only = true)
|
181
|
+
add_resource(resource, 'deploymentPlans', read_only)
|
182
|
+
end
|
183
|
+
|
184
|
+
# Add a Golden Image to this ArtifactBundle
|
185
|
+
# @param [OneviewSDK::ImageStreamer::API300::GoldenImage] resource The GoldenImage resource with uri
|
186
|
+
# @param [TrueClass, FalseClass] read_only Indicates whether the GoldenImage will be readonly in artifact bundle package
|
187
|
+
# @raise [RuntimeError] if the GoldenImage uri is not set or it is not valid
|
188
|
+
def add_golden_image(resource, read_only = true)
|
189
|
+
add_resource(resource, 'goldenImages', read_only)
|
190
|
+
end
|
191
|
+
|
192
|
+
# Fail unless resource can be retrieved
|
193
|
+
def self.ensure_resource!(resource)
|
194
|
+
raise IncompleteResource, "The resource #{resource.class} can not be retrieved. Ensure it can be retrieved." unless resource.retrieve!
|
195
|
+
end
|
196
|
+
|
197
|
+
# Fail unless file extension of file_path is in ACCEPTED_FORMATS array
|
198
|
+
def self.ensure_file_path_extension!(file_path)
|
199
|
+
raise InvalidFormat, "File extension should be #{ACCEPTED_FORMATS}" unless ACCEPTED_FORMATS.include?(File.extname(file_path))
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
# Add resource data to data hash
|
205
|
+
# @param [OneviewSDK::Resource] resource The resource with uri
|
206
|
+
# @param [String] key_name The hash key of data hash
|
207
|
+
# @param [TrueClass, FalseClass] read_only The value of readOnly attribute
|
208
|
+
def add_resource(resource, key_name, read_only)
|
209
|
+
self.class.ensure_resource!(resource)
|
210
|
+
@data[key_name] << { 'resourceUri' => resource['uri'], 'readOnly' => read_only }
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -15,11 +15,18 @@ module OneviewSDK
|
|
15
15
|
module ImageStreamer
|
16
16
|
module API300
|
17
17
|
# Build Plan resource implementation for Image Streamer
|
18
|
-
# @note This resource is unimplemented/unfinished at this point, so use at your own risk.
|
19
|
-
# This resource is subject to change drastically in the near future without a major version
|
20
|
-
# bump, which may break your code.
|
21
18
|
class BuildPlan < Resource
|
22
19
|
BASE_URI = '/rest/build-plans'.freeze
|
20
|
+
|
21
|
+
# Create a resource object, associate it with a client, and set its properties.
|
22
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
23
|
+
# @param [Hash] params The options for this resource (key-value pairs)
|
24
|
+
# @param [Integer] api_ver The api version to use when interracting with this resource.
|
25
|
+
def initialize(client, params = {}, api_ver = nil)
|
26
|
+
super
|
27
|
+
# Default values:
|
28
|
+
@data['type'] ||= 'OeBuildPlan'
|
29
|
+
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
data/lib/oneview-sdk/image-streamer/resource/api300/{artifacts_bundle.rb → deployment_group.rb}
RENAMED
@@ -14,12 +14,27 @@ require_relative 'resource'
|
|
14
14
|
module OneviewSDK
|
15
15
|
module ImageStreamer
|
16
16
|
module API300
|
17
|
-
#
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
17
|
+
# Deployment Group resource implementation for Image Streamer
|
18
|
+
class DeploymentGroup < Resource
|
19
|
+
BASE_URI = '/rest/deployment-groups'.freeze
|
20
|
+
|
21
|
+
# Method is not available
|
22
|
+
# @raise [OneviewSDK::MethodUnavailable] method is not available
|
23
|
+
def create(*)
|
24
|
+
unavailable_method
|
25
|
+
end
|
26
|
+
|
27
|
+
# Method is not available
|
28
|
+
# @raise [OneviewSDK::MethodUnavailable] method is not available
|
29
|
+
def update(*)
|
30
|
+
unavailable_method
|
31
|
+
end
|
32
|
+
|
33
|
+
# Method is not available
|
34
|
+
# @raise [OneviewSDK::MethodUnavailable] method is not available
|
35
|
+
def delete(*)
|
36
|
+
unavailable_method
|
37
|
+
end
|
23
38
|
end
|
24
39
|
end
|
25
40
|
end
|
@@ -15,11 +15,18 @@ module OneviewSDK
|
|
15
15
|
module ImageStreamer
|
16
16
|
module API300
|
17
17
|
# Deployment Plan resource implementation for Image Streamer
|
18
|
-
# @note This resource is unimplemented/unfinished at this point, so use at your own risk.
|
19
|
-
# This resource is subject to change drastically in the near future without a major version
|
20
|
-
# bump, which may break your code.
|
21
18
|
class DeploymentPlan < Resource
|
22
19
|
BASE_URI = '/rest/deployment-plans'.freeze
|
20
|
+
|
21
|
+
# Create a resource object, associate it with a client, and set its properties.
|
22
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
23
|
+
# @param [Hash] params The options for this resource (key-value pairs)
|
24
|
+
# @param [Integer] api_ver The api version to use when interracting with this resource.
|
25
|
+
def initialize(client, params = {}, api_ver = nil)
|
26
|
+
super
|
27
|
+
# Default values:
|
28
|
+
@data['type'] ||= 'OEDeploymentPlan'
|
29
|
+
end
|
23
30
|
end
|
24
31
|
end
|
25
32
|
end
|
@@ -10,16 +10,134 @@
|
|
10
10
|
# language governing permissions and limitations under the License.
|
11
11
|
|
12
12
|
require_relative 'resource'
|
13
|
+
require 'net/http/post/multipart'
|
13
14
|
|
14
15
|
module OneviewSDK
|
15
16
|
module ImageStreamer
|
16
17
|
module API300
|
17
18
|
# Golden Image resource implementation for Image Streamer
|
18
|
-
# @note This resource is unimplemented/unfinished at this point, so use at your own risk.
|
19
|
-
# This resource is subject to change drastically in the near future without a major version
|
20
|
-
# bump, which may break your code.
|
21
19
|
class GoldenImage < Resource
|
22
20
|
BASE_URI = '/rest/golden-images'.freeze
|
21
|
+
READ_TIMEOUT = 300 # in seconds (5 minutes)
|
22
|
+
ACCEPTED_FORMATS = %w(.zip .ZIP).freeze # Supported upload extensions
|
23
|
+
|
24
|
+
# Create a resource object, associate it with a client, and set its properties.
|
25
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
26
|
+
# @param [Hash] params The options for this resource (key-value pairs)
|
27
|
+
# @param [Integer] api_ver The api version to use when interracting with this resource.
|
28
|
+
def initialize(client, params = {}, api_ver = nil)
|
29
|
+
super
|
30
|
+
# Default values:
|
31
|
+
@data['type'] ||= 'GoldenImage'
|
32
|
+
end
|
33
|
+
|
34
|
+
# Download the details of the golden image capture logs which has been archived based on the specific attribute ID.
|
35
|
+
# @param [String] file_path
|
36
|
+
# @return [True] When was saved successfully
|
37
|
+
def download_details_archive(file_path)
|
38
|
+
ensure_client && ensure_uri
|
39
|
+
resp = @client.rest_api(:get, "#{BASE_URI}/archive/#{@data['uri'].split('/').last}")
|
40
|
+
File.open(file_path, 'wb') { |file| file.write(resp.body) }
|
41
|
+
true
|
42
|
+
end
|
43
|
+
|
44
|
+
# Downloads the content of the selected golden image to the specified file path.
|
45
|
+
# @param [String] file_path
|
46
|
+
# @param [Integer] timeout The number of seconds to wait for the request to complete
|
47
|
+
# @return [True] When was saved successfully
|
48
|
+
def download(file_path, timeout = READ_TIMEOUT)
|
49
|
+
ensure_client && ensure_uri
|
50
|
+
uri = URI.parse(URI.escape("#{client.url}#{BASE_URI}/download/#{@data['uri'].split('/').last}"))
|
51
|
+
req = Net::HTTP::Get.new(uri.request_uri)
|
52
|
+
|
53
|
+
options = {}
|
54
|
+
options['Content-Type'] = 'application/json'
|
55
|
+
options['X-Api-Version'] = @client.api_version.to_s
|
56
|
+
options['auth'] = @client.token
|
57
|
+
options.each do |key, val|
|
58
|
+
req[key] = val
|
59
|
+
end
|
60
|
+
|
61
|
+
http_request = Net::HTTP.new(uri.host, uri.port)
|
62
|
+
http_request.use_ssl = true
|
63
|
+
http_request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
64
|
+
http_request.read_timeout = timeout
|
65
|
+
|
66
|
+
http_request.start do |http|
|
67
|
+
http.request(req) do |res|
|
68
|
+
client.response_handler(res) unless res.code.to_i.between?(200, 204)
|
69
|
+
File.open(file_path, 'wb') do |file|
|
70
|
+
res.read_body do |segment|
|
71
|
+
file.write(segment)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
true
|
77
|
+
end
|
78
|
+
|
79
|
+
# Upload a golden image from the specified local file path.
|
80
|
+
# Only the .zip format file can be used for upload.
|
81
|
+
# @param [OneviewSDK::ImageStreamer::Client] client The client object for the Image Streamer appliance
|
82
|
+
# @param [String] file_path
|
83
|
+
# @param [Hash] data_options Attributes of the golden image, passed in the request
|
84
|
+
# @option data_options [String] :name The name of the Golden Image (required)
|
85
|
+
# @option data_options [String] :description The description of the Golden Image (required)
|
86
|
+
# @param [Integer] timeout The number of seconds to wait for the request to complete
|
87
|
+
# @return [OneviewSDK::ImageStreamer::API300::GoldenImage] if the upload was successful, return a GoldenImage object
|
88
|
+
def self.add(client, file_path, data_options, timeout = READ_TIMEOUT)
|
89
|
+
data_options = Hash[data_options.map { |k, v| [k.to_s, v] }] # Convert symbols hash keys to string
|
90
|
+
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
|
91
|
+
raise InvalidFormat, 'ERROR: File with extension not supported!' unless ACCEPTED_FORMATS.include? File.extname(file_path)
|
92
|
+
raise IncompleteResource, 'Please set the name of the golden image!' unless data_options['name']
|
93
|
+
raise IncompleteResource, 'Please set the description of the golden image!' unless data_options['description']
|
94
|
+
options = {}
|
95
|
+
options['Content-Type'] = 'multipart/form-data'
|
96
|
+
options['X-Api-Version'] = client.api_version.to_s
|
97
|
+
options['auth'] = client.token
|
98
|
+
options['file'] = File.basename(file_path)
|
99
|
+
url = URI.parse(URI.escape("#{client.url}#{BASE_URI}"))
|
100
|
+
|
101
|
+
File.open(file_path) do |file|
|
102
|
+
req = Net::HTTP::Post::Multipart.new(
|
103
|
+
url.path,
|
104
|
+
{ 'file' => UploadIO.new(file, 'application/octet-stream', File.basename(file_path)) }.merge(data_options),
|
105
|
+
options
|
106
|
+
)
|
107
|
+
|
108
|
+
http_request = Net::HTTP.new(url.host, url.port)
|
109
|
+
http_request.use_ssl = true if url.scheme == 'https'
|
110
|
+
if client.ssl_enabled
|
111
|
+
http_request.cert_store = client.cert_store if client.cert_store
|
112
|
+
else http_request.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
113
|
+
end
|
114
|
+
http_request.read_timeout = timeout
|
115
|
+
|
116
|
+
http_request.start do |http|
|
117
|
+
response = http.request(req)
|
118
|
+
data = client.response_handler(response)
|
119
|
+
return OneviewSDK::ImageStreamer::API300::GoldenImage.new(client, data)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Sets the OS volume
|
125
|
+
# @param [OneviewSDK::ImageStreamer::API300::OSVolume] os_volume
|
126
|
+
# @raise [OneviewSDK::NotFound] if the os volume uri is not set and cannot be retrieved
|
127
|
+
def set_os_volume(os_volume)
|
128
|
+
os_volume.retrieve! unless os_volume['uri']
|
129
|
+
raise NotFound, 'The os volume was not found!' unless os_volume['uri']
|
130
|
+
set('osVolumeURI', os_volume['uri'])
|
131
|
+
end
|
132
|
+
|
133
|
+
# Sets the build plan
|
134
|
+
# @param [OneviewSDK::ImageStreamer::API300::BuildPlan] build_plan
|
135
|
+
# @raise [OneviewSDK::NotFound] if the build plan uri is not set and cannot be retrieved
|
136
|
+
def set_build_plan(build_plan)
|
137
|
+
build_plan.retrieve! unless build_plan['uri']
|
138
|
+
raise NotFound, 'The build plan was not found!' unless build_plan['uri']
|
139
|
+
set('buildPlanUri', build_plan['uri'])
|
140
|
+
end
|
23
141
|
end
|
24
142
|
end
|
25
143
|
end
|
data/lib/oneview-sdk/resource.rb
CHANGED
@@ -31,7 +31,8 @@ module OneviewSDK
|
|
31
31
|
# @param [Integer] api_ver The api version to use when interracting with this resource.
|
32
32
|
# Defaults to the client.api_version if it exists, or the OneviewSDK::Client::DEFAULT_API_VERSION.
|
33
33
|
def initialize(client, params = {}, api_ver = nil)
|
34
|
-
raise InvalidClient, 'Must specify a valid client'
|
34
|
+
raise InvalidClient, 'Must specify a valid client'\
|
35
|
+
unless client.is_a?(OneviewSDK::Client) || client.is_a?(OneviewSDK::ImageStreamer::Client)
|
35
36
|
@client = client
|
36
37
|
@logger = @client.logger
|
37
38
|
@api_version = api_ver || @client.api_version
|
@@ -364,9 +365,8 @@ module OneviewSDK
|
|
364
365
|
# @param [String] variant API module variant to fetch resource from
|
365
366
|
# @return [Class] Resource class or nil if not found
|
366
367
|
def self.resource_named(type, api_ver = @api_version, variant = nil)
|
367
|
-
|
368
|
-
|
369
|
-
end
|
368
|
+
raise UnsupportedVersion, "API version #{api_ver} is not supported! Try one of: #{SUPPORTED_API_VERSIONS}"\
|
369
|
+
unless SUPPORTED_API_VERSIONS.include?(api_ver)
|
370
370
|
api_module = OneviewSDK.const_get("API#{api_ver}")
|
371
371
|
variant ? api_module.resource_named(type, variant) : api_module.resource_named(type)
|
372
372
|
end
|
@@ -21,7 +21,7 @@ module OneviewSDK
|
|
21
21
|
new_type = type.to_s.downcase.gsub(/[ -_]/, '')
|
22
22
|
constants.each do |c|
|
23
23
|
klass = const_get(c)
|
24
|
-
next unless klass.is_a?(Class)
|
24
|
+
next unless klass.is_a?(Class)
|
25
25
|
name = klass.name.split('::').last.downcase.delete('_').delete('-')
|
26
26
|
return klass if new_type =~ /^#{name}[s]?$/
|
27
27
|
end
|
@@ -22,7 +22,7 @@ module OneviewSDK
|
|
22
22
|
# @param [OneviewSDK::Client] client The client object for the OneView appliance
|
23
23
|
# @param [String] file_path
|
24
24
|
# @param [Integer] timeout The number of seconds to wait for completing the request
|
25
|
-
# @return [OneviewSDK::FirmwareDriver] if the upload was
|
25
|
+
# @return [OneviewSDK::FirmwareDriver] if the upload was successful, return a FirmwareDriver object
|
26
26
|
def self.add(client, file_path, timeout = READ_TIMEOUT)
|
27
27
|
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
|
28
28
|
options = {}
|
@@ -45,9 +45,16 @@ module OneviewSDK
|
|
45
45
|
http_request.read_timeout = timeout
|
46
46
|
|
47
47
|
http_request.start do |http|
|
48
|
-
|
49
|
-
|
50
|
-
|
48
|
+
begin
|
49
|
+
response = http.request(req)
|
50
|
+
data = client.response_handler(response)
|
51
|
+
return OneviewSDK::FirmwareDriver.new(client, data)
|
52
|
+
rescue Net::ReadTimeout
|
53
|
+
raise "The connection was closed because the timeout of #{timeout} seconds has expired."\
|
54
|
+
'You can specify the timeout in seconds by passing the timeout on the method call.'\
|
55
|
+
'Interrupted firmware uploads may result in corrupted firmware remaining in the appliance.'\
|
56
|
+
'HPE recommends checking the appliance for corrupted firmware and removing it.'
|
57
|
+
end
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
@@ -60,7 +60,7 @@ module OneviewSDK
|
|
60
60
|
type: 'ExtraUnmanagedStorageVolumes',
|
61
61
|
resourceUri: resource['uri']
|
62
62
|
}
|
63
|
-
response = client.rest_post(BASE_URI + '/repair', 'body' => requestBody)
|
63
|
+
response = client.rest_post(BASE_URI + '/repair', { 'Accept-Language' => 'en_US', 'body' => requestBody }, client.api_version)
|
64
64
|
client.response_handler(response)
|
65
65
|
end
|
66
66
|
|
@@ -27,7 +27,7 @@ module OneviewSDK
|
|
27
27
|
api_module = OneviewSDK::API300.const_get(variant)
|
28
28
|
api_module.constants.each do |c|
|
29
29
|
klass = api_module.const_get(c)
|
30
|
-
next unless klass.is_a?(Class)
|
30
|
+
next unless klass.is_a?(Class)
|
31
31
|
name = klass.name.split('::').last.downcase.delete('_').delete('-')
|
32
32
|
return klass if new_type =~ /^#{name}[s]?$/
|
33
33
|
end
|
@@ -10,20 +10,20 @@
|
|
10
10
|
# language governing permissions and limitations under the License.
|
11
11
|
|
12
12
|
require_relative '../../api200/switch'
|
13
|
+
require_relative 'scope'
|
13
14
|
|
14
15
|
module OneviewSDK
|
15
16
|
module API300
|
16
17
|
module C7000
|
17
18
|
# Switch resource implementation
|
18
19
|
class Switch < OneviewSDK::API200::Switch
|
20
|
+
include OneviewSDK::API300::C7000::Scope::ScopeHelperMethods
|
19
21
|
|
20
22
|
# Updates the scope URIs of a specific switch
|
21
23
|
# @param [Array] scope_uris Array of scope uri strings
|
24
|
+
# @deprecated Use {#add_scope}, {#remove_scope}, and {#replace_scopes} instead.
|
22
25
|
def set_scope_uris(scope_uris)
|
23
|
-
|
24
|
-
body = { op: 'replace', path: '/scopeUris', value: scope_uris }
|
25
|
-
response = @client.rest_patch(@data['uri'], { 'body' => [body] }, @api_version)
|
26
|
-
@client.response_handler(response)
|
26
|
+
patch('replace', '/scopeUris', scope_uris)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
data/lib/oneview-sdk/rest.rb
CHANGED
@@ -13,10 +13,13 @@ require 'uri'
|
|
13
13
|
require 'net/http'
|
14
14
|
require 'openssl'
|
15
15
|
require 'json'
|
16
|
+
require 'net/http/post/multipart'
|
16
17
|
|
17
18
|
module OneviewSDK
|
18
19
|
# Contains all of the methods for making API REST calls
|
19
20
|
module Rest
|
21
|
+
READ_TIMEOUT = 300 # in seconds, 5 minutes
|
22
|
+
|
20
23
|
# Makes a restful API request to OneView
|
21
24
|
# @param [Symbol] type The rest method/type Options: [:get, :post, :delete, :patch, :put]
|
22
25
|
# @param [String] path The path for the request. Usually starts with "/rest/"
|
@@ -32,17 +35,8 @@ module OneviewSDK
|
|
32
35
|
def rest_api(type, path, options = {}, api_ver = @api_version, redirect_limit = 3)
|
33
36
|
@logger.debug "Making :#{type} rest call to #{@url}#{path}"
|
34
37
|
raise InvalidRequest, 'Must specify path' unless path
|
35
|
-
|
36
38
|
uri = URI.parse(URI.escape(@url + path))
|
37
|
-
http =
|
38
|
-
http.use_ssl = true if uri.scheme == 'https'
|
39
|
-
if @ssl_enabled
|
40
|
-
http.cert_store = @cert_store if @cert_store
|
41
|
-
else http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
42
|
-
end
|
43
|
-
http.read_timeout = @timeout if @timeout # Timeout for a request
|
44
|
-
http.open_timeout = @timeout if @timeout # Timeout for a connection
|
45
|
-
|
39
|
+
http = build_http_object(uri)
|
46
40
|
request = build_request(type, uri, options.dup, api_ver)
|
47
41
|
response = http.request(request)
|
48
42
|
@logger.debug " Response: Code=#{response.code}. Headers=#{response.to_hash}\n Body=#{response.body}"
|
@@ -121,6 +115,64 @@ module OneviewSDK
|
|
121
115
|
rest_api(:delete, path, options, api_ver)
|
122
116
|
end
|
123
117
|
|
118
|
+
# Uploads a file to a specific uri
|
119
|
+
# @param [String] file_path
|
120
|
+
# @param [String] path The url path starting with "/"
|
121
|
+
# @param [Hash] body_params The params to append to body of http request. Default is {}.
|
122
|
+
# @option body_params [String] 'name' The name to show (when resource accepts a name)
|
123
|
+
# @param [Integer] timeout The number of seconds to wait for completing the request. Default is 300.
|
124
|
+
# @return [Hash] The parsed JSON body of response
|
125
|
+
def upload_file(file_path, path, body_params = {}, timeout = READ_TIMEOUT)
|
126
|
+
raise NotFound, "ERROR: File '#{file_path}' not found!" unless File.file?(file_path)
|
127
|
+
options = {
|
128
|
+
'Content-Type' => 'multipart/form-data',
|
129
|
+
'X-Api-Version' => @api_version.to_s,
|
130
|
+
'auth' => @token
|
131
|
+
}
|
132
|
+
|
133
|
+
File.open(file_path) do |file|
|
134
|
+
name_to_show = body_params.delete('name') || body_params.delete(:name) || File.basename(file_path)
|
135
|
+
body_params['file'] = UploadIO.new(file, 'application/octet-stream', name_to_show)
|
136
|
+
|
137
|
+
uri = URI.parse(URI.escape(@url + path))
|
138
|
+
http_request = build_http_object(uri)
|
139
|
+
http_request.read_timeout = timeout
|
140
|
+
|
141
|
+
req = Net::HTTP::Post::Multipart.new(
|
142
|
+
uri.path,
|
143
|
+
body_params,
|
144
|
+
options
|
145
|
+
)
|
146
|
+
|
147
|
+
http_request.start do |http|
|
148
|
+
response = http.request(req)
|
149
|
+
return response_handler(response)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
# Download a file from a specific uri
|
155
|
+
# @param [String] path The url path starting with "/"
|
156
|
+
# @param [String] local_drive_path Path to save file downloaded
|
157
|
+
# @return [Boolean] if file was downloaded
|
158
|
+
def download_file(path, local_drive_path)
|
159
|
+
uri = URI.parse(URI.escape(@url + path))
|
160
|
+
http_request = build_http_object(uri)
|
161
|
+
req = build_request(:get, uri, {}, @api_version.to_s)
|
162
|
+
|
163
|
+
http_request.start do |http|
|
164
|
+
http.request(req) do |res|
|
165
|
+
response_handler(res) unless res.code.to_i.between?(200, 204)
|
166
|
+
File.open(local_drive_path, 'wb') do |file|
|
167
|
+
res.read_body do |segment|
|
168
|
+
file.write(segment)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
true
|
174
|
+
end
|
175
|
+
|
124
176
|
RESPONSE_CODE_OK = 200
|
125
177
|
RESPONSE_CODE_CREATED = 201
|
126
178
|
RESPONSE_CODE_ACCEPTED = 202
|
@@ -133,8 +185,7 @@ module OneviewSDK
|
|
133
185
|
# If an asynchronous task was started, this waits for it to complete.
|
134
186
|
# @param [HTTPResponse] response HTTP response
|
135
187
|
# @param [Boolean] wait_on_task Wait on task (or just return task details)
|
136
|
-
# @raise [
|
137
|
-
# @raise [StandardError] if a task was returned that did not complete successfully
|
188
|
+
# @raise [OneviewSDK::OneViewError] if the request failed or a task did not complete successfully
|
138
189
|
# @return [Hash] The parsed JSON body
|
139
190
|
def response_handler(response, wait_on_task = true)
|
140
191
|
case response.code.to_i
|
@@ -158,19 +209,32 @@ module OneviewSDK
|
|
158
209
|
when RESPONSE_CODE_NO_CONTENT # Synchronous delete
|
159
210
|
return {}
|
160
211
|
when RESPONSE_CODE_BAD_REQUEST
|
161
|
-
raise
|
212
|
+
BadRequest.raise! "400 BAD REQUEST #{response.body}", response
|
162
213
|
when RESPONSE_CODE_UNAUTHORIZED
|
163
|
-
raise
|
214
|
+
Unauthorized.raise! "401 UNAUTHORIZED #{response.body}", response
|
164
215
|
when RESPONSE_CODE_NOT_FOUND
|
165
|
-
raise
|
216
|
+
NotFound.raise! "404 NOT FOUND #{response.body}", response
|
166
217
|
else
|
167
|
-
raise
|
218
|
+
RequestError.raise! "#{response.code} #{response.body}", response
|
168
219
|
end
|
169
220
|
end
|
170
221
|
|
171
222
|
|
172
223
|
private
|
173
224
|
|
225
|
+
# Builds a http object using the data given
|
226
|
+
def build_http_object(uri)
|
227
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
228
|
+
http.use_ssl = true if uri.scheme == 'https'
|
229
|
+
if @ssl_enabled
|
230
|
+
http.cert_store = @cert_store if @cert_store
|
231
|
+
else http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
232
|
+
end
|
233
|
+
http.read_timeout = @timeout if @timeout # Timeout for a request
|
234
|
+
http.open_timeout = @timeout if @timeout # Timeout for a connection
|
235
|
+
http
|
236
|
+
end
|
237
|
+
|
174
238
|
# Builds a request object using the data given
|
175
239
|
def build_request(type, uri, options, api_ver)
|
176
240
|
case type.downcase.to_sym
|
data/lib/oneview-sdk/version.rb
CHANGED
data/oneview-sdk.gemspec
CHANGED
@@ -34,11 +34,11 @@ Gem::Specification.new do |spec|
|
|
34
34
|
spec.add_runtime_dependency 'pry'
|
35
35
|
spec.add_runtime_dependency 'multipart-post'
|
36
36
|
|
37
|
+
spec.add_development_dependency 'coveralls'
|
37
38
|
spec.add_development_dependency 'bundler'
|
38
|
-
spec.add_development_dependency '
|
39
|
+
spec.add_development_dependency 'byebug'
|
39
40
|
spec.add_development_dependency 'rake'
|
40
|
-
spec.add_development_dependency '
|
41
|
+
spec.add_development_dependency 'rspec'
|
41
42
|
spec.add_development_dependency 'rubocop', '= 0.42.0'
|
42
|
-
spec.add_development_dependency '
|
43
|
-
|
43
|
+
spec.add_development_dependency 'simplecov'
|
44
44
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oneview-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henrique Diomede
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-02-
|
14
|
+
date: 2017-02-24 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: thor
|
@@ -69,6 +69,20 @@ dependencies:
|
|
69
69
|
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: coveralls
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: '0'
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - ">="
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
72
86
|
- !ruby/object:Gem::Dependency
|
73
87
|
name: bundler
|
74
88
|
requirement: !ruby/object:Gem::Requirement
|
@@ -84,7 +98,7 @@ dependencies:
|
|
84
98
|
- !ruby/object:Gem::Version
|
85
99
|
version: '0'
|
86
100
|
- !ruby/object:Gem::Dependency
|
87
|
-
name:
|
101
|
+
name: byebug
|
88
102
|
requirement: !ruby/object:Gem::Requirement
|
89
103
|
requirements:
|
90
104
|
- - ">="
|
@@ -112,7 +126,7 @@ dependencies:
|
|
112
126
|
- !ruby/object:Gem::Version
|
113
127
|
version: '0'
|
114
128
|
- !ruby/object:Gem::Dependency
|
115
|
-
name:
|
129
|
+
name: rspec
|
116
130
|
requirement: !ruby/object:Gem::Requirement
|
117
131
|
requirements:
|
118
132
|
- - ">="
|
@@ -140,7 +154,7 @@ dependencies:
|
|
140
154
|
- !ruby/object:Gem::Version
|
141
155
|
version: 0.42.0
|
142
156
|
- !ruby/object:Gem::Dependency
|
143
|
-
name:
|
157
|
+
name: simplecov
|
144
158
|
requirement: !ruby/object:Gem::Requirement
|
145
159
|
requirements:
|
146
160
|
- - ">="
|
@@ -176,8 +190,9 @@ files:
|
|
176
190
|
- lib/oneview-sdk/config_loader.rb
|
177
191
|
- lib/oneview-sdk/exceptions.rb
|
178
192
|
- lib/oneview-sdk/image-streamer/client.rb
|
179
|
-
- lib/oneview-sdk/image-streamer/resource/api300/
|
193
|
+
- lib/oneview-sdk/image-streamer/resource/api300/artifact_bundle.rb
|
180
194
|
- lib/oneview-sdk/image-streamer/resource/api300/build_plan.rb
|
195
|
+
- lib/oneview-sdk/image-streamer/resource/api300/deployment_group.rb
|
181
196
|
- lib/oneview-sdk/image-streamer/resource/api300/deployment_plan.rb
|
182
197
|
- lib/oneview-sdk/image-streamer/resource/api300/golden_image.rb
|
183
198
|
- lib/oneview-sdk/image-streamer/resource/api300/os_volume.rb
|