cloudstack-cli 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile.lock +1 -1
- data/README.md +33 -1
- data/lib/cloudstack-cli/commands/server.rb +20 -16
- data/lib/cloudstack-cli/commands/stack.rb +46 -8
- data/lib/cloudstack-cli/helper.rb +36 -24
- data/lib/cloudstack-cli/version.rb +1 -1
- data/test/stack_example.json +15 -20
- metadata +9 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 71a5b85637b159d9b71b76d9c5703ec7eff903c9
|
4
|
+
data.tar.gz: 92774b4af91e17a60e84156c8532ec5eafad2fb2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ee45344f2a30049f4de0c8c9aa5cd884faaf6b3a7535656880c9357832846cd197c8ab4c5459ccb703dbda51f2b28098086b51d7fb5840e36352e51ea4c7f648
|
7
|
+
data.tar.gz: 6edfcef7302b4dfd45ddef2ab998c01d908084b1d3f33df872ff7402a4a0951ba38f827a97023f38838c4bb4aa99173b8e125c482394c38d36c6eeb8a8fa75fe
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -44,11 +44,43 @@ Run a custom API command:
|
|
44
44
|
|
45
45
|
### Example 3
|
46
46
|
|
47
|
+
Create a stack of servers:
|
48
|
+
|
49
|
+
$ cs stack create my_stackfile.json
|
50
|
+
|
51
|
+
An example stackfile looks like this
|
52
|
+
|
53
|
+
{
|
54
|
+
"name": "web_stack-a",
|
55
|
+
"description": "Web Application Stack",
|
56
|
+
"version": "1.0",
|
57
|
+
"zone": "DC-BIE-1",
|
58
|
+
"servers": [
|
59
|
+
{
|
60
|
+
"name": "web-d1, web-d2",
|
61
|
+
"description": "Web nodes",
|
62
|
+
"template": "CentOS-6.4-x64-v1.2",
|
63
|
+
"offering": "1cpu_1gb",
|
64
|
+
"networks": "server_network",
|
65
|
+
"port_rules": ":80, :443"
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"name": "db-01",
|
69
|
+
"description": "PostgreSQL Master",
|
70
|
+
"template": "CentOS-6.4-x64-v1.2",
|
71
|
+
"offering": "2cpu_4gb",
|
72
|
+
"networks": "server_network, storage_network"
|
73
|
+
}
|
74
|
+
]
|
75
|
+
}
|
76
|
+
|
77
|
+
### Example 4
|
78
|
+
|
47
79
|
Sort all computing offerings by CPU and Memory grouped my Domain:
|
48
80
|
|
49
81
|
$ cs offering sort
|
50
82
|
|
51
|
-
### Example
|
83
|
+
### Example 5
|
52
84
|
|
53
85
|
Stop all virtual routers of project Demo (you could filter by Zone too):
|
54
86
|
(This command is helpful if you have to deploy new versions of Cloudstack when using redumdant routers)
|
@@ -37,7 +37,9 @@ class Server < CloudstackCli::Base
|
|
37
37
|
option :offering, required: true
|
38
38
|
option :networks, type: :array, required: true
|
39
39
|
option :project
|
40
|
-
option :
|
40
|
+
option :port_rules, type: :array, aliases: :pf,
|
41
|
+
default: [],
|
42
|
+
description: "Port Forwarding Rules [public_ip]:port ..."
|
41
43
|
option :interactive, type: :boolean
|
42
44
|
def create(name)
|
43
45
|
CloudstackCli::Helper.new(options[:config]).bootstrap_server(
|
@@ -46,28 +48,30 @@ class Server < CloudstackCli::Base
|
|
46
48
|
options[:template],
|
47
49
|
options[:offering],
|
48
50
|
options[:networks],
|
49
|
-
options[:
|
51
|
+
options[:port_rules],
|
50
52
|
options[:project]
|
51
53
|
)
|
52
54
|
end
|
53
55
|
|
54
|
-
desc "destroy NAME", "destroy a server"
|
56
|
+
desc "destroy NAME [NAME2 ..]", "destroy a server"
|
57
|
+
option :project
|
55
58
|
option :force, description: "destroy without asking", type: :boolean, aliases: '-f'
|
56
|
-
def destroy(name)
|
57
|
-
|
58
|
-
unless server
|
59
|
-
error "Server not found."
|
60
|
-
exit
|
61
|
-
end
|
62
|
-
ask = "Are you sure you want to destroy the following server?\n"
|
63
|
-
ask += "#{server['name']} (#{server['state']})?"
|
59
|
+
def destroy(*name)
|
60
|
+
projectid = find_project['id'] if options[:project]
|
64
61
|
|
65
|
-
|
66
|
-
|
62
|
+
name.each do |server_name|
|
63
|
+
server = client.get_server(server_name, projectid)
|
64
|
+
unless server
|
65
|
+
say "Server #{server_name} not found.", :red
|
66
|
+
else
|
67
|
+
ask = "Destroy #{server_name} (#{server['state']})?"
|
68
|
+
if options[:force] == true || yes?(ask)
|
69
|
+
say "Destroying #{server_name} "
|
70
|
+
client.destroy_server(server["id"])
|
71
|
+
puts
|
72
|
+
end
|
73
|
+
end
|
67
74
|
end
|
68
|
-
|
69
|
-
client.destroy_server(server["id"])
|
70
|
-
puts
|
71
75
|
end
|
72
76
|
|
73
77
|
desc "bootstrap", "interactive creation of a server with network access"
|
@@ -1,14 +1,52 @@
|
|
1
1
|
class Stack < CloudstackCli::Base
|
2
2
|
|
3
3
|
desc "create STACKFILE", "create a stack of servers"
|
4
|
-
def create(
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
def create(stackfile)
|
5
|
+
stack = parse_stackfile(stackfile)
|
6
|
+
say "Crate stack #{stack["name"]}..."
|
7
|
+
puts
|
8
|
+
stack["servers"].each do |server|
|
9
|
+
server["name"].split(', ').each do |name|
|
10
|
+
CloudstackCli::Helper.new(options[:config]).bootstrap_server(
|
11
|
+
name,
|
12
|
+
server["zone"] || stack['zone'],
|
13
|
+
server["template"],
|
14
|
+
server["offering"],
|
15
|
+
server["networks"] ? server["networks"].split(', ') : nil,
|
16
|
+
server["port_rules"] ? server["port_rules"].split(', ') : nil,
|
17
|
+
stack["project"]
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "destroy STACKFILE", "destroy a stack of servers"
|
24
|
+
option :force,
|
25
|
+
description: "destroy without asking",
|
26
|
+
type: :boolean,
|
27
|
+
default: false,
|
28
|
+
aliases: '-f'
|
29
|
+
def destroy(stackfile)
|
30
|
+
stack = parse_stackfile(stackfile)
|
31
|
+
servers = []
|
32
|
+
server = stack["servers"].collect do |server|
|
33
|
+
server["name"].split(', ').each {|name| servers << name}
|
34
|
+
end
|
35
|
+
say "Destroy stack #{stack["name"]}...", :yellow
|
36
|
+
invoke "server:destroy", servers, project: stack["project"], force: options[:force]
|
37
|
+
end
|
38
|
+
|
39
|
+
no_commands do
|
40
|
+
def parse_stackfile(stackfile)
|
41
|
+
begin
|
42
|
+
return JSON.parse File.read(stackfile)
|
43
|
+
rescue SystemCallError
|
44
|
+
$stderr.puts "Can't find the stack file #{stackfile}."
|
45
|
+
rescue JSON::ParserError => e
|
46
|
+
$stderr.puts "Error parsing json file.\n#{e.message}."
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
12
50
|
end
|
13
51
|
|
14
52
|
end
|
@@ -55,36 +55,48 @@ module CloudstackCli
|
|
55
55
|
end
|
56
56
|
|
57
57
|
def bootstrap_server(name, zone, template, offering, networks, pf_rules = [], project = nil)
|
58
|
-
puts "Create server #{name}...".color(:yellow)
|
59
|
-
server = @cs.create_server(
|
60
|
-
name,
|
61
|
-
offering,
|
62
|
-
template,
|
63
|
-
zone,
|
64
|
-
networks,
|
65
|
-
project
|
66
|
-
)
|
67
58
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
59
|
+
server = @cs.get_server(name)
|
60
|
+
|
61
|
+
unless server
|
62
|
+
puts "Create server #{name}...".color(:yellow)
|
63
|
+
server = @cs.create_server(
|
64
|
+
name,
|
65
|
+
offering,
|
66
|
+
template,
|
67
|
+
zone,
|
68
|
+
networks,
|
69
|
+
project
|
70
|
+
)
|
71
|
+
|
72
|
+
puts
|
73
|
+
puts "Server #{server["name"]} has been created.".color(:green)
|
74
|
+
puts
|
75
|
+
puts "Make sure the server is running...".color(:yellow)
|
76
|
+
@cs.wait_for_server_state(server["id"], "Running")
|
77
|
+
puts "OK!".color(:green)
|
78
|
+
else
|
79
|
+
puts "Server #{name} already exists".color(:green)
|
80
|
+
end
|
78
81
|
|
79
|
-
if pf_rules.size > 0
|
82
|
+
if pf_rules && pf_rules.size > 0
|
80
83
|
puts
|
84
|
+
frontendip = nil
|
85
|
+
project = @cs.get_project(project)
|
81
86
|
pf_rules.each do |pf_rule|
|
82
87
|
ip = pf_rule.split(":")[0]
|
83
|
-
|
88
|
+
if ip != ''
|
89
|
+
ip_addr = @cs.get_public_ip_address(ip)
|
90
|
+
else
|
91
|
+
ip_addr = frontendip ||= @cs.associate_ip_address(
|
92
|
+
@cs.get_network(networks[0], project ? project["id"] : nil)["id"]
|
93
|
+
)
|
94
|
+
end
|
84
95
|
port = pf_rule.split(":")[1]
|
85
|
-
|
86
|
-
|
87
|
-
|
96
|
+
puts
|
97
|
+
print "Create port forwarding rule #{ip}:#{port} ".color(:yellow)
|
98
|
+
@cs.create_port_forwarding_rule(ip_addr["id"], port, 'TCP', port, server["id"])
|
99
|
+
puts
|
88
100
|
end
|
89
101
|
end
|
90
102
|
|
data/test/stack_example.json
CHANGED
@@ -1,29 +1,24 @@
|
|
1
1
|
{
|
2
|
-
"name": "
|
3
|
-
"description": "
|
2
|
+
"name": "web_stack_a",
|
3
|
+
"description": "Web Application Stack",
|
4
4
|
"version": "1.0",
|
5
|
+
"zone": "BIEL_CU01",
|
6
|
+
"project": "Playground",
|
5
7
|
"servers": [
|
6
8
|
{
|
7
|
-
"name": "
|
8
|
-
"description": "
|
9
|
-
"template": "
|
10
|
-
"
|
11
|
-
"
|
9
|
+
"name": "web-01, web-02",
|
10
|
+
"description": "Web nodes",
|
11
|
+
"template": "CentOS-6.4-x64-v1.2",
|
12
|
+
"offering": "1cpu_1gb",
|
13
|
+
"networks": "M_ROOT",
|
14
|
+
"port_rules": ":80, :443"
|
12
15
|
},
|
13
16
|
{
|
14
|
-
"name": "
|
15
|
-
"description": "
|
16
|
-
"template": "
|
17
|
-
"
|
18
|
-
"networks": "
|
19
|
-
"port_rules": "50070, 50030, 60010",
|
20
|
-
},
|
21
|
-
{
|
22
|
-
"name": "hadoop-worker-a hadoop-worker-b hadoop-worker-c",
|
23
|
-
"description": "Hadoop worker nodes",
|
24
|
-
"template": "rhel-5.6-base",
|
25
|
-
"service": "medium",
|
26
|
-
"port_rules": "50075, 50060, 60030",
|
17
|
+
"name": "db-01",
|
18
|
+
"description": "PostgreSQL Master",
|
19
|
+
"template": "CentOS-6.4-x64-v1.2",
|
20
|
+
"offering": "2cpu_4gb",
|
21
|
+
"networks": "M_ROOT"
|
27
22
|
}
|
28
23
|
]
|
29
24
|
}
|
metadata
CHANGED
@@ -1,36 +1,32 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudstack-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Nik Wolfgramm
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-08-02 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rdoc
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rake
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -46,7 +41,6 @@ dependencies:
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: thor
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
45
|
- - ~>
|
52
46
|
- !ruby/object:Gem::Version
|
@@ -54,7 +48,6 @@ dependencies:
|
|
54
48
|
type: :runtime
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
52
|
- - ~>
|
60
53
|
- !ruby/object:Gem::Version
|
@@ -62,7 +55,6 @@ dependencies:
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: net-ssh
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
59
|
- - ~>
|
68
60
|
- !ruby/object:Gem::Version
|
@@ -70,7 +62,6 @@ dependencies:
|
|
70
62
|
type: :runtime
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
66
|
- - ~>
|
76
67
|
- !ruby/object:Gem::Version
|
@@ -78,7 +69,6 @@ dependencies:
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: rainbow
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
73
|
- - ~>
|
84
74
|
- !ruby/object:Gem::Version
|
@@ -86,7 +76,6 @@ dependencies:
|
|
86
76
|
type: :runtime
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
80
|
- - ~>
|
92
81
|
- !ruby/object:Gem::Version
|
@@ -134,6 +123,7 @@ files:
|
|
134
123
|
- test/stack_example.json
|
135
124
|
homepage: https://bitbucket.org/swisstxt/cloudstack-cli
|
136
125
|
licenses: []
|
126
|
+
metadata: {}
|
137
127
|
post_install_message:
|
138
128
|
rdoc_options:
|
139
129
|
- --line-numbers
|
@@ -141,22 +131,20 @@ rdoc_options:
|
|
141
131
|
require_paths:
|
142
132
|
- lib
|
143
133
|
required_ruby_version: !ruby/object:Gem::Requirement
|
144
|
-
none: false
|
145
134
|
requirements:
|
146
|
-
- -
|
135
|
+
- - '>='
|
147
136
|
- !ruby/object:Gem::Version
|
148
137
|
version: 1.9.3
|
149
138
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
|
-
none: false
|
151
139
|
requirements:
|
152
|
-
- -
|
140
|
+
- - '>='
|
153
141
|
- !ruby/object:Gem::Version
|
154
142
|
version: '0'
|
155
143
|
requirements: []
|
156
144
|
rubyforge_project:
|
157
|
-
rubygems_version:
|
145
|
+
rubygems_version: 2.0.2
|
158
146
|
signing_key:
|
159
|
-
specification_version:
|
147
|
+
specification_version: 4
|
160
148
|
summary: cloudstack-cli CloudStack API client
|
161
149
|
test_files:
|
162
150
|
- test/stack_example.json
|