vmware-vra 2.6.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +3 -1
  3. data/CHANGELOG.md +35 -2
  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 +62 -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 +14 -13
  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 +272 -227
  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 +3 -5
  44. metadata +44 -36
  45. data/.travis.yml +0 -14
  46. data/Jenkinsfile +0 -31
  47. data/lib/vra/catalog_request.rb +0 -126
  48. data/lib/vra/requests.rb +0 -41
  49. data/spec/catalog_request_spec.rb +0 -267
  50. data/spec/requests_spec.rb +0 -60
  51. 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");
@@ -51,7 +51,7 @@ module Vra
51
51
 
52
52
  def set(key, type, value)
53
53
  if key.to_s.include? "~"
54
- split_key = key.split("~")
54
+ split_key = key.to_s.split("~")
55
55
  parent = nil
56
56
  split_key.each_with_index do |item, index|
57
57
  if index == 0
@@ -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,28 +135,29 @@ module Vra
135
135
 
136
136
  def to_vra
137
137
  hash = {}
138
-
139
- if @children.count > 0
138
+ if @children.count.positive?
140
139
  hash[@key] = {}
141
140
 
142
- hash[@key]["data"] = {}
141
+ hash[@key]['inputs'] = {}
143
142
 
144
143
  @children.each do |c|
145
- hash[@key]["data"].merge!(c.to_vra)
144
+ hash[@key]['inputs'].merge!(c.to_vra)
146
145
  end
147
146
  else
148
147
  hash[@key] = format_value
149
148
  end
150
149
 
151
- hash
150
+ hash.each_with_object({}) { |(key, value), h| h[key.to_s] = value }
152
151
  end
153
152
 
154
153
  def format_value
155
154
  case @type
156
- when "integer"
155
+ when 'integer'
157
156
  @value.to_i
158
- when "string"
157
+ when 'string'
159
158
  @value
159
+ when 'boolean'
160
+ @value.to_s == 'true'
160
161
  else
161
162
  @value
162
163
  end