knife-cloudstack 0.0.13 → 0.0.14

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 (38) hide show
  1. data/CHANGES.rdoc +50 -0
  2. data/README.rdoc +221 -42
  3. data/lib/chef/knife/cs_account_list.rb +130 -0
  4. data/lib/chef/knife/cs_base.rb +98 -0
  5. data/lib/chef/knife/cs_baselist.rb +81 -0
  6. data/lib/chef/knife/cs_cluster_list.rb +93 -0
  7. data/lib/chef/knife/cs_config_list.rb +85 -0
  8. data/lib/chef/knife/cs_disk_list.rb +89 -0
  9. data/lib/chef/knife/cs_domain_list.rb +83 -0
  10. data/lib/chef/knife/cs_firewallrule_list.rb +95 -0
  11. data/lib/chef/knife/cs_host_list.rb +95 -0
  12. data/lib/chef/knife/cs_hosts.rb +2 -2
  13. data/lib/chef/knife/cs_iso_list.rb +103 -0
  14. data/lib/chef/knife/cs_network_list.rb +56 -46
  15. data/lib/chef/knife/cs_oscategory_list.rb +78 -0
  16. data/lib/chef/knife/cs_ostype_list.rb +80 -0
  17. data/lib/chef/knife/cs_pod_list.rb +93 -0
  18. data/lib/chef/knife/cs_project_list.rb +92 -0
  19. data/lib/chef/knife/cs_router_list.rb +94 -0
  20. data/lib/chef/knife/cs_server_create.rb +185 -144
  21. data/lib/chef/knife/cs_server_delete.rb +62 -79
  22. data/lib/chef/knife/cs_server_list.rb +136 -57
  23. data/lib/chef/knife/cs_server_reboot.rb +50 -54
  24. data/lib/chef/knife/cs_server_start.rb +48 -52
  25. data/lib/chef/knife/cs_server_stop.rb +54 -55
  26. data/lib/chef/knife/cs_service_list.rb +62 -41
  27. data/lib/chef/knife/cs_stack_create.rb +2 -2
  28. data/lib/chef/knife/cs_stack_delete.rb +2 -2
  29. data/lib/chef/knife/cs_template_create.rb +121 -0
  30. data/lib/chef/knife/cs_template_extract.rb +104 -0
  31. data/lib/chef/knife/cs_template_list.rb +65 -63
  32. data/lib/chef/knife/cs_template_register.rb +180 -0
  33. data/lib/chef/knife/cs_user_list.rb +93 -0
  34. data/lib/chef/knife/cs_volume_list.rb +94 -0
  35. data/lib/chef/knife/cs_zone_list.rb +55 -36
  36. data/lib/knife-cloudstack/connection.rb +75 -22
  37. data/lib/knife-cloudstack/string_to_regexp.rb +32 -0
  38. metadata +93 -61
@@ -1,6 +1,8 @@
1
1
  #
2
2
  # Author:: Ryan Holmes (<rholmes@edmunds.com>)
3
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
4
  # Copyright:: Copyright (c) 2011 Edmunds, Inc.
5
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
6
  # License:: Apache License, Version 2.0
5
7
  #
6
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,50 +18,24 @@
16
18
  # limitations under the License.
17
19
  #
18
20
 
19
- require 'chef/knife'
21
+ require 'chef/knife/cs_base'
20
22
 
21
23
  module KnifeCloudstack
22
24
  class CsServerDelete < Chef::Knife
23
25
 
26
+ include Chef::Knife::KnifeCloudstackBase
27
+
24
28
  deps do
25
29
  require 'knife-cloudstack/connection'
26
30
  require 'chef/api_client'
31
+ require 'chef/knife'
32
+ Chef::Knife.load_deps
27
33
  end
28
34
 
29
35
  banner "knife cs server delete SERVER_NAME [SERVER_NAME ...] (options)"
30
36
 
31
- option :cloudstack_url,
32
- :short => "-U URL",
33
- :long => "--cloudstack-url URL",
34
- :description => "The CloudStack endpoint URL",
35
- :proc => Proc.new { |url| Chef::Config[:knife][:cloudstack_url] = url }
36
-
37
- option :cloudstack_api_key,
38
- :short => "-A KEY",
39
- :long => "--cloudstack-api-key KEY",
40
- :description => "Your CloudStack API key",
41
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_api_key] = key }
42
-
43
- option :cloudstack_secret_key,
44
- :short => "-K SECRET",
45
- :long => "--cloudstack-secret-key SECRET",
46
- :description => "Your CloudStack secret key",
47
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_secret_key] = key }
48
-
49
- option :cloudstack_project,
50
- :short => "-P PROJECT_NAME",
51
- :long => '--cloudstack-project PROJECT_NAME',
52
- :description => "Cloudstack Project in which to create server",
53
- :proc => Proc.new { |v| Chef::Config[:knife][:cloudstack_project] = v },
54
- :default => nil
55
-
56
- option :use_http_ssl,
57
- :long => '--[no-]use-http-ssl',
58
- :description => 'Support HTTPS',
59
- :boolean => true,
60
- :default => true
61
-
62
37
  def run
38
+ validate_base_options
63
39
 
64
40
  @name_args.each do |hostname|
65
41
  server = connection.get_server(hostname)
@@ -74,31 +50,62 @@ module KnifeCloudstack
74
50
  next
75
51
  end
76
52
 
77
- puts "\n"
78
- msg("Name", server['name'])
79
- msg("Public IP", connection.get_server_public_ip(server) || '?')
80
- msg("Service", server['serviceofferingname'])
81
- msg("Template", server['templatename'])
82
- msg("Domain", server['domain'])
83
- msg("Zone", server['zonename'])
84
- msg("State", server['state'])
85
-
86
- puts "\n"
87
- ui.confirm("Do you really want to delete this server")
88
-
89
- print "#{ui.color("Waiting for deletion", :magenta)}"
90
- disassociate_virtual_ip_address server
91
- connection.delete_server hostname
92
- puts "\n"
93
- ui.msg("Deleted server #{hostname}")
94
-
95
- # delete chef client and node
96
- node_name = connection.get_server_fqdn server
97
- ui.confirm("Do you want to delete the chef node and client '#{node_name}")
98
- delete_node node_name
99
- delete_client node_name
53
+ rules = connection.list_port_forwarding_rules
54
+
55
+ show_object_details(server, connection, rules)
56
+
57
+ result = confirm_action("Do you really want to delete this server")
58
+ if result
59
+ print "#{ui.color("Waiting for deletion", :magenta)}"
60
+ disassociate_virtual_ip_address server
61
+ connection.delete_server hostname
62
+ puts "\n"
63
+ ui.msg("Deleted server #{hostname}")
64
+
65
+ # delete chef client and node
66
+ node_name = connection.get_server_fqdn server
67
+ delete_chef = confirm_action("Do you want to delete the chef node and client '#{node_name}")
68
+ if delete_chef
69
+ delete_node node_name
70
+ delete_client node_name
71
+ end
72
+
73
+ end
100
74
  end
75
+ end
101
76
 
77
+ def show_object_details(s, connection, rules)
78
+ return if locate_config_value(:yes)
79
+
80
+ object_fields = []
81
+ object_fields << ui.color("Name:", :cyan)
82
+ object_fields << s['name'].to_s
83
+ object_fields << ui.color("Public IP:", :cyan)
84
+ object_fields << (connection.get_server_public_ip(s, rules) || '')
85
+ object_fields << ui.color("Service:", :cyan)
86
+ object_fields << s['serviceofferingname'].to_s
87
+ object_fields << ui.color("Template:", :cyan)
88
+ object_fields << s['templatename']
89
+ object_fields << ui.color("Domain:", :cyan)
90
+ object_fields << s['domain']
91
+ object_fields << ui.color("Zone:", :cyan)
92
+ object_fields << s['zonename']
93
+ object_fields << ui.color("State:", :cyan)
94
+ object_fields << s['state']
95
+
96
+ puts "\n"
97
+ puts ui.list(object_fields, :uneven_columns_across, 2)
98
+ puts "\n"
99
+ end
100
+
101
+ def confirm_action(question)
102
+ return true if locate_config_value(:yes)
103
+ result = ui.ask_question(question, :default => "Y" )
104
+ if result == "Y" || result == "y" then
105
+ return true
106
+ else
107
+ return false
108
+ end
102
109
  end
103
110
 
104
111
  def disassociate_virtual_ip_address(server)
@@ -135,29 +142,5 @@ module KnifeCloudstack
135
142
  ui.msg "Deleted node #{name}"
136
143
  end
137
144
 
138
- def connection
139
- unless @connection
140
- @connection = CloudstackClient::Connection.new(
141
- locate_config_value(:cloudstack_url),
142
- locate_config_value(:cloudstack_api_key),
143
- locate_config_value(:cloudstack_secret_key),
144
- locate_config_value(:cloudstack_project),
145
- locate_config_value(:use_http_ssl)
146
- )
147
- end
148
- @connection
149
- end
150
-
151
- def msg(label, value)
152
- if value && !value.empty?
153
- puts "#{ui.color(label, :cyan)}: #{value}"
154
- end
155
- end
156
-
157
- def locate_config_value(key)
158
- key = key.to_sym
159
- Chef::Config[:knife][key] || config[key]
160
- end
161
-
162
145
  end
163
146
  end
@@ -1,6 +1,8 @@
1
1
  #
2
2
  # Author:: Ryan Holmes (<rholmes@edmunds.com>)
3
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
4
  # Copyright:: Copyright (c) 2011 Edmunds, Inc.
5
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
6
  # License:: Apache License, Version 2.0
5
7
  #
6
8
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -16,92 +18,169 @@
16
18
  # limitations under the License.
17
19
  #
18
20
 
19
- require 'chef/knife'
21
+ require 'chef/knife/cs_base'
22
+ require 'chef/knife/cs_baselist'
20
23
 
21
24
  module KnifeCloudstack
22
25
  class CsServerList < Chef::Knife
23
26
 
27
+ include Chef::Knife::KnifeCloudstackBase
28
+ include Chef::Knife::KnifeCloudstackBaseList
29
+
24
30
  deps do
31
+ require 'chef/knife'
25
32
  require 'knife-cloudstack/connection'
33
+ Chef::Knife.load_deps
26
34
  end
27
35
 
28
36
  banner "knife cs server list (options)"
29
37
 
30
- option :cloudstack_url,
31
- :short => "-U URL",
32
- :long => "--cloudstack-url URL",
33
- :description => "The CloudStack endpoint URL",
34
- :proc => Proc.new { |url| Chef::Config[:knife][:cloudstack_url] = url }
35
-
36
- option :cloudstack_api_key,
37
- :short => "-A KEY",
38
- :long => "--cloudstack-api-key KEY",
39
- :description => "Your CloudStack API key",
40
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_api_key] = key }
41
-
42
- option :cloudstack_secret_key,
43
- :short => "-K SECRET",
44
- :long => "--cloudstack-secret-key SECRET",
45
- :description => "Your CloudStack secret key",
46
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_secret_key] = key }
47
-
48
- option :cloudstack_project,
49
- :short => "-P PROJECT_NAME",
50
- :long => '--cloudstack-project PROJECT_NAME',
51
- :description => "Cloudstack Project in which to create server",
52
- :proc => Proc.new { |v| Chef::Config[:knife][:cloudstack_project] = v },
53
- :default => nil
54
-
55
- option :use_http_ssl,
56
- :long => '--[no-]use-http-ssl',
57
- :description => 'Support HTTPS',
58
- :boolean => true,
59
- :default => true
60
- def run
38
+ option :listall,
39
+ :long => "--listall",
40
+ :description => "List all the accounts",
41
+ :boolean => true
61
42
 
62
- $stdout.sync = true
43
+ option :name,
44
+ :long => "--name NAME",
45
+ :description => "Specify hostname to list"
63
46
 
64
- connection = CloudstackClient::Connection.new(
65
- locate_config_value(:cloudstack_url),
66
- locate_config_value(:cloudstack_api_key),
67
- locate_config_value(:cloudstack_secret_key),
68
- locate_config_value(:cloudstack_project),
69
- locate_config_value(:use_http_ssl)
70
- )
47
+ option :keyword,
48
+ :long => "--keyword NAME",
49
+ :description => "Specify part of instancename to list"
71
50
 
72
- server_list = [
51
+ option :action,
52
+ :short => "-a ACTION",
53
+ :long => "--action ACTION",
54
+ :description => "start, stop or destroy the instances in your result"
55
+
56
+ def run
57
+ validate_base_options
58
+
59
+ if locate_config_value(:fields)
60
+ object_list = []
61
+ locate_config_value(:fields).split(',').each { |n| object_list << ui.color(("#{n}").strip, :bold) }
62
+ else
63
+ object_list = [
73
64
  ui.color('Name', :bold),
74
65
  ui.color('Public IP', :bold),
75
66
  ui.color('Service', :bold),
76
67
  ui.color('Template', :bold),
77
68
  ui.color('State', :bold),
69
+ ui.color('Instance', :bold),
78
70
  ui.color('Hypervisor', :bold)
79
- ]
71
+ ]
72
+ end
80
73
 
81
- servers = connection.list_servers
82
- rules = connection.list_port_forwarding_rules
74
+ columns = object_list.count
75
+ object_list = [] if locate_config_value(:noheader)
76
+
77
+ connection_result = connection.list_object(
78
+ "listVirtualMachines",
79
+ "virtualmachine",
80
+ locate_config_value(:filter),
81
+ locate_config_value(:listall),
82
+ locate_config_value(:keyword),
83
+ locate_config_value(:name)
84
+ )
85
+
86
+ output_format(connection_result)
83
87
 
84
- servers.each do |server|
88
+ rules = connection.list_port_forwarding_rules
85
89
 
86
- name = server['name']
87
- display_name = server['displayname']
90
+ connection_result.each do |r|
91
+ name = r['name']
92
+ display_name = r['displayname']
88
93
  if display_name && !display_name.empty? && display_name != name
89
94
  name << " (#{display_name})"
90
95
  end
91
- server_list << server['name']
92
- server_list << (connection.get_server_public_ip(server, rules) || '')
93
- server_list << server['serviceofferingname']
94
- server_list << server['templatename']
95
- server_list << server['state']
96
- server_list << (server['hostname'] || 'N/A')
96
+
97
+ if locate_config_value(:fields)
98
+ locate_config_value(:fields).downcase.split(',').each { |n| object_list << ((r[("#{n}").strip]).to_s || 'N/A') }
99
+ else
100
+ object_list << r['name']
101
+ object_list << (connection.get_server_public_ip(r, rules) || '')
102
+ object_list << r['serviceofferingname']
103
+ object_list << r['templatename']
104
+ object_list << r['state']
105
+ object_list << (r['instancename'] || 'N/A')
106
+ object_list << (r['hostname'] || 'N/A')
107
+ end
97
108
  end
98
- puts ui.list(server_list, :columns_across, 6)
99
109
 
110
+ puts ui.list(object_list, :uneven_columns_across, columns)
111
+ list_object_fields(connection_result) if locate_config_value(:fieldlist)
112
+
113
+ ##
114
+ # Executing actions against the list results that are returned.
115
+
116
+ if locate_config_value(:action)
117
+ connection_result.each do |r|
118
+ hostname = r['name']
119
+ case locate_config_value(:action).downcase
120
+ when "start" then
121
+ show_object_details(r, connection, rules)
122
+ result = confirm_action("Do you really want to start this server ")
123
+ if result then
124
+ print "#{ui.color("Waiting for startup", :magenta)}"
125
+ connection.start_server(hostname)
126
+ puts "\n"
127
+ ui.msg("Started server #{hostname}")
128
+ end
129
+ when "stop" then
130
+ show_object_details(r, connection, rules)
131
+ result = confirm_action("Do you really want to stop this server ")
132
+ if result then
133
+ print "#{ui.color("Waiting for shutdown", :magenta)}"
134
+ connection.stop_server(hostname)
135
+ puts "\n"
136
+ ui.msg("Shutdown server #{hostname}")
137
+ end
138
+ when "destroy" then
139
+ show_object_details(r, connection, rules)
140
+ result = confirm_action("Do you really want to destroy this server ")
141
+ if result then
142
+ print "#{ui.color("Waiting for demolition", :magenta)}"
143
+ connection.delete_server(hostname)
144
+ puts "\n"
145
+ ui.msg("Destroyed server #{hostname}")
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ def show_object_details(s, connection, rules)
153
+ return if locate_config_value(:yes)
154
+
155
+ object_fields = []
156
+ object_fields << ui.color("Name:", :cyan)
157
+ object_fields << s['name'].to_s
158
+ object_fields << ui.color("Public IP:", :cyan)
159
+ object_fields << (connection.get_server_public_ip(s, rules) || '')
160
+ object_fields << ui.color("Service:", :cyan)
161
+ object_fields << s['serviceofferingname'].to_s
162
+ object_fields << ui.color("Template:", :cyan)
163
+ object_fields << s['templatename']
164
+ object_fields << ui.color("Domain:", :cyan)
165
+ object_fields << s['domain']
166
+ object_fields << ui.color("Zone:", :cyan)
167
+ object_fields << s['zonename']
168
+ object_fields << ui.color("State:", :cyan)
169
+ object_fields << s['state']
170
+
171
+ puts "\n"
172
+ puts ui.list(object_fields, :uneven_columns_across, 2)
173
+ puts "\n"
100
174
  end
101
175
 
102
- def locate_config_value(key)
103
- key = key.to_sym
104
- Chef::Config[:knife][key] || config[key]
176
+ def confirm_action(question)
177
+ return true if locate_config_value(:yes)
178
+ result = ui.ask_question(question, :default => "Y" )
179
+ if result == "Y" || result == "y" then
180
+ return true
181
+ else
182
+ return false
183
+ end
105
184
  end
106
185
 
107
186
  end
@@ -1,7 +1,9 @@
1
1
  #
2
2
  # Author:: Ryan Holmes (<rholmes@edmunds.com>)
3
3
  # Author:: KC Braunschweig (<kcbraunschweig@gmail.com>)
4
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
4
5
  # Copyright:: Copyright (c) 2011 Edmunds, Inc.
6
+ # Copyright:: Copyright (c) 2013 Sander Botman.
5
7
  # License:: Apache License, Version 2.0
6
8
  #
7
9
  # Licensed under the Apache License, Version 2.0 (the "License");
@@ -17,38 +19,25 @@
17
19
  # limitations under the License.
18
20
  #
19
21
 
20
- require 'chef/knife'
22
+ require 'chef/knife/cs_base'
21
23
 
22
24
  module KnifeCloudstack
23
25
  class CsServerReboot < Chef::Knife
24
26
 
27
+ include Chef::Knife::KnifeCloudstackBase
28
+
25
29
  deps do
26
30
  require 'knife-cloudstack/connection'
27
31
  require 'chef/api_client'
32
+ require 'chef/knife'
33
+ Chef::Knife.load_deps
28
34
  end
29
35
 
30
36
  banner "knife cs server reboot SERVER_NAME [SERVER_NAME ...] (options)"
31
37
 
32
- option :cloudstack_url,
33
- :short => "-U URL",
34
- :long => "--cloudstack-url URL",
35
- :description => "The CloudStack endpoint URL",
36
- :proc => Proc.new { |url| Chef::Config[:knife][:cloudstack_url] = url }
37
-
38
- option :cloudstack_api_key,
39
- :short => "-A KEY",
40
- :long => "--cloudstack-api-key KEY",
41
- :description => "Your CloudStack API key",
42
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_api_key] = key }
43
-
44
- option :cloudstack_secret_key,
45
- :short => "-K SECRET",
46
- :long => "--cloudstack-secret-key SECRET",
47
- :description => "Your CloudStack secret key",
48
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_secret_key] = key }
49
-
50
38
  def run
51
-
39
+ validate_base_options
40
+
52
41
  @name_args.each do |hostname|
53
42
  server = connection.get_server(hostname)
54
43
 
@@ -57,47 +46,54 @@ module KnifeCloudstack
57
46
  next
58
47
  end
59
48
 
60
- puts "\n"
61
- msg("Name", server['name'])
62
- msg("Public IP", connection.get_server_public_ip(server) || '?')
63
- msg("Service", server['serviceofferingname'])
64
- msg("Template", server['templatename'])
65
- msg("Domain", server['domain'])
66
- msg("Zone", server['zonename'])
67
- msg("State", server['state'])
68
-
69
- puts "\n"
70
- ui.confirm("Do you really want to reboot this server")
71
- print "#{ui.color("Rebooting", :magenta)}"
72
-
73
- connection.reboot_server(hostname)
74
- puts "\n"
75
- ui.msg("Rebooted server #{hostname}")
49
+ rules = connection.list_port_forwarding_rules
50
+
51
+ show_object_details(server, connection, rules)
52
+
53
+ result = confirm_action("Do you really want to reboot this server")
54
+
55
+ if result
56
+ print "#{ui.color("Rebooting", :magenta)}"
57
+ connection.reboot_server(hostname)
58
+ puts "\n"
59
+ ui.msg("Rebooted server #{hostname}")
60
+ end
76
61
  end
77
-
78
62
  end
79
63
 
80
- def connection
81
- unless @connection
82
- @connection = CloudstackClient::Connection.new(
83
- locate_config_value(:cloudstack_url),
84
- locate_config_value(:cloudstack_api_key),
85
- locate_config_value(:cloudstack_secret_key)
86
- )
87
- end
88
- @connection
64
+ def show_object_details(s, connection, rules)
65
+ return if locate_config_value(:yes)
66
+
67
+ object_fields = []
68
+ object_fields << ui.color("Name:", :cyan)
69
+ object_fields << s['name'].to_s
70
+ object_fields << ui.color("Public IP:", :cyan)
71
+ object_fields << (connection.get_server_public_ip(s, rules) || '')
72
+ object_fields << ui.color("Service:", :cyan)
73
+ object_fields << s['serviceofferingname'].to_s
74
+ object_fields << ui.color("Template:", :cyan)
75
+ object_fields << s['templatename']
76
+ object_fields << ui.color("Domain:", :cyan)
77
+ object_fields << s['domain']
78
+ object_fields << ui.color("Zone:", :cyan)
79
+ object_fields << s['zonename']
80
+ object_fields << ui.color("State:", :cyan)
81
+ object_fields << s['state']
82
+
83
+ puts "\n"
84
+ puts ui.list(object_fields, :uneven_columns_across, 2)
85
+ puts "\n"
89
86
  end
90
87
 
91
- def msg(label, value)
92
- if value && !value.empty?
93
- puts "#{ui.color(label, :cyan)}: #{value}"
88
+ def confirm_action(question)
89
+ return true if locate_config_value(:yes)
90
+ result = ui.ask_question(question, :default => "Y" )
91
+ if result == "Y" || result == "y" then
92
+ return true
93
+ else
94
+ return false
94
95
  end
95
96
  end
96
97
 
97
- def locate_config_value(key)
98
- key = key.to_sym
99
- Chef::Config[:knife][key] || config[key]
100
- end
101
-
102
98
  end
103
99
  end