knife-digital_ocean 0.7.0 → 2.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.
- checksums.yaml +4 -4
- data/.travis.yml +1 -8
- data/CHANGELOG.md +6 -1
- data/Guardfile +4 -5
- data/README.md +98 -117
- data/Rakefile +9 -9
- data/knife-digital_ocean.gemspec +9 -9
- data/lib/chef/knife/digital_ocean_base.rb +12 -24
- data/lib/chef/knife/digital_ocean_droplet_create.rb +102 -101
- data/lib/chef/knife/digital_ocean_droplet_destroy.rb +8 -9
- data/lib/chef/knife/digital_ocean_droplet_list.rb +16 -34
- data/lib/chef/knife/digital_ocean_image_list.rb +18 -31
- data/lib/chef/knife/digital_ocean_region_list.rb +8 -12
- data/lib/chef/knife/digital_ocean_size_list.rb +6 -12
- data/lib/chef/knife/digital_ocean_sshkey_list.rb +8 -11
- data/lib/knife-digital_ocean.rb +1 -1
- data/lib/knife-digital_ocean/version.rb +1 -1
- data/spec/lib/chef/knife/digital_ocean_droplet_create_spec.rb +64 -66
- data/spec/lib/chef/knife/digital_ocean_droplet_destroy_spec.rb +0 -1
- data/spec/lib/chef/knife/digital_ocean_droplet_list_spec.rb +0 -1
- data/spec/lib/chef/knife/digital_ocean_image_list_spec.rb +0 -1
- data/spec/lib/chef/knife/digital_ocean_region_list_spec.rb +0 -1
- data/spec/lib/chef/knife/digital_ocean_size_list_spec.rb +0 -1
- data/spec/lib/chef/knife/digital_ocean_sshkey_list_spec.rb +0 -1
- data/spec/lib/knife-digital_ocean/version_spec.rb +1 -2
- data/spec/spec_helper.rb +2 -4
- metadata +17 -15
@@ -1,9 +1,9 @@
|
|
1
1
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
2
|
# you may not use this file except in compliance with the License.
|
3
3
|
# You may obtain a copy of the License at
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software
|
8
8
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
9
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -30,120 +30,120 @@ class Chef
|
|
30
30
|
banner 'knife digital_ocean droplet create (options)'
|
31
31
|
|
32
32
|
option :server_name,
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
short: '-N NAME',
|
34
|
+
long: '--server-name NAME',
|
35
|
+
description: 'The server name',
|
36
|
+
proc: proc { |server_name| Chef::Config[:knife][:server_name] = server_name }
|
37
37
|
|
38
38
|
option :image,
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
39
|
+
short: '-I IMAGE',
|
40
|
+
long: '--image IMAGE',
|
41
|
+
description: 'Your DigitalOcean Image',
|
42
|
+
proc: proc { |image| Chef::Config[:knife][:image] = image }
|
43
43
|
|
44
44
|
option :size,
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
short: '-S SIZE',
|
46
|
+
long: '--size SIZE',
|
47
|
+
description: 'Your DigitalOcean Size',
|
48
|
+
proc: proc { |size| Chef::Config[:knife][:size] = size }
|
49
49
|
|
50
50
|
option :location,
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
51
|
+
short: '-L REGION',
|
52
|
+
long: '--location REGION',
|
53
|
+
description: 'DigitalOcean Location (Region)',
|
54
|
+
proc: proc { |location| Chef::Config[:knife][:location] = location }
|
55
55
|
|
56
56
|
option :ssh_key_ids,
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
short: '-K KEYID',
|
58
|
+
long: '--ssh-keys KEY_ID',
|
59
|
+
description: 'Comma spearated list of your SSH key ids',
|
60
|
+
proc: lambda { |o| o.split(/[\s,]+/) }
|
61
61
|
|
62
62
|
option :identity_file,
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
63
|
+
short: '-i IDENTITY_FILE',
|
64
|
+
long: '--identity-file IDENTITY_FILE',
|
65
|
+
description: 'The SSH identity file used for authentication',
|
66
|
+
proc: proc { |identity| Chef::Config[:knife][:identity_file] = identity }
|
67
67
|
|
68
68
|
option :bootstrap,
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
short: '-B',
|
70
|
+
long: '--bootstrap',
|
71
|
+
description: 'Do a chef-client bootstrap on the created droplet (for use with chef-server)'
|
72
72
|
|
73
73
|
option :solo,
|
74
|
-
|
75
|
-
|
76
|
-
|
74
|
+
long: '--[no-]solo',
|
75
|
+
description: 'Do a chef-solo bootstrap on the droplet using knife-solo',
|
76
|
+
proc: proc { |s| Chef::Config[:knife][:solo] = s }
|
77
77
|
|
78
78
|
option :ssh_user,
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
79
|
+
short: '-x USERNAME',
|
80
|
+
long: '--ssh-user USERNAME',
|
81
|
+
description: 'The ssh username; default is "root"',
|
82
|
+
default: 'root'
|
83
83
|
|
84
84
|
option :distro,
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
short: '-d DISTRO',
|
86
|
+
long: '--distro DISTRO',
|
87
|
+
description: 'Chef-Bootstrap a distro using a template; default is "chef-full"',
|
88
|
+
proc: proc { |d| Chef::Config[:knife][:distro] = d },
|
89
|
+
default: 'chef-full'
|
90
90
|
|
91
91
|
option :run_list,
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
92
|
+
short: '-r RUN_LIST',
|
93
|
+
long: '--run-list RUN_LIST',
|
94
|
+
description: 'Comma separated list of roles/recipes to apply',
|
95
|
+
proc: lambda { |o| o.split(/[\s,]+/) },
|
96
|
+
default: []
|
97
97
|
|
98
98
|
option :template_file,
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
99
|
+
long: '--template-file TEMPLATE',
|
100
|
+
description: 'Full path to location of template to use',
|
101
|
+
proc: proc { |t| Chef::Config[:knife][:template_file] = t },
|
102
|
+
default: false
|
103
103
|
|
104
104
|
option :host_key_verify,
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
long: '--[no-]host-key-verify',
|
106
|
+
description: 'Verify host key, enabled by default',
|
107
|
+
default: true
|
108
108
|
|
109
109
|
option :prerelease,
|
110
|
-
|
111
|
-
|
110
|
+
long: '--prerelease',
|
111
|
+
description: 'Install the pre-release chef gems'
|
112
112
|
|
113
113
|
option :bootstrap_version,
|
114
|
-
|
115
|
-
|
116
|
-
|
114
|
+
long: '--bootstrap-version VERSION',
|
115
|
+
description: 'The version of Chef to install',
|
116
|
+
proc: proc { |v| Chef::Config[:knife][:bootstrap_version] = v }
|
117
117
|
|
118
118
|
option :environment,
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
short: '-E ENVIRONMENT',
|
120
|
+
long: '--environment ENVIRONMENT',
|
121
|
+
description: 'The name of the chef environment to use',
|
122
|
+
proc: proc { |e| Chef::Config[:knife][:environment] = e },
|
123
|
+
default: '_default'
|
124
124
|
|
125
125
|
option :json_attributes,
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
126
|
+
short: '-j JSON',
|
127
|
+
long: '--json-attributes JSON',
|
128
|
+
description: 'A JSON string to be added to the first run of chef-client',
|
129
|
+
proc: lambda { |o| JSON.parse(o) }
|
130
130
|
|
131
131
|
option :private_networking,
|
132
|
-
|
133
|
-
|
134
|
-
|
132
|
+
long: '--private_networking',
|
133
|
+
description: 'Enables private networking if the selected region supports it',
|
134
|
+
default: false
|
135
135
|
|
136
136
|
option :secret_file,
|
137
|
-
|
138
|
-
|
139
|
-
|
137
|
+
long: '--secret-file SECRET_FILE',
|
138
|
+
description: 'A file containing the secret key to use to encrypt data bag item values',
|
139
|
+
proc: proc { |sf| Chef::Config[:knife][:secret_file] = sf }
|
140
140
|
|
141
141
|
option :ssh_port,
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
142
|
+
short: '-p PORT',
|
143
|
+
long: '--ssh-port PORT',
|
144
|
+
description: 'The ssh port',
|
145
|
+
default: '22',
|
146
|
+
proc: proc { |port| Chef::Config[:knife][:ssh_port] = port }
|
147
147
|
|
148
148
|
def run
|
149
149
|
$stdout.sync = true
|
@@ -180,40 +180,42 @@ class Chef
|
|
180
180
|
'Knife plugin knife-solo was not found.',
|
181
181
|
'Please add the knife-solo gem to your Gemfile or',
|
182
182
|
'install it manually with `gem install knife-solo`.'
|
183
|
-
].join(
|
183
|
+
].join(' ')
|
184
184
|
exit 1
|
185
185
|
end
|
186
186
|
|
187
|
-
|
188
|
-
:
|
189
|
-
:
|
190
|
-
:
|
191
|
-
:
|
192
|
-
:
|
187
|
+
droplet = DropletKit::Droplet.new(name: locate_config_value(:server_name),
|
188
|
+
size: locate_config_value(:size),
|
189
|
+
image: locate_config_value(:image),
|
190
|
+
region: locate_config_value(:location),
|
191
|
+
ssh_keys: locate_config_value(:ssh_key_ids).split(/, ?/),
|
192
|
+
private_networking: locate_config_value(:private_networking))
|
193
193
|
|
194
|
-
|
195
|
-
ui.error("Droplet could not be started #{response.inspect}")
|
196
|
-
exit 1
|
197
|
-
end
|
194
|
+
server = client.droplets.create(droplet)
|
198
195
|
|
199
|
-
|
196
|
+
# if client.droplets.find(id: server.id).status != 'in-progress'
|
197
|
+
# ui.error("Droplet could not be started #{server.inspect}")
|
198
|
+
# exit 1
|
199
|
+
# end
|
200
200
|
|
201
|
-
|
201
|
+
puts "Droplet creation for #{locate_config_value(:server_name)} started. Droplet-ID is #{server.id}"
|
202
|
+
|
203
|
+
unless !config.key?(:json_attributes) || config[:json_attributes].empty?
|
202
204
|
puts ui.color("JSON Attributes: #{config[:json_attributes]}", :magenta)
|
203
205
|
end
|
204
206
|
|
205
|
-
print ui.color(
|
206
|
-
print(
|
207
|
+
print ui.color('Waiting for IPv4-Address', :magenta)
|
208
|
+
print('.') until ip_address = ip_address_available(server.id) do
|
207
209
|
puts 'done'
|
208
|
-
|
210
|
+
end
|
209
211
|
|
210
212
|
puts ui.color("IPv4 address is: #{ip_address}", :green)
|
211
213
|
|
212
214
|
print ui.color('Waiting for sshd:', :magenta)
|
213
|
-
print('.') until tcp_test_ssh(ip_address)
|
215
|
+
print('.') until tcp_test_ssh(ip_address) do
|
214
216
|
sleep 2
|
215
217
|
puts 'done'
|
216
|
-
|
218
|
+
end
|
217
219
|
|
218
220
|
if locate_config_value(:bootstrap) || solo_bootstrap?
|
219
221
|
bootstrap_for_node(ip_address).run
|
@@ -221,14 +223,13 @@ class Chef
|
|
221
223
|
puts ip_address
|
222
224
|
exit 0
|
223
225
|
end
|
224
|
-
|
225
226
|
end
|
226
227
|
|
227
228
|
def ip_address_available(droplet_id)
|
228
|
-
|
229
|
-
if
|
229
|
+
server = client.droplets.find(id: droplet_id)
|
230
|
+
if server.public_ip
|
230
231
|
yield
|
231
|
-
|
232
|
+
server.public_ip
|
232
233
|
else
|
233
234
|
sleep @initial_sleep_delay ||= 10
|
234
235
|
false
|
@@ -262,7 +263,7 @@ class Chef
|
|
262
263
|
|
263
264
|
def bootstrap_for_node(ip_address)
|
264
265
|
bootstrap = bootstrap_class.new
|
265
|
-
bootstrap.name_args = [
|
266
|
+
bootstrap.name_args = [ip_address]
|
266
267
|
bootstrap.config.merge! config
|
267
268
|
bootstrap.config[:chef_node_name] = locate_config_value(:server_name)
|
268
269
|
bootstrap.config[:bootstrap_version] = locate_config_value(:bootstrap_version)
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
2
|
# you may not use this file except in compliance with the License.
|
3
3
|
# You may obtain a copy of the License at
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software
|
8
8
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
9
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -20,9 +20,9 @@ class Chef
|
|
20
20
|
banner 'knife digital_ocean droplet destroy (options)'
|
21
21
|
|
22
22
|
option :server,
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
short: '-S ID',
|
24
|
+
long: '--server ID',
|
25
|
+
description: 'The server id'
|
26
26
|
|
27
27
|
def run
|
28
28
|
$stdout.sync = true
|
@@ -30,14 +30,13 @@ class Chef
|
|
30
30
|
validate!
|
31
31
|
|
32
32
|
unless locate_config_value(:server)
|
33
|
-
ui.error(
|
33
|
+
ui.error('Server cannot be empty. ALL DATA WILL BE LOST! => -S <server-id>')
|
34
34
|
exit 1
|
35
35
|
end
|
36
36
|
|
37
|
-
result = client.droplets.delete locate_config_value(:server)
|
38
|
-
puts result
|
37
|
+
result = client.droplets.delete(id: locate_config_value(:server))
|
38
|
+
puts JSON.parse(result)['message'] rescue 'OK'
|
39
39
|
end
|
40
|
-
|
41
40
|
end
|
42
41
|
end
|
43
42
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
2
|
# you may not use this file except in compliance with the License.
|
3
3
|
# You may obtain a copy of the License at
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software
|
8
8
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
9
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -25,46 +25,28 @@ class Chef
|
|
25
25
|
validate!
|
26
26
|
|
27
27
|
droplet_list = [
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
28
|
+
ui.color('ID', :bold),
|
29
|
+
ui.color('Name', :bold),
|
30
|
+
ui.color('Size', :bold),
|
31
|
+
ui.color('Region', :bold),
|
32
|
+
ui.color('IPv4', :bold),
|
33
|
+
ui.color('Image', :bold),
|
34
|
+
ui.color('Status', :bold)
|
35
35
|
]
|
36
|
+
droplets = client.droplets.all
|
36
37
|
|
37
|
-
|
38
|
-
h[region.id] = region.name
|
39
|
-
h
|
40
|
-
end
|
41
|
-
|
42
|
-
sizes = client.sizes.list.sizes.inject({}) do |h, size|
|
43
|
-
h[size.id] = size.name
|
44
|
-
h
|
45
|
-
end
|
46
|
-
|
47
|
-
client.droplets.list.droplets.each do |droplet|
|
38
|
+
droplets.each do |droplet|
|
48
39
|
droplet_list << droplet.id.to_s
|
49
40
|
droplet_list << droplet.name.to_s
|
50
|
-
droplet_list <<
|
51
|
-
droplet_list <<
|
52
|
-
droplet_list << droplet.
|
53
|
-
|
54
|
-
image_details = client.images.show(droplet.image_id)
|
55
|
-
if image_details.status != 'OK'
|
56
|
-
image_os_info = 'N/A'
|
57
|
-
else
|
58
|
-
image_os_info = image_details.image.name
|
59
|
-
end
|
60
|
-
|
61
|
-
droplet_list << droplet.image_id.to_s + ' (' + image_os_info + ')'
|
41
|
+
droplet_list << droplet.size_slug.to_s
|
42
|
+
droplet_list << droplet.region.name.to_s
|
43
|
+
droplet_list << droplet.public_ip.to_s
|
44
|
+
droplet_list << droplet.image.name.to_s
|
62
45
|
droplet_list << droplet.status.to_s
|
63
46
|
end
|
64
47
|
|
65
|
-
puts
|
48
|
+
puts ui.list(droplet_list, :uneven_columns_across, 7)
|
66
49
|
end
|
67
|
-
|
68
50
|
end
|
69
51
|
end
|
70
52
|
end
|
@@ -1,9 +1,9 @@
|
|
1
1
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
2
|
# you may not use this file except in compliance with the License.
|
3
3
|
# You may obtain a copy of the License at
|
4
|
-
#
|
4
|
+
#
|
5
5
|
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# Unless required by applicable law or agreed to in writing, software
|
8
8
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
9
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -19,10 +19,10 @@ class Chef
|
|
19
19
|
|
20
20
|
banner 'knife digital_ocean image list (options)'
|
21
21
|
|
22
|
-
option :
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
option :public_images,
|
23
|
+
short: '-P',
|
24
|
+
long: '--public',
|
25
|
+
description: 'Show public images'
|
26
26
|
|
27
27
|
def run
|
28
28
|
$stdout.sync = true
|
@@ -30,42 +30,29 @@ class Chef
|
|
30
30
|
validate!
|
31
31
|
|
32
32
|
image_list = [
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
ui.color('ID', :bold),
|
34
|
+
ui.color('Distribution', :bold),
|
35
|
+
ui.color('Name', :bold),
|
36
|
+
ui.color('Slug', :bold)
|
37
37
|
]
|
38
38
|
|
39
|
-
|
40
|
-
filter = 'global'
|
41
|
-
else
|
42
|
-
filter = 'my_images'
|
43
|
-
end
|
44
|
-
|
45
|
-
images = client.images.list(:filter => filter).images
|
39
|
+
images = client.images.all
|
46
40
|
|
47
|
-
|
48
|
-
|
41
|
+
if config[:public_images]
|
42
|
+
found_images = images.find_all { |i| i.public == true }
|
43
|
+
else
|
44
|
+
found_images = images.find_all { |i| i.public == false }
|
49
45
|
end
|
50
46
|
|
51
|
-
|
47
|
+
found_images.each do |image|
|
52
48
|
image_list << image.id.to_s
|
53
49
|
image_list << image.distribution.to_s
|
54
50
|
image_list << image.name.to_s
|
55
|
-
image_list <<
|
51
|
+
image_list << image.slug.to_s
|
56
52
|
end
|
57
53
|
|
58
|
-
puts
|
54
|
+
puts ui.list(image_list, :uneven_columns_across, 4)
|
59
55
|
end
|
60
|
-
|
61
|
-
def truefalse(boolean)
|
62
|
-
if boolean
|
63
|
-
'+'
|
64
|
-
else
|
65
|
-
'-'
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
56
|
end
|
70
57
|
end
|
71
58
|
end
|