jdc 0.1.2 → 0.2.0
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/LICENSE +1277 -24
- data/Rakefile +13 -0
- data/bin/jdc +12 -2
- data/lib/admin/README.md +15 -0
- data/lib/admin/curl.rb +60 -0
- data/lib/admin/guid.rb +89 -0
- data/lib/admin/plugin.rb +6 -0
- data/lib/admin/service_auth_token.rb +94 -0
- data/lib/admin/service_broker/add.rb +47 -0
- data/lib/admin/service_broker/service_brokers.rb +24 -0
- data/lib/admin/set_quota.rb +44 -0
- data/lib/console/README.md +8 -0
- data/lib/console/console.rb +187 -0
- data/lib/console/plugin.rb +33 -0
- data/lib/jdc/cli/app/app.rb +43 -0
- data/lib/jdc/cli/app/apps.rb +87 -0
- data/lib/jdc/cli/app/base.rb +72 -0
- data/lib/jdc/cli/app/delete.rb +95 -0
- data/lib/jdc/cli/app/deprecated.rb +11 -0
- data/lib/jdc/cli/app/env.rb +78 -0
- data/lib/jdc/cli/app/events.rb +45 -0
- data/lib/jdc/cli/app/files.rb +137 -0
- data/lib/jdc/cli/app/health.rb +26 -0
- data/lib/jdc/cli/app/instances.rb +53 -0
- data/lib/jdc/cli/app/logs.rb +76 -0
- data/lib/jdc/cli/app/push/create.rb +108 -0
- data/lib/jdc/cli/app/push/interactions.rb +86 -0
- data/lib/jdc/cli/app/push/sync.rb +57 -0
- data/lib/jdc/cli/app/push.rb +103 -0
- data/lib/jdc/cli/app/rename.rb +35 -0
- data/lib/jdc/cli/app/restart.rb +31 -0
- data/lib/jdc/cli/app/scale.rb +63 -0
- data/lib/jdc/cli/app/start.rb +161 -0
- data/lib/jdc/cli/app/stats.rb +67 -0
- data/lib/jdc/cli/app/stop.rb +27 -0
- data/lib/jdc/cli/domain/base.rb +9 -0
- data/lib/jdc/cli/domain/domains.rb +40 -0
- data/lib/jdc/cli/domain/map.rb +55 -0
- data/lib/jdc/cli/domain/unmap.rb +56 -0
- data/lib/jdc/cli/help.rb +15 -0
- data/lib/jdc/cli/interactive.rb +105 -0
- data/lib/jdc/cli/login_requirements.rb +15 -0
- data/lib/jdc/cli/organization/base.rb +14 -0
- data/lib/jdc/cli/organization/create.rb +37 -0
- data/lib/jdc/cli/organization/delete.rb +63 -0
- data/lib/jdc/cli/organization/org.rb +45 -0
- data/lib/jdc/cli/organization/orgs.rb +30 -0
- data/lib/jdc/cli/organization/rename.rb +37 -0
- data/lib/jdc/cli/populators/base.rb +16 -0
- data/lib/jdc/cli/populators/organization.rb +32 -0
- data/lib/jdc/cli/populators/populator_methods.rb +64 -0
- data/lib/jdc/cli/populators/space.rb +33 -0
- data/lib/jdc/cli/populators/target.rb +13 -0
- data/lib/jdc/cli/route/base.rb +9 -0
- data/lib/jdc/cli/route/delete.rb +28 -0
- data/lib/jdc/cli/route/map.rb +68 -0
- data/lib/jdc/cli/route/routes.rb +26 -0
- data/lib/jdc/cli/route/unmap.rb +56 -0
- data/lib/jdc/cli/service/base.rb +9 -0
- data/lib/jdc/cli/service/bind.rb +44 -0
- data/lib/jdc/cli/service/create.rb +159 -0
- data/lib/jdc/cli/service/delete.rb +83 -0
- data/lib/jdc/cli/service/rename.rb +36 -0
- data/lib/jdc/cli/service/service.rb +42 -0
- data/lib/jdc/cli/service/service_instance_helper.rb +99 -0
- data/lib/jdc/cli/service/services.rb +111 -0
- data/lib/jdc/cli/service/unbind.rb +37 -0
- data/lib/jdc/cli/space/base.rb +29 -0
- data/lib/jdc/cli/space/create.rb +67 -0
- data/lib/jdc/cli/space/delete.rb +56 -0
- data/lib/jdc/cli/space/rename.rb +38 -0
- data/lib/jdc/cli/space/space.rb +66 -0
- data/lib/jdc/cli/space/spaces.rb +57 -0
- data/lib/jdc/cli/space/switch.rb +19 -0
- data/lib/jdc/cli/start/base.rb +41 -0
- data/lib/jdc/cli/start/colors.rb +13 -0
- data/lib/jdc/cli/start/target.rb +50 -0
- data/lib/jdc/cli/start/target_prettifier.rb +17 -0
- data/lib/jdc/cli/start/targets.rb +16 -0
- data/lib/jdc/cli/user/base.rb +30 -0
- data/lib/jdc/cli/user/create.rb +52 -0
- data/lib/jdc/cli/user/passwd.rb +37 -0
- data/lib/jdc/cli/user/register.rb +43 -0
- data/lib/jdc/cli/user/users.rb +32 -0
- data/lib/jdc/cli.rb +544 -0
- data/lib/jdc/constants.rb +11 -0
- data/lib/jdc/errors.rb +19 -0
- data/lib/jdc/object_extensions.rb +15 -0
- data/lib/jdc/plugin.rb +56 -0
- data/lib/jdc/spacing.rb +89 -0
- data/lib/jdc/spec_helper.rb +1 -0
- data/lib/jdc/test_support.rb +6 -0
- data/lib/jdc/version.rb +3 -0
- data/lib/jdc.rb +15 -2
- data/lib/manifests/errors.rb +35 -0
- data/lib/manifests/loader/builder.rb +39 -0
- data/lib/manifests/loader/normalizer.rb +145 -0
- data/lib/manifests/loader/resolver.rb +79 -0
- data/lib/manifests/loader.rb +31 -0
- data/lib/manifests/manifests.rb +344 -0
- data/lib/manifests/plugin.rb +140 -0
- data/lib/micro/README.md +9 -0
- data/lib/micro/errors.rb +4 -0
- data/lib/{jdc → micro}/micro.rb +15 -15
- data/lib/micro/plugin.rb +197 -0
- data/lib/micro/switcher/base.rb +79 -0
- data/lib/{jdc/micro → micro}/switcher/darwin.rb +5 -3
- data/lib/{jdc/micro → micro}/switcher/dummy.rb +1 -1
- data/lib/micro/switcher/linux.rb +16 -0
- data/lib/{jdc/micro → micro}/switcher/windows.rb +5 -5
- data/lib/{jdc/micro → micro}/vmrun.rb +26 -19
- data/lib/tasks/gem_release.rake +42 -0
- data/lib/tunnel/README.md +29 -0
- data/{config → lib/tunnel/config}/clients.yml +2 -2
- data/lib/tunnel/helper-app/Gemfile +10 -0
- data/lib/tunnel/helper-app/Gemfile.lock +48 -0
- data/{caldecott_helper → lib/tunnel/helper-app}/server.rb +5 -5
- data/lib/tunnel/plugin.rb +183 -0
- data/lib/tunnel/tunnel.rb +295 -0
- metadata +319 -89
- data/README.md +0 -102
- data/config/micro/paths.yml +0 -22
- data/config/micro/refresh_ip.rb +0 -20
- data/lib/cli/commands/admin.rb +0 -58
- data/lib/cli/commands/apps.rb +0 -1129
- data/lib/cli/commands/base.rb +0 -228
- data/lib/cli/commands/manifest.rb +0 -56
- data/lib/cli/commands/micro.rb +0 -115
- data/lib/cli/commands/misc.rb +0 -126
- data/lib/cli/commands/services.rb +0 -178
- data/lib/cli/commands/user.rb +0 -14
- data/lib/cli/config.rb +0 -173
- data/lib/cli/console_helper.rb +0 -170
- data/lib/cli/core_ext.rb +0 -122
- data/lib/cli/errors.rb +0 -19
- data/lib/cli/frameworks.rb +0 -265
- data/lib/cli/manifest_helper.rb +0 -302
- data/lib/cli/runner.rb +0 -505
- data/lib/cli/services_helper.rb +0 -84
- data/lib/cli/tunnel_helper.rb +0 -332
- data/lib/cli/usage.rb +0 -86
- data/lib/cli/version.rb +0 -7
- data/lib/cli/zip_util.rb +0 -77
- data/lib/cli.rb +0 -53
- data/lib/jdc/client.rb +0 -457
- data/lib/jdc/const.rb +0 -25
- data/lib/jdc/micro/switcher/base.rb +0 -97
- data/lib/jdc/micro/switcher/linux.rb +0 -16
- data/lib/jdc/signature/version.rb +0 -27
- data/lib/jdc/signer.rb +0 -13
- data/lib/jdc/timer.rb +0 -12
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
module JDC
|
|
2
|
+
module Populators
|
|
3
|
+
module PopulatorMethods
|
|
4
|
+
def self.included(klass)
|
|
5
|
+
klass.class_eval do
|
|
6
|
+
define_method(:type) do
|
|
7
|
+
klass.name.split("::").last.downcase.to_sym
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def populate_and_save!
|
|
13
|
+
obj = get_object
|
|
14
|
+
info[type] = obj.guid unless obj.nil?
|
|
15
|
+
save_target_info(info)
|
|
16
|
+
invalidate_client
|
|
17
|
+
|
|
18
|
+
obj
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def get_object
|
|
24
|
+
previous_object = client.send(type, (info[type])) if info[type]
|
|
25
|
+
|
|
26
|
+
if input.has?(type)
|
|
27
|
+
if respond_to?(:finder_argument, true)
|
|
28
|
+
object = input[type, finder_argument]
|
|
29
|
+
else
|
|
30
|
+
object = input[type]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
with_progress("Switching to #{type} #{c(object.name, :name)}") {}
|
|
34
|
+
elsif info[type]
|
|
35
|
+
object = previous_object if valid?(previous_object)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
object ||= prompt_user
|
|
39
|
+
|
|
40
|
+
if (previous_object != object) && respond_to?(:changed, true)
|
|
41
|
+
changed
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
object
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def prompt_user
|
|
48
|
+
object_choices = choices
|
|
49
|
+
|
|
50
|
+
if object_choices.empty?
|
|
51
|
+
with_progress("There are no #{type}s. You may want to create one with #{c("create-#{type == :organization ? "org" : type}", :good)}.") {}
|
|
52
|
+
elsif object_choices.is_a?(String)
|
|
53
|
+
raise JDC::UserFriendlyError.new(object_choices)
|
|
54
|
+
elsif object_choices.size == 1 && !input.interactive?(type)
|
|
55
|
+
object_choices.first
|
|
56
|
+
else
|
|
57
|
+
ask(type.to_s.capitalize, :choices => object_choices.sort_by(&:name), :display => proc(&:name)).tap do |object|
|
|
58
|
+
with_progress("Switching to #{type} #{c(object.name, :name)}") {}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "jdc/cli/populators/base"
|
|
2
|
+
require "jdc/cli/populators/populator_methods"
|
|
3
|
+
|
|
4
|
+
module JDC
|
|
5
|
+
module Populators
|
|
6
|
+
class Space < Base
|
|
7
|
+
attr_reader :organization
|
|
8
|
+
include PopulatorMethods
|
|
9
|
+
|
|
10
|
+
def initialize(input, organization)
|
|
11
|
+
super(input)
|
|
12
|
+
@organization = organization
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
def valid?(space)
|
|
18
|
+
return false unless space.guid
|
|
19
|
+
space.developers.include? client.current_user
|
|
20
|
+
rescue JFoundry::APIError
|
|
21
|
+
false
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def choices
|
|
25
|
+
organization.spaces(:depth => 0)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def finder_argument
|
|
29
|
+
organization
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require "jdc/cli/populators/organization"
|
|
2
|
+
require "jdc/cli/populators/space"
|
|
3
|
+
|
|
4
|
+
module JDC
|
|
5
|
+
module Populators
|
|
6
|
+
class Target < Base
|
|
7
|
+
def populate_and_save!
|
|
8
|
+
organization = JDC::Populators::Organization.new(input).populate_and_save!
|
|
9
|
+
JDC::Populators::Space.new(input, organization).populate_and_save!
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "jdc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module JDC::Route
|
|
4
|
+
class Delete < Base
|
|
5
|
+
desc "Delete a route"
|
|
6
|
+
group :routes
|
|
7
|
+
input :route, :desc => "Route to unmap", :argument => true,
|
|
8
|
+
:from_given => find_by_name("route") { client.routes }
|
|
9
|
+
input :really, :type => :boolean, :forget => true, :hidden => true,
|
|
10
|
+
:default => proc { force? || interact }
|
|
11
|
+
|
|
12
|
+
def delete_route
|
|
13
|
+
route = input[:route, client.routes]
|
|
14
|
+
|
|
15
|
+
return unless input[:really, route]
|
|
16
|
+
|
|
17
|
+
with_progress("Deleting route #{c(route.name, :name)}") do
|
|
18
|
+
route.delete!
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def ask_really(route)
|
|
25
|
+
ask("Really delete #{c(route.name, :name)}?", :default => false)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
require "jdc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module JDC::Route
|
|
4
|
+
class Map < Base
|
|
5
|
+
desc "Add a URL mapping"
|
|
6
|
+
group :apps, :info
|
|
7
|
+
input :app, :desc => "Application to add the URL to",
|
|
8
|
+
:argument => :optional, :from_given => by_name(:app)
|
|
9
|
+
input :host, :desc => "Host name for the route",
|
|
10
|
+
:argument => :optional, :default => ""
|
|
11
|
+
input :domain, :desc => "Domain to add the route to",
|
|
12
|
+
:argument => true,
|
|
13
|
+
:from_given => proc { |name, space|
|
|
14
|
+
space.domain_by_name(name) ||
|
|
15
|
+
fail_unknown("domain", name)
|
|
16
|
+
}
|
|
17
|
+
def map
|
|
18
|
+
app = input[:app]
|
|
19
|
+
space = app.space
|
|
20
|
+
|
|
21
|
+
host = input[:host]
|
|
22
|
+
domain = input[:domain, space]
|
|
23
|
+
|
|
24
|
+
route = find_or_create_route(domain, host, space)
|
|
25
|
+
|
|
26
|
+
bind_route(route, app) if app
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def bind_route(route, app)
|
|
32
|
+
with_progress("Binding #{c(route.name, :name)} to #{c(app.name, :name)}") do
|
|
33
|
+
app.add_route(route)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def find_or_create_route(domain, host, space)
|
|
38
|
+
find_route(domain, host) || create_route(domain, host, space)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def find_route(domain, host)
|
|
42
|
+
client.routes_by_host(host, :depth => 0).find { |r| r.domain == domain }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create_route(domain, host, space)
|
|
46
|
+
route = client.route
|
|
47
|
+
route.host = host
|
|
48
|
+
route.domain = domain
|
|
49
|
+
route.space = space
|
|
50
|
+
|
|
51
|
+
with_progress("Creating route #{c(route.name, :name)}") do
|
|
52
|
+
route.create!
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
route
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def find_domain(space, name)
|
|
59
|
+
domain = space.domain_by_name(name, :depth => 0)
|
|
60
|
+
fail "Invalid domain '#{name}'" unless domain
|
|
61
|
+
domain
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def ask_app
|
|
65
|
+
ask("Which application?", :choices => client.apps, :display => proc(&:name))
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require "jdc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module JDC::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
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
require "jdc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module JDC::Route
|
|
4
|
+
class Unmap < Base
|
|
5
|
+
desc "Remove a URL mapping"
|
|
6
|
+
group :apps, :info
|
|
7
|
+
input :url, :desc => "URL to unmap", :argument => :optional,
|
|
8
|
+
:from_given => find_by_name("route") { client.routes }
|
|
9
|
+
input :app, :desc => "Application to remove the URL from",
|
|
10
|
+
:argument => :optional, :from_given => by_name(:app)
|
|
11
|
+
input :all, :desc => "Act on all routes", :type => :boolean
|
|
12
|
+
input :really, :type => :boolean, :forget => true, :hidden => true,
|
|
13
|
+
:default => proc { force? || interact }
|
|
14
|
+
|
|
15
|
+
def unmap
|
|
16
|
+
if input[:all]
|
|
17
|
+
if input.has?(:app)
|
|
18
|
+
app = target = input[:app]
|
|
19
|
+
else
|
|
20
|
+
target = client
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
target.routes.each do |r|
|
|
24
|
+
begin
|
|
25
|
+
invoke :unmap, :url => r, :really => true, :app => app
|
|
26
|
+
rescue JFoundry::APIError => e
|
|
27
|
+
err "#{e.class}: #{e.message}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
return
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
app = input[:app]
|
|
35
|
+
url = input[:url, app ? app.routes : client.routes]
|
|
36
|
+
|
|
37
|
+
if app
|
|
38
|
+
with_progress("Unbinding #{c(url.name, :name)} from #{c(app.name, :name)}") do
|
|
39
|
+
app.remove_route(url)
|
|
40
|
+
end
|
|
41
|
+
else
|
|
42
|
+
fail "Missing --app."
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def ask_url(choices)
|
|
49
|
+
ask("Which URL?", :choices => choices.sort_by(&:name), :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
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "jdc/cli/service/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::Service
|
|
4
|
+
class Bind < Base
|
|
5
|
+
desc "Bind a service to an application"
|
|
6
|
+
group :services, :manage
|
|
7
|
+
input :service, :desc => "Service to bind", :argument => :optional,
|
|
8
|
+
:from_given => by_name(:service_instance, "service")
|
|
9
|
+
input :app, :desc => "Application to bind to", :argument => :optional,
|
|
10
|
+
:from_given => by_name(:app)
|
|
11
|
+
def bind_service
|
|
12
|
+
app = input[:app]
|
|
13
|
+
service = input[:service, app]
|
|
14
|
+
finalize
|
|
15
|
+
|
|
16
|
+
with_progress(
|
|
17
|
+
"Binding #{c(service.name, :name)} to #{c(app.name, :name)}") do |s|
|
|
18
|
+
if app.binds?(service)
|
|
19
|
+
s.skip do
|
|
20
|
+
err "App #{b(app.name)} already binds #{b(service.name)}."
|
|
21
|
+
end
|
|
22
|
+
else
|
|
23
|
+
app.bind(service)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def ask_service(app)
|
|
31
|
+
services = client.service_instances
|
|
32
|
+
fail "No services." if services.empty?
|
|
33
|
+
|
|
34
|
+
ask "Which service?", :choices => services - app.services,
|
|
35
|
+
:display => proc(&:name)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def ask_app
|
|
39
|
+
ask "Which application?", :choices => client.apps,
|
|
40
|
+
:display => proc(&:name)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
=end
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
require "jdc/cli/service/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::Service
|
|
4
|
+
USER_PROVIDED_OFFERING = "user-provided" # I'd rather move this to JFoundry
|
|
5
|
+
|
|
6
|
+
class UPDummy
|
|
7
|
+
def label
|
|
8
|
+
"user-provided"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
attr_reader :version, :provider
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
class Create < Base
|
|
15
|
+
offerings_from_label = proc { |label, offerings|
|
|
16
|
+
offerings.select { |s| s.label == label }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
desc "Create a service"
|
|
20
|
+
group :services, :manage
|
|
21
|
+
input :offering, :desc => "What kind of service (e.g. redis, mysql)",
|
|
22
|
+
:argument => :optional, :from_given => offerings_from_label
|
|
23
|
+
input :name, :desc => "Name for your service", :argument => :optional
|
|
24
|
+
input :plan, :desc => "Service plan",
|
|
25
|
+
:from_given => find_by_name_insensitive("plan"),
|
|
26
|
+
:default => proc {
|
|
27
|
+
interact
|
|
28
|
+
}
|
|
29
|
+
input :provider, :desc => "Service provider"
|
|
30
|
+
input :version, :desc => "Service version"
|
|
31
|
+
input :app, :desc => "Application to immediately bind to",
|
|
32
|
+
:alias => "--bind", :from_given => by_name(:app)
|
|
33
|
+
|
|
34
|
+
def create_service
|
|
35
|
+
offerings = client.services
|
|
36
|
+
|
|
37
|
+
if input[:provider]
|
|
38
|
+
offerings.reject! { |s| s.provider != input[:provider] }
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if input[:version]
|
|
42
|
+
offerings.reject! { |s| s.version != input[:version] }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# filter the offerings based on a given plan value, which will be a
|
|
46
|
+
# string if the user provided it with a flag, or a ServicePlan if
|
|
47
|
+
# something invoked this command with a particular plan
|
|
48
|
+
if plan = input.direct(:plan)
|
|
49
|
+
offerings.reject! do |s|
|
|
50
|
+
if plan.is_a?(String)
|
|
51
|
+
s.service_plans.none? { |p| p.name.casecmp(plan) == 0 }
|
|
52
|
+
else
|
|
53
|
+
!s.service_plans.include? plan
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
finalize
|
|
58
|
+
|
|
59
|
+
offerings << UPDummy.new
|
|
60
|
+
|
|
61
|
+
selected_offerings = offerings.any? ? Array(input[:offering, offerings.sort_by(&:label)]) : []
|
|
62
|
+
finalize
|
|
63
|
+
|
|
64
|
+
if selected_offerings.empty?
|
|
65
|
+
fail "Cannot find services matching the given criteria."
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
offering = selected_offerings.first
|
|
69
|
+
|
|
70
|
+
if offering.label == JDC::Service::USER_PROVIDED_OFFERING
|
|
71
|
+
service_instance = client.user_provided_service_instance
|
|
72
|
+
service_instance.name = input[:name, offering]
|
|
73
|
+
finalize
|
|
74
|
+
|
|
75
|
+
# at this point there's no way input[:credentials] can work interactively...
|
|
76
|
+
service_instance.credentials = input[:credentials, nil] || ask_credentials
|
|
77
|
+
else
|
|
78
|
+
service_instance = client.managed_service_instance
|
|
79
|
+
service_instance.name = input[:name, offering]
|
|
80
|
+
finalize
|
|
81
|
+
|
|
82
|
+
plan = input[:plan, offering.service_plans]
|
|
83
|
+
finalize
|
|
84
|
+
service_instance.service_plan = if plan.is_a?(String)
|
|
85
|
+
offering.service_plans.find { |p| p.name.casecmp(plan) == 0 }
|
|
86
|
+
else
|
|
87
|
+
plan
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
service_instance.space = client.current_space
|
|
92
|
+
|
|
93
|
+
with_progress("Creating service #{c(service_instance.name, :name)}") do
|
|
94
|
+
service_instance.create!
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
app = input[:app]
|
|
98
|
+
finalize
|
|
99
|
+
|
|
100
|
+
if app
|
|
101
|
+
invoke :bind_service, :service => service_instance, :app => app
|
|
102
|
+
end
|
|
103
|
+
service_instance
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
private
|
|
107
|
+
|
|
108
|
+
def ask_credentials
|
|
109
|
+
credentials = {}
|
|
110
|
+
|
|
111
|
+
while keys = ask("What credential parameters should applications use to connect to this service instance?\n(e.g. hostname, port, password)").split(/\s*,\s*/).map(&:strip)
|
|
112
|
+
if bad_key = keys.detect { |key| key !~ /^[-\w]+$/ }
|
|
113
|
+
line("'#{bad_key}' is not a valid key")
|
|
114
|
+
else
|
|
115
|
+
break
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
finalize
|
|
119
|
+
keys.each do |key|
|
|
120
|
+
value = ask(key)
|
|
121
|
+
finalize
|
|
122
|
+
credentials[key] = value
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
credentials
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def ask_offering(offerings)
|
|
129
|
+
[ask("What kind?", :choices => offerings.sort_by(&:label),
|
|
130
|
+
:display => proc do |s|
|
|
131
|
+
str = "#{c(s.label, :name)} #{s.version}"
|
|
132
|
+
if s.provider != "core"
|
|
133
|
+
str << ", via #{s.provider}"
|
|
134
|
+
end
|
|
135
|
+
str
|
|
136
|
+
end,
|
|
137
|
+
:complete => proc { |s| "#{s.label} #{s.version}" })]
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def ask_name(offering)
|
|
141
|
+
default = nil
|
|
142
|
+
unless offering == JDC::Service::USER_PROVIDED_OFFERING
|
|
143
|
+
random = sprintf("%x", rand(1000000))
|
|
144
|
+
default = "#{offering.label}-#{random}"
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
ask "Name?", :default => default
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
def ask_plan(plans)
|
|
151
|
+
ask "Which plan?",
|
|
152
|
+
:choices => plans.sort_by(&:name),
|
|
153
|
+
:indexed => true,
|
|
154
|
+
:display => proc { |p| "#{p.name}: #{p.description || 'No description'}" },
|
|
155
|
+
:complete => proc(&:name)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
=end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require "jdc/cli/service/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::Service
|
|
4
|
+
class Delete < Base
|
|
5
|
+
desc "Delete a service"
|
|
6
|
+
group :services, :manage
|
|
7
|
+
input :service, :desc => "Service to delete", :argument => :optional,
|
|
8
|
+
:from_given => by_name(:service_instance, :service)
|
|
9
|
+
input :unbind, :desc => "Unbind from applications before deleting?",
|
|
10
|
+
:type => :boolean, :default => proc { force? || interact }
|
|
11
|
+
input :all, :desc => "Delete all services", :default => false
|
|
12
|
+
input :really, :type => :boolean, :forget => true, :hidden => true,
|
|
13
|
+
:default => proc { force? || interact }
|
|
14
|
+
def delete_service
|
|
15
|
+
if input[:all]
|
|
16
|
+
return unless input[:really, "ALL SERVICES", :bad]
|
|
17
|
+
|
|
18
|
+
client.service_instances.each do |i|
|
|
19
|
+
invoke :delete_service, :service => i, :really => true
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
return
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
service = input[:service]
|
|
26
|
+
|
|
27
|
+
return unless input[:really, service.name, :name]
|
|
28
|
+
|
|
29
|
+
bindings = service.service_bindings
|
|
30
|
+
|
|
31
|
+
unless bindings.empty? || !input[:unbind, bindings.collect(&:app)]
|
|
32
|
+
bindings.each do |b|
|
|
33
|
+
invoke :unbind_service, :service => service, :app => b.app
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
bindings = []
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
with_progress("Deleting #{c(service.name, :name)}") do |s|
|
|
40
|
+
if bindings.empty?
|
|
41
|
+
service.delete!
|
|
42
|
+
else
|
|
43
|
+
s.skip do
|
|
44
|
+
apps = bindings.collect(&:app).collect { |a| b(a.name) }
|
|
45
|
+
err "Service is bound to #{human_list(apps)}."
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def ask_service
|
|
54
|
+
services = client.service_instances
|
|
55
|
+
fail "No services." if services.empty?
|
|
56
|
+
|
|
57
|
+
ask "Which service?", :choices => services,
|
|
58
|
+
:display => proc(&:name)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def ask_unbind(apps)
|
|
62
|
+
names = human_list(apps.collect { |a| c(a.name, :name) })
|
|
63
|
+
|
|
64
|
+
ask("Unbind from #{names} before deleting?", :default => true)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def ask_really(name, color)
|
|
68
|
+
ask("Really delete #{c(name, color)}?", :default => false)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def human_list(xs)
|
|
72
|
+
if xs.size == 1
|
|
73
|
+
xs.first
|
|
74
|
+
elsif xs.size == 2
|
|
75
|
+
"#{xs.first} and #{xs.last}"
|
|
76
|
+
else
|
|
77
|
+
last = xs.pop
|
|
78
|
+
xs.join(", ") + ", and #{last}"
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
=end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require "jdc/cli/service/base"
|
|
2
|
+
=begin
|
|
3
|
+
module JDC::Service
|
|
4
|
+
class Rename < Base
|
|
5
|
+
desc "Rename a service"
|
|
6
|
+
group :services, :manage
|
|
7
|
+
input :service, :desc => "Service to rename", :argument => :optional,
|
|
8
|
+
:from_given => by_name(:service_instance, :service)
|
|
9
|
+
input :name, :desc => "New service name", :argument => :optional
|
|
10
|
+
def rename_service
|
|
11
|
+
service = input[:service]
|
|
12
|
+
name = input[:name]
|
|
13
|
+
|
|
14
|
+
service.name = name
|
|
15
|
+
|
|
16
|
+
with_progress("Renaming to #{c(name, :name)}") do
|
|
17
|
+
service.update!
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def ask_service
|
|
24
|
+
services = client.service_instances
|
|
25
|
+
fail "No services." if services.empty?
|
|
26
|
+
|
|
27
|
+
ask("Rename which service?", :choices => services.sort_by(&:name),
|
|
28
|
+
:display => proc(&:name))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def ask_name
|
|
32
|
+
ask("New name")
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
=end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
require "jdc/cli/service/base"
|
|
2
|
+
|
|
3
|
+
=begin
|
|
4
|
+
module JDC::Service
|
|
5
|
+
class Service < Base
|
|
6
|
+
desc "Show service information"
|
|
7
|
+
group :services
|
|
8
|
+
input :service, :desc => "Service to show", :argument => :required,
|
|
9
|
+
:from_given => by_name(:service_instance, :service)
|
|
10
|
+
def service
|
|
11
|
+
display_service(input[:service])
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def display_service(i)
|
|
17
|
+
if quiet?
|
|
18
|
+
line i.name
|
|
19
|
+
else
|
|
20
|
+
plan = i.service_plan
|
|
21
|
+
service = plan.service
|
|
22
|
+
|
|
23
|
+
apps = i.service_bindings.collect { |b|
|
|
24
|
+
c(b.app.name, :name)
|
|
25
|
+
}.join(", ")
|
|
26
|
+
|
|
27
|
+
line "#{c(i.name, :name)}: #{service.label} #{service.version}"
|
|
28
|
+
|
|
29
|
+
indented do
|
|
30
|
+
line "provider: #{c(service.provider, :name)}"
|
|
31
|
+
line "bound to: #{apps}" unless apps.empty?
|
|
32
|
+
line "plan: #{c(plan.name, :name)}"
|
|
33
|
+
|
|
34
|
+
indented do
|
|
35
|
+
line "description: #{plan.description}"
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
=end
|