knife-cloudstack 0.0.13 → 0.0.14

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