scalarium 0.0.1 → 0.2.0
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/CHANGELOG +5 -0
- data/README.md +3 -0
- data/lib/scalarium.rb +25 -18
- data/lib/scalarium/api.rb +32 -0
- data/lib/scalarium/app.rb +17 -0
- data/lib/scalarium/cli.rb +167 -6
- data/lib/scalarium/cloud.rb +19 -0
- data/lib/scalarium/resource.rb +9 -0
- data/lib/scalarium/version.rb +1 -1
- data/scalarium.gemspec +1 -0
- metadata +27 -10
data/CHANGELOG
ADDED
data/README.md
ADDED
data/lib/scalarium.rb
CHANGED
@@ -1,20 +1,33 @@
|
|
1
|
-
require "scalarium/version"
|
2
1
|
require 'rest-client'
|
3
2
|
require 'json'
|
4
3
|
require 'dispatch_queue'
|
5
4
|
require 'ostruct'
|
6
5
|
|
6
|
+
require "scalarium/version"
|
7
|
+
require "scalarium/api"
|
8
|
+
require "scalarium/resource"
|
9
|
+
require "scalarium/cloud"
|
10
|
+
require "scalarium/app"
|
11
|
+
|
7
12
|
class Scalarium
|
8
|
-
|
9
|
-
|
10
|
-
class
|
13
|
+
include Scalarium::Api
|
14
|
+
|
15
|
+
class Instance < Resource ; end
|
16
|
+
class Rol < Resource ; end
|
11
17
|
|
12
18
|
attr_reader :clouds
|
19
|
+
|
20
|
+
#
|
21
|
+
# cloud could be:
|
22
|
+
# nil => Fetch infor from all clouds
|
23
|
+
# string => Regular expresion that will match cloud names
|
24
|
+
# false => Don't fetch neighter roles neigher instances
|
25
|
+
#
|
13
26
|
def initialize(token, cloud = nil)
|
14
27
|
@token = token
|
15
28
|
@clouds = []
|
16
29
|
|
17
|
-
@clouds = get('clouds').map{|c| Cloud.new(c) }
|
30
|
+
@clouds = get('clouds').map{|c| Cloud.new(@token,c) }
|
18
31
|
|
19
32
|
return if cloud == false
|
20
33
|
|
@@ -27,23 +40,17 @@ class Scalarium
|
|
27
40
|
DQ[*(@clouds.map { |cloud| lambda { process_cloud(cloud) } })]
|
28
41
|
end
|
29
42
|
|
30
|
-
|
31
|
-
|
32
|
-
def get(resource)
|
33
|
-
$stderr.puts "Getting #{resource}" if $DEBUG
|
34
|
-
url = "https://manage.scalarium.com/api/#{resource}"
|
35
|
-
headers = {
|
36
|
-
'X-Scalarium-Token' => @token,
|
37
|
-
'Accept' => 'application/vnd.scalarium-v1+json'
|
38
|
-
}
|
39
|
-
response = RestClient.get(url, headers)
|
40
|
-
JSON.parse(response)
|
43
|
+
def apps
|
44
|
+
get('applications').map{ |app| App.new(@token,app) }
|
41
45
|
end
|
42
46
|
|
47
|
+
protected
|
48
|
+
|
49
|
+
|
43
50
|
def get_roles_proc(cloud_id)
|
44
51
|
lambda do
|
45
52
|
get("clouds/#{cloud_id}/roles").map { |hash|
|
46
|
-
Rol.new(hash)
|
53
|
+
Rol.new(@token,hash)
|
47
54
|
}
|
48
55
|
end
|
49
56
|
end
|
@@ -51,7 +58,7 @@ class Scalarium
|
|
51
58
|
def get_instances_proc(cloud_id)
|
52
59
|
lambda do
|
53
60
|
get("clouds/#{cloud_id}/instances").map { |hash|
|
54
|
-
Instance.new(hash)
|
61
|
+
Instance.new(@token,hash)
|
55
62
|
}
|
56
63
|
end
|
57
64
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# @nodoc
|
2
|
+
class Scalarium
|
3
|
+
module Api
|
4
|
+
class TokenNotFound < StandardError; end
|
5
|
+
|
6
|
+
def get(resource)
|
7
|
+
raise TokenNotFound unless @token
|
8
|
+
$stderr.puts "Getting #{resource}" if $DEBUG
|
9
|
+
url = "https://manage.scalarium.com/api/#{resource}"
|
10
|
+
headers = {
|
11
|
+
'X-Scalarium-Token' => @token,
|
12
|
+
'Accept' => 'application/vnd.scalarium-v1+json'
|
13
|
+
}
|
14
|
+
response = RestClient.get(url, headers)
|
15
|
+
JSON.parse(response)
|
16
|
+
end
|
17
|
+
|
18
|
+
def post(resource, data)
|
19
|
+
raise TokenNotFound unless @token
|
20
|
+
$stderr.puts "Posting #{data.inspect} to #{resource}" if $DEBUG
|
21
|
+
url = "https://manage.scalarium.com/api/#{resource}"
|
22
|
+
headers = {
|
23
|
+
'X-Scalarium-Token' => @token,
|
24
|
+
'Accept' => 'application/vnd.scalarium-v1+json'
|
25
|
+
}
|
26
|
+
response = RestClient.post(url, JSON.dump(data), headers)
|
27
|
+
JSON.parse(response)
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Scalarium
|
2
|
+
class App < Resource
|
3
|
+
|
4
|
+
def deploy!
|
5
|
+
post("applications/#{id}/deploy", :command => 'deploy')
|
6
|
+
end
|
7
|
+
|
8
|
+
def deploy_info(deploy_id)
|
9
|
+
get("applications/#{id}/deployments/#{deploy_id}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def deploys
|
13
|
+
get("applications/#{id}/deployments")
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
data/lib/scalarium/cli.rb
CHANGED
@@ -37,19 +37,127 @@ class Scalarium
|
|
37
37
|
}
|
38
38
|
say("Configuration file updated")
|
39
39
|
end
|
40
|
+
end
|
41
|
+
|
42
|
+
desc 'update_cookbooks', "Make instances to pull changes from recipies repository"
|
43
|
+
method_option :cloud, :aliases => "-c", :desc => "only for clouds matchin this regexp"
|
44
|
+
def update_cookbooks
|
45
|
+
capture_exceptions do
|
46
|
+
scalarium = ::Scalarium.new(get_token, options[:cloud])
|
47
|
+
|
48
|
+
scalarium.clouds.each do |cloud|
|
49
|
+
puts "Updating cookbooks for #{cloud.name}"
|
50
|
+
next unless (ask "Continue? (say yes)").strip == "yes"
|
51
|
+
|
52
|
+
deploy_info = cloud.update_cookbooks!
|
53
|
+
|
54
|
+
puts "Waiting the deploy finish"
|
55
|
+
puts "Check https://manage.scalarium.com/clouds/#{cloud.id}/deployments/#{deploy_info["id"]} if you want"
|
56
|
+
while deploy_info["successful"] == nil
|
57
|
+
sleep 1
|
58
|
+
deploy_info = cloud.check_deploy(deploy_info["id"])
|
59
|
+
end
|
60
|
+
puts "Deploy was #{deploy_info["successful"]}"
|
61
|
+
exit (deploy_info["successful"] ? 0 : -1)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
desc 'run_recipe RECIPE', 'Execute recipes in given'
|
67
|
+
method_option :cloud, :aliases => "-c", :desc => "only for clouds matchin this regexp"
|
68
|
+
method_option :instance, :aliases => "-i", :type => :array, :desc => "List of instances: -i instace1 instace2"
|
69
|
+
def run_recipe(recipes_names)
|
70
|
+
capture_exceptions do
|
71
|
+
scalarium = ::Scalarium.new(get_token, options[:cloud])
|
72
|
+
instances = nil
|
73
|
+
|
74
|
+
if scalarium.clouds.size > 1
|
75
|
+
$stderr.puts "This operation should be done in only one cloud"
|
76
|
+
exit -1
|
77
|
+
elsif scalarium.clouds.size < 1
|
78
|
+
$stderr.puts "You should select at least one cloud"
|
79
|
+
exit -2
|
80
|
+
end
|
81
|
+
cloud = scalarium.clouds.first
|
82
|
+
instances = options[:instance] ? get_instances_ids(cloud, options[:instance]) : nil
|
83
|
+
|
84
|
+
deploy_info = cloud.run_recipe!(recipes_names, instances)
|
85
|
+
|
86
|
+
puts "Waiting the recipe to finish"
|
87
|
+
puts "Check https://manage.scalarium.com/clouds/#{cloud.id}/deployments/#{deploy_info["id"]} if you want"
|
88
|
+
while deploy_info["successful"] == nil
|
89
|
+
sleep 1
|
90
|
+
deploy_info = cloud.check_deploy(deploy_info["id"])
|
91
|
+
end
|
92
|
+
puts "Deploy was #{deploy_info["successful"]}"
|
93
|
+
exit (deploy_info["successful"] ? 0 : -1)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
desc 'deploy APP', "Deploy application named APP"
|
98
|
+
def deploy(name)
|
99
|
+
capture_exceptions do
|
100
|
+
scalarium = ::Scalarium.new(get_token, false)
|
101
|
+
|
102
|
+
all_apps = scalarium.apps
|
103
|
+
posible_apps = all_apps.select{|app|
|
104
|
+
[app.name, app.slug_name].any?{|a| a =~ Regexp.new(name, ::Regexp::IGNORECASE)}
|
105
|
+
}
|
106
|
+
if posible_apps.size > 1
|
107
|
+
$stderr.puts "Found more than one application matching #{name}"
|
108
|
+
posible_apps.each do |app|
|
109
|
+
puts " #{app.name} (#{app.slug_name}) "
|
110
|
+
end
|
111
|
+
elsif posible_apps.size == 0
|
112
|
+
$stderr.puts "App with name #{name} not found"
|
113
|
+
available_apps = all_apps.map {|app|
|
114
|
+
"#{app.name} (#{app.slug_name})"
|
115
|
+
}
|
116
|
+
$stderr.puts "Available apps: #{available_apps.join(" ")}"
|
117
|
+
else
|
118
|
+
app = posible_apps.first
|
40
119
|
|
120
|
+
deploy_info = app.deploy!
|
41
121
|
|
122
|
+
puts "Waiting the deploy finish"
|
123
|
+
puts "Check https://manage.scalarium.com/applications/#{app.id}/deployments/#{deploy_info["id"]} if you want"
|
124
|
+
while deploy_info["successful"] == nil
|
125
|
+
sleep 1
|
126
|
+
deploy_info = app.deploy_info(deploy_info["id"])
|
127
|
+
end
|
128
|
+
puts "Deploy was #{deploy_info["successful"]}"
|
129
|
+
exit (deploy_info["successful"] ? 0 : -1)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
desc 'apps', "List the apps"
|
136
|
+
method_option :cloud, :aliases => "-c", :desc => "only for clouds matchin this regexp"
|
137
|
+
def apps
|
138
|
+
capture_exceptions do
|
139
|
+
scalarium = ::Scalarium.new( get_token, false )
|
42
140
|
|
141
|
+
scalarium.apps.each do |app|
|
142
|
+
say app.name, Color::BLUE
|
143
|
+
cool_inspect(app, 2)
|
144
|
+
end
|
145
|
+
end
|
43
146
|
end
|
44
147
|
|
148
|
+
|
149
|
+
|
45
150
|
desc 'inspect', "Show Clouds, Roles and Instance names"
|
46
151
|
method_option :cloud, :aliases => "-c", :desc => "only for clouds matchin this regexp"
|
152
|
+
method_option :verbose, :aliases => "-v", :desc => "Show all the availabe", :type => :boolean
|
47
153
|
def inspect
|
48
154
|
capture_exceptions do
|
49
|
-
|
155
|
+
load_all = options[:cloud]
|
156
|
+
load_all = false if options[:verbose]
|
157
|
+
scalarium = ::Scalarium.new( get_token, load_all )
|
50
158
|
|
51
159
|
scalarium.clouds.each do |cloud|
|
52
|
-
print_cloud(cloud)
|
160
|
+
print_cloud(cloud, options[:verbose])
|
53
161
|
end
|
54
162
|
end
|
55
163
|
end
|
@@ -67,6 +175,21 @@ class Scalarium
|
|
67
175
|
|
68
176
|
protected
|
69
177
|
|
178
|
+
def get_instances_ids(cloud, instances)
|
179
|
+
posible_instances = cloud.instances.select{|instance|
|
180
|
+
instances.include?(instance.nickname.downcase)
|
181
|
+
}
|
182
|
+
if posible_instances.size != instances.size
|
183
|
+
if posible_instances.size == 0
|
184
|
+
$stderr.puts "Not to be able to found any instance with name/names #{instances}"
|
185
|
+
else
|
186
|
+
$stderr.puts "Only be able to found #{posible_instances.map{|i| i.nickname}.join(" ")} instances"
|
187
|
+
end
|
188
|
+
exit -3
|
189
|
+
end
|
190
|
+
posible_instances.map{|i| i.id }
|
191
|
+
end
|
192
|
+
|
70
193
|
def format_ssh_config_host(instance)
|
71
194
|
return "" if instance.ip.to_s.strip.empty?
|
72
195
|
host = "\nHost #{instance.nickname}\n" << " Hostname #{instance.ip}\n"
|
@@ -80,9 +203,12 @@ class Scalarium
|
|
80
203
|
say("The token is not valid", Color::RED)
|
81
204
|
File.unlink token_path
|
82
205
|
retry
|
83
|
-
rescue ::OpenSSL::SSL::SSLError
|
206
|
+
rescue ::OpenSSL::SSL::SSLError, ::RestClient::ServerBrokeConnection
|
84
207
|
say("There were problems with ssl. Pleas retry")
|
85
208
|
exit -2
|
209
|
+
rescue ::Errno::ETIMEDOUT
|
210
|
+
say("There were problems with connection (timeout)")
|
211
|
+
exit -3
|
86
212
|
end
|
87
213
|
|
88
214
|
def get_token
|
@@ -99,15 +225,50 @@ class Scalarium
|
|
99
225
|
File.expand_path("~/.scalarium_token")
|
100
226
|
end
|
101
227
|
|
102
|
-
def print_cloud(cloud)
|
228
|
+
def print_cloud(cloud, verbose=false)
|
103
229
|
say "#{cloud.name} (#{cloud.id[0..6]})", Color::GREEN
|
230
|
+
return cool_inspect(cloud, 2) if verbose
|
104
231
|
cloud.roles.each do |rol|
|
105
232
|
say " #{rol.name}", Color::BLUE
|
106
|
-
|
107
|
-
|
233
|
+
if verbose
|
234
|
+
cool_inspect(role, 2)
|
235
|
+
else
|
236
|
+
rol.instances.each do |instance|
|
237
|
+
puts " #{instance.nickname} (#{instance.ip})"
|
238
|
+
end
|
108
239
|
end
|
109
240
|
end
|
110
241
|
end
|
111
242
|
|
243
|
+
def cool_inspect(what, indent = 0)
|
244
|
+
case what
|
245
|
+
when OpenStruct
|
246
|
+
cool_inspect( what.instance_variable_get("@table"), indent)
|
247
|
+
when Hash
|
248
|
+
what.each do |key,value|
|
249
|
+
case value
|
250
|
+
when String, Integer, false, true, nil
|
251
|
+
say( " " * indent+ key.to_s + ": " + Color::BLACK + value.inspect, Color::YELLOW)
|
252
|
+
else
|
253
|
+
if (what === Array || what === Hash) && what.size == 0
|
254
|
+
say( " " * indent + key.to_s + ": " + Color::MAGENTA + what.inspect, Color::YELLOW)
|
255
|
+
else
|
256
|
+
say( " " * indent+ key.to_s + ": ", Color::YELLOW)
|
257
|
+
cool_inspect(value, indent + 2)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
when Array
|
262
|
+
say( " " * indent + '[', Color::MAGENTA)
|
263
|
+
what.each_with_index do |value, index|
|
264
|
+
say( " " * indent + index.to_s + ".")
|
265
|
+
cool_inspect(value, indent + 2)
|
266
|
+
end
|
267
|
+
say( " " * indent + ']', Color::MAGENTA)
|
268
|
+
else
|
269
|
+
say((" " * indent + what.inspect ), Color::BLACK)
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
112
273
|
end
|
113
274
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
class Scalarium
|
3
|
+
class Cloud < Resource
|
4
|
+
def update_cookbooks!
|
5
|
+
post("clouds/#{id}/deploy", :command => 'update_custom_cookbooks' )
|
6
|
+
end
|
7
|
+
|
8
|
+
def check_deploy(deploy_id)
|
9
|
+
get("clouds/#{id}/deployments/#{deploy_id}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def run_recipe!(recipe, instances = nil)
|
13
|
+
opt = {:command => "execute_recipes", :recipes => recipe}
|
14
|
+
opt[:instances] = instances if instances
|
15
|
+
|
16
|
+
post("clouds/#{id}/deploy", opt)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/scalarium/version.rb
CHANGED
data/scalarium.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scalarium
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-09-
|
12
|
+
date: 2011-09-14 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rest-client
|
16
|
-
requirement: &
|
16
|
+
requirement: &2154051880 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *2154051880
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: dispatch_queue
|
27
|
-
requirement: &
|
27
|
+
requirement: &2154051460 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *2154051460
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: thor
|
38
|
-
requirement: &
|
38
|
+
requirement: &2154051040 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,21 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2154051040
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: ruby-debug19
|
49
|
+
requirement: &2154050620 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2154050620
|
47
58
|
- !ruby/object:Gem::Dependency
|
48
59
|
name: rake
|
49
|
-
requirement: &
|
60
|
+
requirement: &2154050200 !ruby/object:Gem::Requirement
|
50
61
|
none: false
|
51
62
|
requirements:
|
52
63
|
- - ! '>='
|
@@ -54,7 +65,7 @@ dependencies:
|
|
54
65
|
version: '0'
|
55
66
|
type: :development
|
56
67
|
prerelease: false
|
57
|
-
version_requirements: *
|
68
|
+
version_requirements: *2154050200
|
58
69
|
description: Access your scalarium clouds from console
|
59
70
|
email:
|
60
71
|
- guillermo@cientifico.net
|
@@ -64,11 +75,17 @@ extensions: []
|
|
64
75
|
extra_rdoc_files: []
|
65
76
|
files:
|
66
77
|
- .gitignore
|
78
|
+
- CHANGELOG
|
67
79
|
- Gemfile
|
80
|
+
- README.md
|
68
81
|
- Rakefile
|
69
82
|
- bin/scalarium
|
70
83
|
- lib/scalarium.rb
|
84
|
+
- lib/scalarium/api.rb
|
85
|
+
- lib/scalarium/app.rb
|
71
86
|
- lib/scalarium/cli.rb
|
87
|
+
- lib/scalarium/cloud.rb
|
88
|
+
- lib/scalarium/resource.rb
|
72
89
|
- lib/scalarium/version.rb
|
73
90
|
- scalarium.gemspec
|
74
91
|
homepage: ''
|