knife-digital_ocean 2.2.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/README.md +112 -20
  4. data/Rakefile +6 -0
  5. data/knife-digital_ocean.gemspec +4 -0
  6. data/lib/chef/knife/digital_ocean_base.rb +15 -0
  7. data/lib/chef/knife/digital_ocean_domain_create.rb +9 -10
  8. data/lib/chef/knife/digital_ocean_domain_destroy.rb +5 -5
  9. data/lib/chef/knife/digital_ocean_domain_list.rb +1 -2
  10. data/lib/chef/knife/digital_ocean_domain_record_create.rb +18 -18
  11. data/lib/chef/knife/digital_ocean_domain_record_destroy.rb +9 -10
  12. data/lib/chef/knife/digital_ocean_domain_record_edit.rb +21 -21
  13. data/lib/chef/knife/digital_ocean_domain_record_list.rb +4 -5
  14. data/lib/chef/knife/digital_ocean_droplet_create.rb +4 -5
  15. data/lib/chef/knife/digital_ocean_droplet_destroy.rb +3 -6
  16. data/lib/chef/knife/digital_ocean_droplet_power.rb +66 -0
  17. data/lib/chef/knife/digital_ocean_droplet_powercycle.rb +48 -0
  18. data/lib/chef/knife/digital_ocean_droplet_reboot.rb +48 -0
  19. data/lib/chef/knife/digital_ocean_droplet_rebuild.rb +58 -0
  20. data/lib/chef/knife/digital_ocean_droplet_rename.rb +58 -0
  21. data/lib/chef/knife/digital_ocean_droplet_resize.rb +58 -0
  22. data/lib/chef/knife/digital_ocean_droplet_snapshot.rb +58 -0
  23. data/lib/chef/knife/digital_ocean_image_destroy.rb +42 -0
  24. data/lib/chef/knife/digital_ocean_image_list.rb +1 -1
  25. data/lib/chef/knife/digital_ocean_image_transfer.rb +66 -0
  26. data/lib/chef/knife/digital_ocean_region_list.rb +1 -1
  27. data/lib/chef/knife/digital_ocean_sshkey_create.rb +11 -11
  28. data/lib/chef/knife/digital_ocean_sshkey_destroy.rb +6 -6
  29. data/lib/chef/knife/digital_ocean_sshkey_list.rb +1 -1
  30. data/lib/knife-digital_ocean/version.rb +1 -1
  31. data/spec/fixtures/keys/id_rsa.pub +1 -0
  32. data/spec/fixtures/vcr_cassettes/accountinfo.yml +7 -9
  33. data/spec/fixtures/vcr_cassettes/domain_create.yml +65 -0
  34. data/spec/fixtures/vcr_cassettes/{domainlist.yml → domain_list.yml} +15 -12
  35. data/spec/fixtures/vcr_cassettes/domain_record_create.yml +65 -0
  36. data/spec/fixtures/vcr_cassettes/domain_record_list.yml +63 -0
  37. data/spec/fixtures/vcr_cassettes/droplet.yml +12 -17
  38. data/spec/fixtures/vcr_cassettes/droplet_power.yml +65 -0
  39. data/spec/fixtures/vcr_cassettes/droplet_powercycle.yml +127 -0
  40. data/spec/fixtures/vcr_cassettes/droplet_reboot.yml +127 -0
  41. data/spec/fixtures/vcr_cassettes/droplet_rebuild.yml +65 -0
  42. data/spec/fixtures/vcr_cassettes/droplet_rename.yml +127 -0
  43. data/spec/fixtures/vcr_cassettes/droplet_resize.yml +65 -0
  44. data/spec/fixtures/vcr_cassettes/droplet_snapshot.yml +1057 -0
  45. data/spec/fixtures/vcr_cassettes/image.yml +55 -59
  46. data/spec/fixtures/vcr_cassettes/public_images.yml +54 -59
  47. data/spec/fixtures/vcr_cassettes/region.yml +8 -10
  48. data/spec/fixtures/vcr_cassettes/sizes.yml +8 -10
  49. data/spec/fixtures/vcr_cassettes/sshkey.yml +8 -10
  50. data/spec/fixtures/vcr_cassettes/sshkey_create.yml +68 -0
  51. data/spec/lib/chef/knife/digital_ocean_account_info_spec.rb +4 -4
  52. data/spec/lib/chef/knife/digital_ocean_domain_create_spec.rb +35 -1
  53. data/spec/lib/chef/knife/digital_ocean_domain_list_spec.rb +8 -9
  54. data/spec/lib/chef/knife/digital_ocean_domain_record_create_spec.rb +37 -1
  55. data/spec/lib/chef/knife/digital_ocean_domain_record_list_spec.rb +34 -1
  56. data/spec/lib/chef/knife/digital_ocean_droplet_create_spec.rb +5 -1
  57. data/spec/lib/chef/knife/digital_ocean_droplet_list_spec.rb +4 -4
  58. data/spec/lib/chef/knife/digital_ocean_droplet_power_spec.rb +39 -0
  59. data/spec/lib/chef/knife/digital_ocean_droplet_powercycle_spec.rb +38 -0
  60. data/spec/lib/chef/knife/digital_ocean_droplet_reboot_spec.rb +38 -0
  61. data/spec/lib/chef/knife/digital_ocean_droplet_rebuild_spec.rb +39 -0
  62. data/spec/lib/chef/knife/digital_ocean_droplet_rename_spec.rb +39 -0
  63. data/spec/lib/chef/knife/digital_ocean_droplet_resize_spec.rb +39 -0
  64. data/spec/lib/chef/knife/digital_ocean_droplet_snapshot_spec.rb +39 -0
  65. data/spec/lib/chef/knife/digital_ocean_image_list_spec.rb +8 -10
  66. data/spec/lib/chef/knife/digital_ocean_region_list_spec.rb +4 -4
  67. data/spec/lib/chef/knife/digital_ocean_size_list_spec.rb +4 -4
  68. data/spec/lib/chef/knife/digital_ocean_sshkey_create_spec.rb +35 -1
  69. data/spec/lib/chef/knife/digital_ocean_sshkey_list_spec.rb +4 -4
  70. data/spec/spec_helper.rb +29 -2
  71. metadata +93 -6
  72. data/spec/lib/chef/knife/digital_ocean_domain_record_edit_spec.rb +0 -5
@@ -0,0 +1,58 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ #
13
+ require 'chef/knife/digital_ocean_base'
14
+
15
+ class Chef
16
+ class Knife
17
+ class DigitalOceanDropletResize < Knife
18
+ include Knife::DigitalOceanBase
19
+
20
+ banner 'knife digital_ocean droplet resize (options)'
21
+
22
+ option :size,
23
+ short: '-s SIZE',
24
+ long: '--size SIZE',
25
+ description: 'Power Action On/Off'
26
+
27
+ option :id,
28
+ short: '-I ID',
29
+ long: '--droplet-id ID',
30
+ description: 'Droplet ID'
31
+
32
+ def run
33
+ $stdout.sync = true
34
+
35
+ validate!
36
+
37
+ unless locate_config_value(:size)
38
+ ui.error('Size cannot be empty. => -s <size>')
39
+ exit 1
40
+ end
41
+
42
+ unless locate_config_value(:id)
43
+ ui.error('ID cannot be empty. => -I <id>')
44
+ exit 1
45
+ end
46
+
47
+ result = client.droplet_actions.resize(droplet_id: locate_config_value(:id), size: locate_config_value(:size))
48
+
49
+ unless result.class == DropletKit::Action
50
+ ui.error JSON.parse(result)['message']
51
+ exit 1
52
+ end
53
+
54
+ wait_for_status(result)
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,58 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ #
13
+ require 'chef/knife/digital_ocean_base'
14
+
15
+ class Chef
16
+ class Knife
17
+ class DigitalOceanDropletSnapshot < Knife
18
+ include Knife::DigitalOceanBase
19
+
20
+ banner 'knife digital_ocean droplet snapshot (options)'
21
+
22
+ option :name,
23
+ short: '-N NAME',
24
+ long: '--snapshot-name NAME',
25
+ description: 'Name of snapshot'
26
+
27
+ option :id,
28
+ short: '-I ID',
29
+ long: '--droplet-id ID',
30
+ description: 'Droplet ID'
31
+
32
+ def run
33
+ $stdout.sync = true
34
+
35
+ validate!
36
+
37
+ unless locate_config_value(:name)
38
+ ui.error('Name cannot be empty. => -N <name>')
39
+ exit 1
40
+ end
41
+
42
+ unless locate_config_value(:id)
43
+ ui.error('ID cannot be empty. => -I <id>')
44
+ exit 1
45
+ end
46
+
47
+ result = client.droplet_actions.snapshot(droplet_id: locate_config_value(:id), name: locate_config_value(:name))
48
+
49
+ unless result.class == DropletKit::Action
50
+ ui.error JSON.parse(result)['message']
51
+ exit 1
52
+ end
53
+
54
+ wait_for_status(result, status: 'active')
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ #
13
+ require 'chef/knife/digital_ocean_base'
14
+
15
+ class Chef
16
+ class Knife
17
+ class DigitalOceanImageDestroy < Knife
18
+ include Knife::DigitalOceanBase
19
+
20
+ banner 'knife digital_ocean image destroy (options)'
21
+
22
+ option :id,
23
+ short: '-I ID',
24
+ long: '--image-id ID',
25
+ description: 'The image ID'
26
+
27
+ def run
28
+ $stdout.sync = true
29
+
30
+ validate!
31
+
32
+ unless locate_config_value(:id)
33
+ ui.error('Image ID cannot be empty. => -I <image-id>')
34
+ exit 1
35
+ end
36
+
37
+ result = client.images.delete(id: locate_config_value(:id))
38
+ ui.info 'OK' if result == true or ui.error JSON.parse(result)['message']
39
+ end
40
+ end
41
+ end
42
+ end
@@ -44,7 +44,7 @@ class Chef
44
44
  found_images = images.find_all { |i| i.public == false }
45
45
  end
46
46
 
47
- found_images.each do |image|
47
+ found_images.sort_by(&:slug).each do |image|
48
48
  image_list << image.id.to_s
49
49
  image_list << image.distribution.to_s
50
50
  image_list << image.name.to_s
@@ -0,0 +1,66 @@
1
+ # Licensed under the Apache License, Version 2.0 (the "License");
2
+ # you may not use this file except in compliance with the License.
3
+ # You may obtain a copy of the License at
4
+ #
5
+ # http://www.apache.org/licenses/LICENSE-2.0
6
+ #
7
+ # Unless required by applicable law or agreed to in writing, software
8
+ # distributed under the License is distributed on an "AS IS" BASIS,
9
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10
+ # See the License for the specific language governing permissions and
11
+ # limitations under the License.
12
+ #
13
+ require 'chef/knife/digital_ocean_base'
14
+
15
+ class Chef
16
+ class Knife
17
+ class DigitalOceanImageTransfer < Knife
18
+ include Knife::DigitalOceanBase
19
+
20
+ banner 'knife digital_ocean image transfer (options)'
21
+
22
+ option :id,
23
+ short: '-I ID',
24
+ long: '--image-id ID',
25
+ description: 'The image ID'
26
+
27
+ option :region,
28
+ short: '-R REGION',
29
+ long: '--region REGION',
30
+ description: 'The region name'
31
+
32
+ def run
33
+ $stdout.sync = true
34
+
35
+ validate!
36
+
37
+ unless locate_config_value(:id)
38
+ ui.error('Image ID cannot be empty. => -I <image-id>')
39
+ exit 1
40
+ end
41
+
42
+ unless locate_config_value(:region)
43
+ ui.error('Image ID cannot be empty. => -R <region>')
44
+ exit 1
45
+ end
46
+
47
+ result = client.image_actions.transfer(image_id: locate_config_value(:id), region: locate_config_value(:region))
48
+
49
+ unless result.class == DropletKit::ImageAction
50
+ ui.error JSON.parse(result)['message']
51
+ exit 1
52
+ end
53
+
54
+ print 'Waiting '
55
+ while result.status == 'in-progress' do
56
+ sleep 8
57
+ print('.')
58
+
59
+ break if client.images.find(id: locate_config_value(:id)).
60
+ regions.include? locate_config_value(:region)
61
+ end
62
+ ui.info 'OK'
63
+ end
64
+ end
65
+ end
66
+ end
@@ -31,7 +31,7 @@ class Chef
31
31
 
32
32
  regions = client.regions.all
33
33
 
34
- regions.each do |region|
34
+ regions.sort_by(&:name).each do |region|
35
35
  region_list << region.name
36
36
  region_list << region.slug
37
37
  end
@@ -20,15 +20,15 @@ class Chef
20
20
 
21
21
  banner 'knife digital_ocean sshkey create (options)'
22
22
 
23
- option :name,
24
- :short => '-n NAME',
25
- :long => '--sshkey-name NAME',
26
- :description => 'The ssh key name'
23
+ option :name,
24
+ short: '-n NAME',
25
+ long: '--sshkey-name NAME',
26
+ description: 'The ssh key name'
27
27
 
28
- option :public_key,
29
- :short => '-i PUBLIC KEY',
30
- :long => '--public-key PUBLIC KEY',
31
- :description => 'File that contains your public ssh key'
28
+ option :public_key,
29
+ short: '-i PUBLIC KEY',
30
+ long: '--public-key PUBLIC KEY',
31
+ description: 'File that contains your public ssh key'
32
32
 
33
33
  def run
34
34
  $stdout.sync = true
@@ -36,18 +36,18 @@ class Chef
36
36
  validate!
37
37
 
38
38
  unless locate_config_value(:name)
39
- ui.error("SSH Key name cannot be empty. => -N <sshkey-name>")
39
+ ui.error('SSH Key name cannot be empty. => -N <sshkey-name>')
40
40
  exit 1
41
41
  end
42
42
 
43
43
  unless locate_config_value(:public_key)
44
- ui.error("SSH key file needs to be specified. => -I <public_key>")
44
+ ui.error('SSH key file needs to be specified. => -I <public_key>')
45
45
  exit 1
46
46
  end
47
47
 
48
48
  ssh_key = DropletKit::SSHKey.new name: locate_config_value(:name), public_key: File.read(File.expand_path(locate_config_value(:public_key)))
49
49
  result = client.ssh_keys.create(ssh_key)
50
- ui.error JSON.parse(result)['message'] rescue 'OK'
50
+ ui.info 'OK' if result.class == DropletKit::SSHKey or ui.error JSON.parse(result)['message']
51
51
  end
52
52
  end
53
53
  end
@@ -20,10 +20,10 @@ class Chef
20
20
 
21
21
  banner 'knife digital_ocean sshkey destroy (options)'
22
22
 
23
- option :id,
24
- :short => '-i ID',
25
- :long => '--sshkey-id ID',
26
- :description => 'The ssh key id'
23
+ option :id,
24
+ short: '-i ID',
25
+ long: '--sshkey-id ID',
26
+ description: 'The ssh key id'
27
27
 
28
28
  def run
29
29
  $stdout.sync = true
@@ -31,12 +31,12 @@ class Chef
31
31
  validate!
32
32
 
33
33
  unless locate_config_value(:id)
34
- ui.error("SSH key id cannot be empty. => -i <id>")
34
+ ui.error('SSH key id cannot be empty. => -i <id>')
35
35
  exit 1
36
36
  end
37
37
 
38
38
  result = client.ssh_keys.delete id: locate_config_value(:id)
39
- ui.error JSON.parse(result)['message'] rescue 'OK'
39
+ ui.info 'OK' if result == true or ui.error JSON.parse(result)['message']
40
40
  end
41
41
  end
42
42
  end
@@ -32,7 +32,7 @@ class Chef
32
32
 
33
33
  sshkeys = client.ssh_keys.all
34
34
 
35
- sshkeys.each do |sshkey|
35
+ sshkeys.sort_by(&:name).each do |sshkey|
36
36
  sshkey_list << sshkey.id.to_s
37
37
  sshkey_list << sshkey.name.to_s
38
38
  sshkey_list << sshkey.fingerprint.to_s
@@ -1,5 +1,5 @@
1
1
  module Knife
2
2
  module DigitalOcean
3
- VERSION = '2.2.0'
3
+ VERSION = '2.3.0'
4
4
  end
5
5
  end
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDb2qoPVE2V/w5QZPC6MdPnnJVg8o9w4DNk7hT2rGAM7cyIOL4tqmmcfABPGCEpxen048aXhabpq2BgQXWP9WJw8/FUiqjV1Aohqyev5nl0v00f9xlFRfCP/hatNsn8EvnUL32ijJI/vnKaVhXF6cPz9mYH8DumKE9SxAXC9m6ALu/JJHPUmRqONTUwIASkdxiuBJsjIKei4jU0H1nb8dc/ar1f5KXGgnMTikMnoDIuZosv8+I8r1R2gTIx1HmdJaK9IJx3KbaEHoCasTAK5W2PiP/vkGKQlAjolakE6CVapgDOvkKH7YfT0UBB9JGsGMhEzUphZ6kddSBYLscpKhAx gregf@betsy
@@ -25,16 +25,14 @@ http_interactions:
25
25
  Server:
26
26
  - cloudflare-nginx
27
27
  Date:
28
- - Tue, 11 Nov 2014 03:48:34 GMT
28
+ - Sun, 16 Nov 2014 00:35:57 GMT
29
29
  Content-Type:
30
30
  - application/json; charset=utf-8
31
31
  Transfer-Encoding:
32
32
  - chunked
33
33
  Connection:
34
34
  - keep-alive
35
- Set-Cookie:
36
- - __cfduid=d4ff495c6a4297ba6a268c69722a7928c1415677714886; expires=Mon, 23-Dec-2019
37
- 23:50:00 GMT; path=/; domain=.digitalocean.com; HttpOnly
35
+ Set-Cookie: _COOKIE_ID_
38
36
  Status:
39
37
  - 200 OK
40
38
  X-Frame-Options:
@@ -48,18 +46,18 @@ http_interactions:
48
46
  Ratelimit-Remaining:
49
47
  - '1180'
50
48
  Ratelimit-Reset:
51
- - '1415677540'
49
+ - '1416100824'
52
50
  Cache-Control:
53
51
  - max-age=0, private, must-revalidate
54
52
  X-Request-Id:
55
- - 8e7ba67a-eeca-432d-9a5f-951d3956a67c
53
+ - 0b0ea2dd-4632-4a9e-a799-cf8f5369ee8a
56
54
  X-Runtime:
57
- - '0.022150'
55
+ - '0.023825'
58
56
  Cf-Ray:
59
- - 187783d60a990ecd-EWR
57
+ - 189f9c8d006b0ec7-EWR
60
58
  body:
61
59
  encoding: UTF-8
62
60
  string: '{"account":{"droplet_limit":20,"email":"greg@gregf.org","uuid":"49e2e737d3a7407a042bb7e88f4da8629166f2b9","email_verified":true}}'
63
61
  http_version:
64
- recorded_at: Tue, 11 Nov 2014 03:48:34 GMT
62
+ recorded_at: Sun, 16 Nov 2014 00:35:57 GMT
65
63
  recorded_with: VCR 2.9.3
@@ -0,0 +1,65 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://api.digitalocean.com/v2/domains
6
+ body:
7
+ encoding: UTF-8
8
+ string: '{"name":"kitchen-digital.org","ip_address":"192.168.1.1"}'
9
+ headers:
10
+ Content-Type:
11
+ - application/json
12
+ Authorization:
13
+ - Bearer FAKE_ACCESS_TOKEN
14
+ User-Agent:
15
+ - Faraday v0.9.0
16
+ Accept-Encoding:
17
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
18
+ Accept:
19
+ - "*/*"
20
+ response:
21
+ status:
22
+ code: 201
23
+ message: Created
24
+ headers:
25
+ Server:
26
+ - cloudflare-nginx
27
+ Date:
28
+ - Sun, 16 Nov 2014 03:56:18 GMT
29
+ Content-Type:
30
+ - application/json; charset=utf-8
31
+ Transfer-Encoding:
32
+ - chunked
33
+ Connection:
34
+ - keep-alive
35
+ Set-Cookie: _COOKIE_ID_
36
+ Status:
37
+ - 201 Created
38
+ X-Frame-Options:
39
+ - SAMEORIGIN
40
+ X-Xss-Protection:
41
+ - 1; mode=block
42
+ X-Content-Type-Options:
43
+ - nosniff
44
+ Ratelimit-Limit:
45
+ - '1200'
46
+ Ratelimit-Remaining:
47
+ - '1169'
48
+ Ratelimit-Reset:
49
+ - '1416110320'
50
+ Etag:
51
+ - '"994a804e0eb309991d38d7a3985ec0d7"'
52
+ Cache-Control:
53
+ - max-age=0, private, must-revalidate
54
+ X-Request-Id:
55
+ - f80d9dde-9125-40a8-ac81-663b08ad6acd
56
+ X-Runtime:
57
+ - '0.458649'
58
+ Cf-Ray:
59
+ - 18a0c204fc560ec7-EWR
60
+ body:
61
+ encoding: UTF-8
62
+ string: '{"domain":{"name":"kitchen-digital.org","ttl":1800,"zone_file":null}}'
63
+ http_version:
64
+ recorded_at: Sun, 16 Nov 2014 03:56:18 GMT
65
+ recorded_with: VCR 2.9.3