shelly 0.3.4 → 0.3.5.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -269,7 +269,7 @@ module Shelly
269
269
  end
270
270
 
271
271
  def upload(source)
272
- console_connection.tap do |conn|
272
+ tunnel_connection.tap do |conn|
273
273
  rsync(source, "#{conn['host']}:#{persistent_disk}", conn)
274
274
  end
275
275
  end
@@ -281,7 +281,7 @@ module Shelly
281
281
  end
282
282
 
283
283
  def download(relative_source, destination)
284
- console_connection.tap do |conn|
284
+ tunnel_connection.tap do |conn|
285
285
  source = File.join("#{conn['host']}:#{persistent_disk}", relative_source)
286
286
  rsync(source, destination, conn)
287
287
  end
@@ -291,6 +291,10 @@ module Shelly
291
291
  ssh(:command => "delete_file #{remote_path}")
292
292
  end
293
293
 
294
+ def setup_tunnel(conn, local_port)
295
+ system "ssh #{ssh_options(conn)} -N -L #{local_port}:localhost:#{conn['service']['port']} #{conn['host']}"
296
+ end
297
+
294
298
  # Public: Return databases for given Cloud in Cloudfile
295
299
  # Returns Array of databases
296
300
  def cloud_databases
@@ -351,6 +355,11 @@ module Shelly
351
355
  IO.popen(%Q{git log --no-merges --oneline --pretty=format:"#{format}" #{range}}).read.strip
352
356
  end
353
357
 
358
+ # Returns first at least configured virtual server
359
+ def tunnel_connection(service = "ssh", server = nil)
360
+ shelly.tunnel(code_name, service, server)
361
+ end
362
+
354
363
  private
355
364
 
356
365
  def assign_attributes(response)
@@ -373,18 +382,13 @@ module Shelly
373
382
  content["servers"].any? {|_, settings| settings.has_key?(option)}
374
383
  end
375
384
 
376
- # Returns first at least configured virtual server
377
- def console_connection(server = nil)
378
- shelly.console(code_name, server)
379
- end
380
-
381
385
  # Returns first at least configured virtual server if databases are configured
382
386
  def configured_db_server_connection(server = nil)
383
387
  shelly.configured_db_server(code_name, server)
384
388
  end
385
389
 
386
390
  def ssh(options = {})
387
- conn = console_connection(options[:server])
391
+ conn = tunnel_connection("ssh", options[:server])
388
392
  system "ssh #{ssh_options(conn)} -t #{conn['host']} #{options[:command]}"
389
393
  end
390
394
 
@@ -6,7 +6,7 @@ module Shelly
6
6
  class Database < Command
7
7
  namespace :database
8
8
  include Helpers
9
- before_hook :logged_in?, :only => [:reset]
9
+ before_hook :logged_in?, :only => [:reset, :tunnel]
10
10
  class_option :cloud, :type => :string, :aliases => "-c", :desc => "Specify cloud"
11
11
 
12
12
  desc "reset KIND", "Reset database"
@@ -23,6 +23,22 @@ module Shelly
23
23
  rescue Client::ConflictException
24
24
  say_error "Cloud #{app} wasn't deployed properly. Cannot reset database."
25
25
  end
26
+
27
+ desc "tunnel KIND", "Setup tunnel to given database"
28
+ method_option :port, :type => :string, :aliases => "-p",
29
+ :desc => "Local port on which tunnel will be set up"
30
+ def tunnel(kind)
31
+ app = multiple_clouds(options[:cloud], "database tunnel")
32
+ local_port = options[:port] || 9900
33
+ conn = app.tunnel_connection(kind)
34
+ say "Connection details", :green
35
+ say "host: localhost"
36
+ say "port: #{local_port}"
37
+ say "database: #{conn['service']['database_name']}"
38
+ say "username: #{conn['service']['username']}"
39
+ say "password: #{conn['service']['password']}"
40
+ app.setup_tunnel(conn, local_port)
41
+ end
26
42
  end
27
43
  end
28
44
  end
@@ -38,27 +38,32 @@ module Shelly
38
38
  specify_log(log)
39
39
  app = multiple_clouds(options[:cloud], "deploy show #{log}")
40
40
  content = app.deploy_log(log)
41
- say "Log for deploy done on #{content["created_at"]}", :green
42
- if content["bundle_install"]
43
- say("Starting bundle install", :green); say(content["bundle_install"])
44
- end
45
- if content["whenever"]
46
- say("Starting whenever", :green); say(content["whenever"])
47
- end
48
- if content["callbacks"]
49
- say("Starting callbacks", :green); say(content["callbacks"])
50
- end
51
- if content["delayed_job"]
52
- say("Starting delayed job", :green); say(content["delayed_job"])
53
- end
54
- if content["sidekiq"]
55
- say("Starting sidekiq", :green); say(content["sidekiq"])
56
- end
57
- if content["thin_restart"]
58
- say("Starting thin", :green); say(content["thin_restart"])
59
- end
60
- if content["puma_restart"]
61
- say("Starting puma", :green); say(content["puma_restart"])
41
+ unless content.empty?
42
+ say "Log for deploy done on #{content["created_at"]}", :green
43
+ if content["bundle_install"]
44
+ say("Starting bundle install", :green); say(content["bundle_install"])
45
+ end
46
+ if content["whenever"]
47
+ say("Starting whenever", :green); say(content["whenever"])
48
+ end
49
+ if content["callbacks"]
50
+ say("Starting callbacks", :green); say(content["callbacks"])
51
+ end
52
+ if content["delayed_job"]
53
+ say("Starting delayed job", :green); say(content["delayed_job"])
54
+ end
55
+ if content["sidekiq"]
56
+ say("Starting sidekiq", :green); say(content["sidekiq"])
57
+ end
58
+ if content["thin_restart"]
59
+ say("Starting thin", :green); say(content["thin_restart"])
60
+ end
61
+ if content["puma_restart"]
62
+ say("Starting puma", :green); say(content["puma_restart"])
63
+ end
64
+ else
65
+ say_error("There was an error and log is not available", :with_exit => false)
66
+ say_error("Please contact our support https://shellycloud.com/support")
62
67
  end
63
68
  rescue Client::NotFoundException => e
64
69
  raise unless e.resource == :log
@@ -7,6 +7,7 @@ module Shelly
7
7
  class Client
8
8
  require 'shelly/client/errors'
9
9
  require 'shelly/client/shellyapp'
10
+ require 'shelly/client/tunnels'
10
11
  require 'shelly/client/users'
11
12
  require 'shelly/client/apps'
12
13
  require 'shelly/client/configs'
@@ -33,12 +33,4 @@ class Shelly::Client
33
33
  def command(cloud, body, type)
34
34
  post("/apps/#{cloud}/command", {:body => body, :type => type})
35
35
  end
36
-
37
- def console(code_name, server = nil)
38
- get("/apps/#{code_name}/console", {:server => server})
39
- end
40
-
41
- def configured_db_server(code_name, server = nil)
42
- get("/apps/#{code_name}/configured_db_server", {:server => server})
43
- end
44
36
  end
@@ -0,0 +1,10 @@
1
+ class Shelly::Client
2
+ def tunnel(code_name, service, server = nil)
3
+ post("/apps/#{code_name}/tunnels", {:server => server, :service => service})
4
+ end
5
+
6
+ def configured_db_server(code_name, server = nil)
7
+ get("/apps/#{code_name}/configured_db_server",
8
+ {:server => server, :service => "ssh"})
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  module Shelly
2
- VERSION = "0.3.4"
2
+ VERSION = "0.3.5.pre"
3
3
  end
@@ -291,7 +291,7 @@ describe Shelly::App do
291
291
 
292
292
  describe "#rake" do
293
293
  it "should return result of rake task" do
294
- @client.stub(:console).and_return(
294
+ @client.stub(:tunnel).and_return(
295
295
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
296
296
  @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com rake_runner \"test\"")
297
297
  @app.rake("test")
@@ -349,7 +349,7 @@ describe Shelly::App do
349
349
 
350
350
  describe "#console" do
351
351
  it "should run ssh with all parameters" do
352
- @client.stub(:console).and_return(
352
+ @client.stub(:tunnel).and_return(
353
353
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
354
354
  @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 40010 -l foo -t console.example.com ")
355
355
  @app.console
@@ -357,7 +357,7 @@ describe Shelly::App do
357
357
 
358
358
  context "when server passed" do
359
359
  it "should request console on given server" do
360
- @client.should_receive(:console).with("foo-staging", "app1").and_return({})
360
+ @client.should_receive(:tunnel).with("foo-staging", "ssh", "app1").and_return({})
361
361
  @app.stub(:system)
362
362
  @app.console("app1")
363
363
  end
@@ -373,7 +373,7 @@ describe Shelly::App do
373
373
 
374
374
  describe "#upload" do
375
375
  it "should run rsync with proper parameters" do
376
- @client.stub(:console).and_return(
376
+ @client.stub(:tunnel).and_return(
377
377
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
378
378
  @app.should_receive(:system).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress /path console.example.com:/home/foo-staging/disk")
379
379
  @app.upload("/path")
@@ -382,7 +382,7 @@ describe Shelly::App do
382
382
 
383
383
  describe "#download" do
384
384
  it "should run rsync with proper parameters" do
385
- @client.stub(:console).and_return(
385
+ @client.stub(:tunnel).and_return(
386
386
  {"host" => "console.example.com", "port" => "40010", "user" => "foo"})
387
387
  @app.should_receive(:system).with("rsync -avz -e 'ssh -o StrictHostKeyChecking=no -p 40010 -l foo' --progress console.example.com:/home/foo-staging/disk/. /tmp")
388
388
  @app.download(".", "/tmp")
@@ -545,4 +545,11 @@ describe Shelly::App do
545
545
  @app.pending_commits.should == "c10c5f6 Some changes"
546
546
  end
547
547
  end
548
+
549
+ describe "#setup_tunnel" do
550
+ it "should setup tunnel with given options" do
551
+ @app.should_receive(:system).with("ssh -o StrictHostKeyChecking=no -p 43000 -l foo -N -L 9999:localhost:5432 console.example.com")
552
+ @app.setup_tunnel({"service" => {"port" => "5432"}, "host" => "console.example.com", "port" => 43000, "user" => "foo"}, 9999)
553
+ end
554
+ end
548
555
  end
@@ -30,4 +30,36 @@ describe Shelly::CLI::Database do
30
30
  end
31
31
  end
32
32
  end
33
+
34
+ describe "#tunnel" do
35
+ it "should ensure user has logged in" do
36
+ hooks(@database, :tunnel).should include(:logged_in?)
37
+ end
38
+
39
+ it "should show tunnel's details" do
40
+ @app.stub(:setup_tunnel)
41
+ conn = {
42
+ 'service' => {
43
+ 'database_name' => 'foo',
44
+ 'username' => 'foo',
45
+ 'password' => 'secret'
46
+ }
47
+ }
48
+ @app.should_receive(:tunnel_connection).and_return(conn)
49
+ $stdout.should_receive(:puts).with("host: localhost")
50
+ $stdout.should_receive(:puts).with("port: 9900")
51
+ $stdout.should_receive(:puts).with("database: foo")
52
+ $stdout.should_receive(:puts).with("username: foo")
53
+ $stdout.should_receive(:puts).with("password: secret")
54
+ invoke(@database, :tunnel, "mongodb")
55
+ end
56
+
57
+ it "should setup tunnel" do
58
+ conn = {"host" => "localhost", "service" => {"port" => "27010"}}
59
+ @app.should_receive(:tunnel_connection).and_return(conn)
60
+ @app.should_receive(:setup_tunnel).with(conn, 10103)
61
+ @database.options = {:port => 10103}
62
+ invoke(@database, :tunnel, "mongodb")
63
+ end
64
+ end
33
65
  end
@@ -86,6 +86,15 @@ describe Shelly::CLI::Deploy do
86
86
  end
87
87
  end
88
88
 
89
+ context "log is missing" do
90
+ it "should show error about contact support" do
91
+ @client.should_receive(:deploy_log).with("foo-staging", "last").and_return({})
92
+ $stdout.should_receive(:puts).with(red "There was an error and log is not available")
93
+ $stdout.should_receive(:puts).with(red "Please contact our support https://shellycloud.com/support")
94
+ lambda { invoke(@deploys, :show, "last") }.should raise_error(SystemExit)
95
+ end
96
+ end
97
+
89
98
  def expected_output
90
99
  $stdout.should_receive(:puts).with(green "Log for deploy done on 2011-12-12 at 14:14:59")
91
100
  $stdout.should_receive(:puts).with(green "Starting bundle install")
@@ -28,7 +28,7 @@ describe Shelly::CLI::File do
28
28
 
29
29
  context "cloud is not running" do
30
30
  it "should display error" do
31
- @client.stub(:console).and_raise(Shelly::Client::ConflictException)
31
+ @client.stub(:tunnel).and_raise(Shelly::Client::ConflictException)
32
32
  $stdout.should_receive(:puts).with(red "Cloud foo-production wasn't deployed properly. Cannot list files.")
33
33
  lambda {
34
34
  invoke(@cli_files, :list, "some/path")
@@ -45,7 +45,7 @@ describe Shelly::CLI::File do
45
45
 
46
46
  it "should upload files" do
47
47
  expected = {"host" => "console.example.com", "port" => "40010", "user" => "foo"}
48
- @client.stub(:console).and_return(expected)
48
+ @client.stub(:tunnel).and_return(expected)
49
49
  @app.should_receive(:upload).with("some/path")
50
50
  invoke(@cli_files, :upload, "some/path")
51
51
  end
@@ -59,7 +59,7 @@ describe Shelly::CLI::File do
59
59
 
60
60
  context "cloud is not running" do
61
61
  it "should display error" do
62
- @client.stub(:console).and_raise(Shelly::Client::ConflictException)
62
+ @client.stub(:tunnel).and_raise(Shelly::Client::ConflictException)
63
63
  $stdout.should_receive(:puts).with(red "Cloud foo-production wasn't deployed properly. Cannot upload files.")
64
64
  lambda {
65
65
  invoke(@cli_files, :upload, "some/path")
@@ -81,14 +81,14 @@ describe Shelly::CLI::File do
81
81
 
82
82
  it "should download files" do
83
83
  expected = {"host" => "console.example.com", "port" => "40010", "user" => "foo"}
84
- @client.stub(:console).and_return(expected)
84
+ @client.stub(:tunnel).and_return(expected)
85
85
  @app.should_receive(:download).with("some/path", "/destination")
86
86
  invoke(@cli_files, :download, "some/path", "/destination")
87
87
  end
88
88
 
89
89
  context "cloud is not running" do
90
90
  it "should display error" do
91
- @client.stub(:console).and_raise(Shelly::Client::ConflictException)
91
+ @client.stub(:tunnel).and_raise(Shelly::Client::ConflictException)
92
92
  $stdout.should_receive(:puts).with(red "Cloud foo-production wasn't deployed properly. Cannot download files.")
93
93
  lambda {
94
94
  invoke(@cli_files, :download, "some/path")
@@ -1379,7 +1379,7 @@ Wait until cloud is in 'turned off' state and try again.")
1379
1379
 
1380
1380
  context "virtual servers are not running" do
1381
1381
  it "should display error" do
1382
- @client.stub(:console).and_raise(Shelly::Client::ConflictException)
1382
+ @client.stub(:tunnel).and_raise(Shelly::Client::ConflictException)
1383
1383
  $stdout.should_receive(:puts).with(red "Cloud foo-production is not running. Cannot run console.")
1384
1384
  lambda {
1385
1385
  invoke(@main, :console)
@@ -1390,7 +1390,7 @@ Wait until cloud is in 'turned off' state and try again.")
1390
1390
  context "virtual server not found" do
1391
1391
  it "should display error" do
1392
1392
  ex = Shelly::Client::NotFoundException.new("resource" => "virtual_server")
1393
- @client.stub(:console).and_raise(ex)
1393
+ @client.stub(:tunnel).and_raise(ex)
1394
1394
  @main.options = {:server => "foobar"}
1395
1395
  $stdout.should_receive(:puts).with(red "Virtual Server 'foobar' not found")
1396
1396
  lambda {
@@ -250,12 +250,12 @@ describe Shelly::Client do
250
250
  end
251
251
  end
252
252
 
253
- describe "#console" do
253
+ describe "#tunnel" do
254
254
  it "should fetch virtual server data from API" do
255
255
  body = {:port => "40010", :host => "console.example.com", :user => "foo-production"}
256
- FakeWeb.register_uri(:get, api_url("apps/staging-foo/console"),
256
+ FakeWeb.register_uri(:post, api_url("apps/staging-foo/tunnels"),
257
257
  :body => body.to_json)
258
- response = @client.console("staging-foo")
258
+ response = @client.tunnel("staging-foo", "ssh")
259
259
  response.should == {"port" => "40010", "host" => "console.example.com", "user"=>"foo-production"}
260
260
  end
261
261
  end
metadata CHANGED
@@ -1,25 +1,25 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: shelly
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
5
- prerelease:
4
+ prerelease: 6
5
+ version: 0.3.5.pre
6
6
  platform: ruby
7
7
  authors:
8
8
  - Shelly Cloud team
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-02 00:00:00.000000000 Z
12
+ date: 2013-07-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
+ type: :development
16
17
  requirement: !ruby/object:Gem::Requirement
17
18
  none: false
18
19
  requirements:
19
20
  - - ~>
20
21
  - !ruby/object:Gem::Version
21
22
  version: 2.11.0
22
- type: :development
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
@@ -29,13 +29,13 @@ dependencies:
29
29
  version: 2.11.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: rake
32
+ type: :development
32
33
  requirement: !ruby/object:Gem::Requirement
33
34
  none: false
34
35
  requirements:
35
36
  - - ! '>='
36
37
  - !ruby/object:Gem::Version
37
38
  version: '0'
38
- type: :development
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
@@ -45,13 +45,13 @@ dependencies:
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: guard
48
+ type: :development
48
49
  requirement: !ruby/object:Gem::Requirement
49
50
  none: false
50
51
  requirements:
51
52
  - - ! '>='
52
53
  - !ruby/object:Gem::Version
53
54
  version: '0'
54
- type: :development
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
@@ -61,13 +61,13 @@ dependencies:
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
63
  name: guard-rspec
64
+ type: :development
64
65
  requirement: !ruby/object:Gem::Requirement
65
66
  none: false
66
67
  requirements:
67
68
  - - ! '>='
68
69
  - !ruby/object:Gem::Version
69
70
  version: '0'
70
- type: :development
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
@@ -77,13 +77,45 @@ dependencies:
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
79
  name: simplecov
80
+ type: :development
81
+ requirement: !ruby/object:Gem::Requirement
82
+ none: false
83
+ requirements:
84
+ - - ! '>='
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: ruby_gntp
96
+ type: :development
80
97
  requirement: !ruby/object:Gem::Requirement
81
98
  none: false
82
99
  requirements:
83
100
  - - ! '>='
84
101
  - !ruby/object:Gem::Version
85
102
  version: '0'
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rb-fsevent
86
112
  type: :development
113
+ requirement: !ruby/object:Gem::Requirement
114
+ none: false
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
87
119
  prerelease: false
88
120
  version_requirements: !ruby/object:Gem::Requirement
89
121
  none: false
@@ -93,13 +125,13 @@ dependencies:
93
125
  version: '0'
94
126
  - !ruby/object:Gem::Dependency
95
127
  name: fakefs
128
+ type: :development
96
129
  requirement: !ruby/object:Gem::Requirement
97
130
  none: false
98
131
  requirements:
99
132
  - - ! '>='
100
133
  - !ruby/object:Gem::Version
101
134
  version: '0'
102
- type: :development
103
135
  prerelease: false
104
136
  version_requirements: !ruby/object:Gem::Requirement
105
137
  none: false
@@ -109,13 +141,13 @@ dependencies:
109
141
  version: '0'
110
142
  - !ruby/object:Gem::Dependency
111
143
  name: fakeweb
144
+ type: :development
112
145
  requirement: !ruby/object:Gem::Requirement
113
146
  none: false
114
147
  requirements:
115
148
  - - ! '>='
116
149
  - !ruby/object:Gem::Version
117
150
  version: '0'
118
- type: :development
119
151
  prerelease: false
120
152
  version_requirements: !ruby/object:Gem::Requirement
121
153
  none: false
@@ -125,13 +157,13 @@ dependencies:
125
157
  version: '0'
126
158
  - !ruby/object:Gem::Dependency
127
159
  name: wijet-thor
160
+ type: :runtime
128
161
  requirement: !ruby/object:Gem::Requirement
129
162
  none: false
130
163
  requirements:
131
164
  - - ~>
132
165
  - !ruby/object:Gem::Version
133
166
  version: 0.14.9
134
- type: :runtime
135
167
  prerelease: false
136
168
  version_requirements: !ruby/object:Gem::Requirement
137
169
  none: false
@@ -141,13 +173,13 @@ dependencies:
141
173
  version: 0.14.9
142
174
  - !ruby/object:Gem::Dependency
143
175
  name: rest-client
176
+ type: :runtime
144
177
  requirement: !ruby/object:Gem::Requirement
145
178
  none: false
146
179
  requirements:
147
180
  - - ! '>='
148
181
  - !ruby/object:Gem::Version
149
182
  version: '0'
150
- type: :runtime
151
183
  prerelease: false
152
184
  version_requirements: !ruby/object:Gem::Requirement
153
185
  none: false
@@ -157,13 +189,13 @@ dependencies:
157
189
  version: '0'
158
190
  - !ruby/object:Gem::Dependency
159
191
  name: json
192
+ type: :runtime
160
193
  requirement: !ruby/object:Gem::Requirement
161
194
  none: false
162
195
  requirements:
163
196
  - - ! '>='
164
197
  - !ruby/object:Gem::Version
165
198
  version: '0'
166
- type: :runtime
167
199
  prerelease: false
168
200
  version_requirements: !ruby/object:Gem::Requirement
169
201
  none: false
@@ -173,13 +205,13 @@ dependencies:
173
205
  version: '0'
174
206
  - !ruby/object:Gem::Dependency
175
207
  name: progressbar
208
+ type: :runtime
176
209
  requirement: !ruby/object:Gem::Requirement
177
210
  none: false
178
211
  requirements:
179
212
  - - ! '>='
180
213
  - !ruby/object:Gem::Version
181
214
  version: '0'
182
- type: :runtime
183
215
  prerelease: false
184
216
  version_requirements: !ruby/object:Gem::Requirement
185
217
  none: false
@@ -189,13 +221,13 @@ dependencies:
189
221
  version: '0'
190
222
  - !ruby/object:Gem::Dependency
191
223
  name: launchy
224
+ type: :runtime
192
225
  requirement: !ruby/object:Gem::Requirement
193
226
  none: false
194
227
  requirements:
195
228
  - - ! '>='
196
229
  - !ruby/object:Gem::Version
197
230
  version: '0'
198
- type: :runtime
199
231
  prerelease: false
200
232
  version_requirements: !ruby/object:Gem::Requirement
201
233
  none: false
@@ -205,13 +237,13 @@ dependencies:
205
237
  version: '0'
206
238
  - !ruby/object:Gem::Dependency
207
239
  name: netrc
240
+ type: :runtime
208
241
  requirement: !ruby/object:Gem::Requirement
209
242
  none: false
210
243
  requirements:
211
244
  - - ! '>='
212
245
  - !ruby/object:Gem::Version
213
246
  version: '0'
214
- type: :runtime
215
247
  prerelease: false
216
248
  version_requirements: !ruby/object:Gem::Requirement
217
249
  none: false
@@ -264,6 +296,7 @@ files:
264
296
  - lib/shelly/client/organizations.rb
265
297
  - lib/shelly/client/shellyapp.rb
266
298
  - lib/shelly/client/ssh_keys.rb
299
+ - lib/shelly/client/tunnels.rb
267
300
  - lib/shelly/client/users.rb
268
301
  - lib/shelly/cloudfile.rb
269
302
  - lib/shelly/download_progress_bar.rb
@@ -315,22 +348,39 @@ required_ruby_version: !ruby/object:Gem::Requirement
315
348
  - - ! '>='
316
349
  - !ruby/object:Gem::Version
317
350
  version: '0'
318
- segments:
319
- - 0
320
- hash: 3404836754866729086
321
351
  required_rubygems_version: !ruby/object:Gem::Requirement
322
352
  none: false
323
353
  requirements:
324
- - - ! '>='
354
+ - - ! '>'
325
355
  - !ruby/object:Gem::Version
326
- version: '0'
327
- segments:
328
- - 0
329
- hash: 3404836754866729086
356
+ version: 1.3.1
330
357
  requirements: []
331
358
  rubyforge_project: shelly
332
- rubygems_version: 1.8.25
359
+ rubygems_version: 1.8.23
333
360
  signing_key:
334
361
  specification_version: 3
335
362
  summary: Shelly Cloud command line tool
336
- test_files: []
363
+ test_files:
364
+ - spec/helpers.rb
365
+ - spec/input_faker.rb
366
+ - spec/shelly/app_spec.rb
367
+ - spec/shelly/backup_spec.rb
368
+ - spec/shelly/cli/backup_spec.rb
369
+ - spec/shelly/cli/config_spec.rb
370
+ - spec/shelly/cli/database_spec.rb
371
+ - spec/shelly/cli/deploy_spec.rb
372
+ - spec/shelly/cli/file_spec.rb
373
+ - spec/shelly/cli/logs_spec.rb
374
+ - spec/shelly/cli/main_spec.rb
375
+ - spec/shelly/cli/organization_spec.rb
376
+ - spec/shelly/cli/runner_spec.rb
377
+ - spec/shelly/cli/user_spec.rb
378
+ - spec/shelly/client_spec.rb
379
+ - spec/shelly/cloudfile_spec.rb
380
+ - spec/shelly/download_progress_bar_spec.rb
381
+ - spec/shelly/model_spec.rb
382
+ - spec/shelly/organization_spec.rb
383
+ - spec/shelly/structure_validator_spec.rb
384
+ - spec/shelly/user_spec.rb
385
+ - spec/spec_helper.rb
386
+ - spec/thor/options_spec.rb