vmware-vra 1.0.0.rc1

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.
@@ -0,0 +1,57 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'ffi_yajl'
20
+
21
+ module Vra
22
+ module Exception
23
+ class NotFound < RuntimeError; end
24
+ class RequestError < RuntimeError; end
25
+ class Unauthorized < RuntimeError; end
26
+
27
+ class HTTPError < RuntimeError
28
+ attr_accessor :klass, :code, :body, :errors, :path
29
+ def initialize(opts={})
30
+ @code = opts[:code]
31
+ @body = opts[:body]
32
+ @path = opts[:path]
33
+ @klass = opts[:klass]
34
+ @errors = []
35
+
36
+ parse_errors
37
+ end
38
+
39
+ def parse_errors
40
+ begin
41
+ data = FFI_Yajl::Parser.parse(@body)
42
+ rescue FFI_Yajl::ParseError
43
+ return
44
+ end
45
+
46
+ return if data.nil?
47
+ return unless data['errors'].respond_to?(:each)
48
+
49
+ data['errors'].each do |error|
50
+ @errors << error['systemMessage']
51
+ end
52
+ end
53
+ end
54
+
55
+ class HTTPNotFound < HTTPError; end
56
+ end
57
+ end
@@ -0,0 +1,97 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'ffi_yajl'
20
+
21
+ module Vra
22
+ class Request
23
+ attr_reader :client, :id
24
+ def initialize(client, id)
25
+ @client = client
26
+ @id = id
27
+
28
+ @request_data = nil
29
+ @status = nil
30
+ @completion_state = nil
31
+ @completion_details = nil
32
+ end
33
+
34
+ def refresh
35
+ @request_data = FFI_Yajl::Parser.parse(client.http_get!("/catalog-service/api/consumer/requests/#{@id}"))
36
+ rescue Vra::Exception::HTTPNotFound
37
+ raise Vra::Exception::NotFound, "request ID #{@id} is not found"
38
+ end
39
+
40
+ def refresh_if_empty
41
+ refresh if request_empty?
42
+ end
43
+
44
+ def request_empty?
45
+ @request_data.nil?
46
+ end
47
+
48
+ def status
49
+ refresh_if_empty
50
+ return if request_empty?
51
+
52
+ @request_data['phase']
53
+ end
54
+
55
+ def completed?
56
+ successful? || failed?
57
+ end
58
+
59
+ def successful?
60
+ status == 'SUCCESSFUL'
61
+ end
62
+
63
+ def failed?
64
+ status == 'FAILED'
65
+ end
66
+
67
+ def completion_state
68
+ refresh_if_empty
69
+ return if request_empty?
70
+
71
+ @request_data['requestCompletion']['requestCompletionState']
72
+ end
73
+
74
+ def completion_details
75
+ refresh_if_empty
76
+ return if request_empty?
77
+
78
+ @request_data['requestCompletion']['completionDetails']
79
+ end
80
+
81
+ def resources
82
+ resources = []
83
+
84
+ begin
85
+ request_resources = client.http_get_paginated_array!("/catalog-service/api/consumer/requests/#{@id}/resources")
86
+ rescue Vra::Exception::HTTPNotFound
87
+ raise Vra::Exception::NotFound, "resources for request ID #{@id} are not found"
88
+ end
89
+
90
+ request_resources.each do |resource|
91
+ resources << Vra::Resource.new(client, data: resource)
92
+ end
93
+
94
+ resources
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Vra
20
+ class RequestParameters
21
+ def initialize
22
+ @entries = {}
23
+ end
24
+
25
+ def set(key, type, value)
26
+ @entries[key] = Vra::RequestParameter.new(key, type, value)
27
+ end
28
+
29
+ def delete(key)
30
+ @entries.delete(key)
31
+ end
32
+
33
+ def all_entries
34
+ @entries.values
35
+ end
36
+ end
37
+
38
+ class RequestParameter
39
+ attr_accessor :key, :type, :value
40
+ def initialize(key, type, value)
41
+ @key = key
42
+ @type = type
43
+ @value = value
44
+ end
45
+
46
+ def to_h
47
+ {
48
+ 'key' => @key,
49
+ 'value' => {
50
+ 'type' => @type,
51
+ 'value' => format_value
52
+ }
53
+ }
54
+ end
55
+
56
+ def format_value
57
+ case @type
58
+ when 'integer'
59
+ @value.to_i
60
+ when 'string'
61
+ @value.to_s
62
+ else
63
+ @value.to_s
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,40 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Vra
20
+ class Requests
21
+ def initialize(client)
22
+ @client = client
23
+ end
24
+
25
+ def all_requests
26
+ requests = []
27
+
28
+ items = @client.http_get_paginated_array!('/catalog-service/api/consumer/requests')
29
+ items.each do |item|
30
+ requests << Vra::Request.new(@client, item['id'])
31
+ end
32
+
33
+ requests
34
+ end
35
+
36
+ def by_id(id)
37
+ Vra::Request.new(@client, id)
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,173 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'ffi_yajl'
20
+
21
+ module Vra
22
+ # rubocop:disable ClassLength
23
+ class Resource
24
+ attr_reader :client, :id, :resource_data
25
+
26
+ def initialize(client, opts)
27
+ @client = client
28
+ @id = opts[:id]
29
+ @resource_data = opts[:data]
30
+ @resource_actions = []
31
+
32
+ if @id.nil? && @resource_data.nil?
33
+ raise ArgumentError, 'must supply an id or a resource data hash'
34
+ end
35
+
36
+ if ! @id.nil? && ! @resource_data.nil?
37
+ raise ArgumentError, 'must supply an id OR a resource data hash, not both'
38
+ end
39
+
40
+ if @resource_data.nil?
41
+ fetch_resource_data
42
+ else
43
+ @id = @resource_data['id']
44
+ end
45
+ end
46
+
47
+ def fetch_resource_data
48
+ @resource_data = FFI_Yajl::Parser.parse(client.http_get!("/catalog-service/api/consumer/resources/#{@id}"))
49
+ rescue Vra::Exception::HTTPNotFound
50
+ raise Vra::Exception::NotFound, "resource ID #{@id} does not exist"
51
+ end
52
+
53
+ def name
54
+ @resource_data['name']
55
+ end
56
+
57
+ def status
58
+ @resource_data['status']
59
+ end
60
+
61
+ def vm?
62
+ @resource_data['resourceTypeRef']['id'] == 'Infrastructure.Virtual'
63
+ end
64
+
65
+ def tenant_id
66
+ @resource_data['organization']['tenantRef']
67
+ end
68
+
69
+ def tenant_name
70
+ @resource_data['organization']['tenantLabel']
71
+ end
72
+
73
+ def subtenant_id
74
+ @resource_data['organization']['subtenantRef']
75
+ end
76
+
77
+ def subtenant_name
78
+ @resource_data['organization']['subtenantLabel']
79
+ end
80
+
81
+ def catalog_id
82
+ @resource_data['catalogItem']['id']
83
+ end
84
+
85
+ def catalog_name
86
+ @resource_data['catalogItem']['label']
87
+ end
88
+
89
+ def network_interfaces
90
+ return unless vm?
91
+
92
+ network_list = @resource_data['resourceData']['entries'].find { |x| x['key'] == 'NETWORK_LIST' }
93
+ return if network_list.nil?
94
+
95
+ network_list['value']['items'].each_with_object([]) do |item, nics|
96
+ nic = {}
97
+ item['values']['entries'].each do |entry|
98
+ key = entry['key']
99
+ value = entry['value']['value']
100
+ nic[key] = value
101
+ end
102
+
103
+ nics << nic
104
+ end
105
+ end
106
+
107
+ def ip_addresses
108
+ return if !vm? || network_interfaces.nil?
109
+
110
+ addrs = []
111
+ network_interfaces.each do |nic|
112
+ next unless nic.key?('NETWORK_ADDRESS')
113
+ addrs << nic['NETWORK_ADDRESS']
114
+ end
115
+
116
+ addrs
117
+ end
118
+
119
+ def actions
120
+ # if this Resource instance was created with data from a "all_resources" fetch,
121
+ # it is likely missing operations data because the vRA API is not pleasant sometimes.
122
+ fetch_resource_data if @resource_data['operations'].nil?
123
+
124
+ @resource_data['operations']
125
+ end
126
+
127
+ def action_id_by_name(name)
128
+ return if actions.nil?
129
+
130
+ action = actions.find { |x| x['name'] == name }
131
+ return if action.nil?
132
+
133
+ action['id']
134
+ end
135
+
136
+ def destroy
137
+ action_id = action_id_by_name('Destroy')
138
+ raise Vra::Exception::NotFound, "No destroy action found for resource #{@id}" if action_id.nil?
139
+
140
+ submit_action_request(action_id)
141
+ end
142
+
143
+ def action_request_payload(action_id)
144
+ {
145
+ '@type' => 'ResourceActionRequest',
146
+ 'resourceRef' => {
147
+ 'id' => @id
148
+ },
149
+ 'resourceActionRef' => {
150
+ 'id' => action_id
151
+ },
152
+ 'organization' => {
153
+ 'tenantRef' => tenant_id,
154
+ 'tenantLabel' => tenant_name,
155
+ 'subtenantRef' => subtenant_id,
156
+ 'subtenantLabel' => subtenant_name
157
+ },
158
+ 'state' => 'SUBMITTED',
159
+ 'requestNumber' => 0,
160
+ 'requestData' => {
161
+ 'entries' => []
162
+ }
163
+ }
164
+ end
165
+
166
+ def submit_action_request(action_id)
167
+ payload = action_request_payload(action_id).to_json
168
+ response = client.http_post('/catalog-service/api/consumer/requests', payload)
169
+ request_id = response.headers[:location].split('/')[-1]
170
+ Vra::Request.new(client, request_id)
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,42 @@
1
+ #
2
+ # Author:: Chef Partner Engineering (<partnereng@chef.io>)
3
+ # Copyright:: Copyright (c) 2015 Chef Software, Inc.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ module Vra
20
+ class Resources
21
+ attr_reader :client
22
+
23
+ def initialize(client)
24
+ @client = client
25
+ end
26
+
27
+ def all_resources
28
+ resources = []
29
+
30
+ items = client.http_get_paginated_array!('/catalog-service/api/consumer/resources')
31
+ items.each do |item|
32
+ resources << Vra::Resource.new(client, data: item)
33
+ end
34
+
35
+ resources
36
+ end
37
+
38
+ def by_id(id)
39
+ Vra::Resource.new(client, id: id)
40
+ end
41
+ end
42
+ end