cloudstack-cli 0.1.1 → 0.1.2
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.
- 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
|