vmc 0.4.0.beta.93 → 0.4.0.beta.94
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/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
|