vmc 0.4.0.beta.93 → 0.4.0.beta.94
Sign up to get free protection for your applications and to get access to all the features.
- data/vmc-ng/Rakefile +21 -30
- data/vmc-ng/lib/vmc.rb +4 -3
- data/vmc-ng/lib/vmc/cli.rb +10 -9
- data/vmc-ng/lib/vmc/cli/app/app.rb +45 -0
- data/vmc-ng/lib/vmc/cli/app/apps.rb +97 -0
- data/vmc-ng/lib/vmc/cli/app/base.rb +82 -0
- data/vmc-ng/lib/vmc/cli/app/crashes.rb +41 -0
- data/vmc-ng/lib/vmc/cli/app/delete.rb +90 -0
- data/vmc-ng/lib/vmc/cli/app/deprecated.rb +11 -0
- data/vmc-ng/lib/vmc/cli/app/env.rb +86 -0
- data/vmc-ng/lib/vmc/cli/app/files.rb +85 -0
- data/vmc-ng/lib/vmc/cli/app/health.rb +27 -0
- data/vmc-ng/lib/vmc/cli/app/instances.rb +49 -0
- data/vmc-ng/lib/vmc/cli/app/logs.rb +80 -0
- data/vmc-ng/lib/vmc/cli/app/push.rb +336 -0
- data/vmc-ng/lib/vmc/cli/app/rename.rb +31 -0
- data/vmc-ng/lib/vmc/cli/app/restart.rb +23 -0
- data/vmc-ng/lib/vmc/cli/app/routes.rb +97 -0
- data/vmc-ng/lib/vmc/cli/app/scale.rb +67 -0
- data/vmc-ng/lib/vmc/cli/app/start.rb +96 -0
- data/vmc-ng/lib/vmc/cli/app/stats.rb +68 -0
- data/vmc-ng/lib/vmc/cli/app/stop.rb +29 -0
- data/vmc-ng/lib/vmc/cli/domain/add_domain.rb +27 -0
- data/vmc-ng/lib/vmc/cli/domain/base.rb +12 -0
- data/vmc-ng/lib/vmc/cli/domain/create_domain.rb +31 -0
- data/vmc-ng/lib/vmc/cli/domain/delete_domain.rb +51 -0
- data/vmc-ng/lib/vmc/cli/domain/domains.rb +43 -0
- data/vmc-ng/lib/vmc/cli/domain/remove_domain.rb +26 -0
- data/vmc-ng/lib/vmc/cli/help.rb +0 -1
- data/vmc-ng/lib/vmc/cli/interactive.rb +4 -0
- data/vmc-ng/lib/vmc/cli/route/base.rb +12 -0
- data/vmc-ng/lib/vmc/cli/route/create_route.rb +42 -0
- data/vmc-ng/lib/vmc/cli/route/delete_route.rb +42 -0
- data/vmc-ng/lib/vmc/cli/route/routes.rb +26 -0
- data/vmc-ng/lib/vmc/detect.rb +2 -2
- data/vmc-ng/lib/vmc/spec_helper.rb +1 -0
- data/vmc-ng/lib/vmc/version.rb +1 -1
- data/vmc-ng/spec/cli/app/push_spec.rb +34 -0
- data/vmc-ng/spec/cli/app/rename_spec.rb +108 -0
- data/vmc-ng/spec/cli/route/delete_route_spec.rb +160 -0
- data/vmc-ng/spec/detect_spec.rb +54 -0
- data/vmc-ng/spec/factories/app_factory.rb +9 -0
- data/vmc-ng/spec/factories/client_factory.rb +16 -0
- data/vmc-ng/spec/factories/domain_factory.rb +9 -0
- data/vmc-ng/spec/factories/factory.rb +3 -0
- data/vmc-ng/spec/factories/framework_factory.rb +9 -0
- data/vmc-ng/spec/factories/route_factory.rb +10 -0
- data/vmc-ng/spec/spec_helper.rb +17 -0
- data/vmc-ng/spec/support/interact_helpers.rb +23 -0
- metadata +135 -62
- data/vmc-ng/lib/vmc/cli/app.rb +0 -1333
- data/vmc-ng/lib/vmc/cli/domain.rb +0 -164
- data/vmc-ng/lib/vmc/cli/route.rb +0 -106
- data/vmc-ng/lib/vmc/spec_helpers.rb +0 -431
- data/vmc-ng/lib/vmc/spec_helpers/eventlog.rb +0 -277
- data/vmc-ng/lib/vmc/spec_helpers/patches.rb +0 -94
- data/vmc-ng/spec/Rakefile +0 -13
- data/vmc-ng/spec/app/app_spec.rb +0 -19
- data/vmc-ng/spec/app/apps_spec.rb +0 -79
- data/vmc-ng/spec/app/push_spec.rb +0 -74
- data/vmc-ng/spec/assets/hello-sinatra/Gemfile +0 -2
- data/vmc-ng/spec/assets/hello-sinatra/main.rb +0 -5
- data/vmc-ng/spec/assets/hello-sinatra/manifest.yml +0 -9
- data/vmc-ng/spec/helpers.rb +0 -7
- data/vmc-ng/spec/start/target_spec.rb +0 -60
@@ -0,0 +1,31 @@
|
|
1
|
+
require "vmc/cli/domain/base"
|
2
|
+
|
3
|
+
module VMC::Domain
|
4
|
+
class CreateDomain < Base
|
5
|
+
desc "Create a domain"
|
6
|
+
group :domains
|
7
|
+
input :name, :argument => :required,
|
8
|
+
:desc => "Domain name to create"
|
9
|
+
input :organization, :aliases => ["--org", "-o"],
|
10
|
+
:from_given => by_name("organization"),
|
11
|
+
:default => proc { client.current_organization },
|
12
|
+
:desc => "Organization to add the domain to"
|
13
|
+
input :shared, :type => :boolean, :default => false,
|
14
|
+
:desc => "Create a shared domain (admin-only)"
|
15
|
+
|
16
|
+
def create_domain
|
17
|
+
org = input[:organization]
|
18
|
+
name = input[:name].sub(/^\*\./, "")
|
19
|
+
|
20
|
+
domain = client.domain
|
21
|
+
domain.name = name
|
22
|
+
domain.owning_organization = org unless input[:shared]
|
23
|
+
|
24
|
+
with_progress("Creating domain #{c(name, :name)}") do
|
25
|
+
domain.create!
|
26
|
+
end
|
27
|
+
|
28
|
+
domain
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "vmc/cli/domain/base"
|
2
|
+
|
3
|
+
module VMC::Domain
|
4
|
+
class DeleteDomain < Base
|
5
|
+
desc "Delete a domain"
|
6
|
+
group :domains
|
7
|
+
input(:domain, :argument => :optional,
|
8
|
+
:from_given => find_by_name("domain"),
|
9
|
+
:desc => "URL to map to the application") { |domains|
|
10
|
+
fail "No domains." if domains.empty?
|
11
|
+
|
12
|
+
ask "Which domain?", :choices => domains.sort_by(&:name),
|
13
|
+
:display => proc(&:name)
|
14
|
+
}
|
15
|
+
input :organization, :aliases => ["--org", "-o"],
|
16
|
+
:from_given => by_name("organization"),
|
17
|
+
:desc => "Organization to delete the domain from"
|
18
|
+
input(:really, :type => :boolean, :forget => true,
|
19
|
+
:default => proc { force? || interact }) { |name, color|
|
20
|
+
ask("Really delete #{c(name, color)}?", :default => false)
|
21
|
+
}
|
22
|
+
input :all, :type => :boolean, :default => false,
|
23
|
+
:desc => "Delete all domains"
|
24
|
+
|
25
|
+
def delete_domain
|
26
|
+
target = input[:organization] || client
|
27
|
+
|
28
|
+
if input[:all]
|
29
|
+
return unless input[:really, "ALL DOMAINS", :bad]
|
30
|
+
|
31
|
+
target.domains.each do |r|
|
32
|
+
begin
|
33
|
+
invoke :delete_domain, :domain => r, :really => true
|
34
|
+
rescue CFoundry::APIError => e
|
35
|
+
err "#{e.class}: #{e.message}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
return
|
40
|
+
end
|
41
|
+
|
42
|
+
domain = input[:domain, target.domains]
|
43
|
+
|
44
|
+
return unless input[:really, domain.name, :name]
|
45
|
+
|
46
|
+
with_progress("Deleting domain #{c(domain.name, :name)}") do
|
47
|
+
domain.delete!
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require "vmc/cli/domain/base"
|
2
|
+
|
3
|
+
module VMC::Domain
|
4
|
+
class Domains < Base
|
5
|
+
desc "List domains in a space"
|
6
|
+
group :domains
|
7
|
+
input :space, :argument => :optional,
|
8
|
+
:default => proc { client.current_space },
|
9
|
+
:from_given => by_name("space"),
|
10
|
+
:desc => "Space to list the domains from"
|
11
|
+
input :all, :type => :boolean, :default => false,
|
12
|
+
:desc => "List all domains"
|
13
|
+
|
14
|
+
def domains
|
15
|
+
space = input[:space]
|
16
|
+
|
17
|
+
domains =
|
18
|
+
if input[:all]
|
19
|
+
with_progress("Getting all domains") do
|
20
|
+
client.domains
|
21
|
+
end
|
22
|
+
else
|
23
|
+
with_progress("Getting domains in #{c(space.name, :name)}") do
|
24
|
+
space.domains
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
line unless quiet?
|
29
|
+
|
30
|
+
table(
|
31
|
+
%w{name owner},
|
32
|
+
domains.sort_by(&:name).collect { |r|
|
33
|
+
[c(r.name, :name),
|
34
|
+
if org = r.owning_organization
|
35
|
+
c(org.name, :name)
|
36
|
+
else
|
37
|
+
d("none")
|
38
|
+
end
|
39
|
+
]
|
40
|
+
})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "vmc/cli/domain/base"
|
2
|
+
|
3
|
+
module VMC::Domain
|
4
|
+
class RemoveDomain < Base
|
5
|
+
desc "Remove a domain from a space"
|
6
|
+
group :domains
|
7
|
+
input(:domain, :argument => :optional,
|
8
|
+
:from_given => by_name("domain"),
|
9
|
+
:desc => "Domain to add") { |space|
|
10
|
+
ask "Which domain?", :choices => space.domains,
|
11
|
+
:display => proc(&:name)
|
12
|
+
}
|
13
|
+
input :space, :from_given => by_name("space"),
|
14
|
+
:default => proc { client.current_space },
|
15
|
+
:desc => "Space to add the domain to"
|
16
|
+
|
17
|
+
def remove_domain
|
18
|
+
space = input[:space]
|
19
|
+
domain = input[:domain, space]
|
20
|
+
|
21
|
+
with_progress("Removing #{c(domain.name, :name)} from #{c(space.name, :name)}") do
|
22
|
+
space.remove_domain(domain)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/vmc-ng/lib/vmc/cli/help.rb
CHANGED
@@ -1,8 +1,12 @@
|
|
1
1
|
require "interact"
|
2
|
+
require "interact/pretty"
|
3
|
+
require "interact/progress"
|
2
4
|
|
3
5
|
module VMC
|
4
6
|
module Interactive
|
5
7
|
include ::Interactive::Rewindable
|
8
|
+
include Interact::Pretty
|
9
|
+
include Interact::Progress
|
6
10
|
|
7
11
|
def ask(question, options = {})
|
8
12
|
if force? and options.key?(:default)
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "vmc/cli/route/base"
|
2
|
+
|
3
|
+
module VMC::Route
|
4
|
+
class CreateRoute < Base
|
5
|
+
desc "Create a route"
|
6
|
+
group :routes
|
7
|
+
input :url, :argument => :optional,
|
8
|
+
:desc => "Full route in URL form"
|
9
|
+
input(:host, :desc => "Host name") {
|
10
|
+
ask "Host name?"
|
11
|
+
}
|
12
|
+
input(:domain, :desc => "Domain to add the route to",
|
13
|
+
:from_given => find_by_name("domain")) { |domains|
|
14
|
+
ask "Which domain?", :choices => domains,
|
15
|
+
:display => proc(&:name)
|
16
|
+
}
|
17
|
+
|
18
|
+
def create_route
|
19
|
+
if url = input[:url]
|
20
|
+
host, domain_name = url.split(".", 2)
|
21
|
+
return invoke :create_route, {}, :host => host, :domain => domain_name
|
22
|
+
end
|
23
|
+
|
24
|
+
domain = input[:domain, client.current_organization.domains]
|
25
|
+
host = input[:host]
|
26
|
+
|
27
|
+
route = client.route
|
28
|
+
route.host = host
|
29
|
+
route.domain = domain
|
30
|
+
route.space = client.current_space
|
31
|
+
|
32
|
+
with_progress("Creating route #{c("#{host}.#{domain.name}", :name)}") do
|
33
|
+
route.create!
|
34
|
+
end
|
35
|
+
rescue CFoundry::RouteHostTaken => e
|
36
|
+
line c(e.description, :error)
|
37
|
+
line
|
38
|
+
input.forget(:host)
|
39
|
+
retry
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require "vmc/cli/route/base"
|
2
|
+
|
3
|
+
module VMC::Route
|
4
|
+
class DeleteRoute < Base
|
5
|
+
desc "Delete a route"
|
6
|
+
group :routes
|
7
|
+
input(:route, :argument => :optional,
|
8
|
+
:from_given => find_by_name("route"),
|
9
|
+
:desc => "Route to delete") { |routes|
|
10
|
+
ask "Which route?", :choices => routes.sort_by(&:name),
|
11
|
+
:display => proc(&:name)
|
12
|
+
}
|
13
|
+
input(:really, :type => :boolean, :forget => true, :hidden => true,
|
14
|
+
:default => proc { force? || interact }) { |name, color|
|
15
|
+
ask("Really delete #{c(name, color)}?", :default => false)
|
16
|
+
}
|
17
|
+
input :all, :type => :boolean, :default => false,
|
18
|
+
:desc => "Delete all routes"
|
19
|
+
def delete_route
|
20
|
+
if input[:all]
|
21
|
+
return unless input[:really, "ALL ROUTES", :bad]
|
22
|
+
|
23
|
+
client.routes.each do |r|
|
24
|
+
invoke :delete_route, :route => r, :really => true
|
25
|
+
end
|
26
|
+
|
27
|
+
return
|
28
|
+
end
|
29
|
+
|
30
|
+
routes = client.routes
|
31
|
+
fail "No routes." if routes.empty?
|
32
|
+
|
33
|
+
route = input[:route, client.routes]
|
34
|
+
|
35
|
+
return unless input[:really, route.name, :name]
|
36
|
+
|
37
|
+
with_progress("Deleting route #{c(route.name, :name)}") do
|
38
|
+
route.delete!
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "vmc/cli/route/base"
|
2
|
+
|
3
|
+
module VMC::Route
|
4
|
+
class Routes < Base
|
5
|
+
desc "List routes in a space"
|
6
|
+
group :routes
|
7
|
+
|
8
|
+
def routes
|
9
|
+
# TODO: scope to space once space.routes is possible
|
10
|
+
routes =
|
11
|
+
with_progress("Getting routes") do
|
12
|
+
client.routes
|
13
|
+
end
|
14
|
+
|
15
|
+
line unless quiet?
|
16
|
+
|
17
|
+
table(
|
18
|
+
%w{host domain},
|
19
|
+
routes.sort_by { |r| "#{r.domain.name} #{r.host}" }.collect { |r|
|
20
|
+
[c(r.host, :name),
|
21
|
+
r.domain.name
|
22
|
+
]
|
23
|
+
})
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/vmc-ng/lib/vmc/detect.rb
CHANGED
@@ -87,11 +87,11 @@ module VMC
|
|
87
87
|
@detector_frameworks = {}
|
88
88
|
|
89
89
|
Clouseau.detectors.each do |d|
|
90
|
-
name = d.framework_name
|
90
|
+
name = d.framework_name
|
91
91
|
lang = d.language_name
|
92
92
|
|
93
93
|
framework = all_frameworks.find { |f|
|
94
|
-
f.name == name ||
|
94
|
+
f.name == name.to_s ||
|
95
95
|
f.name == FRAMEWORK_NAMES[name]
|
96
96
|
}
|
97
97
|
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.expand_path("../../../spec/spec_helper", __FILE__)
|
data/vmc-ng/lib/vmc/version.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "vmc/cli/app/push"
|
3
|
+
|
4
|
+
describe VMC::App::Push do
|
5
|
+
let(:global_inputs) { { :color => false, :quiet => true } }
|
6
|
+
let(:inputs) { {} }
|
7
|
+
let(:given) { {} }
|
8
|
+
let(:client) { FactoryGirl.build(:client) }
|
9
|
+
|
10
|
+
before do
|
11
|
+
any_instance_of(VMC::CLI) do |cli|
|
12
|
+
stub(cli).client { client }
|
13
|
+
stub(cli).precondition { nil }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'CLI' do
|
18
|
+
subject { Mothership.new.invoke(:push, inputs, given, global_inputs) }
|
19
|
+
|
20
|
+
context 'when creating a new app' do
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when syncing an existing app' do
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#create_app' do
|
28
|
+
xit 'should detect the correct framework'
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#sync_app' do
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require "vmc/cli/app/rename"
|
3
|
+
|
4
|
+
describe VMC::App::Rename do
|
5
|
+
let(:global_inputs) { { :color => false, :quiet => true } }
|
6
|
+
let(:inputs) { {} }
|
7
|
+
let(:given) { {} }
|
8
|
+
let(:client) { FactoryGirl.build(:client) }
|
9
|
+
let(:app) {}
|
10
|
+
let(:new_name) { "some-new-name" }
|
11
|
+
|
12
|
+
before do
|
13
|
+
any_instance_of(VMC::CLI) do |cli|
|
14
|
+
stub(cli).client { client }
|
15
|
+
stub(cli).precondition { nil }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
subject { Mothership.new.invoke(:rename, inputs, given, global_inputs) }
|
20
|
+
|
21
|
+
describe 'metadata' do
|
22
|
+
let(:command) { Mothership.commands[:rename] }
|
23
|
+
|
24
|
+
describe 'command' do
|
25
|
+
subject { command }
|
26
|
+
its(:description) { should eq "Rename an application" }
|
27
|
+
it { expect(Mothership::Help.group(:apps, :manage)).to include(subject) }
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'inputs' do
|
31
|
+
subject { command.inputs }
|
32
|
+
it { expect(subject[:app][:description]).to eq "Application to rename" }
|
33
|
+
it { expect(subject[:name][:description]).to eq "New application name" }
|
34
|
+
end
|
35
|
+
|
36
|
+
describe 'arguments' do
|
37
|
+
subject { command.arguments }
|
38
|
+
it 'has the correct argument order' do
|
39
|
+
should eq([
|
40
|
+
{ :type => :optional, :value => nil, :name => :app },
|
41
|
+
{ :type => :optional, :value => nil, :name => :name }
|
42
|
+
])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when there are no apps' do
|
48
|
+
context 'and an app is given' do
|
49
|
+
let(:given) { { :app => "some-app" } }
|
50
|
+
it { expect { subject }.to raise_error(VMC::UserError, "Unknown app 'some-app'.") }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'and an app is not given' do
|
54
|
+
it { expect { subject }.to raise_error(VMC::UserError, "No applications.") }
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
context 'when there are apps' do
|
59
|
+
let(:client) { FactoryGirl.build(:client, :apps => apps) }
|
60
|
+
let(:apps) { FactoryGirl.build_list(:app, 2) }
|
61
|
+
let(:renamed_app) { apps.first }
|
62
|
+
|
63
|
+
context 'when the defaults are used' do
|
64
|
+
it 'asks for the app and new name and renames' do
|
65
|
+
mock_ask("Rename which application?", anything) { renamed_app }
|
66
|
+
mock_ask("New name") { new_name }
|
67
|
+
mock(renamed_app).name=(new_name)
|
68
|
+
mock(renamed_app).update!
|
69
|
+
subject
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when no name is provided, but a app is' do
|
74
|
+
let(:given) { { :app => renamed_app.name } }
|
75
|
+
|
76
|
+
it 'asks for the new name and renames' do
|
77
|
+
dont_allow_ask("Rename which application?", anything)
|
78
|
+
mock_ask("New name") { new_name }
|
79
|
+
mock(renamed_app).name=(new_name)
|
80
|
+
mock(renamed_app).update!
|
81
|
+
subject
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when an app is provided and a name' do
|
86
|
+
let(:inputs) { { :app => renamed_app, :name => new_name } }
|
87
|
+
|
88
|
+
it 'renames the app' do
|
89
|
+
mock(renamed_app).update!
|
90
|
+
subject
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'displays the progress' do
|
94
|
+
mock_with_progress("Renaming to #{new_name}")
|
95
|
+
mock(renamed_app).update!
|
96
|
+
|
97
|
+
subject
|
98
|
+
end
|
99
|
+
|
100
|
+
context 'and the name already exists' do
|
101
|
+
it 'fails' do
|
102
|
+
mock(renamed_app).update! { raise CFoundry::AppNameTaken }
|
103
|
+
expect { subject }.to raise_error(CFoundry::AppNameTaken)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|