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.
@@ -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: ''