vmware-vra 2.7.0 → 3.0.1

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/CHANGELOG.md +27 -1
  4. data/README.md +91 -141
  5. data/Rakefile +1 -12
  6. data/lib/vra/catalog.rb +39 -8
  7. data/lib/vra/catalog_base.rb +62 -0
  8. data/lib/vra/catalog_item.rb +29 -75
  9. data/lib/vra/catalog_source.rb +116 -0
  10. data/lib/vra/catalog_type.rb +56 -0
  11. data/lib/vra/client.rb +72 -53
  12. data/lib/vra/deployment.rb +155 -0
  13. data/lib/vra/deployment_request.rb +117 -0
  14. data/lib/vra/{resources.rb → deployments.rb} +26 -17
  15. data/lib/vra/exceptions.rb +2 -2
  16. data/lib/vra/http.rb +20 -7
  17. data/lib/vra/request.rb +28 -36
  18. data/lib/vra/request_parameters.rb +12 -10
  19. data/lib/vra/resource.rb +33 -203
  20. data/lib/vra/version.rb +2 -2
  21. data/lib/vra.rb +15 -12
  22. data/spec/catalog_item_spec.rb +64 -222
  23. data/spec/catalog_source_spec.rb +178 -0
  24. data/spec/catalog_spec.rb +112 -72
  25. data/spec/catalog_type_spec.rb +114 -0
  26. data/spec/client_spec.rb +287 -228
  27. data/spec/deployment_request_spec.rb +192 -0
  28. data/spec/deployment_spec.rb +227 -0
  29. data/spec/deployments_spec.rb +80 -0
  30. data/spec/fixtures/resource/sample_catalog_item.json +18 -0
  31. data/spec/fixtures/resource/sample_catalog_item_2.json +18 -0
  32. data/spec/fixtures/resource/sample_catalog_source.json +20 -0
  33. data/spec/fixtures/resource/sample_catalog_type.json +49 -0
  34. data/spec/fixtures/resource/sample_dep_actions.json +58 -0
  35. data/spec/fixtures/resource/sample_dep_request.json +19 -0
  36. data/spec/fixtures/resource/sample_dep_resource.json +112 -0
  37. data/spec/fixtures/resource/sample_deployment.json +26 -0
  38. data/spec/fixtures/resource/sample_entitlements.json +25 -0
  39. data/spec/http_spec.rb +63 -61
  40. data/spec/request_spec.rb +62 -68
  41. data/spec/resource_spec.rb +71 -390
  42. data/spec/spec_helper.rb +10 -4
  43. data/vmware-vra.gemspec +2 -4
  44. metadata +42 -32
  45. data/.travis.yml +0 -14
  46. data/lib/vra/catalog_request.rb +0 -127
  47. data/lib/vra/requests.rb +0 -41
  48. data/spec/catalog_request_spec.rb +0 -265
  49. data/spec/requests_spec.rb +0 -60
  50. data/spec/resources_spec.rb +0 -71
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+ #
3
+ # Author:: Ashique Saidalavi (<ashique.saidalavi@progress.com>)
4
+ # Copyright:: Copyright (c) 2022 Chef Software, Inc.
5
+ # License:: Apache License, Version 2.0
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ require 'ffi_yajl' unless defined?(FFI_Yajl)
20
+
21
+ # Overriding the hash object to add the deep_merge method
22
+ class ::Hash
23
+ def deep_merge(second)
24
+ merger = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
25
+ merge(second, &merger)
26
+ end
27
+ end
28
+
29
+ module Vra
30
+ # class that handles the deployment request with catalog
31
+ class DeploymentRequest
32
+ attr_reader :catalog_id
33
+ attr_accessor :image_mapping, :name, :flavor_mapping,
34
+ :project_id, :version, :count
35
+
36
+ def initialize(client, catalog_id, opts = {})
37
+ @client = client
38
+ @catalog_id = catalog_id
39
+ @image_mapping = opts[:image_mapping]
40
+ @name = opts[:name]
41
+ @flavor_mapping = opts[:flavor_mapping]
42
+ @project_id = opts[:project_id]
43
+ @version = opts[:version]
44
+ @count = opts[:count] || 1
45
+ @additional_params = opts[:additional_params] || Vra::RequestParameters.new
46
+ end
47
+
48
+ def submit
49
+ validate!
50
+ begin
51
+ response = send_request!
52
+ rescue Vra::Exception::HTTPError => e
53
+ raise Vra::Exception::RequestError, "Unable to submit request: #{e.message}, trace: #{e.errors.join(', ')}"
54
+ rescue StandardError => e
55
+ raise e, e.message
56
+ end
57
+
58
+ request_id = FFI_Yajl::Parser.parse(response)[0]['deploymentId']
59
+ Vra::Deployment.new(client, id: request_id)
60
+ end
61
+
62
+ def set_parameter(key, type, value)
63
+ @additional_params.set(key, type, value)
64
+ end
65
+
66
+ def set_parameters(key, value_data)
67
+ @additional_params.set_parameters(key, value_data)
68
+ end
69
+
70
+ def delete_parameter(key)
71
+ @additional_params.delete(key)
72
+ end
73
+
74
+ def parameters
75
+ @additional_params.to_vra
76
+ end
77
+
78
+ def hash_parameters
79
+ @additional_params.to_h
80
+ end
81
+
82
+ private
83
+
84
+ attr_reader :client
85
+
86
+ def validate!
87
+ missing_params = []
88
+ %i[image_mapping flavor_mapping name project_id version].each do |arg|
89
+ missing_params << arg if send(arg).nil?
90
+ end
91
+
92
+ return if missing_params.empty?
93
+
94
+ raise ArgumentError, "Unable to submit request, required param(s) missing => #{missing_params.join(', ')}"
95
+ end
96
+
97
+ def send_request!
98
+ client.http_post!(
99
+ "/catalog/api/items/#{catalog_id}/request",
100
+ FFI_Yajl::Encoder.encode(request_payload)
101
+ )
102
+ end
103
+
104
+ def request_payload
105
+ {
106
+ 'deploymentName': name,
107
+ 'projectId': project_id,
108
+ 'version': version,
109
+ 'inputs': {
110
+ 'count': count,
111
+ 'image': image_mapping,
112
+ 'flavor': flavor_mapping
113
+ }
114
+ }.deep_merge(parameters)
115
+ end
116
+ end
117
+ end
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
-
3
2
  #
4
- # Author:: Chef Partner Engineering (<partnereng@chef.io>)
5
- # Copyright:: Copyright (c) 2015 Chef Software, Inc.
3
+ # Author:: Ashique Saidalavi (<ashique.saidalavi@progress.com>)
4
+ # Copyright:: Copyright (c) 2022 Chef Software, Inc.
6
5
  # License:: Apache License, Version 2.0
7
6
  #
8
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,29 +16,39 @@
17
16
  # See the License for the specific language governing permissions and
18
17
  # limitations under the License.
19
18
  #
20
-
21
19
  module Vra
22
- class Resources
23
- attr_reader :client
24
-
20
+ # class that represents the Deployments Object
21
+ class Deployments
25
22
  def initialize(client)
26
23
  @client = client
27
24
  end
28
25
 
29
- # @return [Array[Vra::Resource]] - returns an array of all the resources owned by the user
30
- # @param [Vra::Client]
31
- def self.all(client)
32
- items = client.http_get_paginated_array!("/catalog-service/api/consumer/resources")
33
- items.map { |item| Vra::Resource.new(client, data: item) }
26
+ def by_id(dep_id)
27
+ Vra::Deployment.new(client, id: dep_id)
28
+ end
29
+
30
+ def all
31
+ fetch_all_resources
34
32
  end
35
33
 
36
- # @return [Array[Vra::Resource]] - returns an array of all the resources owned by the user
37
- def all_resources
38
- self.class.all(client)
34
+ class << self
35
+ def all(client)
36
+ new(client).all
37
+ end
38
+
39
+ def by_id(client, id)
40
+ new(client).by_id(id)
41
+ end
39
42
  end
40
43
 
41
- def by_id(id)
42
- Vra::Resource.new(client, id: id)
44
+ private
45
+
46
+ attr_reader :client
47
+
48
+ def fetch_all_resources
49
+ client
50
+ .http_get_paginated_array!('/deployment/api/deployments')
51
+ .map! { |x| Vra::Deployment.new(client, data: x) }
43
52
  end
44
53
  end
45
54
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2022 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,7 +17,7 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require "ffi_yajl"
20
+ require "ffi_yajl" unless defined?(FFI_Yajl)
21
21
 
22
22
  module Vra
23
23
  module Exception
data/lib/vra/http.rb CHANGED
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
- require "net/http"
3
- require "openssl"
2
+
3
+ require 'net/http' unless defined?(Net::HTTP)
4
+ require 'openssl' unless defined?(OpenSSL)
5
+ require 'ffi_yajl' unless defined?(FFI_Yajl)
6
+ require 'json'
4
7
 
5
8
  module Vra
6
9
  module Http
@@ -8,7 +11,13 @@ module Vra
8
11
  request = Request.new(params)
9
12
  response = request.call
10
13
  response = response.forward(request).call until response.final?
14
+ if ENV["VRA_HTTP_TRACE"]
15
+ puts "#{request.params[:method].upcase} #{request.params[:url]}" unless request.params.nil?
16
+ puts ">>>>> #{JSON.parse(request.params[:payload]).to_json.gsub(/\"password\":\"(.+)\",/, '"password":"********",' )}" unless request.params[:payload].nil?
17
+ puts "<<<<< #{JSON.parse(response.body).to_json}" unless response.body.nil?
18
+ end
11
19
  raise error(response) unless response.success?
20
+
12
21
  response
13
22
  end
14
23
 
@@ -24,7 +33,7 @@ module Vra
24
33
  end
25
34
 
26
35
  def redirectable?
27
- [:get, :head].include?(params[:method])
36
+ %i{get head}.include?(params[:method])
28
37
  end
29
38
 
30
39
  def redirect_to(location)
@@ -55,6 +64,7 @@ module Vra
55
64
  get: Net::HTTP::Get,
56
65
  head: Net::HTTP::Head,
57
66
  post: Net::HTTP::Post,
67
+ delete: Net::HTTP::Delete
58
68
  }.fetch(method, nil)
59
69
 
60
70
  raise "Unknown HTTP method #{method}!" unless type
@@ -70,6 +80,7 @@ module Vra
70
80
 
71
81
  def verify_ssl?
72
82
  return true if params[:verify_ssl].nil?
83
+
73
84
  params[:verify_ssl]
74
85
  end
75
86
  end
@@ -84,6 +95,7 @@ module Vra
84
95
  def forward(request)
85
96
  if redirect?
86
97
  raise Http.error(self) unless request.redirectable?
98
+
87
99
  request.redirect_to(location)
88
100
  elsif see_other?
89
101
  request.see_other(location)
@@ -134,13 +146,14 @@ module Vra
134
146
  end
135
147
 
136
148
  class Error < StandardError
149
+ attr_reader :http_code, :response
150
+
137
151
  def self.from_response(http_response)
138
- new(http_response.message, http_response.code, http_response.body)
152
+ body = FFI_Yajl::Parser.parse(http_response.body) || {}
153
+ message = body['message'] || body['serverMessage']
154
+ new(message, http_response.code, body)
139
155
  end
140
156
 
141
- attr_reader :http_code
142
- attr_reader :response
143
-
144
157
  def initialize(message, http_code, response)
145
158
  super(message)
146
159
  @http_code = http_code
data/lib/vra/request.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2022 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,23 +17,34 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
- require "ffi_yajl"
21
-
22
20
  module Vra
21
+ # class to represent the Deployment request
23
22
  class Request
24
- attr_reader :client, :id
25
- def initialize(client, id)
26
- @client = client
27
- @id = id
23
+ attr_reader :id, :deployment_id
24
+
25
+ def initialize(client, deployment_id, opts = {})
26
+ @client = client
27
+ @deployment_id = deployment_id
28
+ @id = opts[:id]
29
+ @request_data = opts[:data]
30
+
31
+ if @request_data.nil?
32
+ refresh
33
+ else
34
+ @id = @request_data['id']
35
+ end
36
+ end
37
+
38
+ def requested_by
39
+ request_data['requestedBy']
40
+ end
28
41
 
29
- @request_data = nil
30
- @status = nil
31
- @completion_state = nil
32
- @completion_details = nil
42
+ def name
43
+ request_data['name']
33
44
  end
34
45
 
35
46
  def refresh
36
- @request_data = client.get_parsed("/catalog-service/api/consumer/requests/#{@id}")
47
+ @request_data = client.get_parsed("/deployment/api/deployments/#{deployment_id}/requests/#{id}?deleted=true")
37
48
  rescue Vra::Exception::HTTPNotFound
38
49
  raise Vra::Exception::NotFound, "request ID #{@id} is not found"
39
50
  end
@@ -50,7 +61,7 @@ module Vra
50
61
  refresh_if_empty
51
62
  return if request_empty?
52
63
 
53
- @request_data["phase"]
64
+ request_data['status']
54
65
  end
55
66
 
56
67
  def completed?
@@ -58,34 +69,15 @@ module Vra
58
69
  end
59
70
 
60
71
  def successful?
61
- status == "SUCCESSFUL"
72
+ status == 'SUCCESSFUL'
62
73
  end
63
74
 
64
75
  def failed?
65
- status == "FAILED"
66
- end
67
-
68
- def completion_state
69
- refresh_if_empty
70
- return if request_empty?
71
-
72
- @request_data["requestCompletion"]["requestCompletionState"]
76
+ status == 'FAILED'
73
77
  end
74
78
 
75
- def completion_details
76
- refresh_if_empty
77
- return if request_empty?
78
-
79
- @request_data["requestCompletion"]["completionDetails"]
80
- end
79
+ private
81
80
 
82
- def resources
83
- begin
84
- request_resources = client.http_get_paginated_array!("/catalog-service/api/consumer/requests/#{@id}/resources")
85
- rescue Vra::Exception::HTTPNotFound
86
- raise Vra::Exception::NotFound, "resources for request ID #{@id} are not found"
87
- end
88
- request_resources.map { |resource| Vra::Resource.new(client, data: resource) }
89
- end
81
+ attr_reader :request_data, :client
90
82
  end
91
83
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  # Author:: Chef Partner Engineering (<partnereng@chef.io>)
4
- # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # Copyright:: Copyright (c) 2022 Chef Software, Inc.
5
5
  # License:: Apache License, Version 2.0
6
6
  #
7
7
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -93,11 +93,11 @@ module Vra
93
93
 
94
94
  def to_vra
95
95
  hash = {
96
- "data" => {},
96
+ 'inputs': {}
97
97
  }
98
98
 
99
- @entries.each do |k, v|
100
- hash["data"].merge!(v.to_vra)
99
+ @entries.each do |_, v|
100
+ hash[:inputs].merge!(v.to_vra)
101
101
  end
102
102
 
103
103
  hash
@@ -120,7 +120,7 @@ module Vra
120
120
  def to_h
121
121
  hash = {}
122
122
 
123
- if @children.count > 0
123
+ if @children.count.positive?
124
124
  hash[@key] = {}
125
125
 
126
126
  @children.each do |c|
@@ -135,13 +135,13 @@ module Vra
135
135
 
136
136
  def to_vra
137
137
  hash = {}
138
- if @children.count > 0
138
+ if @children.count.positive?
139
139
  hash[@key] = {}
140
140
 
141
- hash[@key]["data"] = {}
141
+ hash[@key]['inputs'] = {}
142
142
 
143
143
  @children.each do |c|
144
- hash[@key]["data"].merge!(c.to_vra)
144
+ hash[@key]['inputs'].merge!(c.to_vra)
145
145
  end
146
146
  else
147
147
  hash[@key] = format_value
@@ -152,10 +152,12 @@ module Vra
152
152
 
153
153
  def format_value
154
154
  case @type
155
- when "integer"
155
+ when 'integer'
156
156
  @value.to_i
157
- when "string"
157
+ when 'string'
158
158
  @value
159
+ when 'boolean'
160
+ @value.to_s == 'true'
159
161
  else
160
162
  @value
161
163
  end