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
@@ -0,0 +1,36 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Rename < Base
7
+ desc "Rename a space"
8
+ group :spaces, :hidden => true
9
+ input :organization, :aliases => ["--org", "-o"],
10
+ :from_given => by_name("organization"),
11
+ :default => proc { client.current_organization },
12
+ :desc => "Space's organization"
13
+ input(:space, :argument => :optional, :from_given => space_by_name,
14
+ :desc => "Space to rename") {
15
+ spaces = client.spaces
16
+ fail "No spaces." if spaces.empty?
17
+
18
+ ask("Rename which space?", :choices => spaces.sort_by(&:name),
19
+ :display => proc(&:name))
20
+ }
21
+ input(:name, :argument => :optional, :desc => "New space name") {
22
+ ask("New name")
23
+ }
24
+ def rename_space
25
+ org = input[:organization]
26
+ space = input[:space, org]
27
+ name = input[:name]
28
+
29
+ space.name = name
30
+
31
+ with_progress("Renaming to #{c(name, :name)}") do
32
+ space.update!
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,67 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Space < Base
7
+ desc "Show space information"
8
+ group :spaces
9
+ input :organization, :aliases => ["--org", "-o"],
10
+ :from_given => by_name("organization"),
11
+ :default => proc { client.current_organization },
12
+ :desc => "Space's organization"
13
+ input :space, :argument => :optional,
14
+ :from_given => space_by_name,
15
+ :default => proc { client.current_space },
16
+ :desc => "Space to show"
17
+ input :full, :type => :boolean,
18
+ :desc => "Show full information for apps, service instances, etc."
19
+ def space
20
+ org = input[:organization]
21
+ space = input[:space, org]
22
+
23
+ unless space
24
+ return if quiet?
25
+ fail "No current space."
26
+ end
27
+
28
+ if quiet?
29
+ puts space.name
30
+ return
31
+ end
32
+
33
+ line "#{c(space.name, :name)}:"
34
+
35
+ indented do
36
+ line "organization: #{c(space.organization.name, :name)}"
37
+
38
+ if input[:full]
39
+ line
40
+ line "apps:"
41
+
42
+ spaced(space.apps(:depth => 2)) do |a|
43
+ indented do
44
+ invoke :app, :app => a
45
+ end
46
+ end
47
+ else
48
+ line "apps: #{name_list(space.apps)}"
49
+ end
50
+
51
+ if input[:full]
52
+ line
53
+ line "services:"
54
+ spaced(space.service_instances(:depth => 2)) do |i|
55
+ indented do
56
+ invoke :service, :instance => i
57
+ end
58
+ end
59
+ else
60
+ line "services: #{name_list(space.service_instances)}"
61
+ end
62
+
63
+ line "domains: #{name_list(space.domains)}"
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,57 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Spaces < Base
7
+ desc "List spaces in an organization"
8
+ group :spaces
9
+ input :organization, :argument => :optional, :aliases => ["--org", "-o"],
10
+ :from_given => by_name("organization"),
11
+ :default => proc { client.current_organization },
12
+ :desc => "Organization to list spaces from"
13
+ input :name, :desc => "Filter by name"
14
+ input :one_line, :alias => "-l", :type => :boolean, :default => false,
15
+ :desc => "Single-line tabular format"
16
+ input :full, :type => :boolean, :default => false,
17
+ :desc => "Show full information for apps, service instances, etc."
18
+ def spaces
19
+ org = input[:organization]
20
+ spaces =
21
+ with_progress("Getting spaces in #{c(org.name, :name)}") do
22
+ org.spaces
23
+ end
24
+
25
+ line unless quiet?
26
+
27
+ spaces.filter! do |s|
28
+ space_matches?(s, input)
29
+ end
30
+
31
+ if input[:one_line]
32
+ table(
33
+ %w{name apps services},
34
+ spaces.collect { |s|
35
+ [ c(s.name, :name),
36
+ name_list(s.apps),
37
+ name_list(s.service_instances)
38
+ ]
39
+ })
40
+ else
41
+ spaced(spaces) do |s|
42
+ invoke :space, :space => s, :full => input[:full]
43
+ end
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def space_matches?(s, options)
50
+ if name = options[:name]
51
+ return false if s.name !~ /#{name}/
52
+ end
53
+
54
+ true
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,18 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Take < Base
7
+ desc "Switch to a space, creating it if it doesn't exist"
8
+ group :spaces, :hidden => true
9
+ input :name, :argument => true, :desc => "Space name"
10
+ def take_space
11
+ if space = client.space_by_name(input[:name])
12
+ invoke :target, :space => space
13
+ else
14
+ invoke :create_space, :name => input[:name], :target => true
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,100 @@
1
+ require "vmc/cli"
2
+
3
+ module VMC
4
+ module Start
5
+ class Base < CLI
6
+ # Make sure we only show the target once
7
+ @@displayed_target = false
8
+
9
+ def displayed_target?
10
+ @@displayed_target
11
+ end
12
+
13
+
14
+ # These commands don't require authentication.
15
+ def precondition; end
16
+
17
+ private
18
+
19
+ def show_context
20
+ return if quiet? || displayed_target?
21
+
22
+ display_target
23
+
24
+ line
25
+
26
+ @@displayed_target = true
27
+ end
28
+
29
+ def display_target
30
+ if quiet?
31
+ line client.target
32
+ else
33
+ line "target: #{c(client.target, :name)}"
34
+ end
35
+ end
36
+
37
+ def select_org_and_space(input, info)
38
+ changed_org = false
39
+
40
+ if input.given?(:organization) || !org_valid?(info[:organization])
41
+ orgs = client.organizations
42
+ fail "No organizations!" if orgs.empty?
43
+
44
+ if orgs.size == 1 && !input.given?(:organization)
45
+ org = orgs.first
46
+ else
47
+ org = input[:organization, orgs.sort_by(&:name)]
48
+ end
49
+
50
+ with_progress("Switching to organization #{c(org.name, :name)}") do
51
+ info[:organization] = org.guid
52
+ changed_org = true
53
+ end
54
+ else
55
+ org = client.current_organization
56
+ end
57
+
58
+ # switching org means switching space
59
+ if changed_org || input.given?(:space) || !space_valid?(info[:space])
60
+ spaces = org.spaces
61
+
62
+ if spaces.empty?
63
+ if changed_org
64
+ line c("There are no spaces in #{b(org.name)}.", :warning)
65
+ line "You may want to create one with #{c("create-space", :good)}."
66
+ return
67
+ else
68
+ fail "No spaces!"
69
+ end
70
+ end
71
+
72
+ if spaces.size == 1 && !input.given?(:space)
73
+ space = spaces.first
74
+ else
75
+ line if changed_org && input.interactive?(:organization)
76
+ space = input[:space, spaces.sort_by(&:name)]
77
+ end
78
+
79
+ with_progress("Switching to space #{c(space.name, :name)}") do
80
+ info[:space] = space.guid
81
+ end
82
+ end
83
+ end
84
+
85
+ def org_valid?(guid, user = client.current_user)
86
+ return false unless guid
87
+ client.organization(guid).users.include? user
88
+ rescue CFoundry::APIError
89
+ false
90
+ end
91
+
92
+ def space_valid?(guid, user = client.current_user)
93
+ return false unless guid
94
+ client.space(guid).developers.include? user
95
+ rescue CFoundry::APIError
96
+ false
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,14 @@
1
+ require "vmc/detect"
2
+ require "vmc/cli/start/base"
3
+
4
+ module VMC::Start
5
+ class Colors < Base
6
+ desc "Show color configuration"
7
+ group :start, :hidden => true
8
+ def colors
9
+ user_colors.each do |n, c|
10
+ line "#{n}: #{c(c.to_s, n)}"
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,124 @@
1
+ require "vmc/detect"
2
+ require "vmc/cli/start/base"
3
+
4
+ module VMC::Start
5
+ class Info < Base
6
+ desc "Display information on the current target, user, etc."
7
+ group :start
8
+ input :runtimes, :type => :boolean,
9
+ :desc => "List supported runtimes"
10
+ input :frameworks, :type => :boolean,
11
+ :desc => "List supported frameworks"
12
+ input :services, :type => :boolean,
13
+ :desc => "List supported services"
14
+ input :all, :type => :boolean, :alias => "-a",
15
+ :desc => "Show all information"
16
+
17
+ def info
18
+ all = input[:all]
19
+
20
+ if all || input[:runtimes]
21
+ runtimes =
22
+ with_progress("Getting runtimes") do
23
+ client.runtimes
24
+ end
25
+ end
26
+
27
+ if all || input[:frameworks]
28
+ frameworks =
29
+ with_progress("Getting frameworks") do
30
+ client.frameworks
31
+ end
32
+ end
33
+
34
+ if all || input[:services]
35
+ services =
36
+ with_progress("Getting services") do
37
+ client.services
38
+ end
39
+ end
40
+
41
+ info = client.info
42
+
43
+ showing_any = runtimes || services || frameworks
44
+
45
+ unless !all && showing_any
46
+ line if showing_any
47
+ line info[:description]
48
+ line
49
+ line "target: #{b(client.target)}"
50
+
51
+ indented do
52
+ line "version: #{info[:version]}"
53
+ line "support: #{info[:support]}"
54
+ end
55
+
56
+ if user = client.current_user
57
+ line
58
+ line "user: #{b(user.email || user.guid)}"
59
+ end
60
+ end
61
+
62
+ if runtimes
63
+ line unless quiet?
64
+
65
+ if runtimes.empty? && !quiet?
66
+ line "#{d("none")}"
67
+ elsif input[:quiet]
68
+ runtimes.each do |r|
69
+ line r.name
70
+ end
71
+ else
72
+ table(
73
+ %w{runtime description},
74
+ runtimes.sort_by(&:name).collect { |r|
75
+ [c(r.name, :name), r.description]
76
+ })
77
+ end
78
+ end
79
+
80
+ if frameworks
81
+ line unless quiet?
82
+
83
+ if frameworks.empty? && !quiet?
84
+ line "#{d("none")}"
85
+ elsif input[:quiet]
86
+ frameworks.each do |f|
87
+ line f.name
88
+ end
89
+ else
90
+ table(
91
+ %w{framework description},
92
+ frameworks.sort_by(&:name).collect { |f|
93
+ [c(f.name, :name), f.description]
94
+ })
95
+ end
96
+ end
97
+
98
+ if services
99
+ line unless quiet?
100
+
101
+ if services.empty? && !quiet?
102
+ line "#{d("none")}"
103
+ elsif input[:quiet]
104
+ services.each do |s|
105
+ line s.label
106
+ end
107
+ else
108
+ table(
109
+ ["service", "version", "provider", v2? && "plans", "description"],
110
+ services.sort_by(&:label).collect { |s|
111
+ next if !v2? && s.deprecated?
112
+
113
+ [c(s.label, :name),
114
+ s.version,
115
+ s.provider,
116
+ v2? && s.service_plans.collect(&:name).join(", "),
117
+ s.description
118
+ ]
119
+ })
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,94 @@
1
+ require "vmc/detect"
2
+ require "vmc/cli/start/base"
3
+
4
+ module VMC::Start
5
+ class Login < Base
6
+ desc "Authenticate with the target"
7
+ group :start
8
+ input :username, :alias => "--email", :argument => :optional,
9
+ :desc => "Account email"
10
+ input :password, :desc => "Account password"
11
+ input(:organization, :aliases => ["--org", "-o"],
12
+ :from_given => find_by_name("organization"),
13
+ :desc => "Organization") { |orgs|
14
+ ask("Organization", :choices => orgs, :display => proc(&:name))
15
+ }
16
+ input(:space, :alias => "-s",
17
+ :from_given => find_by_name("space"),
18
+ :desc => "Space") { |spaces|
19
+ ask("Space", :choices => spaces, :display => proc(&:name))
20
+ }
21
+ def login
22
+ show_context
23
+
24
+ credentials =
25
+ { :username => input[:username],
26
+ :password => input[:password]
27
+ }
28
+
29
+ prompts = client.login_prompts
30
+
31
+ # ask username first
32
+ if prompts.key? :username
33
+ type, label = prompts.delete :username
34
+ credentials[:username] ||= ask_prompt(type, label)
35
+ end
36
+
37
+ info = target_info
38
+
39
+ authenticated = false
40
+ failed = false
41
+ remaining_attempts = 3
42
+ until authenticated || remaining_attempts <= 0
43
+ remaining_attempts -= 1
44
+ unless force?
45
+ ask_prompts(credentials, prompts)
46
+ end
47
+
48
+ with_progress("Authenticating") do |s|
49
+ begin
50
+ info[:token] = client.login(credentials)
51
+ authenticated = true
52
+ rescue CFoundry::Denied
53
+ return if force?
54
+
55
+ s.fail do
56
+ failed = true
57
+ credentials.delete(:password)
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ save_target_info(info)
64
+ invalidate_client
65
+
66
+ if v2?
67
+ line if input.interactive?(:organization) || input.interactive?(:space)
68
+ select_org_and_space(input, info)
69
+ save_target_info(info)
70
+ end
71
+ ensure
72
+ exit_status 1 if not authenticated
73
+ end
74
+
75
+ private
76
+
77
+ def ask_prompts(credentials, prompts)
78
+ prompts.each do |name, meta|
79
+ type, label = meta
80
+ credentials[name] ||= ask_prompt(type, label)
81
+ end
82
+ end
83
+
84
+ def ask_prompt(type, label)
85
+ if type == "password"
86
+ options = { :echo => "*", :forget => true }
87
+ else
88
+ options = {}
89
+ end
90
+
91
+ ask(label, options)
92
+ end
93
+ end
94
+ end