cloudstack-cli 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/README.md +14 -0
- data/cloudstack-cli.gemspec +7 -5
- data/lib/cloudstack-cli/cli.rb +31 -2
- data/lib/cloudstack-cli/commands/account.rb +1 -1
- data/lib/cloudstack-cli/commands/domain.rb +1 -1
- data/lib/cloudstack-cli/commands/load_balancer.rb +3 -3
- data/lib/cloudstack-cli/commands/network.rb +1 -3
- data/lib/cloudstack-cli/commands/offering.rb +4 -4
- data/lib/cloudstack-cli/commands/project.rb +1 -1
- data/lib/cloudstack-cli/commands/publicip.rb +1 -1
- data/lib/cloudstack-cli/commands/router.rb +37 -12
- data/lib/cloudstack-cli/commands/server.rb +1 -1
- data/lib/cloudstack-cli/commands/template.rb +1 -1
- data/lib/cloudstack-cli/commands/volume.rb +1 -1
- data/lib/cloudstack-cli/commands/zone.rb +1 -1
- data/lib/cloudstack-cli/helper.rb +14 -5
- data/lib/cloudstack-cli/version.rb +1 -1
- data/lib/cloudstack-client/client.rb +32 -1
- data/lib/cloudstack-client/helper.rb +3 -2
- metadata +6 -6
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -16,6 +16,20 @@ Or install it yourself as:
|
|
16
16
|
|
17
17
|
$ gem install cloudstack-cli
|
18
18
|
|
19
|
+
## Setup
|
20
|
+
|
21
|
+
Create the initial configuration:
|
22
|
+
|
23
|
+
cs setup
|
24
|
+
|
25
|
+
cloudstack-cli expects to find a configuartion file with the API URL and your CloudStack credentials in your home directory named .cloudstack-cli.yml. If the file is located elsewhere you can specify the loaction using the --config option.
|
26
|
+
|
27
|
+
Example content of the configuration file:
|
28
|
+
|
29
|
+
:url: "https://my-cloudstack-server/client/api/"
|
30
|
+
:api_key: "cloudstack-api-key"
|
31
|
+
:secret_key: "cloudstack-api-secret"
|
32
|
+
|
19
33
|
## Usage
|
20
34
|
|
21
35
|
See the help screen
|
data/cloudstack-cli.gemspec
CHANGED
@@ -6,18 +6,20 @@ require 'cloudstack-cli/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "cloudstack-cli"
|
8
8
|
gem.version = CloudstackCli::VERSION
|
9
|
-
gem.authors = ["
|
9
|
+
gem.authors = ["Nik Wolfgramm"]
|
10
10
|
gem.email = ["nik.wolfgramm@gmail.com"]
|
11
|
-
gem.description = %q{
|
12
|
-
gem.summary = %q{cloudstack-cli}
|
13
|
-
gem.homepage = ""
|
11
|
+
gem.description = %q{cloudstack-cli is a CloudStack API client written in Ruby.}
|
12
|
+
gem.summary = %q{cloudstack-cli CloudStack API client}
|
13
|
+
gem.homepage = "https://bitbucket.org/swisstxt/cloudstack-cli"
|
14
14
|
|
15
15
|
gem.files = `git ls-files`.split($/)
|
16
|
-
gem.executables =
|
16
|
+
gem.executables = ['cs']
|
17
17
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
18
|
gem.require_paths = ["lib"]
|
19
|
+
|
19
20
|
gem.add_development_dependency('rdoc')
|
20
21
|
gem.add_development_dependency('rake', '~> 10.0.4')
|
22
|
+
|
21
23
|
gem.add_dependency('thor', '~> 0.18.1')
|
22
24
|
gem.add_dependency('net-ssh', '~> 2.6.7')
|
23
25
|
gem.add_dependency('rainbow', '~> 1.1.4')
|
data/lib/cloudstack-cli/cli.rb
CHANGED
@@ -1,11 +1,40 @@
|
|
1
1
|
module CloudstackCli
|
2
2
|
class Cli < Thor
|
3
|
-
|
3
|
+
include Thor::Actions
|
4
|
+
|
5
|
+
class_option :config, default: File.join(Dir.home, '.cloudstack-cli.yml'), aliases: '-c'
|
4
6
|
class_option :verbose, type: :boolean
|
5
7
|
|
8
|
+
desc "setup", "initial setup of the Cloudstack connection"
|
9
|
+
option :url
|
10
|
+
option :api_key
|
11
|
+
option :secret_key
|
12
|
+
def setup(file = options[:config])
|
13
|
+
config = {}
|
14
|
+
unless options[:url]
|
15
|
+
say "What's the URL of your Cloudstack API?", :blue
|
16
|
+
say "Example: https://my-cloudstack-server/client/api/", :blue
|
17
|
+
config[:url] = ask("URL:", :magenta)
|
18
|
+
end
|
19
|
+
|
20
|
+
unless options[:api_key]
|
21
|
+
config[:api_key] = ask("API Key:", :magenta)
|
22
|
+
end
|
23
|
+
|
24
|
+
unless options[:secret_key]
|
25
|
+
config[:secret_key] = ask("Secret Key:", :magenta)
|
26
|
+
end
|
27
|
+
|
28
|
+
if File.exists? file
|
29
|
+
say "Warning: #{file} already exists.", :red
|
30
|
+
exit unless yes?("Overwrite [y/N]", :red)
|
31
|
+
end
|
32
|
+
File.open(file, 'w+') {|f| f.write(config.to_yaml) }
|
33
|
+
end
|
34
|
+
|
6
35
|
desc "command COMMAND [arg1=val1 arg2=val2...]", "run a custom api command"
|
7
36
|
def command(command, *args)
|
8
|
-
client = CloudstackCli::Helper.new
|
37
|
+
client = CloudstackCli::Helper.new(options[:config])
|
9
38
|
params = {'command' => command}
|
10
39
|
args.each do |arg|
|
11
40
|
arg = arg.split('=')
|
@@ -2,7 +2,7 @@ class Lb < Thor
|
|
2
2
|
desc "list", "list load balancer rules"
|
3
3
|
option :project
|
4
4
|
def list
|
5
|
-
cs_cli = CloudstackCli::Helper.new
|
5
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
6
6
|
if options[:project]
|
7
7
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
8
8
|
exit_now! "Project '#{options[:project]}' not found" unless project
|
@@ -24,7 +24,7 @@ class Lb < Thor
|
|
24
24
|
option :public_port, :required => true
|
25
25
|
option :private_port
|
26
26
|
def create(name)
|
27
|
-
cs_cli = CloudstackCli::Helper.new
|
27
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
28
28
|
if options[:project]
|
29
29
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
30
30
|
exit_now! "Project '#{options[:project]}' not found" unless project
|
@@ -44,7 +44,7 @@ class Lb < Thor
|
|
44
44
|
option :project
|
45
45
|
option :servers, required: true, type: :array, description: 'server names'
|
46
46
|
def add(name)
|
47
|
-
cs_cli = CloudstackCli::Helper.new
|
47
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
48
48
|
if options[:project]
|
49
49
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
50
50
|
exit_now! "Project '#{options[:project]}' not found" unless project
|
@@ -11,7 +11,7 @@ class Network < Thor
|
|
11
11
|
option :project
|
12
12
|
option :physical, type: :boolean
|
13
13
|
def list
|
14
|
-
cs_cli = CloudstackCli::Helper.new
|
14
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
15
15
|
if options[:project]
|
16
16
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
17
17
|
raise "Project '#{options[:project]}' not found" unless project
|
@@ -19,7 +19,6 @@ class Network < Thor
|
|
19
19
|
|
20
20
|
if options[:physical]
|
21
21
|
networks = cs_cli.physical_networks
|
22
|
-
|
23
22
|
if networks.size < 1
|
24
23
|
puts "No networks found"
|
25
24
|
else
|
@@ -42,7 +41,6 @@ class Network < Thor
|
|
42
41
|
end
|
43
42
|
else
|
44
43
|
networks = cs_cli.networks(project ? project['id'] : -1)
|
45
|
-
|
46
44
|
if networks.size < 1
|
47
45
|
puts "No networks found"
|
48
46
|
else
|
@@ -4,7 +4,7 @@ class Offering < Thor
|
|
4
4
|
desc 'list', 'list offerings by type [compute|network|storage]'
|
5
5
|
option :domain
|
6
6
|
def list(type='compute')
|
7
|
-
cs_cli = CloudstackCli::Helper.new
|
7
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
8
8
|
offerings = cs_cli.server_offerings(options[:domain])
|
9
9
|
|
10
10
|
offerings.group_by{|o| o["domain"]}.each_value do |offers|
|
@@ -47,20 +47,20 @@ class Offering < Thor
|
|
47
47
|
option :tags
|
48
48
|
def create(name)
|
49
49
|
options[:name] = name
|
50
|
-
cs_cli = CloudstackCli::Helper.new
|
50
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
51
51
|
puts "OK" if cs_cli.create_offering(options)
|
52
52
|
end
|
53
53
|
|
54
54
|
desc 'delete ID', 'delete offering'
|
55
55
|
def delete(id)
|
56
|
-
cs_cli = CloudstackCli::Helper.new
|
56
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
57
57
|
puts "OK" if cs_cli.delete_offering(id)
|
58
58
|
end
|
59
59
|
|
60
60
|
|
61
61
|
desc 'sort', 'sort by cpu and memory grouped by domain'
|
62
62
|
def sort
|
63
|
-
cs_cli = CloudstackCli::Helper.new
|
63
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
64
64
|
offerings = cs_cli.server_offerings(options[:domain])
|
65
65
|
sortkey = -1
|
66
66
|
offerings.group_by{|o| o["domain"]}.each_value do |offers|
|
@@ -1,15 +1,18 @@
|
|
1
1
|
class Router < Thor
|
2
|
+
include Thor::Actions
|
2
3
|
include CommandLineReporter
|
3
4
|
|
4
5
|
desc "list", "list virtual routers"
|
5
6
|
option :project
|
6
7
|
option :account
|
8
|
+
option :zone
|
7
9
|
option :status, desc: "Running or Stopped"
|
8
10
|
option :redundant_state, desc: "MASTER, BACKUP or UNKNOWN"
|
9
11
|
option :listall, type: :boolean
|
10
12
|
option :text, type: :boolean, desc: "text output (only the instance name)"
|
13
|
+
option :command, desc: "command to execute for each router: START or STOP"
|
11
14
|
def list
|
12
|
-
cs_cli = CloudstackCli::Helper.new
|
15
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
13
16
|
if options[:project]
|
14
17
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
15
18
|
raise "Project '#{options[:project]}' not found" unless project
|
@@ -21,6 +24,7 @@ class Router < Thor
|
|
21
24
|
account: options[:account],
|
22
25
|
projectid: projectid,
|
23
26
|
status: options[:status],
|
27
|
+
zone: options[:zone]
|
24
28
|
},
|
25
29
|
options[:redundant_state]
|
26
30
|
)
|
@@ -33,7 +37,8 @@ class Router < Thor
|
|
33
37
|
{
|
34
38
|
account: options[:account],
|
35
39
|
projectid: project['id'],
|
36
|
-
status: options[:status]
|
40
|
+
status: options[:status],
|
41
|
+
zone: options[:zone]
|
37
42
|
},
|
38
43
|
options[:redundant_state]
|
39
44
|
)
|
@@ -70,24 +75,44 @@ class Router < Thor
|
|
70
75
|
end
|
71
76
|
end
|
72
77
|
|
78
|
+
if options[:command]
|
79
|
+
case options[:command].downcase
|
80
|
+
when "start"
|
81
|
+
exit unless yes?("Start the routers above? [y/N]:", :magenta)
|
82
|
+
routers.each do |router|
|
83
|
+
say "Start router #{router['name']}"
|
84
|
+
cs_cli.start_router router['id']
|
85
|
+
end
|
86
|
+
when "stop"
|
87
|
+
exit unless yes?("Stop the routers above? [y/N]:", :magenta)
|
88
|
+
routers.each do |router|
|
89
|
+
say "Stop router #{router['name']}"
|
90
|
+
cs_cli.stop_router router['id']
|
91
|
+
end
|
92
|
+
else
|
93
|
+
say "Command #{options[:command]} not supported", :red
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
end
|
73
97
|
end
|
74
98
|
|
75
|
-
desc "stop
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
99
|
+
desc "stop ID", "stop virtual router"
|
100
|
+
def stop(id)
|
101
|
+
exit unless yes?("Stop the router with ID #{id}?", :magenta)
|
102
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
103
|
+
cs_cli.stop_router id
|
80
104
|
end
|
81
105
|
|
82
|
-
desc "start
|
83
|
-
|
84
|
-
|
85
|
-
|
106
|
+
desc "start ID", "start virtual router"
|
107
|
+
def start(id)
|
108
|
+
exit unless yes?("Start the router with ID #{id}?", :magenta)
|
109
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
110
|
+
cs_cli.start_router id
|
86
111
|
end
|
87
112
|
|
88
113
|
desc "destroy ID", "destroy virtual router"
|
89
114
|
def destroy(id)
|
90
|
-
cs_cli = CloudstackCli::Helper.new
|
115
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
91
116
|
puts "OK" if cs_cli.destroy_router(name)
|
92
117
|
end
|
93
118
|
|
@@ -6,7 +6,7 @@ class Server < Thor
|
|
6
6
|
option :project
|
7
7
|
option :account
|
8
8
|
def list
|
9
|
-
cs_cli = CloudstackCli::Helper.new
|
9
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
10
10
|
if options[:project]
|
11
11
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
12
12
|
exit_now! "Project '#{options[:project]}' not found" unless project
|
@@ -3,7 +3,7 @@ class Template < Thor
|
|
3
3
|
desc 'list', 'list templates by type [featured|self|self-executable|executable|community]'
|
4
4
|
option :project
|
5
5
|
def list(type='featured')
|
6
|
-
cs_cli = CloudstackCli::Helper.new
|
6
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
7
7
|
|
8
8
|
if options[:project]
|
9
9
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
@@ -2,7 +2,7 @@ class Volume < Thor
|
|
2
2
|
desc "list", "list networks"
|
3
3
|
option :project
|
4
4
|
def list
|
5
|
-
cs_cli = CloudstackCli::Helper.new
|
5
|
+
cs_cli = CloudstackCli::Helper.new(options[:config])
|
6
6
|
if options[:project]
|
7
7
|
project = cs_cli.projects.select { |p| p['name'] == options[:project] }.first
|
8
8
|
raise "Project '#{options[:project]}' not found" unless project
|
@@ -4,11 +4,12 @@ module CloudstackCli
|
|
4
4
|
|
5
5
|
attr_reader :cs
|
6
6
|
|
7
|
-
def initialize
|
7
|
+
def initialize(config_file)
|
8
|
+
@config_file = config_file
|
8
9
|
@cs = CloudstackClient::Connection.new(
|
9
|
-
options[:
|
10
|
-
options[:
|
11
|
-
options[:
|
10
|
+
options[:url],
|
11
|
+
options[:api_key],
|
12
|
+
options[:secret_key]
|
12
13
|
)
|
13
14
|
end
|
14
15
|
|
@@ -175,8 +176,16 @@ module CloudstackCli
|
|
175
176
|
@cs.destroy_router(id)
|
176
177
|
end
|
177
178
|
|
179
|
+
def start_router(id)
|
180
|
+
@cs.start_router(id)
|
181
|
+
end
|
182
|
+
|
183
|
+
def stop_router(id)
|
184
|
+
@cs.stop_router(id)
|
185
|
+
end
|
186
|
+
|
178
187
|
def options
|
179
|
-
@options ||= CloudstackClient::ConnectionHelper.load_configuration()
|
188
|
+
@options ||= CloudstackClient::ConnectionHelper.load_configuration(@config_file)
|
180
189
|
end
|
181
190
|
|
182
191
|
def print_options(options, attr = 'name')
|
@@ -728,7 +728,14 @@ module CloudstackClient
|
|
728
728
|
'listall' => 'true',
|
729
729
|
'isrecursive' => 'true'
|
730
730
|
}
|
731
|
-
|
731
|
+
if args[:zone]
|
732
|
+
zone = get_zone(args[:zone])
|
733
|
+
unless zone
|
734
|
+
puts "Error: Zone #{args[:zone]} not found"
|
735
|
+
exit 1
|
736
|
+
end
|
737
|
+
params['zoneid'] = zone['id']
|
738
|
+
end
|
732
739
|
params['projectid'] = args[:projectid] if args[:projectid]
|
733
740
|
params['state'] = args[:status] if args[:status]
|
734
741
|
params['name'] = args[:name] if args[:name]
|
@@ -754,6 +761,30 @@ module CloudstackClient
|
|
754
761
|
json['router'].first
|
755
762
|
end
|
756
763
|
|
764
|
+
##
|
765
|
+
# Start virtual router.
|
766
|
+
|
767
|
+
def start_router(id)
|
768
|
+
params = {
|
769
|
+
'command' => 'startRouter',
|
770
|
+
'id' => id
|
771
|
+
}
|
772
|
+
|
773
|
+
json = send_async_request(params)
|
774
|
+
end
|
775
|
+
|
776
|
+
##
|
777
|
+
# Stop virtual router.
|
778
|
+
|
779
|
+
def stop_router(id)
|
780
|
+
params = {
|
781
|
+
'command' => 'stopRouter',
|
782
|
+
'id' => id
|
783
|
+
}
|
784
|
+
|
785
|
+
json = send_async_request(params)
|
786
|
+
end
|
787
|
+
|
757
788
|
##
|
758
789
|
# Lists accounts.
|
759
790
|
|
@@ -1,10 +1,11 @@
|
|
1
1
|
module CloudstackClient
|
2
2
|
class ConnectionHelper
|
3
|
-
def self.load_configuration(config_file
|
3
|
+
def self.load_configuration(config_file)
|
4
4
|
begin
|
5
5
|
return YAML::load(IO.read(config_file))
|
6
6
|
rescue Exception => e
|
7
|
-
puts "
|
7
|
+
$stderr.puts "Can't find the config file '#{config_file}'"
|
8
|
+
$stderr.puts "Please see https://bitbucket.org/swisstxt/cloudstack-cli under 'Setup'"
|
8
9
|
exit
|
9
10
|
end
|
10
11
|
end
|
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudstack-cli
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
|
-
-
|
8
|
+
- Nik Wolfgramm
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-07-
|
12
|
+
date: 2013-07-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
@@ -107,7 +107,7 @@ dependencies:
|
|
107
107
|
- - ~>
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: 3.2.1
|
110
|
-
description:
|
110
|
+
description: cloudstack-cli is a CloudStack API client written in Ruby.
|
111
111
|
email:
|
112
112
|
- nik.wolfgramm@gmail.com
|
113
113
|
executables:
|
@@ -144,7 +144,7 @@ files:
|
|
144
144
|
- lib/cloudstack-client/ssh_command.rb
|
145
145
|
- lib/cloudstack_cli.rb
|
146
146
|
- lib/cloudstack_client.rb
|
147
|
-
homepage:
|
147
|
+
homepage: https://bitbucket.org/swisstxt/cloudstack-cli
|
148
148
|
licenses: []
|
149
149
|
post_install_message:
|
150
150
|
rdoc_options: []
|
@@ -167,5 +167,5 @@ rubyforge_project:
|
|
167
167
|
rubygems_version: 1.8.23
|
168
168
|
signing_key:
|
169
169
|
specification_version: 3
|
170
|
-
summary: cloudstack-cli
|
170
|
+
summary: cloudstack-cli CloudStack API client
|
171
171
|
test_files: []
|