knife-oraclecloud 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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