knife-profitbricks 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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +201 -0
  5. data/README.md +209 -0
  6. data/Rakefile +7 -0
  7. data/knife-profitbricks.gemspec +27 -0
  8. data/lib/chef/knife/profitbricks_base.rb +56 -0
  9. data/lib/chef/knife/profitbricks_datacenter_create.rb +51 -0
  10. data/lib/chef/knife/profitbricks_datacenter_delete.rb +44 -0
  11. data/lib/chef/knife/profitbricks_datacenter_list.rb +32 -0
  12. data/lib/chef/knife/profitbricks_firewall_create.rb +121 -0
  13. data/lib/chef/knife/profitbricks_firewall_delete.rb +58 -0
  14. data/lib/chef/knife/profitbricks_firewall_list.rb +59 -0
  15. data/lib/chef/knife/profitbricks_image_list.rb +35 -0
  16. data/lib/chef/knife/profitbricks_ipblock_create.rb +43 -0
  17. data/lib/chef/knife/profitbricks_ipblock_delete.rb +32 -0
  18. data/lib/chef/knife/profitbricks_ipblock_list.rb +29 -0
  19. data/lib/chef/knife/profitbricks_lan_create.rb +54 -0
  20. data/lib/chef/knife/profitbricks_lan_delete.rb +38 -0
  21. data/lib/chef/knife/profitbricks_lan_list.rb +35 -0
  22. data/lib/chef/knife/profitbricks_location_list.rb +26 -0
  23. data/lib/chef/knife/profitbricks_nic_create.rb +78 -0
  24. data/lib/chef/knife/profitbricks_nic_delete.rb +45 -0
  25. data/lib/chef/knife/profitbricks_nic_list.rb +44 -0
  26. data/lib/chef/knife/profitbricks_server_create.rb +81 -0
  27. data/lib/chef/knife/profitbricks_server_delete.rb +40 -0
  28. data/lib/chef/knife/profitbricks_server_list.rb +45 -0
  29. data/lib/chef/knife/profitbricks_server_reboot.rb +32 -0
  30. data/lib/chef/knife/profitbricks_server_start.rb +32 -0
  31. data/lib/chef/knife/profitbricks_server_stop.rb +32 -0
  32. data/lib/chef/knife/profitbricks_volume_attach.rb +38 -0
  33. data/lib/chef/knife/profitbricks_volume_create.rb +82 -0
  34. data/lib/chef/knife/profitbricks_volume_delete.rb +40 -0
  35. data/lib/chef/knife/profitbricks_volume_detach.rb +45 -0
  36. data/lib/chef/knife/profitbricks_volume_list.rb +61 -0
  37. data/lib/knife-profitbricks/version.rb +6 -0
  38. data/spec/chef/knife/profitbricks_datacenter_list_spec.rb +23 -0
  39. data/spec/spec_helper.rb +15 -0
  40. data/spec/test.sh +3 -0
  41. metadata +157 -0
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'knife-profitbricks/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "knife-profitbricks"
8
+ spec.version = Knife::ProfitBricks::VERSION
9
+ spec.authors = ["Ethan Devenport"]
10
+ spec.email = ["ethand@stackpointcloud.com"]
11
+ spec.summary = %q{Chef Knife plugin for ProfitBricks platform}
12
+ spec.description = %q{Official Chef Knife plugin for ProfitBricks platform using REST API}
13
+ spec.homepage = "https://github.com/profitbricks/knife-profitbricks"
14
+ spec.license = "Apache"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "profitbricks-sdk-ruby", "~> 1.0"
22
+ spec.add_runtime_dependency "chef", "~> 12"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.6"
25
+ spec.add_development_dependency "rake", "~> 10.4"
26
+ spec.add_development_dependency "rspec", "~> 3.2"
27
+ end
@@ -0,0 +1,56 @@
1
+ require 'chef/knife'
2
+
3
+ class Chef
4
+ class Knife
5
+ module ProfitbricksBase
6
+ def self.included(includer)
7
+ includer.class_eval do
8
+ deps do
9
+ require 'profitbricks'
10
+ end
11
+
12
+ option :profitbricks_username,
13
+ short: '-u USERNAME',
14
+ long: '--username USERNAME',
15
+ description: 'Your ProfitBricks username',
16
+ proc: proc { |username| Chef::Config[:knife][:profitbricks_username] = username }
17
+
18
+ option :profitbricks_password,
19
+ short: '-p PASSWORD',
20
+ long: '--password PASSWORD',
21
+ description: 'Your ProfitBricks password',
22
+ proc: proc { |password| Chef::Config[:knife][:profitbricks_password] = password }
23
+
24
+ option :profitbricks_url,
25
+ short: '-U URL',
26
+ long: '--url URL',
27
+ description: 'The ProfitBricks API URL',
28
+ proc: proc { |url| Chef::Config[:knife][:profitbricks_url] = url }
29
+ end
30
+ end
31
+
32
+ def connection
33
+ ProfitBricks.configure do |config|
34
+ config.username = Chef::Config[:knife][:profitbricks_username]
35
+ config.password = Chef::Config[:knife][:profitbricks_password]
36
+ config.url = Chef::Config[:knife][:profitbricks_url]
37
+ config.debug = Chef::Config[:knife][:profitbricks_debug] || false
38
+ config.global_classes = false
39
+ end
40
+ end
41
+
42
+ def msg_pair(label, value, color = :cyan)
43
+ if value && !value.to_s.empty?
44
+ puts "#{ui.color(label, color)}: #{value}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ # compact method will remove nil values from Hash
52
+ class Hash
53
+ def compact
54
+ delete_if { |_k, v| v.nil? }
55
+ end
56
+ end
@@ -0,0 +1,51 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksDatacenterCreate < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks datacenter create (options)'
9
+
10
+ option :name,
11
+ short: '-n NAME',
12
+ long: '--name NAME',
13
+ description: 'Name of the data center'
14
+
15
+ option :description,
16
+ short: '-D DESCRIPTION',
17
+ long: '--description DESCRIPTION',
18
+ description: 'Description of the data center'
19
+
20
+ option :location,
21
+ short: '-l LOCATION',
22
+ long: '--location LOCATION',
23
+ description: 'Location of the data center',
24
+ proc: proc { |location| Chef::Config[:knife][:location] = location }
25
+
26
+ def run
27
+ $stdout.sync = true
28
+
29
+ print "#{ui.color('Creating data center...', :magenta)}"
30
+
31
+ connection
32
+ datacenter = ProfitBricks::Datacenter.create(
33
+ name: config[:name],
34
+ description: config[:description],
35
+ location: config[:location]
36
+ )
37
+
38
+ dot = ui.color('.', :magenta)
39
+ datacenter.wait_for { print dot; ready? }
40
+ datacenter.reload
41
+
42
+ puts "\n"
43
+ puts "#{ui.color('ID', :cyan)}: #{datacenter.id}"
44
+ puts "#{ui.color('Name', :cyan)}: #{datacenter.properties['name']}"
45
+ puts "#{ui.color('Description', :cyan)}: #{datacenter.properties['description']}"
46
+ puts "#{ui.color('Location', :cyan)}: #{datacenter.properties['location']}"
47
+ puts 'done'
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,44 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksDatacenterDelete < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks datacenter delete DATACENTER_ID' \
9
+ ' [DATACENTER_ID] (options)'
10
+
11
+ option :purge,
12
+ short: '-p',
13
+ long: '--purge',
14
+ boolean: true,
15
+ default: false,
16
+ description: 'Recursively delete the datacenter and all' \
17
+ ' corresponding resources under the datacenter.'
18
+
19
+ def run
20
+ connection
21
+ @name_args.each do |datacenter_id|
22
+ begin
23
+ datacenter = ProfitBricks::Datacenter.get(datacenter_id)
24
+ rescue Excon::Errors::NotFound
25
+ ui.error("Data center ID #{datacenter_id} not found. Skipping.")
26
+ next
27
+ end
28
+
29
+ msg_pair('ID', datacenter.id)
30
+ msg_pair('Name', datacenter.properties['name'])
31
+ msg_pair('Description', datacenter.properties['description'])
32
+ msg_pair('Location', datacenter.properties['location'])
33
+ msg_pair('Version', datacenter.properties['version'])
34
+
35
+ puts "\n"
36
+ confirm('Do you really want to delete this data center')
37
+
38
+ datacenter.delete
39
+ ui.warn("Deleted data center #{datacenter.id}")
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,32 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksDatacenterList < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks datacenter list'
9
+
10
+ def run
11
+ $stdout.sync = true
12
+ datacenter_list = [
13
+ ui.color('ID', :bold),
14
+ ui.color('Name', :bold),
15
+ ui.color('Description', :bold),
16
+ ui.color('Location', :bold),
17
+ ui.color('Version', :bold)
18
+ ]
19
+ connection
20
+ ProfitBricks::Datacenter.list.each do |datacenter|
21
+ datacenter_list << datacenter.id
22
+ datacenter_list << datacenter.properties['name']
23
+ datacenter_list << (datacenter.properties['description'] == nil ? '' : datacenter.properties['description'])
24
+ datacenter_list << datacenter.properties['location']
25
+ datacenter_list << datacenter.properties['version'].to_s
26
+ end
27
+
28
+ puts ui.list(datacenter_list, :uneven_columns_across, 5)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,121 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksFirewallCreate < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks firewall create (options)'
9
+
10
+ option :datacenter_id,
11
+ short: '-D DATACENTER_UUID',
12
+ long: '--datacenter-id DATACENTER_UUID',
13
+ description: 'UUID of the data center',
14
+ proc: proc { |datacenter_id| Chef::Config[:knife][:datacenter_id] = datacenter_id }
15
+
16
+ option :server_id,
17
+ short: '-S SERVER_UUID',
18
+ long: '--server-id SERVER_UUID',
19
+ description: 'UUID of the server'
20
+
21
+ option :nic_id,
22
+ short: '-N NIC_UUID',
23
+ long: '--nic-id NIC_UUID',
24
+ description: 'UUID of the NIC'
25
+
26
+ option :name,
27
+ short: '-n NAME',
28
+ long: '--name NAME',
29
+ description: 'Name of the NIC'
30
+
31
+ option :protocol,
32
+ short: '-P PROTOCOL',
33
+ long: '--protocol PROTOCOL',
34
+ default: 'TCP',
35
+ description: 'The protocol of the firewall rule (TCP, UDP, ICMP,' \
36
+ ' ANY)'
37
+
38
+ option :sourcemac,
39
+ short: '-m MAC',
40
+ long: '--source-mac MAC',
41
+ description: 'Only traffic originating from the respective MAC' \
42
+ ' address is allowed'
43
+
44
+ option :sourceip,
45
+ short: '-I IP',
46
+ long: '--source-ip IP',
47
+ description: 'Only traffic originating from the respective IPv4' \
48
+ ' address is allowed; null allows all source IPs'
49
+
50
+ option :targetip,
51
+ long: '--target-ip IP',
52
+ description: 'In case the target NIC has multiple IP addresses,' \
53
+ ' only traffic directed to the respective IP' \
54
+ ' address of the NIC is allowed; null value allows' \
55
+ ' all target IPs'
56
+
57
+ option :portrangestart,
58
+ short: '-p PORT',
59
+ long: '--port-range-start PORT',
60
+ description: 'Defines the start range of the allowed port(s)'
61
+
62
+ option :portrangeend,
63
+ short: '-t PORT',
64
+ long: '--port-range-end PORT',
65
+ description: 'Defines the end range of the allowed port(s)'
66
+
67
+ option :icmptype,
68
+ long: '--icmp-type INT',
69
+ description: 'Defines the allowed type (from 0 to 254) if the' \
70
+ ' protocol ICMP is chosen; null allows all types'
71
+
72
+ option :icmpcode,
73
+ long: '--icmp-code INT',
74
+ description: 'Defines the allowed code (from 0 to 254) if the' \
75
+ ' protocol ICMP is chosen; null allows all codes'
76
+
77
+ def run
78
+ $stdout.sync = true
79
+
80
+ print "#{ui.color('Creating firewall...', :magenta)}"
81
+
82
+ params = {
83
+ name: config[:name],
84
+ protocol: config[:protocol],
85
+ sourceMac: config[:sourcemac],
86
+ sourceIp: config[:sourceip],
87
+ targetIp: config[:targetip],
88
+ portRangeStart: config[:portrangestart],
89
+ portRangeEnd: config[:portrangeend],
90
+ icmpType: config[:icmptype],
91
+ icmpCode: config[:icmpcode]
92
+ }
93
+
94
+ connection
95
+ firewall = ProfitBricks::Firewall.create(
96
+ config[:datacenter_id],
97
+ config[:server_id],
98
+ config[:nic_id],
99
+ params.compact
100
+ )
101
+
102
+ dot = ui.color('.', :magenta)
103
+ firewall.wait_for { print dot; ready? }
104
+ firewall.reload
105
+
106
+ puts "\n"
107
+ puts "#{ui.color('ID', :cyan)}: #{firewall.id}"
108
+ puts "#{ui.color('Name', :cyan)}: #{firewall.properties['name']}"
109
+ puts "#{ui.color('Protocol', :cyan)}: #{firewall.properties['protocol']}"
110
+ puts "#{ui.color('Source MAC', :cyan)}: #{firewall.properties['sourceMac']}"
111
+ puts "#{ui.color('Source IP', :cyan)}: #{firewall.properties['sourceIp']}"
112
+ puts "#{ui.color('Target IP', :cyan)}: #{firewall.properties['targetIp']}"
113
+ puts "#{ui.color('Port Range Start', :cyan)}: #{firewall.properties['portRangeStart']}"
114
+ puts "#{ui.color('Port Range End', :cyan)}: #{firewall.properties['portRangeEnd']}"
115
+ puts "#{ui.color('ICMP Type', :cyan)}: #{firewall.properties['icmpType']}"
116
+ puts "#{ui.color('ICMP Code', :cyan)}: #{firewall.properties['icmpCode']}"
117
+ puts 'done'
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,58 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksFirewallDelete < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks firewall delete FIREWALL_UUID [FIREWALL_UUID] (options)'
9
+
10
+ option :datacenter_id,
11
+ short: '-D DATACENTER_UUID',
12
+ long: '--datacenter-id DATACENTER_UUID',
13
+ description: 'The UUID of the data center',
14
+ proc: proc { |datacenter_id| Chef::Config[:knife][:datacenter_id] = datacenter_id }
15
+
16
+ option :server_id,
17
+ short: '-S SERVER_UUID',
18
+ long: '--server-id SERVER_UUID',
19
+ description: 'The UUID of the server'
20
+
21
+ option :nic_id,
22
+ short: '-N NIC_UUID',
23
+ long: '--nic-id NIC_UUID',
24
+ description: 'UUID of the NIC'
25
+
26
+ def run
27
+ connection
28
+ @name_args.each do |firewall_id|
29
+ begin
30
+ firewall = ProfitBricks::Firewall.get(config[:datacenter_id],
31
+ config[:server_id],
32
+ config[:nic_id],
33
+ firewall_id)
34
+ rescue Excon::Errors::NotFound
35
+ ui.error("Firewall ID #{firewall_id} not found. Skipping.")
36
+ next
37
+ end
38
+
39
+ msg_pair('ID', firewall.id)
40
+ msg_pair('Name', firewall.properties['name'])
41
+ msg_pair('Protocol', firewall.properties['protocol'])
42
+ msg_pair('Source MAC', firewall.properties['sourceMac'])
43
+ msg_pair('Source IP', firewall.properties['sourceIp'])
44
+ msg_pair('Target IP', firewall.properties['targetIp'])
45
+ msg_pair('Port Range Start', firewall.properties['portRangeStart'])
46
+ msg_pair('Port Range End', firewall.properties['portRangeEnd'])
47
+ msg_pair('ICMP Type', firewall.properties['icmpType'])
48
+ msg_pair('ICMP Code', firewall.properties['icmpCode'])
49
+
50
+ confirm('Do you really want to delete this firewall rule')
51
+
52
+ firewall.delete
53
+ ui.warn("Deleted firewall rule #{firewall.id}")
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,59 @@
1
+ require 'chef/knife/profitbricks_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class ProfitbricksFirewallList < Knife
6
+ include Knife::ProfitbricksBase
7
+
8
+ banner 'knife profitbricks firewall list (options)'
9
+
10
+ option :datacenter_id,
11
+ short: '-D DATACENTER_UUID',
12
+ long: '--datacenter-id DATACENTER_UUID',
13
+ description: 'UUID of the data center',
14
+ proc: proc { |datacenter_id| Chef::Config[:knife][:datacenter_id] = datacenter_id }
15
+
16
+ option :server_id,
17
+ short: '-S SERVER_UUID',
18
+ long: '--server-id SERVER_UUID',
19
+ description: 'The UUID of the server'
20
+
21
+ option :nic_id,
22
+ short: '-N NIC_UUID',
23
+ long: '--nic-id NIC_UUID',
24
+ description: 'UUID of the NIC'
25
+
26
+ def run
27
+ $stdout.sync = true
28
+ firewall_list = [
29
+ ui.color('ID', :bold),
30
+ ui.color('Name', :bold),
31
+ ui.color('Protocol', :bold),
32
+ ui.color('Source MAC', :bold),
33
+ ui.color('Source IP', :bold),
34
+ ui.color('Target IP', :bold),
35
+ ui.color('Port Range Start', :bold),
36
+ ui.color('Port Range End', :bold),
37
+ ui.color('ICMP Type', :bold),
38
+ ui.color('ICMP CODE', :bold)
39
+ ]
40
+ connection
41
+
42
+ ProfitBricks::Firewall.list(config[:datacenter_id], config[:server_id], config[:nic_id]).each do |firewall|
43
+ firewall_list << firewall.id
44
+ firewall_list << firewall.properties['name']
45
+ firewall_list << firewall.properties['protocol'].to_s
46
+ firewall_list << firewall.properties['sourceMac'].to_s
47
+ firewall_list << firewall.properties['sourceIp'].to_s
48
+ firewall_list << firewall.properties['targetIp'].to_s
49
+ firewall_list << firewall.properties['portRangeStart'].to_s
50
+ firewall_list << firewall.properties['portRangeEnd'].to_s
51
+ firewall_list << firewall.properties['icmpType'].to_s
52
+ firewall_list << firewall.properties['icmpCode'].to_s
53
+ end
54
+
55
+ puts ui.list(firewall_list, :uneven_columns_across, 10)
56
+ end
57
+ end
58
+ end
59
+ end