vmc 0.5.0.beta.7 → 0.5.0.beta.10

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.
Files changed (59) hide show
  1. data/LICENSE +1277 -746
  2. data/Rakefile +22 -23
  3. data/lib/vmc/cli.rb +21 -27
  4. data/lib/vmc/cli/app/push.rb +1 -0
  5. data/lib/vmc/cli/app/push/create.rb +3 -2
  6. data/lib/vmc/cli/app/push/sync.rb +11 -8
  7. data/lib/vmc/cli/app/scale.rb +19 -17
  8. data/lib/vmc/cli/domain/map.rb +55 -0
  9. data/lib/vmc/cli/domain/unmap.rb +56 -0
  10. data/lib/vmc/cli/route/map.rb +74 -0
  11. data/lib/vmc/cli/route/unmap.rb +94 -0
  12. data/lib/vmc/cli/service/create.rb +4 -1
  13. data/lib/vmc/cli/start/base.rb +2 -2
  14. data/lib/vmc/cli/start/login.rb +5 -2
  15. data/lib/vmc/cli/start/target.rb +4 -3
  16. data/lib/vmc/cli/user/base.rb +19 -0
  17. data/lib/vmc/cli/user/passwd.rb +7 -19
  18. data/lib/vmc/cli/{start → user}/register.rb +12 -23
  19. data/lib/vmc/constants.rb +1 -1
  20. data/lib/vmc/test_support.rb +4 -0
  21. data/lib/vmc/test_support/command_helper.rb +38 -0
  22. data/{spec/support → lib/vmc/test_support}/common_input_examples.rb +0 -0
  23. data/lib/vmc/test_support/fake_home_dir.rb +16 -0
  24. data/lib/vmc/test_support/interact_helper.rb +29 -0
  25. data/lib/vmc/version.rb +1 -1
  26. data/spec/features/new_user_flow_spec.rb +43 -51
  27. data/spec/spec_helper.rb +24 -12
  28. data/spec/vmc/cli/app/instances_spec.rb +3 -8
  29. data/spec/vmc/cli/app/push/create_spec.rb +10 -7
  30. data/spec/vmc/cli/app/push_spec.rb +1 -1
  31. data/spec/vmc/cli/app/rename_spec.rb +1 -1
  32. data/spec/vmc/cli/app/scale_spec.rb +81 -0
  33. data/spec/vmc/cli/app/stats_spec.rb +3 -7
  34. data/spec/vmc/cli/domain/map_spec.rb +140 -0
  35. data/spec/vmc/cli/domain/unmap_spec.rb +73 -0
  36. data/spec/vmc/cli/organization/orgs_spec.rb +13 -16
  37. data/spec/vmc/cli/organization/rename_spec.rb +1 -1
  38. data/spec/vmc/cli/route/map_spec.rb +142 -0
  39. data/spec/vmc/cli/route/unmap_spec.rb +215 -0
  40. data/spec/vmc/cli/service/rename_spec.rb +1 -1
  41. data/spec/vmc/cli/space/rename_spec.rb +15 -18
  42. data/spec/vmc/cli/space/spaces_spec.rb +18 -25
  43. data/spec/vmc/cli/start/info_spec.rb +44 -46
  44. data/spec/vmc/cli/start/login_spec.rb +40 -0
  45. data/spec/vmc/cli/user/create_spec.rb +54 -0
  46. data/spec/vmc/cli/user/passwd_spec.rb +7 -14
  47. data/spec/vmc/cli/{start → user}/register_spec.rb +26 -22
  48. data/spec/vmc/cli_spec.rb +164 -6
  49. metadata +46 -39
  50. data/lib/vmc/cli/app/routes.rb +0 -100
  51. data/lib/vmc/cli/domain/add_domain.rb +0 -25
  52. data/lib/vmc/cli/domain/create_domain.rb +0 -28
  53. data/lib/vmc/cli/domain/delete_domain.rb +0 -56
  54. data/lib/vmc/cli/domain/remove_domain.rb +0 -28
  55. data/lib/vmc/cli/route/create_route.rb +0 -49
  56. data/lib/vmc/cli/route/delete.rb +0 -47
  57. data/spec/support/feature_helpers.rb +0 -16
  58. data/spec/support/interact_helpers.rb +0 -27
  59. data/spec/vmc/cli/route/delete_route_spec.rb +0 -162
@@ -1,25 +0,0 @@
1
- require "vmc/cli/domain/base"
2
-
3
- module VMC::Domain
4
- class AddDomain < Base
5
- desc "Add a domain to a space"
6
- group :domains
7
- input :name, :desc => "Domain to add", :argument => :required
8
- input :space, :desc => "Space to add the domain to",
9
- :default => proc { client.current_space },
10
- :from_given => by_name(:space)
11
- def add_domain
12
- space = input[:space]
13
- name = input[:name].sub(/^\*\./, "")
14
-
15
- org = space.organization
16
-
17
- domain = org.domains.find { |d| d.name == name } ||
18
- invoke(:create_domain, :org => org, :name => name)
19
-
20
- with_progress("Adding #{c(domain.name, :name)} to #{c(space.name, :name)}") do
21
- space.add_domain(domain)
22
- end
23
- end
24
- end
25
- end
@@ -1,28 +0,0 @@
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, :desc => "Domain name to create", :argument => :required
8
- input :organization, :desc => "Organization to add the domain to",
9
- :aliases => %w{--org -o},
10
- :default => proc { client.current_organization },
11
- :from_given => by_name(:organization)
12
- input :shared, :desc => "Create a shared domain", :default => false
13
- def create_domain
14
- org = input[:organization]
15
- name = input[:name].sub(/^\*\./, "")
16
-
17
- domain = client.domain
18
- domain.name = name
19
- domain.owning_organization = org unless input[:shared]
20
-
21
- with_progress("Creating domain #{c(name, :name)}") do
22
- domain.create!
23
- end
24
-
25
- domain
26
- end
27
- end
28
- end
@@ -1,56 +0,0 @@
1
- require "vmc/cli/domain/base"
2
-
3
- module VMC::Domain
4
- class DeleteDomain < Base
5
- # TODO: refactor; using find_by_name, and target cycling between
6
- # org/client, is awkward
7
-
8
- desc "Delete a domain"
9
- group :domains
10
- input :domain, :desc => "URL to map to the application",
11
- :argument => :optional, :from_given => find_by_name("domain")
12
- input :organization, :desc => "Organization to delete the domain from",
13
- :aliases => %w{--org -o}, :from_given => by_name(:organization)
14
- input :all, :desc => "Delete all domains", :default => false
15
- input :really, :type => :boolean, :forget => true, :hidden => true,
16
- :default => proc { force? || interact }
17
- def delete_domain
18
- target = input[:organization] || client
19
-
20
- if input[:all]
21
- return unless input[:really, "ALL DOMAINS", :bad]
22
-
23
- target.domains.each do |r|
24
- begin
25
- invoke :delete_domain, :domain => r, :really => true
26
- rescue CFoundry::APIError => e
27
- err "#{e.class}: #{e.message}"
28
- end
29
- end
30
-
31
- return
32
- end
33
-
34
- domain = input[:domain, target.domains]
35
-
36
- return unless input[:really, domain.name, :name]
37
-
38
- with_progress("Deleting domain #{c(domain.name, :name)}") do
39
- domain.delete!
40
- end
41
- end
42
-
43
- private
44
-
45
- def ask_domain(domains)
46
- fail "No domains." if domains.empty?
47
-
48
- ask "Which domain?", :choices => domains.sort_by(&:name),
49
- :display => proc(&:name)
50
- end
51
-
52
- def ask_really(name, color)
53
- ask("Really delete #{c(name, color)}?", :default => false)
54
- end
55
- end
56
- end
@@ -1,28 +0,0 @@
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, :desc => "Domain to add", :argument => :optional,
8
- :from_given => by_name(:domain)
9
- input :space, :desc => "Space to add the domain to",
10
- :from_given => by_name(:space),
11
- :default => proc { client.current_space }
12
- def remove_domain
13
- space = input[:space]
14
- domain = input[:domain, space]
15
-
16
- with_progress("Removing #{c(domain.name, :name)} from #{c(space.name, :name)}") do
17
- space.remove_domain(domain)
18
- end
19
- end
20
-
21
- private
22
-
23
- def ask_domain(space)
24
- ask "Which domain?", :choices => space.domains,
25
- :display => proc(&:name)
26
- end
27
- end
28
- end
@@ -1,49 +0,0 @@
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, :desc => "Full route in URL form", :argument => :optional
8
- input :host, :desc => "Host name"
9
- input :domain, :desc => "Domain to add the route to",
10
- :from_given => by_name(:domain)
11
- def create_route
12
- if url = input[:url]
13
- host, domain_name = url.split(".", 2)
14
- return invoke :create_route, {}, :host => host, :domain => domain_name
15
- end
16
-
17
- domain = input[:domain]
18
- host = input[:host]
19
-
20
- route = client.route
21
- route.host = host
22
- route.domain = domain
23
- route.space = client.current_space
24
-
25
- with_progress("Creating route #{c("#{host}.#{domain.name}", :name)}") do
26
- route.create!
27
- end
28
- rescue CFoundry::RouteHostTaken => e
29
- line c(e.description, :error)
30
- line
31
- input.forget(:host)
32
- retry
33
- end
34
-
35
- private
36
-
37
- def ask_host
38
- ask("Host name?")
39
- end
40
-
41
- def ask_domain
42
- domains = client.current_organization.domains
43
- fail "No domains!" if domains.empty?
44
-
45
- ask "Which domain?", :choices => domains,
46
- :display => proc(&:name)
47
- end
48
- end
49
- end
@@ -1,47 +0,0 @@
1
- require "vmc/cli/route/base"
2
-
3
- module VMC::Route
4
- class Delete < Base
5
- desc "Delete a route"
6
- group :routes
7
- input :route, :desc => "Route to delete", :argument => :optional,
8
- :from_given => find_by_name("route") { client.routes },
9
- :default => proc { force? || interact }
10
- input :all, :desc => "Delete all routes", :default => false
11
- input :really, :type => :boolean, :forget => true, :hidden => true,
12
- :default => proc { force? || interact }
13
- def delete_route
14
- if input[:all]
15
- return unless input[:really, "ALL ROUTES", :bad]
16
-
17
- client.routes.each do |r|
18
- invoke :delete_route, :route => r, :really => true
19
- end
20
-
21
- return
22
- end
23
-
24
- route = input[:route]
25
-
26
- return unless input[:really, route.name, :name]
27
-
28
- with_progress("Deleting route #{c(route.name, :name)}") do
29
- route.delete!
30
- end
31
- end
32
-
33
- private
34
-
35
- def ask_route
36
- routes = client.routes
37
- fail "No routes." if routes.empty?
38
-
39
- ask "Which route?", :choices => routes.sort_by(&:name),
40
- :display => proc(&:name)
41
- end
42
-
43
- def ask_really(name, color)
44
- ask("Really delete #{c(name, color)}?", :default => false)
45
- end
46
- end
47
- end
@@ -1,16 +0,0 @@
1
- def vmc_ok(argv)
2
- with_output_to do |out|
3
- Mothership.new.exit_status 0
4
- code = VMC::CLI.start(argv + ["--no-script"])
5
- yield out.string.strip_progress_dots if block_given?
6
- expect(code).to eq 0
7
- end
8
- end
9
-
10
- def vmc_fail(argv)
11
- with_output_to do |out|
12
- code = VMC::CLI.start(argv + ["--no-script"])
13
- yield out.string.strip_progress_dots if block_given?
14
- expect(code).to eq 1
15
- end
16
- end
@@ -1,27 +0,0 @@
1
- def stub_ask(*args, &block)
2
- a_stub = nil
3
- any_instance_of VMC::CLI do |interactive|
4
- a_stub = stub(interactive).ask(*args, &block)
5
- end
6
- a_stub
7
- end
8
-
9
- def mock_ask(*args, &block)
10
- a_mock = nil
11
- any_instance_of VMC::CLI do |interactive|
12
- a_mock = mock(interactive).ask(*args, &block)
13
- end
14
- a_mock
15
- end
16
-
17
- def dont_allow_ask(*args)
18
- any_instance_of VMC::CLI do |interactive|
19
- dont_allow(interactive).ask(*args)
20
- end
21
- end
22
-
23
- def mock_with_progress(message)
24
- any_instance_of VMC::CLI do |interactive|
25
- mock(interactive).with_progress(message) { |_, block| block.call }
26
- end
27
- end
@@ -1,162 +0,0 @@
1
- require 'spec_helper'
2
- require "vmc/cli/route/delete"
3
-
4
- describe VMC::Route::Delete do
5
- let(:global) { { :color => false, :quiet => true } }
6
- let(:inputs) { {} }
7
- let(:given) { {} }
8
- let(:client) { fake_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
- subject { Mothership.new.invoke(:delete_route, inputs, given, global) }
18
-
19
- describe 'metadata' do
20
- let(:command) { Mothership.commands[:delete_route] }
21
-
22
- describe 'command' do
23
- subject { command }
24
- its(:description) { should eq "Delete a route" }
25
- it { expect(Mothership::Help.group(:routes)).to include(subject) }
26
- end
27
-
28
- include_examples 'inputs must have descriptions'
29
-
30
- describe 'inputs' do
31
- subject { command.inputs }
32
- it { expect(subject[:route][:description]).to eq "Route to delete" }
33
- it { expect(subject[:really][:hidden]).to be_true }
34
- it { expect(subject[:all][:description]).to eq "Delete all routes" }
35
- end
36
-
37
- describe 'arguments' do
38
- subject { command.arguments }
39
- it 'has the correct argument order' do
40
- should eq([
41
- { :type => :optional, :value => nil, :name => :route }
42
- ])
43
- end
44
- end
45
- end
46
-
47
- context 'when there are no routes' do
48
- context 'and a name is given' do
49
- let(:given) { { :route => "some-route" } }
50
- it { expect { subject }.to raise_error(VMC::UserError, "Unknown route 'some-route'.") }
51
- end
52
-
53
- context 'and a name is not given' do
54
- it { expect { subject }.to raise_error(VMC::UserError, "No routes.") }
55
- end
56
- end
57
-
58
- context "when there are routes" do
59
- let(:client) { fake_client(:routes => routes) }
60
- let(:routes) { fake_list(:route, 2) }
61
- let(:deleted_route) { routes.first }
62
-
63
- context 'when the defaults are used' do
64
- it 'asks for the route and confirmation' do
65
- mock_ask('Which route?', anything) { deleted_route }
66
- mock_ask("Really delete #{deleted_route.name}?", :default => false) { true }
67
- stub(deleted_route).delete!
68
- subject
69
- end
70
-
71
- it 'does not try to delete all routes' do
72
- stub_ask("Which route?", anything) { deleted_route }
73
- stub_ask(/Really delete/, anything) { true }
74
- mock(deleted_route).delete!
75
- dont_allow(routes.last).delete!
76
- subject
77
- end
78
- end
79
-
80
- context 'when the route is inputted' do
81
- let(:inputs) { { :route => deleted_route } }
82
-
83
- it 'does not ask which route but still asks for confirmation' do
84
- dont_allow_ask('Which route?', anything)
85
- mock_ask("Really delete #{deleted_route.name}?", :default => false) { true }
86
- stub(deleted_route).delete!
87
- subject
88
- end
89
-
90
- it 'deletes the route' do
91
- dont_allow_ask("Which route?", anything)
92
- stub_ask(/Really delete/, anything) { true }
93
- mock(deleted_route).delete!
94
- subject
95
- end
96
- end
97
-
98
- context 'when the all flag is provided' do
99
- let(:inputs) { { :all => true } }
100
-
101
- it 'deletes the route' do
102
- stub_ask { true }
103
- routes.each do |route|
104
- mock(route).delete!
105
- end
106
- subject
107
- end
108
-
109
- it 'asks to delete the routes' do
110
- mock_ask("Really delete ALL ROUTES?", :default => false) { true }
111
- dont_allow_ask('Which route?', anything)
112
- routes.each do |route|
113
- stub(route).delete!
114
- end
115
- subject
116
- end
117
-
118
- context 'and also with the really flag' do
119
- let(:inputs) { { :all => true, :really => true } }
120
-
121
- it 'does not ask' do
122
- dont_allow_ask("Really delete ALL ROUTES?", :default => false)
123
- routes.each do |route|
124
- stub(route).delete!
125
- end
126
- subject
127
- end
128
- end
129
- end
130
-
131
- context 'when the really flag is provided' do
132
- context 'when no route given' do
133
- let(:inputs) { { :really => true } }
134
-
135
- it 'asks for the route, and does not confirm deletion' do
136
- dont_allow_ask("Really delete ALL ROUTES?", :default => false)
137
- mock_ask('Which route?', anything) { deleted_route }
138
- mock(deleted_route).delete!
139
- subject
140
- end
141
- end
142
-
143
- context 'when a route is given' do
144
- let(:inputs) { { :route => deleted_route, :really => true } }
145
-
146
- it 'asks for the route, and does not confirm deletion' do
147
- dont_allow_ask("Really delete ALL ROUTES?", :default => false)
148
- dont_allow_ask('Which route?', anything)
149
- mock(deleted_route).delete!
150
- subject
151
- end
152
-
153
- it 'displays the progress' do
154
- mock_with_progress("Deleting route #{deleted_route.name}")
155
- mock(deleted_route).delete!
156
-
157
- subject
158
- end
159
- end
160
- end
161
- end
162
- end