scalarium 0.0.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ Version 0.2.0
2
+ * run_recipe - Allow to run recipes in some instances
3
+ * udpate_cookbooks - Allow to update cookbooks in machines
4
+ * deploy - Allow to Deploy apps
5
+ * apps - List applications
@@ -0,0 +1,3 @@
1
+ = Scalarium =
2
+
3
+ This is a drescription
@@ -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
- class Instance < OpenStruct ; end
9
- class Rol < OpenStruct ; end
10
- class Cloud < OpenStruct ; end
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
- private
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
@@ -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
- scalarium = ::Scalarium.new( get_token, options[:cloud] )
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
- rol.instances.each do |instance|
107
- puts " #{instance.nickname} (#{instance.ip})"
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
@@ -0,0 +1,9 @@
1
+ class Scalarium
2
+ class Resource < OpenStruct
3
+ include Scalarium::Api
4
+ def initialize(token, attributes = {})
5
+ @token = token
6
+ super(attributes)
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,3 @@
1
1
  class Scalarium
2
- VERSION = "0.0.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -21,5 +21,6 @@ Gem::Specification.new do |s|
21
21
  s.add_runtime_dependency 'rest-client'
22
22
  s.add_runtime_dependency 'dispatch_queue'
23
23
  s.add_runtime_dependency 'thor'
24
+ s.add_development_dependency 'ruby-debug19'
24
25
  s.add_development_dependency 'rake'
25
26
  end
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.1
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-09 00:00:00.000000000Z
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: &2160501020 !ruby/object:Gem::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: *2160501020
24
+ version_requirements: *2154051880
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: dispatch_queue
27
- requirement: &2160500600 !ruby/object:Gem::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: *2160500600
35
+ version_requirements: *2154051460
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: thor
38
- requirement: &2160500180 !ruby/object:Gem::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: *2160500180
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: &2160499760 !ruby/object:Gem::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: *2160499760
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: ''