vmc 0.4.2 → 0.4.3

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 (63) hide show
  1. data/lib/vmc.rb +2 -5
  2. data/lib/vmc/cli/app/apps.rb +4 -1
  3. data/lib/vmc/cli/app/push.rb +38 -221
  4. data/lib/vmc/cli/app/push/create.rb +125 -0
  5. data/lib/vmc/cli/app/push/interaction.rb +64 -0
  6. data/lib/vmc/cli/app/push/sync.rb +59 -0
  7. data/lib/vmc/cli/app/rename.rb +1 -1
  8. data/lib/vmc/cli/organization/base.rb +14 -0
  9. data/lib/vmc/cli/organization/create_org.rb +28 -0
  10. data/lib/vmc/cli/organization/delete_org.rb +65 -0
  11. data/lib/vmc/cli/organization/org.rb +46 -0
  12. data/lib/vmc/cli/organization/orgs.rb +35 -0
  13. data/lib/vmc/cli/organization/rename.rb +32 -0
  14. data/lib/vmc/cli/service/base.rb +8 -0
  15. data/lib/vmc/cli/service/binding.rb +66 -0
  16. data/lib/vmc/cli/service/create.rb +104 -0
  17. data/lib/vmc/cli/service/delete.rb +84 -0
  18. data/lib/vmc/cli/service/rename.rb +32 -0
  19. data/lib/vmc/cli/service/service.rb +45 -0
  20. data/lib/vmc/cli/service/services.rb +118 -0
  21. data/lib/vmc/cli/space/base.rb +21 -0
  22. data/lib/vmc/cli/space/create.rb +57 -0
  23. data/lib/vmc/cli/space/delete.rb +92 -0
  24. data/lib/vmc/cli/space/rename.rb +36 -0
  25. data/lib/vmc/cli/space/space.rb +67 -0
  26. data/lib/vmc/cli/space/spaces.rb +57 -0
  27. data/lib/vmc/cli/space/take.rb +18 -0
  28. data/lib/vmc/cli/start/base.rb +100 -0
  29. data/lib/vmc/cli/start/colors.rb +14 -0
  30. data/lib/vmc/cli/start/info.rb +124 -0
  31. data/lib/vmc/cli/start/login.rb +94 -0
  32. data/lib/vmc/cli/start/logout.rb +14 -0
  33. data/lib/vmc/cli/start/register.rb +38 -0
  34. data/lib/vmc/cli/start/target.rb +68 -0
  35. data/lib/vmc/cli/start/targets.rb +17 -0
  36. data/lib/vmc/version.rb +1 -1
  37. data/spec/factories/app_factory.rb +5 -0
  38. data/spec/factories/client_factory.rb +10 -1
  39. data/spec/factories/domain_factory.rb +2 -1
  40. data/spec/factories/factory.rb +1 -0
  41. data/spec/factories/framework_factory.rb +1 -0
  42. data/spec/factories/organization_factory.rb +18 -0
  43. data/spec/factories/route_factory.rb +1 -0
  44. data/spec/factories/runtime_factory.rb +10 -0
  45. data/spec/factories/service_binding_factory.rb +9 -0
  46. data/spec/factories/service_factory.rb +17 -0
  47. data/spec/factories/service_instance_factory.rb +10 -0
  48. data/spec/factories/service_plan_factory.rb +11 -0
  49. data/spec/factories/space_factory.rb +10 -0
  50. data/spec/support/interact_helpers.rb +7 -3
  51. data/spec/vmc/cli/app/push/create_spec.rb +450 -0
  52. data/spec/vmc/cli/app/push_spec.rb +303 -9
  53. data/spec/vmc/cli/app/rename_spec.rb +9 -4
  54. data/spec/vmc/cli/organization/rename_spec.rb +113 -0
  55. data/spec/vmc/cli/route/delete_route_spec.rb +2 -2
  56. data/spec/vmc/cli/service/rename_spec.rb +114 -0
  57. data/spec/vmc/cli/space/rename_spec.rb +114 -0
  58. metadata +109 -64
  59. data/lib/vmc/cli/organization.rb +0 -176
  60. data/lib/vmc/cli/service.rb +0 -387
  61. data/lib/vmc/cli/space.rb +0 -284
  62. data/lib/vmc/cli/start.rb +0 -432
  63. data/spec/assets/hello-sinatra/Gemfile.lock +0 -17
data/lib/vmc/cli/space.rb DELETED
@@ -1,284 +0,0 @@
1
- require "vmc/cli"
2
-
3
- module VMC
4
- class Space < CLI
5
- def precondition
6
- check_target
7
- check_logged_in
8
-
9
- fail "This command is v2-only." unless v2?
10
- end
11
-
12
- def self.by_name(what, obj = what)
13
- proc { |name, *_|
14
- client.send(:"#{obj}_by_name", name) ||
15
- fail("Unknown #{what} '#{name}'")
16
- }
17
- end
18
-
19
- def self.space_by_name
20
- proc { |name, org, *_|
21
- org.space_by_name(name) ||
22
- fail("Unknown space '#{name}'")
23
- }
24
- end
25
-
26
- desc "Show space information"
27
- group :spaces
28
- input :organization, :aliases => ["--org", "-o"],
29
- :from_given => by_name("organization"),
30
- :default => proc { client.current_organization },
31
- :desc => "Space's organization"
32
- input :space, :argument => :optional,
33
- :from_given => space_by_name,
34
- :default => proc { client.current_space },
35
- :desc => "Space to show"
36
- input :full, :type => :boolean,
37
- :desc => "Show full information for apps, service instances, etc."
38
- def space
39
- org = input[:organization]
40
- space = input[:space, org]
41
-
42
- unless space
43
- return if quiet?
44
- fail "No current space."
45
- end
46
-
47
- if quiet?
48
- puts space.name
49
- return
50
- end
51
-
52
- line "#{c(space.name, :name)}:"
53
-
54
- indented do
55
- line "organization: #{c(space.organization.name, :name)}"
56
-
57
- if input[:full]
58
- line
59
- line "apps:"
60
-
61
- spaced(space.apps(:depth => 2)) do |a|
62
- indented do
63
- invoke :app, :app => a
64
- end
65
- end
66
- else
67
- line "apps: #{name_list(space.apps)}"
68
- end
69
-
70
- if input[:full]
71
- line
72
- line "services:"
73
- spaced(space.service_instances(:depth => 2)) do |i|
74
- indented do
75
- invoke :service, :instance => i
76
- end
77
- end
78
- else
79
- line "services: #{name_list(space.service_instances)}"
80
- end
81
-
82
- line "domains: #{name_list(space.domains)}"
83
- end
84
- end
85
-
86
-
87
- desc "List spaces in an organization"
88
- group :spaces
89
- input :organization, :argument => :optional, :aliases => ["--org", "-o"],
90
- :from_given => by_name("organization"),
91
- :default => proc { client.current_organization },
92
- :desc => "Organization to list spaces from"
93
- input :name, :desc => "Filter by name"
94
- input :one_line, :alias => "-l", :type => :boolean, :default => false,
95
- :desc => "Single-line tabular format"
96
- input :full, :type => :boolean, :default => false,
97
- :desc => "Show full information for apps, service instances, etc."
98
- def spaces
99
- org = input[:organization]
100
- spaces =
101
- with_progress("Getting spaces in #{c(org.name, :name)}") do
102
- org.spaces
103
- end
104
-
105
- line unless quiet?
106
-
107
- spaces.reject! do |s|
108
- !space_matches(s, input)
109
- end
110
-
111
- if input[:one_line]
112
- table(
113
- %w{name apps services},
114
- spaces.collect { |s|
115
- [ c(s.name, :name),
116
- name_list(s.apps),
117
- name_list(s.service_instances)
118
- ]
119
- })
120
- else
121
- spaced(spaces) do |s|
122
- invoke :space, :space => s, :full => input[:full]
123
- end
124
- end
125
- end
126
-
127
-
128
- desc "Create a space in an organization"
129
- group :spaces
130
- input(:name, :argument => :optional, :desc => "Space name") {
131
- ask("Name")
132
- }
133
- input :organization, :argument => :optional, :aliases => ["--org", "-o"],
134
- :from_given => by_name("organization"),
135
- :default => proc { client.current_organization },
136
- :desc => "Parent organization"
137
- input :target, :alias => "-t", :type => :boolean,
138
- :desc => "Switch to the space after creation"
139
- input :manager, :type => :boolean, :default => true,
140
- :desc => "Add current user as manager"
141
- input :developer, :type => :boolean, :default => true,
142
- :desc => "Add current user as developer"
143
- input :auditor, :type => :boolean, :default => false,
144
- :desc => "Add current user as auditor"
145
- def create_space
146
- space = client.space
147
- space.organization = input[:organization]
148
- space.name = input[:name]
149
-
150
- with_progress("Creating space #{c(space.name, :name)}") do
151
- space.create!
152
- end
153
-
154
- if input[:manager]
155
- with_progress("Adding you as a manager") do
156
- space.add_manager client.current_user
157
- end
158
- end
159
-
160
- if input[:developer]
161
- with_progress("Adding you as a developer") do
162
- space.add_developer client.current_user
163
- end
164
- end
165
-
166
- if input[:auditor]
167
- with_progress("Adding you as an auditor") do
168
- space.add_auditor client.current_user
169
- end
170
- end
171
-
172
- if input[:target]
173
- invoke :target, :organization => space.organization,
174
- :space => space
175
- end
176
- end
177
-
178
-
179
- desc "Switch to a space, creating it if it doesn't exist"
180
- group :spaces, :hidden => true
181
- input :name, :argument => true, :desc => "Space name"
182
- def take_space
183
- if space = client.space_by_name(input[:name])
184
- invoke :target, :space => space
185
- else
186
- invoke :create_space, :name => input[:name], :target => true
187
- end
188
- end
189
-
190
-
191
- desc "Delete a space and its contents"
192
- group :spaces
193
- input(:spaces, :argument => :splat,
194
- :from_given => space_by_name,
195
- :desc => "Space to delete") { |org|
196
- spaces = org.spaces
197
- fail "No spaces." if spaces.empty?
198
-
199
- [ask("Which space in #{c(org.name, :name)}?", :choices => spaces,
200
- :display => proc(&:name))]
201
- }
202
- input :organization, :aliases => ["--org", "-o"],
203
- :from_given => by_name("organization"),
204
- :default => proc { client.current_organization },
205
- :desc => "Space's organization"
206
- input(:really, :type => :boolean, :forget => true,
207
- :default => proc { force? || interact }) { |space|
208
- ask("Really delete #{c(space.name, :name)}?", :default => false)
209
- }
210
- input(:recursive, :alias => "-r", :type => :boolean, :forget => true) {
211
- ask "Delete #{c("EVERYTHING", :bad)}?", :default => false
212
- }
213
- input :warn, :type => :boolean, :default => true,
214
- :desc => "Show warning if it was the last space"
215
- def delete_space
216
- org = input[:organization]
217
- spaces = input[:spaces, org]
218
-
219
- deleted_current = false
220
-
221
- spaces.each do |space|
222
- next unless input[:really, space]
223
-
224
- next unless clear_space(space)
225
-
226
- deleted_current ||= space == client.current_space
227
-
228
- with_progress("Deleting space #{c(space.name, :name)}") do
229
- space.delete!
230
- end
231
- end
232
-
233
- org.invalidate!
234
-
235
- if org.spaces.empty?
236
- return unless input[:warn]
237
-
238
- line
239
- line c("There are no longer any spaces in #{b(org.name)}.", :warning)
240
- line "You may want to create one with #{c("create-space", :good)}."
241
- elsif deleted_current
242
- invalidate_client
243
- invoke :target, :organization => client.current_organization
244
- end
245
- end
246
-
247
- private
248
-
249
- def space_matches(s, options)
250
- if name = options[:name]
251
- return false if s.name !~ /#{name}/
252
- end
253
-
254
- true
255
- end
256
-
257
- def clear_space(space)
258
- apps = space.apps
259
- instances = space.service_instances
260
-
261
- return true if apps.empty? && instances.empty?
262
-
263
- unless force?
264
- line "This space is not empty!"
265
- line
266
- line "apps: #{name_list(apps)}"
267
- line "service instances: #{name_list(instances)}"
268
- line
269
-
270
- return unless input[:recursive]
271
- end
272
-
273
- apps.each do |a|
274
- invoke :delete, :app => a, :really => true
275
- end
276
-
277
- instances.each do |i|
278
- invoke :delete_service, :instance => i, :really => true
279
- end
280
-
281
- true
282
- end
283
- end
284
- end
data/lib/vmc/cli/start.rb DELETED
@@ -1,432 +0,0 @@
1
- require "vmc/cli"
2
-
3
- module VMC
4
- class Start < CLI
5
- # Make sure we only show the target once
6
- @@displayed_target = false
7
-
8
- def displayed_target?
9
- @@displayed_target
10
- end
11
-
12
-
13
- # These commands don't require authentication.
14
- def precondition; end
15
-
16
-
17
- def self.find_by_name(what)
18
- proc { |name, choices|
19
- choices.find { |c| c.name == name } ||
20
- fail("Unknown #{what} '#{name}'")
21
- }
22
- end
23
-
24
-
25
- desc "Display information on the current target, user, etc."
26
- group :start
27
- input :runtimes, :type => :boolean,
28
- :desc => "List supported runtimes"
29
- input :frameworks, :type => :boolean,
30
- :desc => "List supported frameworks"
31
- input :services, :type => :boolean,
32
- :desc => "List supported services"
33
- input :all, :type => :boolean, :alias => "-a",
34
- :desc => "Show all information"
35
- def info
36
- all = input[:all]
37
-
38
- if all || input[:runtimes]
39
- runtimes =
40
- with_progress("Getting runtimes") do
41
- client.runtimes
42
- end
43
- end
44
-
45
- if all || input[:frameworks]
46
- frameworks =
47
- with_progress("Getting frameworks") do
48
- client.frameworks
49
- end
50
- end
51
-
52
- if all || input[:services]
53
- services =
54
- with_progress("Getting services") do
55
- client.services
56
- end
57
- end
58
-
59
- info = client.info
60
-
61
- showing_any = runtimes || services || frameworks
62
-
63
- unless !all && showing_any
64
- line if showing_any
65
- line info[:description]
66
- line
67
- line "target: #{b(client.target)}"
68
-
69
- indented do
70
- line "version: #{info[:version]}"
71
- line "support: #{info[:support]}"
72
- end
73
-
74
- if user = client.current_user
75
- line
76
- line "user: #{b(user.email || user.guid)}"
77
- end
78
- end
79
-
80
- if runtimes
81
- line unless quiet?
82
-
83
- if runtimes.empty? && !quiet?
84
- line "#{d("none")}"
85
- elsif input[:quiet]
86
- runtimes.each do |r|
87
- line r.name
88
- end
89
- else
90
- table(
91
- %w{runtime description},
92
- runtimes.sort_by(&:name).collect { |r|
93
- [c(r.name, :name), r.description]
94
- })
95
- end
96
- end
97
-
98
- if frameworks
99
- line unless quiet?
100
-
101
- if frameworks.empty? && !quiet?
102
- line "#{d("none")}"
103
- elsif input[:quiet]
104
- frameworks.each do |f|
105
- line f.name
106
- end
107
- else
108
- table(
109
- %w{framework description},
110
- frameworks.sort_by(&:name).collect { |f|
111
- [c(f.name, :name), f.description]
112
- })
113
- end
114
- end
115
-
116
- if services
117
- line unless quiet?
118
-
119
- if services.empty? && !quiet?
120
- line "#{d("none")}"
121
- elsif input[:quiet]
122
- services.each do |s|
123
- line s.label
124
- end
125
- else
126
- table(
127
- ["service", "version", "provider", v2? && "plans", "description"],
128
- services.sort_by(&:label).collect { |s|
129
- next if !v2? && s.deprecated?
130
-
131
- [ c(s.label, :name),
132
- s.version,
133
- s.provider,
134
- v2? && s.service_plans.collect(&:name).join(", "),
135
- s.description
136
- ]
137
- })
138
- end
139
- end
140
- end
141
-
142
- desc "Set or display the target cloud, organization, and space"
143
- group :start
144
- input :url, :argument => :optional, :desc => "Target URL to switch to"
145
- input(:organization, :aliases => ["--org", "-o"],
146
- :from_given => find_by_name("organization"),
147
- :desc => "Organization") { |orgs|
148
- ask("Organization", :choices => orgs, :display => proc(&:name))
149
- }
150
- input(:space, :alias => "-s",
151
- :from_given => find_by_name("space"),
152
- :desc => "Space") { |spaces|
153
- ask("Space", :choices => spaces, :display => proc(&:name))
154
- }
155
- def target
156
- if !input.given?(:url) && !input.given?(:organization) && !input.given?(:space)
157
- display_target
158
- display_org_and_space unless quiet?
159
- return
160
- end
161
-
162
- if input.given?(:url)
163
- target = sane_target_url(input[:url])
164
- with_progress("Setting target to #{c(target, :name)}") do
165
- client(target).info # check that it's valid before setting
166
- set_target(target)
167
- end
168
- end
169
-
170
- return unless v2? && client.logged_in?
171
-
172
- if input.given?(:organization) || input.given?(:space)
173
- info = target_info
174
-
175
- select_org_and_space(input, info)
176
-
177
- save_target_info(info)
178
- end
179
-
180
- return if quiet?
181
-
182
- invalidate_client
183
-
184
- line
185
- display_target
186
- display_org_and_space
187
- end
188
-
189
-
190
- desc "List known targets."
191
- group :start, :hidden => true
192
- def targets
193
- targets_info.each do |target, _|
194
- line target
195
- # TODO: print org/space
196
- end
197
- end
198
-
199
-
200
- desc "Authenticate with the target"
201
- group :start
202
- input :username, :alias => "--email", :argument => :optional,
203
- :desc => "Account email"
204
- input :password, :desc => "Account password"
205
- input(:organization, :aliases => ["--org", "-o"],
206
- :from_given => find_by_name("organization"),
207
- :desc => "Organization") { |orgs|
208
- ask("Organization", :choices => orgs, :display => proc(&:name))
209
- }
210
- input(:space, :alias => "-s",
211
- :from_given => find_by_name("space"),
212
- :desc => "Space") { |spaces|
213
- ask("Space", :choices => spaces, :display => proc(&:name))
214
- }
215
- def login
216
- show_context
217
-
218
- credentials =
219
- { :username => input[:username],
220
- :password => input[:password]
221
- }
222
-
223
- prompts = client.login_prompts
224
-
225
- # ask username first
226
- if prompts.key? :username
227
- type, label = prompts.delete :username
228
- credentials[:username] ||= ask_prompt(type, label)
229
- end
230
-
231
- info = target_info
232
-
233
- authenticated = false
234
- failed = false
235
- remaining_attempts = 3
236
- until authenticated || remaining_attempts <= 0
237
- remaining_attempts -= 1
238
- unless force?
239
- ask_prompts(credentials, prompts)
240
- end
241
-
242
- with_progress("Authenticating") do |s|
243
- begin
244
- info[:token] = client.login(credentials)
245
- authenticated = true
246
- rescue CFoundry::Denied
247
- return if force?
248
-
249
- s.fail do
250
- failed = true
251
- credentials.delete(:password)
252
- end
253
- end
254
- end
255
- end
256
-
257
- save_target_info(info)
258
- invalidate_client
259
-
260
- if v2?
261
- line if input.interactive?(:organization) || input.interactive?(:space)
262
- select_org_and_space(input, info)
263
- save_target_info(info)
264
- end
265
- ensure
266
- exit_status 1 if not authenticated
267
- end
268
-
269
-
270
- desc "Log out from the target"
271
- group :start
272
- def logout
273
- with_progress("Logging out") do
274
- remove_target_info
275
- end
276
- end
277
-
278
-
279
- desc "Create a user and log in"
280
- group :start, :hidden => true
281
- input(:email, :argument => true, :desc => "Desired email") {
282
- ask("Email")
283
- }
284
- input(:password, :desc => "Desired password") {
285
- ask("Password", :echo => "*", :forget => true)
286
- }
287
- input(:verify, :desc => "Repeat password") {
288
- ask("Confirm Password", :echo => "*", :forget => true)
289
- }
290
- input :login, :type => :boolean, :default => true,
291
- :desc => "Automatically log in?"
292
- def register
293
- show_context
294
-
295
- email = input[:email]
296
- password = input[:password]
297
-
298
- if !force? && password != input[:verify]
299
- fail "Passwords do not match."
300
- end
301
-
302
- with_progress("Creating user") do
303
- client.register(email, password)
304
- end
305
-
306
- if input[:login]
307
- invoke :login, :username => email, :password => password
308
- end
309
- end
310
-
311
-
312
- desc "Show color configuration"
313
- group :start, :hidden => true
314
- def colors
315
- user_colors.each do |n, c|
316
- line "#{n}: #{c(c.to_s, n)}"
317
- end
318
- end
319
-
320
- private
321
-
322
- def ask_prompt(type, label)
323
- if type == "password"
324
- options = { :echo => "*", :forget => true }
325
- else
326
- options = {}
327
- end
328
-
329
- ask(label, options)
330
- end
331
-
332
- def ask_prompts(credentials, prompts)
333
- prompts.each do |name, meta|
334
- type, label = meta
335
- credentials[name] ||= ask_prompt(type, label)
336
- end
337
- end
338
-
339
- def show_context
340
- return if quiet? || displayed_target?
341
-
342
- display_target
343
-
344
- line
345
-
346
- @@displayed_target = true
347
- end
348
-
349
- def display_target
350
- if quiet?
351
- line client.target
352
- else
353
- line "target: #{c(client.target, :name)}"
354
- end
355
- end
356
-
357
- def display_org_and_space
358
- return unless v2?
359
-
360
- if org = client.current_organization
361
- line "organization: #{c(org.name, :name)}"
362
- end
363
-
364
- if space = client.current_space
365
- line "space: #{c(space.name, :name)}"
366
- end
367
- rescue CFoundry::APIError
368
- end
369
-
370
- def org_valid?(guid, user = client.current_user)
371
- return false unless guid
372
- client.organization(guid).users.include? user
373
- rescue CFoundry::APIError
374
- false
375
- end
376
-
377
- def space_valid?(guid, user = client.current_user)
378
- return false unless guid
379
- client.space(guid).developers.include? user
380
- rescue CFoundry::APIError
381
- false
382
- end
383
-
384
- def select_org_and_space(input, info)
385
- changed_org = false
386
-
387
- if input.given?(:organization) || !org_valid?(info[:organization])
388
- orgs = client.organizations
389
- fail "No organizations!" if orgs.empty?
390
-
391
- if orgs.size == 1 && !input.given?(:organization)
392
- org = orgs.first
393
- else
394
- org = input[:organization, orgs.sort_by(&:name)]
395
- end
396
-
397
- with_progress("Switching to organization #{c(org.name, :name)}") do
398
- info[:organization] = org.guid
399
- changed_org = true
400
- end
401
- else
402
- org = client.current_organization
403
- end
404
-
405
- # switching org means switching space
406
- if changed_org || input.given?(:space) || !space_valid?(info[:space])
407
- spaces = org.spaces
408
-
409
- if spaces.empty?
410
- if changed_org
411
- line c("There are no spaces in #{b(org.name)}.", :warning)
412
- line "You may want to create one with #{c("create-space", :good)}."
413
- return
414
- else
415
- fail "No spaces!"
416
- end
417
- end
418
-
419
- if spaces.size == 1 && !input.given?(:space)
420
- space = spaces.first
421
- else
422
- line if changed_org && input.interactive?(:organization)
423
- space = input[:space, spaces.sort_by(&:name)]
424
- end
425
-
426
- with_progress("Switching to space #{c(space.name, :name)}") do
427
- info[:space] = space.guid
428
- end
429
- end
430
- end
431
- end
432
- end