vmware-vra 3.0.0 → 3.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +4 -2
- data/lib/vra/catalog_item.rb +14 -2
- data/lib/vra/client.rb +17 -7
- data/lib/vra/deployment_request.rb +11 -3
- data/lib/vra/version.rb +1 -1
- data/spec/catalog_item_spec.rb +33 -0
- data/spec/client_spec.rb +20 -6
- data/spec/deployment_request_spec.rb +39 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '04187d64c2726dfbe9dcf8128710daa94c17593d17da436b4c797932d7399f39'
|
4
|
+
data.tar.gz: 2456b3f5fb84a99f12493ba357e8603d2bfb42c42858139bc53fcbd60b8f8984
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9820fab88049710e06f5814994d6a215338d7039e775523d27c32fbaf6e80463721d9ae5bce0e876a3b5236a14009d6350a2abb7716cda6f10f15e05676107dd
|
7
|
+
data.tar.gz: '0998fa84339c1f467d585041b2b1b4f8dbc0eae3b70f9fd03c7fcb5ea37afd280d61a58fc10fe4d1cd389e782430c532b639f02d09ec888fa3b52b31a71b8f2c'
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## [3.1.1](https://github.com/chef-partners/vmware-vra-gem/tree/v3.1.1) (2022-03-01)
|
4
|
+
|
5
|
+
- Send Authorization: Bearer header instead of csp-auth-token for greater compatibility [@oshvarts]
|
6
|
+
|
7
|
+
## [3.1.0](https://github.com/chef-partners/vmware-vra-gem/tree/v3.1.0) (2022-01-30)
|
8
|
+
[Full Changelog](https://github.com/chef-partners/vmware-vra-gem/compare/v3.0.1...v3.1.0)
|
9
|
+
|
10
|
+
- Make the version param optional in deployment request api
|
11
|
+
|
12
|
+
## [3.0.1](https://github.com/chef-partners/vmware-vra-gem/tree/v3.0.1) (2022-01-25)
|
13
|
+
[Full Changelog](https://github.com/chef-partners/vmware-vra-gem/compare/v3.0.0...v3.0.1)
|
14
|
+
|
15
|
+
- Fix access token workflow to work with VRA8
|
16
|
+
|
3
17
|
## [3.0.0](https://github.com/chef-partners/vmware-vra-gem/tree/v3.0.0) (2022-01-18)
|
4
18
|
[Full Changelog](https://github.com/chef-partners/vmware-vra-gem/compare/v2.7.2...v3.0.0)
|
5
19
|
|
data/README.md
CHANGED
@@ -125,8 +125,10 @@ request = client.catalog.request(
|
|
125
125
|
#<Vra::DeploymentRequest:0x00007fb7340b7438
|
126
126
|
...
|
127
127
|
```
|
128
|
-
To request a deployment from a catalog item, you can use the above method with a project ID that has a cloud template version released to the project.
|
129
|
-
|
128
|
+
To request a deployment from a catalog item, you can use the above method with a project ID that has a cloud template version released to the project.
|
129
|
+
|
130
|
+
The ID of the catalog item from which you are requesting the deployment should be also included, and the version of the released cloud template. If the user doesn't specify a version explicitly, the latest version will be fetched automatically and will be used for the request.
|
131
|
+
|
130
132
|
Additionally, the name of the deployment should be specified and it should be unique.
|
131
133
|
The image mapping specifies the OS image for a VM and the flavor mapping specifies the CPU count and RAM of a VM.
|
132
134
|
|
data/lib/vra/catalog_item.rb
CHANGED
@@ -73,12 +73,24 @@ module Vra
|
|
73
73
|
data['iconId']
|
74
74
|
end
|
75
75
|
|
76
|
+
def versions
|
77
|
+
client
|
78
|
+
.http_get_paginated_array!("/catalog/api/items/#{id}/versions")
|
79
|
+
.map { |v| v['id'] }
|
80
|
+
end
|
81
|
+
|
76
82
|
def entitle!(opts = {})
|
77
83
|
super(opts.merge(type: 'CatalogItemIdentifier'))
|
78
84
|
end
|
79
85
|
|
80
|
-
|
81
|
-
|
86
|
+
class << self
|
87
|
+
def entitle!(client, id)
|
88
|
+
new(client, id: id).entitle!
|
89
|
+
end
|
90
|
+
|
91
|
+
def fetch_latest_version(client, id)
|
92
|
+
new(client, data: { 'id' => id }).versions&.first
|
93
|
+
end
|
82
94
|
end
|
83
95
|
end
|
84
96
|
end
|
data/lib/vra/client.rb
CHANGED
@@ -23,7 +23,8 @@ require 'vra/http'
|
|
23
23
|
|
24
24
|
module Vra
|
25
25
|
class Client
|
26
|
-
|
26
|
+
REFRESH_TOKEN_URL = '/csp/gateway/am/api/login?access_token'
|
27
|
+
ACCESS_TOKEN_URL = '/iaas/api/login'
|
27
28
|
ROLES_URL = '/csp/gateway/am/api/loggedin/user/orgs'
|
28
29
|
|
29
30
|
attr_accessor :page_size
|
@@ -87,7 +88,7 @@ module Vra
|
|
87
88
|
headers = {}
|
88
89
|
headers['Accept'] = 'application/json'
|
89
90
|
headers['Content-Type'] = 'application/json'
|
90
|
-
headers['
|
91
|
+
headers['Authorization'] = 'Bearer ' + @access_token.value unless @access_token.value.nil?
|
91
92
|
|
92
93
|
headers
|
93
94
|
end
|
@@ -106,17 +107,26 @@ module Vra
|
|
106
107
|
end
|
107
108
|
|
108
109
|
def generate_access_token
|
110
|
+
@refresh_token.value = nil
|
109
111
|
@access_token.value = nil
|
110
112
|
validate_client_options!
|
111
113
|
|
112
|
-
|
114
|
+
# VRA 8 has a two-step authentication process - This probably breaks VRA7, who knows?!?
|
115
|
+
# First step: Sending Username/Password to get a Refresh Token
|
116
|
+
refresh_response = http_post(REFRESH_TOKEN_URL,
|
113
117
|
FFI_Yajl::Encoder.encode(token_params),
|
114
118
|
:skip_auth)
|
115
|
-
raise Vra::Exception::Unauthorized, "Unable to get the
|
119
|
+
raise Vra::Exception::Unauthorized, "Unable to get the refresh token: #{refresh_response.body}" unless refresh_response.success_ok?
|
116
120
|
|
117
|
-
|
118
|
-
@
|
119
|
-
|
121
|
+
refresh_response_body = FFI_Yajl::Parser.parse(refresh_response.body)
|
122
|
+
@refresh_token.value = refresh_response_body['refresh_token']
|
123
|
+
|
124
|
+
# Second Step: Sending the refresh token to a separate endpoint to get an Access Token
|
125
|
+
access_response = http_post(ACCESS_TOKEN_URL, "{ \"refreshToken\": \"#{@refresh_token.value}\" }", :skip_auth)
|
126
|
+
raise Vra::Exception::Unauthorized, "Unable to get the access token: #{access_response.body}" unless access_response.success_ok?
|
127
|
+
|
128
|
+
access_response_body = FFI_Yajl::Parser.parse(access_response.body)
|
129
|
+
@access_token.value = access_response_body['token']
|
120
130
|
end
|
121
131
|
|
122
132
|
def full_url(path)
|
@@ -85,13 +85,21 @@ module Vra
|
|
85
85
|
|
86
86
|
def validate!
|
87
87
|
missing_params = []
|
88
|
-
%i[image_mapping flavor_mapping name project_id
|
88
|
+
%i[image_mapping flavor_mapping name project_id].each do |arg|
|
89
89
|
missing_params << arg if send(arg).nil?
|
90
90
|
end
|
91
91
|
|
92
|
-
|
92
|
+
unless missing_params.empty?
|
93
|
+
raise ArgumentError, "Unable to submit request, required param(s) missing => #{missing_params.join(', ')}"
|
94
|
+
end
|
95
|
+
|
96
|
+
# If the user doesn't supply the catalog version, fetch the latest version and use it
|
97
|
+
# and if the API was unable to find a valid version, alert the user.
|
98
|
+
return unless @version.nil?
|
99
|
+
|
93
100
|
|
94
|
-
|
101
|
+
@version = CatalogItem.fetch_latest_version(client, catalog_id)
|
102
|
+
raise ArgumentError, 'Unable to fetch a valid catalog version' if @version.nil?
|
95
103
|
end
|
96
104
|
|
97
105
|
def send_request!
|
data/lib/vra/version.rb
CHANGED
data/spec/catalog_item_spec.rb
CHANGED
@@ -122,4 +122,37 @@ describe Vra::CatalogItem do
|
|
122
122
|
expect(catalog_item.type).to be_a(Vra::CatalogType)
|
123
123
|
end
|
124
124
|
end
|
125
|
+
|
126
|
+
describe '#versions' do
|
127
|
+
let(:versions_response) do
|
128
|
+
[{ id: '2', description: 'v2.0' }, { id: '1', description: 'v1.0' }]
|
129
|
+
end
|
130
|
+
|
131
|
+
before do
|
132
|
+
allow(client).to receive(:authorized?).and_return(true)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should call the api to fetch the versions' do
|
136
|
+
expect(client)
|
137
|
+
.to receive(:http_get_paginated_array!)
|
138
|
+
.with('/catalog/api/items/catalog-12345/versions')
|
139
|
+
.and_return(versions_response)
|
140
|
+
|
141
|
+
described_class.fetch_latest_version(client, 'catalog-12345')
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should return the correct version' do
|
145
|
+
stub_request(:get, client.full_url('/catalog/api/items/catalog-12345/versions?$skip=0&$top=20'))
|
146
|
+
.to_return(
|
147
|
+
status: 200,
|
148
|
+
body: {
|
149
|
+
content: versions_response,
|
150
|
+
totalPages: 1
|
151
|
+
}.to_json,
|
152
|
+
headers: {}
|
153
|
+
)
|
154
|
+
|
155
|
+
expect(described_class.fetch_latest_version(client, 'catalog-12345')).to eq('2')
|
156
|
+
end
|
157
|
+
end
|
125
158
|
end
|
data/spec/client_spec.rb
CHANGED
@@ -54,16 +54,16 @@ describe Vra::Client do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
describe '#request_headers' do
|
57
|
-
context 'when
|
57
|
+
context 'when access token exists' do
|
58
58
|
it 'has an Authorization header' do
|
59
59
|
client.access_token = '12345'
|
60
|
-
expect(client.request_headers.key?('
|
60
|
+
expect(client.request_headers.key?('Authorization')).to be true
|
61
61
|
end
|
62
62
|
end
|
63
63
|
|
64
64
|
context 'when access token does not exist' do
|
65
65
|
it 'does not have an Authorization header' do
|
66
|
-
expect(client.request_headers.key?('
|
66
|
+
expect(client.request_headers.key?('Authorization')).to be false
|
67
67
|
end
|
68
68
|
end
|
69
69
|
end
|
@@ -131,7 +131,7 @@ describe Vra::Client do
|
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
|
-
describe '#
|
134
|
+
describe '#generate_access_token' do
|
135
135
|
let(:payload) do
|
136
136
|
{
|
137
137
|
username: 'user@corp.local',
|
@@ -148,23 +148,37 @@ describe Vra::Client do
|
|
148
148
|
}.to_json
|
149
149
|
end
|
150
150
|
|
151
|
+
let(:refresh_response_body) { { token: '123456' }.to_json }
|
152
|
+
|
151
153
|
it 'posts to the tokens API endpoint' do
|
152
154
|
response = double('response', code: 200, body: success_response, success_ok?: true)
|
155
|
+
refresh_response = double('response', code: 200, body: refresh_response_body, success_ok?: true)
|
156
|
+
# First request to generate the refresh token
|
153
157
|
expect(Vra::Http).to receive(:execute)
|
154
158
|
.with(method: :post,
|
155
|
-
url: client.full_url(described_class::
|
159
|
+
url: client.full_url(described_class::REFRESH_TOKEN_URL),
|
156
160
|
payload: payload,
|
157
161
|
headers: anything,
|
158
162
|
verify_ssl: true)
|
159
163
|
.and_return(response)
|
160
164
|
|
165
|
+
# Second request to generate access token
|
166
|
+
expect(Vra::Http).to receive(:execute)
|
167
|
+
.with(method: :post,
|
168
|
+
url: client.full_url(described_class::ACCESS_TOKEN_URL),
|
169
|
+
payload: "{ \"refreshToken\": \"654321\" }",
|
170
|
+
headers: anything,
|
171
|
+
verify_ssl: true)
|
172
|
+
.and_return(refresh_response)
|
173
|
+
|
161
174
|
client.generate_access_token
|
162
175
|
end
|
163
176
|
|
164
177
|
context 'when token is generated successfully' do
|
165
178
|
it 'sets the token' do
|
166
179
|
response = double('response', code: 200, body: success_response, success_ok?: true)
|
167
|
-
|
180
|
+
refresh_response = double('response', code: 200, body: refresh_response_body, success_ok?: true)
|
181
|
+
allow(Vra::Http).to receive(:execute).twice.and_return(response, refresh_response)
|
168
182
|
|
169
183
|
client.generate_access_token
|
170
184
|
|
@@ -70,6 +70,45 @@ describe Vra::DeploymentRequest do
|
|
70
70
|
|
71
71
|
expect { request.send(:validate!) }.not_to raise_error(ArgumentError)
|
72
72
|
end
|
73
|
+
|
74
|
+
context 'versions' do
|
75
|
+
let(:dep_request) do
|
76
|
+
described_class.new(
|
77
|
+
client,
|
78
|
+
catalog_id,
|
79
|
+
image_mapping: 'centos',
|
80
|
+
name: 'sample dep',
|
81
|
+
flavor_mapping: 'small',
|
82
|
+
project_id: 'pro-123'
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
before do
|
87
|
+
allow(client).to receive(:authorized?).and_return(true)
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'should not call the api to fetch versions if provided in the params' do
|
91
|
+
expect(client).not_to receive(:http_get_paginated_array!)
|
92
|
+
|
93
|
+
dep_request.version = '1'
|
94
|
+
dep_request.send(:validate!)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should fetch version from api if version is blank' do
|
98
|
+
expect(client).to receive(:http_get_paginated_array!).and_return([{ 'id' => '2', 'description' => 'v2.0' }])
|
99
|
+
|
100
|
+
dep_request.send(:validate!)
|
101
|
+
expect(dep_request.version).to eq('2')
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'should raise an exception if no valid versions found' do
|
105
|
+
expect(client).to receive(:http_get_paginated_array!).and_return([])
|
106
|
+
|
107
|
+
expect { dep_request.send(:validate!) }
|
108
|
+
.to raise_error(ArgumentError)
|
109
|
+
.with_message('Unable to fetch a valid catalog version')
|
110
|
+
end
|
111
|
+
end
|
73
112
|
end
|
74
113
|
|
75
114
|
describe '#additional parameters' do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vmware-vra
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Leff
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-03-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi-yajl
|
@@ -206,7 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
206
|
- !ruby/object:Gem::Version
|
207
207
|
version: '0'
|
208
208
|
requirements: []
|
209
|
-
rubygems_version: 3.
|
209
|
+
rubygems_version: 3.3.7
|
210
210
|
signing_key:
|
211
211
|
specification_version: 4
|
212
212
|
summary: Client gem for interacting with VMware vRealize Automation.
|