knife-oraclecloud 1.0.0

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 (36) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +12 -0
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +3 -0
  7. data/LICENSE.txt +202 -0
  8. data/README.md +248 -0
  9. data/Rakefile +6 -0
  10. data/knife-oraclecloud.gemspec +28 -0
  11. data/lib/chef/knife/cloud/oraclecloud_service.rb +206 -0
  12. data/lib/chef/knife/cloud/oraclecloud_service_helpers.rb +48 -0
  13. data/lib/chef/knife/cloud/oraclecloud_service_options.rb +58 -0
  14. data/lib/chef/knife/oraclecloud_image_list.rb +63 -0
  15. data/lib/chef/knife/oraclecloud_orchestration_delete.rb +51 -0
  16. data/lib/chef/knife/oraclecloud_orchestration_list.rb +65 -0
  17. data/lib/chef/knife/oraclecloud_orchestration_show.rb +64 -0
  18. data/lib/chef/knife/oraclecloud_server_create.rb +105 -0
  19. data/lib/chef/knife/oraclecloud_server_delete.rb +48 -0
  20. data/lib/chef/knife/oraclecloud_server_list.rb +67 -0
  21. data/lib/chef/knife/oraclecloud_server_show.rb +52 -0
  22. data/lib/chef/knife/oraclecloud_shape_list.rb +51 -0
  23. data/lib/knife-oraclecloud/version.rb +21 -0
  24. data/spec/spec_helper.rb +17 -0
  25. data/spec/unit/cloud/oraclecloud_service_helpers_spec.rb +94 -0
  26. data/spec/unit/cloud/oraclecloud_service_spec.rb +386 -0
  27. data/spec/unit/oraclecloud_image_list_spec.rb +39 -0
  28. data/spec/unit/oraclecloud_orchestration_delete_spec.rb +59 -0
  29. data/spec/unit/oraclecloud_orchestration_list_spec.rb +56 -0
  30. data/spec/unit/oraclecloud_orchestration_show_spec.rb +96 -0
  31. data/spec/unit/oraclecloud_server_create_spec.rb +118 -0
  32. data/spec/unit/oraclecloud_server_delete_spec.rb +40 -0
  33. data/spec/unit/oraclecloud_server_list_spec.rb +59 -0
  34. data/spec/unit/oraclecloud_server_show_spec.rb +57 -0
  35. data/spec/unit/oraclecloud_shape_list_spec.rb +39 -0
  36. metadata +161 -0
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
@@ -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