knife-cloudstack 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.rdoc +15 -0
- data/README.rdoc +18 -7
- data/lib/chef/knife/cs_base.rb +12 -8
- data/lib/chef/knife/cs_firewallrule_create.rb +115 -0
- data/lib/chef/knife/cs_forwardrule_create.rb +113 -0
- data/lib/chef/knife/cs_hosts.rb +7 -32
- data/lib/chef/knife/cs_keypair_create.rb +72 -0
- data/lib/chef/knife/cs_keypair_delete.rb +60 -0
- data/lib/chef/knife/cs_keypair_list.rb +83 -0
- data/lib/chef/knife/cs_publicip_list.rb +88 -0
- data/lib/chef/knife/cs_securitygroup_list.rb +134 -0
- data/lib/chef/knife/cs_server_create.rb +66 -15
- data/lib/chef/knife/cs_server_list.rb +4 -2
- data/lib/chef/knife/cs_stack_create.rb +17 -43
- data/lib/chef/knife/cs_template_list.rb +1 -1
- data/lib/chef/knife/cs_volume_create.rb +108 -0
- data/lib/knife-cloudstack/connection.rb +243 -100
- metadata +85 -86
- data/lib/knife-cloudstack/string_to_regexp.rb +0 -32
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[:
|
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>
|
101
|
-
The default value of <tt>END_PORT</tt> is <tt>START_PORT</tt>, the default <tt>
|
102
|
-
For example, a rule to open firewall for port 80 to everyone would look like <tt>80:
|
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");
|
data/lib/chef/knife/cs_base.rb
CHANGED
@@ -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 :
|
59
|
-
:long => '--
|
60
|
-
:description =>
|
61
|
-
:boolean => true
|
62
|
-
|
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(:
|
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]
|
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
|
data/lib/chef/knife/cs_hosts.rb
CHANGED
@@ -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
|