knife-cloudstack 0.0.14 → 0.0.15

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.
data/CHANGES.rdoc CHANGED
@@ -1,5 +1,20 @@
1
1
  = Changes
2
2
 
3
+ == 2013-11-04 (0.0.15)
4
+ * Bugfix: fixed the proxy with the option: --cloudstack-proxy http://username:password@yourproxy:8080 or use config file. (Sander Botman, 04 Nov 2013)
5
+ * Added subcommand: <tt>cs publicip list</tt> (Sander Botman, 03 Nov 2013)
6
+ * Bugfix: removed the chef rest dependency because this is changed in chef 11.8.0 (Sander Botman, 03 Nov 2013)
7
+ * Bugfix: added the option --cloudstack-no-ssl-verify in order to ignore ssl verification (Sander Botman, 03 Nov 2013)
8
+ * Added subcommand: <tt>cs forwardrule create</tt> (Sander Botman, 28 Aug 2013)
9
+ * Added subcommand: <tt>cs firewallrule create</tt> (Sander Botman, 28 Aug 2013)
10
+ * Added the option: <tt>--set-display-name</tt> to <tt>server create</tt> (Florin Stan, 5 Aug 2013)
11
+ * Added the option: <tt>--keypair</tt> to <tt>server create</tt> (Florin Stan, 31 Jul 2013)
12
+ * Added subcommand: <tt>cs volume create</tt> (Jeremy Baumont, 17 Jul 2013)
13
+ * Added the option: <tt>--disk</tt> to <tt>server create</tt> (Stanislav Voroniy (voroniys) 13 Jun 2013)
14
+ * Added subcommands: <tt>cs keypair list</tt>, <tt>cs keypair create</tt>, <tt>cs keypair delete</tt> and adding basic zone check. (Sebastian Goasguen (runseb) 29 May 2013)
15
+ * Bugfix: changed output name to password (Warren Bain, 26 May 2013)
16
+ * Bugfix: various bugfixes and fixing bootstrap context (bacoboy, 22 Apr 2013)
17
+
3
18
  == 2013-04-14 (0.0.14)
4
19
  * Added bash/addinstance.sh script in onder to ease instance creation from cli.
5
20
 
data/README.rdoc CHANGED
@@ -36,7 +36,9 @@ Additionally the following options may be set in your <tt>knife.rb</tt>:
36
36
  * knife[:cloudstack_service]
37
37
  * knife[:cloudstack_template]
38
38
  * knife[:cloudstack_zone]
39
- * knife[:distro]
39
+ * knife[:cloudstack_proxy]
40
+ * knife[:cloudstack_no_ssl_verify]
41
+ * knife[:distro]
40
42
  * knife[:template_file]
41
43
 
42
44
  == Public Clouds (Tata InstaCompute, Ninefold etc):
@@ -97,10 +99,9 @@ single number when the start and end ports are the same. For example, a rule to
97
99
  ==== Create Firewall Rule for given ip address
98
100
  The <tt>-f, --fw-rules</tt> option takes a comma separated list of firewall rules which are applied to the public ip address assigned to the current server.
99
101
 
100
- Firewall rules have the syntax <tt>START_PORT[:END_PORT[:PROTOCOL[:CIDR_LIST]]]</tt>. <tt>END_PORT</tt>, <tt>PROTOCOL</tt> and <tt>CIDR_LIST</tt> are optional.
101
- The default value of <tt>END_PORT</tt> is <tt>START_PORT</tt>, the default <tt>PROTOCOL</tt> is 'TCP' and the default <tt>CIDR_LIST</tt> is '0.0.0.0/0'.
102
- For example, a rule to open firewall for port 80 to everyone would look like <tt>80:80:TCP:0.0.0.0/0</tt>.
103
- In this case ,it could even be shortened to <tt>80</tt>.
102
+ Firewall rules have the syntax <tt>PROTOCOL[:CIDR_LIST[:START_PORT[:END_PORT]]]</tt>. <tt>START_PORT</tt> and <tt>END_PORT</tt> must not be specified when <tt>PROTOCOL</tt> is <tt>ICMP</tt>, <tt>CIDR_LIST</tt> is always optional.
103
+ The default value of <tt>END_PORT</tt> is <tt>START_PORT</tt>, the default <tt>CIDR_LIST</tt> is '0.0.0.0/0'.
104
+ For example, a rule to open firewall for port 80 to everyone would look like <tt>TCP::80</tt> and a rule to open ICMP to internal network would look like <tt>ICMP:10.0.0.0/8</tt>.
104
105
 
105
106
  === knife cs server delete
106
107
 
@@ -166,6 +167,9 @@ Returns a link where an extractable template can be downloaded
166
167
  === knife cs template register
167
168
  Creates a template based on a file
168
169
 
170
+ === knife cs volume create
171
+ Creates a volume based on a name
172
+
169
173
  === knife cs zone list
170
174
  Displays a list of all zones available in the currently configured CloudStack account. A zone can be specified
171
175
  when creating a new server by passing the zone name as an argument to the -Z (or --zone) option of the
@@ -255,7 +259,7 @@ Displays all the pods that are currently available within the cloudstack environ
255
259
 
256
260
  <tt>--name</tt> Filters your output on the name that you specify.
257
261
 
258
- ==== knife project list
262
+ ==== knife cs project list
259
263
  Displays all the projects that are within the cloudstack environment.
260
264
 
261
265
  <tt>--listall</tt> This will list all the projects, depending on the account that you are using.
@@ -264,6 +268,11 @@ Displays all the projects that are within the cloudstack environment.
264
268
 
265
269
  <tt>--name</tt> Filters your output on the name that you specify.
266
270
 
271
+ ==== knife cs publicip list
272
+ Displays all public ip's that are used within the cloudstack environment.
273
+
274
+ <tt>--listall</tt> This will list all the public ip's, depending on the account that you are using.
275
+
267
276
  ==== knife cs router list
268
277
  Displays all the routers that are within the cloudstack environment.
269
278
 
@@ -333,6 +342,7 @@ specifying one or more actions to be executed after a server (or group of server
333
342
  { "http_request": "http://${hadoop-master}:50070/index.jsp" }
334
343
  ]
335
344
  }
345
+ ]
336
346
  }
337
347
 
338
348
  ==== Stack Attributes
@@ -378,8 +388,9 @@ Author:: Ryan Holmes <rholmes@edmunds.com>
378
388
  Author:: KC Braunschweig <kcbraunschweig@gmail.com>
379
389
  Author:: John E. Vincent <lusis.org+github.com@gmail.com>
380
390
  Author:: Sander Botman <sbotman@schubergphilis.com>
391
+ Author:: Frank Breedijk <fbreedijk@schubergphilis.com>
392
+ Author:: Jeremy Baumont <jbaumont@schubergphilis.com>
381
393
  Copyright:: Copyright (c) 2011 Edmunds, Inc.
382
- Copyright:: Copyright (c) 2013 Sander Botman.
383
394
  License:: Apache License, Version 2.0
384
395
 
385
396
  Licensed under the Apache License, Version 2.0 (the "License");
@@ -55,12 +55,15 @@ class Chef
55
55
  :proc => Proc.new { |v| Chef::Config[:knife][:cloudstack_project] = v },
56
56
  :default => nil
57
57
 
58
- option :use_http_ssl,
59
- :long => '--[no-]use-http-ssl',
60
- :description => 'Turn HTTPS support On/Off. Default is On',
61
- :boolean => true,
62
- :default => true
63
-
58
+ option :cloudstack_no_ssl_verify,
59
+ :long => '--cloudstack-no-ssl-verify',
60
+ :description => "Disable certificate verify on SSL",
61
+ :boolean => true
62
+
63
+ option :cloudstack_proxy,
64
+ :long => '--cloudstack-proxy PROXY',
65
+ :description => "Enable proxy configuration for cloudstack api access"
66
+
64
67
  def validate_base_options
65
68
  unless locate_config_value :cloudstack_url
66
69
  ui.error "Cloudstack URL not specified"
@@ -82,13 +85,14 @@ class Chef
82
85
  locate_config_value(:cloudstack_api_key),
83
86
  locate_config_value(:cloudstack_secret_key),
84
87
  locate_config_value(:cloudstack_project),
85
- locate_config_value(:use_http_ssl)
88
+ locate_config_value(:cloudstack_no_ssl_verify),
89
+ locate_config_value(:cloudstack_proxy)
86
90
  )
87
91
  end
88
92
 
89
93
  def locate_config_value(key)
90
94
  key = key.to_sym
91
- Chef::Config[:knife][key] || config[key]
95
+ config[key] || Chef::Config[:knife][key]
92
96
  end
93
97
 
94
98
  end
@@ -0,0 +1,115 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife/cs_base'
20
+
21
+ module KnifeCloudstack
22
+ class CsFirewallruleCreate < Chef::Knife
23
+
24
+ include Chef::Knife::KnifeCloudstackBase
25
+
26
+ deps do
27
+ require 'knife-cloudstack/connection'
28
+ Chef::Knife.load_deps
29
+ end
30
+
31
+ banner "knife cs firewallrule create hostname 8080:8090:TCP:10.0.0.0/24"
32
+
33
+ option :syncrequest,
34
+ :long => "--sync",
35
+ :description => "Execute command as sync request",
36
+ :boolean => true
37
+
38
+ def run
39
+
40
+ hostname = @name_args.shift
41
+ unless /^[a-zA-Z0-9][a-zA-Z0-9-]*$/.match hostname then
42
+ ui.error "Invalid hostname. Please specify a short hostname, not an fqdn (e.g. 'myhost' instead of 'myhost.domain.com')."
43
+ exit 1
44
+ end
45
+
46
+ params = {}
47
+ locate_config_value(:openfirewall) ? params['openfirewall'] = 'true' : params['openfirewall'] = 'false'
48
+
49
+ # Lookup all server objects.
50
+ connection_result = connection.list_object(
51
+ "listVirtualMachines",
52
+ "virtualmachine"
53
+ )
54
+
55
+ # Lookup the hostname in the connection result
56
+ server = {}
57
+ connection_result.map { |n| server = n if n['name'].upcase == hostname.upcase }
58
+
59
+ if server['name'].nil?
60
+ ui.error "Cannot find hostname: #{hostname}."
61
+ exit 1
62
+ end
63
+
64
+ # Lookup the public ip address of the server
65
+ server_public_address = connection.get_server_public_ip(server)
66
+ ip_address = connection.get_public_ip_address(server_public_address)
67
+
68
+ if ip_address.nil? || ip_address['id'].nil?
69
+ ui.error "Cannot find public ip address for hostname: #{hostname}."
70
+ exit 1
71
+ end
72
+
73
+ @name_args.each do |rule|
74
+ create_port_forwarding_rule(ip_address, server['id'], rule, connection, params)
75
+ end
76
+
77
+ end
78
+
79
+ def create_port_forwarding_rule(ip_address, server_id, rule, connection, other_params)
80
+ args = rule.split(':')
81
+ startport = args[0]
82
+ endport = args[1] || args[0]
83
+ protocol = args[2] || "TCP"
84
+ cidrlist = args[3] || "0.0.0.0/0"
85
+
86
+ # Required parameters
87
+ params = {
88
+ 'command' => 'createFirewallRule',
89
+ 'ipaddressId' => ip_address['id'],
90
+ 'protocol' => protocol
91
+ }
92
+
93
+ # Optional parameters
94
+ opt_params = {
95
+ 'startport' => startport,
96
+ 'endport' => endport,
97
+ 'cidrlist' => cidrlist
98
+ }
99
+
100
+ params.merge!(opt_params)
101
+
102
+ Chef::Log.debug("Creating Firewall Rule for
103
+ #{ip_address['ipaddress']} with protocol: #{protocol}, start: #{startport} end: #{endport} cidr: #{cidrlist}")
104
+
105
+ if locate_config_value(:syncrequest)
106
+ result = connection.send_request(params)
107
+ Chef::Log.debug("JobResult: #{result}")
108
+ else
109
+ result = connection.send_async_request(params)
110
+ Chef::Log.debug("AsyncJobResult: #{result}")
111
+ end
112
+ end
113
+
114
+ end
115
+ end
@@ -0,0 +1,113 @@
1
+ #
2
+ # Author:: Sander Botman (<sbotman@schubergphilis.com>)
3
+ # Copyright:: Copyright (c) 2013 Sander Botman.
4
+ # License:: Apache License, Version 2.0
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+ #
18
+
19
+ require 'chef/knife/cs_base'
20
+
21
+ module KnifeCloudstack
22
+ class CsForwardruleCreate < Chef::Knife
23
+
24
+ include Chef::Knife::KnifeCloudstackBase
25
+
26
+ deps do
27
+ require 'knife-cloudstack/connection'
28
+ Chef::Knife.load_deps
29
+ end
30
+
31
+ banner "knife cs forwardrule create hostname 8080:8090:TCP"
32
+
33
+ option :openfirewall,
34
+ :long => "--openfirewall",
35
+ :description => "Add rule also to firewall",
36
+ :boolean => true
37
+
38
+ option :syncrequest,
39
+ :long => "--sync",
40
+ :description => "Execute command as sync request",
41
+ :boolean => true
42
+
43
+ def run
44
+
45
+ hostname = @name_args.shift
46
+ unless /^[a-zA-Z0-9][a-zA-Z0-9-]*$/.match hostname then
47
+ ui.error "Invalid hostname. Please specify a short hostname, not an fqdn (e.g. 'myhost' instead of 'myhost.domain.com')."
48
+ exit 1
49
+ end
50
+
51
+ params = {}
52
+ locate_config_value(:openfirewall) ? params['openfirewall'] = 'true' : params['openfirewall'] = 'false'
53
+
54
+ # Lookup all server objects.
55
+ connection_result = connection.list_object(
56
+ "listVirtualMachines",
57
+ "virtualmachine"
58
+ )
59
+
60
+ # Lookup the hostname in the connection result
61
+ server = {}
62
+ connection_result.map { |n| server = n if n['name'].upcase == hostname.upcase }
63
+
64
+ if server['name'].nil?
65
+ ui.error "Cannot find hostname: #{hostname}."
66
+ exit 1
67
+ end
68
+
69
+ # Lookup the public ip address of the server
70
+ server_public_address = connection.get_server_public_ip(server)
71
+ ip_address = connection.get_public_ip_address(server_public_address)
72
+
73
+ if ip_address.nil? || ip_address['id'].nil?
74
+ ui.error "Cannot find public ip address for hostname: #{hostname}."
75
+ exit 1
76
+ end
77
+
78
+ @name_args.each do |rule|
79
+ create_port_forwarding_rule(ip_address, server['id'], rule, connection, params)
80
+ end
81
+
82
+ end
83
+
84
+ def create_port_forwarding_rule(ip_address, server_id, rule, connection, other_params)
85
+ args = rule.split(':')
86
+ public_port = args[0]
87
+ private_port = args[1] || args[0]
88
+ protocol = args[2] || "TCP"
89
+
90
+ params = {
91
+ 'ipaddressId' => ip_address['id'],
92
+ 'protocol' => protocol
93
+ }
94
+
95
+ if ip_address['isstaticnat'] == 'true'
96
+ other_params['command'] = 'createIpForwardingRule'
97
+ other_params['startport'] = public_port
98
+ other_params['endport'] = public_port
99
+ Chef::Log.debug("Creating IP Forwarding Rule for
100
+ #{ip_address['ipaddress']} with protocol: #{protocol}, public port: #{public_port}")
101
+ else
102
+ other_params['command'] = 'createPortForwardingRule'
103
+ other_params['privatePort'] = private_port
104
+ other_params['publicPort'] = public_port
105
+ other_params['virtualMachineId'] = server_id
106
+ Chef::Log.debug("Creating Port Forwarding Rule for #{ip_address['id']} with protocol: #{protocol},
107
+ public port: #{public_port} and private port: #{private_port} and server: #{server_id}")
108
+ end
109
+ locate_config_value(:syncrequest) ? result = connection.send_request(params.merge(other_params)) : result = connection.send_async_request(params.merge(other_params))
110
+ Chef::Log.debug("AsyncJobResult: #{result}")
111
+ end
112
+ end
113
+ end
@@ -17,44 +17,26 @@
17
17
  # limitations under the License.
18
18
  #
19
19
 
20
+ require 'chef/knife/cs_base'
21
+ require 'chef/knife/cs_baselist'
22
+
20
23
  module KnifeCloudstack
21
24
  class CsHosts < Chef::Knife
22
25
 
23
26
  MEGABYTES = 1024 * 1024
24
27
 
28
+ include Chef::Knife::KnifeCloudstackBase
29
+ include Chef::Knife::KnifeCloudstackBaseList
30
+
25
31
  deps do
26
32
  require 'knife-cloudstack/connection'
27
- require 'chef/knife'
28
33
  Chef::Knife.load_deps
29
34
  end
30
35
 
31
36
  banner "knife cs hosts"
32
37
 
33
- option :cloudstack_url,
34
- :short => "-U URL",
35
- :long => "--cloudstack-url URL",
36
- :description => "The CloudStack endpoint URL",
37
- :proc => Proc.new { |url| Chef::Config[:knife][:cloudstack_url] = url }
38
-
39
- option :cloudstack_api_key,
40
- :short => "-A KEY",
41
- :long => "--cloudstack-api-key KEY",
42
- :description => "Your CloudStack API key",
43
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_api_key] = key }
44
-
45
- option :cloudstack_secret_key,
46
- :short => "-K SECRET",
47
- :long => "--cloudstack-secret-key SECRET",
48
- :description => "Your CloudStack secret key",
49
- :proc => Proc.new { |key| Chef::Config[:knife][:cloudstack_secret_key] = key }
50
-
51
38
  def run
52
-
53
- connection = CloudstackClient::Connection.new(
54
- locate_config_value(:cloudstack_url),
55
- locate_config_value(:cloudstack_api_key),
56
- locate_config_value(:cloudstack_secret_key)
57
- )
39
+ validate_base_options
58
40
 
59
41
  host_list = [
60
42
  ui.color('#Public IP', :bold),
@@ -72,12 +54,5 @@ module KnifeCloudstack
72
54
  puts ui.list(host_list, :columns_across, 3)
73
55
 
74
56
  end
75
-
76
-
77
- def locate_config_value(key)
78
- key = key.to_sym
79
- Chef::Config[:knife][key] || config[key]
80
- end
81
-
82
57
  end
83
58
  end
@@ -0,0 +1,72 @@
1
+ # Copyright:: Copyright (c) 2013
2
+ # License:: Apache License, Version 2.0
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'chef/knife/cs_base'
18
+
19
+ module KnifeCloudstack
20
+ class CsKeypairCreate < Chef::Knife
21
+
22
+ include Chef::Knife::KnifeCloudstackBase
23
+
24
+ deps do
25
+ require 'knife-cloudstack/connection'
26
+ Chef::Knife.load_deps
27
+ end
28
+
29
+ banner "knife cs keypair create KEY_NAME (options)"
30
+
31
+ option :name,
32
+ :long => "--name NAME",
33
+ :description => "Specify the ssh keypair name"
34
+
35
+ option :noheader,
36
+ :long => "--noheader",
37
+ :description => "Removes header from output",
38
+ :boolean => true
39
+
40
+ def run
41
+ validate_base_options
42
+
43
+ Chef::Log.debug("Validate keypair name")
44
+ keypairname = locate_config_value(:name) || @name_args.first
45
+ unless /^[a-zA-Z0-9][a-zA-Z0-9\-\_]*$/.match(keypairname) then
46
+ ui.error "Invalid keypairname. Please specify a short name for the keypair"
47
+ exit 1
48
+ end
49
+
50
+ ui.info("#{ui.color("Creating SSH Keypair: #{keypairname}", :magenta)}") unless locate_config_value(:noheader)
51
+
52
+ params = {
53
+ 'command' => 'createSSHKeyPair',
54
+ 'name' => keypairname,
55
+ }
56
+
57
+ json = connection.send_request(params)
58
+
59
+ unless json then
60
+ ui.error("Unable to create SSH Keypair")
61
+ exit 1
62
+ end
63
+
64
+ fingerprint = json['keypair']['fingerprint']
65
+ privatekey = json['keypair']['privatekey']
66
+ ui.info("Fingerprint: #{fingerprint}") unless locate_config_value(:noheader)
67
+ ui.info(privatekey)
68
+ puts "\n" unless locate_config_value(:noheader)
69
+ end
70
+
71
+ end # class
72
+ end