knife-oraclecloud 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +12 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +202 -0
- data/README.md +248 -0
- data/Rakefile +6 -0
- data/knife-oraclecloud.gemspec +28 -0
- data/lib/chef/knife/cloud/oraclecloud_service.rb +206 -0
- data/lib/chef/knife/cloud/oraclecloud_service_helpers.rb +48 -0
- data/lib/chef/knife/cloud/oraclecloud_service_options.rb +58 -0
- data/lib/chef/knife/oraclecloud_image_list.rb +63 -0
- data/lib/chef/knife/oraclecloud_orchestration_delete.rb +51 -0
- data/lib/chef/knife/oraclecloud_orchestration_list.rb +65 -0
- data/lib/chef/knife/oraclecloud_orchestration_show.rb +64 -0
- data/lib/chef/knife/oraclecloud_server_create.rb +105 -0
- data/lib/chef/knife/oraclecloud_server_delete.rb +48 -0
- data/lib/chef/knife/oraclecloud_server_list.rb +67 -0
- data/lib/chef/knife/oraclecloud_server_show.rb +52 -0
- data/lib/chef/knife/oraclecloud_shape_list.rb +51 -0
- data/lib/knife-oraclecloud/version.rb +21 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/unit/cloud/oraclecloud_service_helpers_spec.rb +94 -0
- data/spec/unit/cloud/oraclecloud_service_spec.rb +386 -0
- data/spec/unit/oraclecloud_image_list_spec.rb +39 -0
- data/spec/unit/oraclecloud_orchestration_delete_spec.rb +59 -0
- data/spec/unit/oraclecloud_orchestration_list_spec.rb +56 -0
- data/spec/unit/oraclecloud_orchestration_show_spec.rb +96 -0
- data/spec/unit/oraclecloud_server_create_spec.rb +118 -0
- data/spec/unit/oraclecloud_server_delete_spec.rb +40 -0
- data/spec/unit/oraclecloud_server_list_spec.rb +59 -0
- data/spec/unit/oraclecloud_server_show_spec.rb +57 -0
- data/spec/unit/oraclecloud_shape_list_spec.rb +39 -0
- metadata +161 -0
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'knife-oraclecloud/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'knife-oraclecloud'
|
9
|
+
spec.version = KnifeOracleCloud::VERSION
|
10
|
+
spec.authors = ['Chef Partner Engineering']
|
11
|
+
spec.email = ['partnereng@chef.io']
|
12
|
+
spec.summary = 'Knife plugin to interact with Oracle Cloud.'
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = 'https://github.com/chef-partners/knife-oraclecloud'
|
15
|
+
spec.license = 'Apache 2.0'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0")
|
18
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'chef', '~> 12.0'
|
23
|
+
spec.add_dependency 'knife-cloud', '~> 1.2.0'
|
24
|
+
spec.add_dependency 'oraclecloud', '~> 1.0'
|
25
|
+
|
26
|
+
spec.add_development_dependency 'bundler', '~> 1.7'
|
27
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
28
|
+
end
|
@@ -0,0 +1,206 @@
|
|
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 'chef/knife/cloud/exceptions'
|
20
|
+
require 'chef/knife/cloud/service'
|
21
|
+
require 'chef/knife/cloud/helpers'
|
22
|
+
require 'chef/knife/cloud/oraclecloud_service_helpers'
|
23
|
+
require 'oraclecloud'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Knife
|
27
|
+
class Cloud
|
28
|
+
class OraclecloudService < Service # rubocop:disable Metrics/ClassLength
|
29
|
+
include OraclecloudServiceHelpers
|
30
|
+
|
31
|
+
attr_reader :wait_time, :refresh_time
|
32
|
+
|
33
|
+
def initialize(options = {})
|
34
|
+
super(options)
|
35
|
+
|
36
|
+
@username = options[:username]
|
37
|
+
@password = options[:password]
|
38
|
+
@api_url = options[:api_url]
|
39
|
+
@identity_domain = options[:identity_domain]
|
40
|
+
@verify_ssl = options[:verify_ssl]
|
41
|
+
@wait_time = options[:wait_time]
|
42
|
+
@refresh_time = options[:refresh_time]
|
43
|
+
end
|
44
|
+
|
45
|
+
def connection
|
46
|
+
@client ||= OracleCloud::Client.new(
|
47
|
+
api_url: @api_url,
|
48
|
+
identity_domain: @identity_domain,
|
49
|
+
username: @username,
|
50
|
+
password: @password,
|
51
|
+
verify_ssl: @verify_ssl
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
def prepend_identity_domain(path)
|
56
|
+
"#{connection.compute_identity_domain}/#{path}"
|
57
|
+
end
|
58
|
+
|
59
|
+
def create_server(options = {})
|
60
|
+
orchestration = create_orchestration(options)
|
61
|
+
orchestration.start
|
62
|
+
ui.msg("Orchestration #{orchestration.name_with_container} started - waiting for it to complete...")
|
63
|
+
wait_for_status(orchestration, 'ready')
|
64
|
+
ui.msg("Orchestration started successfully.\n")
|
65
|
+
orchestration_summary(orchestration)
|
66
|
+
ui.msg('')
|
67
|
+
|
68
|
+
servers = orchestration.instances
|
69
|
+
raise CloudExceptions::ServerCreateError, 'The orchestration created more than one server, ' \
|
70
|
+
'but we were only expecting 1' if servers.length > 1
|
71
|
+
raise CloudExceptions::ServerCreateError, 'The orchestration did not create any servers' if servers.length == 0
|
72
|
+
|
73
|
+
servers.first
|
74
|
+
end
|
75
|
+
|
76
|
+
def delete_server(instance_id)
|
77
|
+
instance = get_server(instance_id)
|
78
|
+
server_summary(instance)
|
79
|
+
ui.msg('')
|
80
|
+
|
81
|
+
unless instance.orchestration.nil?
|
82
|
+
ui.error('Unable to delete this server. Delete the orchestration instead.')
|
83
|
+
exit(1)
|
84
|
+
end
|
85
|
+
|
86
|
+
ui.confirm('Do you really want to delete this server')
|
87
|
+
|
88
|
+
ui.msg('Deleting the instance...')
|
89
|
+
instance.delete
|
90
|
+
|
91
|
+
ui.msg('Delete request complete.')
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_orchestration(options)
|
95
|
+
connection.orchestrations.create(
|
96
|
+
name: options[:name],
|
97
|
+
description: "#{options[:name]} by #{connection.username} via Knife",
|
98
|
+
instances: [ instance_request(options) ]
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
def delete_orchestration(orchestration_id)
|
103
|
+
orchestration = get_orchestration(orchestration_id)
|
104
|
+
orchestration_summary(orchestration)
|
105
|
+
ui.msg('')
|
106
|
+
|
107
|
+
ui.confirm('Do you really want to delete this orchestration')
|
108
|
+
|
109
|
+
ui.msg('Stopping the orchestration and any instances...')
|
110
|
+
orchestration.stop
|
111
|
+
wait_for_status(orchestration, 'stopped')
|
112
|
+
|
113
|
+
ui.msg('Deleting the orchestration and any instances...')
|
114
|
+
orchestration.delete
|
115
|
+
|
116
|
+
ui.msg('Delete request complete.')
|
117
|
+
end
|
118
|
+
|
119
|
+
def instance_request(options)
|
120
|
+
connection.instance_request(
|
121
|
+
name: options[:name],
|
122
|
+
shape: options[:shape],
|
123
|
+
imagelist: options[:image],
|
124
|
+
sshkeys: options[:sshkeys],
|
125
|
+
label: options[:label],
|
126
|
+
public_ip: options[:public_ip]
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
def list_servers
|
131
|
+
connection.instances.all
|
132
|
+
end
|
133
|
+
|
134
|
+
def list_orchestrations
|
135
|
+
connection.orchestrations.all
|
136
|
+
end
|
137
|
+
|
138
|
+
def list_images
|
139
|
+
connection.imagelists.all
|
140
|
+
end
|
141
|
+
|
142
|
+
def list_shapes
|
143
|
+
connection.shapes.all
|
144
|
+
end
|
145
|
+
|
146
|
+
def get_server(instance_id)
|
147
|
+
connection.instances.by_name(instance_id)
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_orchestration(orchestration_id)
|
151
|
+
connection.orchestrations.by_name(orchestration_id)
|
152
|
+
end
|
153
|
+
|
154
|
+
def orchestration_summary(orchestration)
|
155
|
+
msg_pair('Orchestration ID', orchestration.name_with_container)
|
156
|
+
msg_pair('Description', orchestration.description)
|
157
|
+
msg_pair('Status', orchestration.status)
|
158
|
+
msg_pair('Instance Count', orchestration.instance_count)
|
159
|
+
end
|
160
|
+
|
161
|
+
def server_summary(server, _columns_with_info = nil)
|
162
|
+
msg_pair('Server Label', server.label)
|
163
|
+
msg_pair('Status', server.status)
|
164
|
+
msg_pair('Hostname', server.hostname)
|
165
|
+
msg_pair('IP Address', server.ip_address.nil? ? 'none' : server.ip_address)
|
166
|
+
msg_pair('Public IP Addresses', server.public_ip_addresses.empty? ? 'none' : server.public_ip_addresses.join(', '))
|
167
|
+
msg_pair('Image', server.image)
|
168
|
+
msg_pair('Shape', server.shape)
|
169
|
+
msg_pair('Orchestration', server.orchestration.nil? ? 'none' : server.orchestration)
|
170
|
+
end
|
171
|
+
|
172
|
+
def wait_for_status(item, requested_status)
|
173
|
+
last_status = ''
|
174
|
+
|
175
|
+
begin
|
176
|
+
Timeout.timeout(wait_time) do
|
177
|
+
loop do
|
178
|
+
item.refresh
|
179
|
+
current_status = item.status
|
180
|
+
|
181
|
+
if current_status == requested_status
|
182
|
+
print "\n"
|
183
|
+
break
|
184
|
+
end
|
185
|
+
|
186
|
+
if last_status == current_status
|
187
|
+
print '.'
|
188
|
+
else
|
189
|
+
last_status = current_status
|
190
|
+
print "\n"
|
191
|
+
print "Current status: #{current_status}."
|
192
|
+
end
|
193
|
+
|
194
|
+
sleep refresh_time
|
195
|
+
end
|
196
|
+
end
|
197
|
+
rescue Timeout::Error
|
198
|
+
ui.msg('')
|
199
|
+
ui.error("Request did not complete in #{wait_time} seconds. Check the Oracle Cloud Web UI for more information.")
|
200
|
+
exit 1
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
@@ -0,0 +1,48 @@
|
|
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
|
+
class Chef
|
20
|
+
class Knife
|
21
|
+
class Cloud
|
22
|
+
module OraclecloudServiceHelpers
|
23
|
+
def create_service_instance
|
24
|
+
Chef::Knife::Cloud::OraclecloudService.new(username: locate_config_value(:oraclecloud_username),
|
25
|
+
password: locate_config_value(:oraclecloud_password),
|
26
|
+
api_url: locate_config_value(:oraclecloud_api_url),
|
27
|
+
identity_domain: locate_config_value(:oraclecloud_domain),
|
28
|
+
wait_time: locate_config_value(:wait_time),
|
29
|
+
refresh_time: locate_config_value(:request_refresh_rate),
|
30
|
+
verify_ssl: verify_ssl?)
|
31
|
+
end
|
32
|
+
|
33
|
+
def verify_ssl?
|
34
|
+
!locate_config_value(:oraclecloud_disable_ssl_verify)
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_for_missing_config_values!(*keys)
|
38
|
+
missing = keys.select { |x| locate_config_value(x).nil? }
|
39
|
+
|
40
|
+
unless missing.empty? # rubocop:disable Style/GuardClause
|
41
|
+
ui.error("The following required parameters are missing: #{missing.join(', ')}")
|
42
|
+
exit(1)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,58 @@
|
|
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
|
+
class Chef
|
20
|
+
class Knife
|
21
|
+
class Cloud
|
22
|
+
# rubocop:disable Style/AlignParameters
|
23
|
+
module OraclecloudServiceOptions
|
24
|
+
def self.included(includer)
|
25
|
+
includer.class_eval do
|
26
|
+
option :oraclecloud_api_url,
|
27
|
+
long: '--oraclecloud-api-url API_URL',
|
28
|
+
description: 'URL for the oraclecloud API server'
|
29
|
+
|
30
|
+
option :oraclecloud_username,
|
31
|
+
long: '--oraclecloud-username USERNAME',
|
32
|
+
description: 'Username to use with the oraclecloud API'
|
33
|
+
|
34
|
+
option :oraclecloud_password,
|
35
|
+
long: '--oraclecloud-password PASSWORD',
|
36
|
+
description: 'Password to use with the oraclecloud API'
|
37
|
+
|
38
|
+
option :oraclecloud_domain,
|
39
|
+
long: '--oraclecloud-domain IDENTITYDOMAIN',
|
40
|
+
description: 'Identity domain to use with the oraclecloud API'
|
41
|
+
|
42
|
+
option :oraclecloud_disable_ssl_verify,
|
43
|
+
long: '--oraclecloud-disable-ssl-verify',
|
44
|
+
description: 'Skip any SSL verification for the oraclecloud API',
|
45
|
+
boolean: true,
|
46
|
+
default: false
|
47
|
+
|
48
|
+
option :request_refresh_rate,
|
49
|
+
long: '--request-refresh-rate SECS',
|
50
|
+
description: 'Number of seconds to sleep between each check of the request status, defaults to 2',
|
51
|
+
default: 2,
|
52
|
+
proc: proc { |secs| secs.to_i }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,63 @@
|
|
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 'chef/knife'
|
20
|
+
require 'chef/knife/cloud/list_resource_command'
|
21
|
+
require 'chef/knife/cloud/oraclecloud_service'
|
22
|
+
require 'chef/knife/cloud/oraclecloud_service_helpers'
|
23
|
+
require 'chef/knife/cloud/oraclecloud_service_options'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Knife
|
27
|
+
class Cloud
|
28
|
+
class OraclecloudImageList < ResourceListCommand
|
29
|
+
include OraclecloudServiceHelpers
|
30
|
+
include OraclecloudServiceOptions
|
31
|
+
|
32
|
+
banner 'knife oraclecloud image list'
|
33
|
+
|
34
|
+
def before_exec_command
|
35
|
+
@columns_with_info = [
|
36
|
+
{ label: 'Image Name', key: 'name' },
|
37
|
+
{ label: 'Description', key: 'description' }
|
38
|
+
]
|
39
|
+
|
40
|
+
@sort_by_field = 'name'
|
41
|
+
end
|
42
|
+
|
43
|
+
def query_resource
|
44
|
+
service.list_images
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_status_value(status)
|
48
|
+
status = status.downcase
|
49
|
+
status_color = case status
|
50
|
+
when 'ready'
|
51
|
+
:green
|
52
|
+
when 'stopped'
|
53
|
+
:red
|
54
|
+
else
|
55
|
+
:yellow
|
56
|
+
end
|
57
|
+
|
58
|
+
ui.color(status, status_color)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,51 @@
|
|
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 'chef/knife'
|
20
|
+
require 'chef/knife/cloud/command'
|
21
|
+
require 'chef/knife/cloud/oraclecloud_service'
|
22
|
+
require 'chef/knife/cloud/oraclecloud_service_helpers'
|
23
|
+
require 'chef/knife/cloud/oraclecloud_service_options'
|
24
|
+
|
25
|
+
class Chef
|
26
|
+
class Knife
|
27
|
+
class Cloud
|
28
|
+
class OraclecloudOrchestrationDelete < Command
|
29
|
+
include OraclecloudServiceHelpers
|
30
|
+
include OraclecloudServiceOptions
|
31
|
+
|
32
|
+
banner 'knife oraclecloud orchestration delete ORCHESTRATION_ID [ORCHESTRATION_ID] (options)'
|
33
|
+
|
34
|
+
def validate_params!
|
35
|
+
if @name_args.empty?
|
36
|
+
ui.error('You must supply at least one Orchestration ID to delete.')
|
37
|
+
exit 1
|
38
|
+
end
|
39
|
+
|
40
|
+
super
|
41
|
+
end
|
42
|
+
|
43
|
+
def execute_command
|
44
|
+
@name_args.each do |orchestration_id|
|
45
|
+
service.delete_orchestration(orchestration_id)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|