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,84 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/service/base"
4
+
5
+ module VMC::Service
6
+ class Delete < Base
7
+ desc "Delete a service"
8
+ group :services, :manage
9
+ input(:instance, :argument => true,
10
+ :from_given => by_name("service instance", :service_instance),
11
+ :desc => "Service to bind") {
12
+ instances = client.service_instances
13
+ fail "No services." if instances.empty?
14
+
15
+ ask "Which service instance?", :choices => instances,
16
+ :display => proc(&:name)
17
+ }
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(:unbind, :type => :boolean, :forget => true,
23
+ :default => proc { force? || interact }) { |apps|
24
+ names = human_list(apps.collect { |a| c(a.name, :name) })
25
+
26
+ ask("Unbind from #{names} before deleting?", :default => true)
27
+ }
28
+ input :all, :type => :boolean, :default => false,
29
+ :desc => "Delete all services"
30
+ def delete_service
31
+ if input[:all]
32
+ return unless input[:really, "ALL SERVICES", :bad]
33
+
34
+ client.service_instances.each do |i|
35
+ invoke :delete_service, :instance => i, :really => true
36
+ end
37
+
38
+ return
39
+ end
40
+
41
+ instance = input[:instance]
42
+
43
+ return unless input[:really, instance.name, :name]
44
+
45
+ bindings = []
46
+
47
+ if v2?
48
+ bindings = instance.service_bindings
49
+
50
+ unless bindings.empty? || !input[:unbind, bindings.collect(&:app)]
51
+ bindings.each do |b|
52
+ invoke :unbind_service, :instance => instance, :app => b.app
53
+ end
54
+
55
+ bindings = []
56
+ end
57
+ end
58
+
59
+ with_progress("Deleting #{c(instance.name, :name)}") do |s|
60
+ if bindings.empty?
61
+ instance.delete!
62
+ else
63
+ s.skip do
64
+ apps = bindings.collect(&:app).collect { |a| b(a.name) }
65
+ err "Service instance is bound to #{human_list(apps)}."
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ private
72
+
73
+ def human_list(xs)
74
+ if xs.size == 1
75
+ xs.first
76
+ elsif xs.size == 2
77
+ "#{xs.first} and #{xs.last}"
78
+ else
79
+ last = xs.pop
80
+ xs.join(", ") + ", and #{last}"
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,32 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/service/base"
4
+
5
+ module VMC::Service
6
+ class Rename < Base
7
+ desc "Rename a service"
8
+ group :services, :manage, :hidden => true
9
+ input(:service, :aliases => ["--org", "-o"],
10
+ :argument => :optional, :desc => "service to rename",
11
+ :from_given => by_name("service", :service_instance)) {
12
+ services = client.service_instances
13
+ fail "No services." if services.empty?
14
+
15
+ ask("Rename which service?", :choices => services.sort_by(&:name),
16
+ :display => proc(&:name))
17
+ }
18
+ input(:name, :argument => :optional, :desc => "New service name") {
19
+ ask("New name")
20
+ }
21
+ def rename_service
22
+ service = input[:service]
23
+ name = input[:name]
24
+
25
+ service.name = name
26
+
27
+ with_progress("Renaming to #{c(name, :name)}") do
28
+ service.update!
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,45 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/service/base"
4
+
5
+ module VMC::Service
6
+ class Service < Base
7
+ desc "Show service instance information"
8
+ group :services
9
+ input :instance, :argument => :required,
10
+ :from_given => by_name("service instance", :service_instance),
11
+ :desc => "Service instance to show"
12
+ def service
13
+ display_service_instance(input[:instance])
14
+ end
15
+
16
+ private
17
+
18
+ def display_service_instance(i)
19
+ if quiet?
20
+ line i.name
21
+ elsif v2?
22
+ plan = i.service_plan
23
+ service = plan.service
24
+
25
+ apps = i.service_bindings.collect { |b|
26
+ c(b.app.name, :name)
27
+ }.join(", ")
28
+
29
+ line "#{c(i.name, :name)}: #{service.label} #{service.version}"
30
+
31
+ indented do
32
+ line "provider: #{c(service.provider, :name)}"
33
+ line "bound to: #{apps}" unless apps.empty?
34
+ line "plan: #{c(plan.name, :name)}"
35
+
36
+ indented do
37
+ line "description: #{plan.description}"
38
+ end
39
+ end
40
+ else
41
+ line "#{c(i.name, :name)}: #{i.vendor} #{i.version}"
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,118 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/service/base"
4
+
5
+ module VMC::Service
6
+ class Services < Base
7
+ desc "List your service instances"
8
+ group :services
9
+ input :space,
10
+ :from_given => by_name("space"),
11
+ :default => proc { client.current_space },
12
+ :desc => "Show services in given space"
13
+ input :name, :desc => "Filter by name"
14
+ input :service, :desc => "Filter by service type"
15
+ input :plan, :desc => "Filter by service plan"
16
+ input :provider, :desc => "Filter by service provider"
17
+ input :version, :desc => "Filter by service version"
18
+ input :app, :desc => "Limit to application's service bindings",
19
+ :from_given => by_name("app")
20
+ input :full, :type => :boolean, :default => false,
21
+ :desc => "Verbose output format"
22
+ def services
23
+ msg =
24
+ if space = input[:space]
25
+ "Getting services in #{c(space.name, :name)}"
26
+ else
27
+ "Getting services"
28
+ end
29
+
30
+ instances =
31
+ with_progress(msg) do
32
+ client.service_instances(:depth => 2)
33
+ end
34
+
35
+ line unless quiet?
36
+
37
+ if instances.empty? and !quiet?
38
+ line "No services."
39
+ return
40
+ end
41
+
42
+ instances.reject! do |i|
43
+ !instance_matches(i, input)
44
+ end
45
+
46
+ if input[:full]
47
+ spaced(instances) do |i|
48
+ display_service_instance(i)
49
+ end
50
+ else
51
+ table(
52
+ ["name", "service", "version", v2? && "plan", v2? && "bound apps"],
53
+ instances.collect { |i|
54
+ if v2?
55
+ plan = i.service_plan
56
+ service = plan.service
57
+
58
+ label = service.label
59
+ version = service.version
60
+ apps = name_list(i.service_bindings.collect(&:app))
61
+ else
62
+ label = i.vendor
63
+ version = i.version
64
+ end
65
+
66
+ [ c(i.name, :name),
67
+ label,
68
+ version,
69
+ v2? && plan.name,
70
+ apps
71
+ ]
72
+ })
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def instance_matches(i, options)
79
+ if app = options[:app]
80
+ return false unless app.services.include? i
81
+ end
82
+
83
+ if name = options[:name]
84
+ return false unless File.fnmatch(name, i.name)
85
+ end
86
+
87
+ plan = i.service_plan if v2?
88
+
89
+ if service = options[:service]
90
+ if v2?
91
+ return false unless File.fnmatch(service, plan.service.label)
92
+ else
93
+ return false unless File.fnmatch(service, i.vendor)
94
+ end
95
+ end
96
+
97
+ if plan = options[:plan]
98
+ fail "--plan is not supported on this target" unless v2?
99
+ return false unless File.fnmatch(plan.upcase, plan.name.upcase)
100
+ end
101
+
102
+ if provider = options[:provider]
103
+ fail "--provider is not supported on this target" unless v2?
104
+ return false unless File.fnmatch(provider, plan.service.provider)
105
+ end
106
+
107
+ if version = options[:version]
108
+ if v2?
109
+ return false unless File.fnmatch(version, plan.service.version)
110
+ else
111
+ return false unless File.fnmatch(version, i.version)
112
+ end
113
+ end
114
+
115
+ true
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,21 @@
1
+ require "vmc/cli"
2
+
3
+ module VMC
4
+ module Space
5
+ class Base < CLI
6
+ def precondition
7
+ check_target
8
+ check_logged_in
9
+
10
+ fail "This command is v2-only." unless v2?
11
+ end
12
+
13
+ def self.space_by_name
14
+ proc { |name, org, *_|
15
+ org.space_by_name(name) ||
16
+ fail("Unknown space '#{name}'.")
17
+ }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,57 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Create < Base
7
+ desc "Create a space in an organization"
8
+ group :spaces
9
+ input(:name, :argument => :optional, :desc => "Space name") {
10
+ ask("Name")
11
+ }
12
+ input :organization, :argument => :optional, :aliases => ["--org", "-o"],
13
+ :from_given => by_name("organization"),
14
+ :default => proc { client.current_organization },
15
+ :desc => "Parent organization"
16
+ input :target, :alias => "-t", :type => :boolean,
17
+ :desc => "Switch to the space after creation"
18
+ input :manager, :type => :boolean, :default => true,
19
+ :desc => "Add current user as manager"
20
+ input :developer, :type => :boolean, :default => true,
21
+ :desc => "Add current user as developer"
22
+ input :auditor, :type => :boolean, :default => false,
23
+ :desc => "Add current user as auditor"
24
+ def create_space
25
+ space = client.space
26
+ space.organization = input[:organization]
27
+ space.name = input[:name]
28
+
29
+ with_progress("Creating space #{c(space.name, :name)}") do
30
+ space.create!
31
+ end
32
+
33
+ if input[:manager]
34
+ with_progress("Adding you as a manager") do
35
+ space.add_manager client.current_user
36
+ end
37
+ end
38
+
39
+ if input[:developer]
40
+ with_progress("Adding you as a developer") do
41
+ space.add_developer client.current_user
42
+ end
43
+ end
44
+
45
+ if input[:auditor]
46
+ with_progress("Adding you as an auditor") do
47
+ space.add_auditor client.current_user
48
+ end
49
+ end
50
+
51
+ if input[:target]
52
+ invoke :target, :organization => space.organization,
53
+ :space => space
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,92 @@
1
+ require "vmc/detect"
2
+
3
+ require "vmc/cli/space/base"
4
+
5
+ module VMC::Space
6
+ class Delete < Base
7
+ desc "Delete a space and its contents"
8
+ group :spaces
9
+ input(:spaces, :argument => :splat,
10
+ :from_given => space_by_name,
11
+ :desc => "Space to delete") { |org|
12
+ spaces = org.spaces
13
+ fail "No spaces." if spaces.empty?
14
+
15
+ [ask("Which space in #{c(org.name, :name)}?", :choices => spaces,
16
+ :display => proc(&:name))]
17
+ }
18
+ input :organization, :aliases => ["--org", "-o"],
19
+ :from_given => by_name("organization"),
20
+ :default => proc { client.current_organization },
21
+ :desc => "Space's organization"
22
+ input(:really, :type => :boolean, :forget => true,
23
+ :default => proc { force? || interact }) { |space|
24
+ ask("Really delete #{c(space.name, :name)}?", :default => false)
25
+ }
26
+ input(:recursive, :alias => "-r", :type => :boolean, :forget => true) {
27
+ ask "Delete #{c("EVERYTHING", :bad)}?", :default => false
28
+ }
29
+ input :warn, :type => :boolean, :default => true,
30
+ :desc => "Show warning if it was the last space"
31
+ def delete_space
32
+ org = input[:organization]
33
+ spaces = input[:spaces, org]
34
+
35
+ deleted_current = false
36
+
37
+ spaces.each do |space|
38
+ next unless input[:really, space]
39
+
40
+ next unless clear_space(space)
41
+
42
+ deleted_current ||= space == client.current_space
43
+
44
+ with_progress("Deleting space #{c(space.name, :name)}") do
45
+ space.delete!
46
+ end
47
+ end
48
+
49
+ org.invalidate!
50
+
51
+ if org.spaces.empty?
52
+ return unless input[:warn]
53
+
54
+ line
55
+ line c("There are no longer any spaces in #{b(org.name)}.", :warning)
56
+ line "You may want to create one with #{c("create-space", :good)}."
57
+ elsif deleted_current
58
+ invalidate_client
59
+ invoke :target, :organization => client.current_organization
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def clear_space(space)
66
+ apps = space.apps
67
+ instances = space.service_instances
68
+
69
+ return true if apps.empty? && instances.empty?
70
+
71
+ unless force?
72
+ line "This space is not empty!"
73
+ line
74
+ line "apps: #{name_list(apps)}"
75
+ line "service instances: #{name_list(instances)}"
76
+ line
77
+
78
+ return unless input[:recursive]
79
+ end
80
+
81
+ apps.each do |a|
82
+ invoke :delete, :app => a, :really => true
83
+ end
84
+
85
+ instances.each do |i|
86
+ invoke :delete_service, :instance => i, :really => true
87
+ end
88
+
89
+ true
90
+ end
91
+ end
92
+ end