cloulu 0.0.0 → 0.1.1
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/bin/{cloulu → cl} +0 -0
- data/lib/cc_api_stub/applications.rb +53 -0
- data/lib/cc_api_stub/domains.rb +16 -0
- data/lib/cc_api_stub/frameworks.rb +22 -0
- data/lib/cc_api_stub/helper.rb +131 -0
- data/lib/cc_api_stub/login.rb +21 -0
- data/lib/cc_api_stub/organization_users.rb +21 -0
- data/lib/cc_api_stub/organizations.rb +70 -0
- data/lib/cc_api_stub/routes.rb +26 -0
- data/lib/cc_api_stub/runtimes.rb +22 -0
- data/lib/cc_api_stub/service_bindings.rb +22 -0
- data/lib/cc_api_stub/service_instances.rb +22 -0
- data/lib/cc_api_stub/services.rb +25 -0
- data/lib/cc_api_stub/spaces.rb +49 -0
- data/lib/cc_api_stub/users.rb +84 -0
- data/lib/cc_api_stub.rb +17 -0
- data/lib/cfoundry/auth_token.rb +63 -0
- data/lib/cfoundry/baseclient.rb +201 -0
- data/lib/cfoundry/chatty_hash.rb +46 -0
- data/lib/cfoundry/client.rb +46 -0
- data/lib/cfoundry/concerns/login_helpers.rb +13 -0
- data/lib/cfoundry/errors.rb +160 -0
- data/lib/cfoundry/rest_client.rb +299 -0
- data/lib/cfoundry/test_support.rb +3 -0
- data/lib/cfoundry/trace_helpers.rb +40 -0
- data/lib/cfoundry/uaaclient.rb +112 -0
- data/lib/cfoundry/upload_helpers.rb +187 -0
- data/lib/cfoundry/v1/app.rb +363 -0
- data/lib/cfoundry/v1/base.rb +72 -0
- data/lib/cfoundry/v1/client.rb +193 -0
- data/lib/cfoundry/v1/framework.rb +21 -0
- data/lib/cfoundry/v1/model.rb +178 -0
- data/lib/cfoundry/v1/model_magic.rb +129 -0
- data/lib/cfoundry/v1/runtime.rb +24 -0
- data/lib/cfoundry/v1/service.rb +39 -0
- data/lib/cfoundry/v1/service_instance.rb +32 -0
- data/lib/cfoundry/v1/service_plan.rb +19 -0
- data/lib/cfoundry/v1/user.rb +22 -0
- data/lib/cfoundry/v2/app.rb +392 -0
- data/lib/cfoundry/v2/base.rb +83 -0
- data/lib/cfoundry/v2/client.rb +138 -0
- data/lib/cfoundry/v2/domain.rb +11 -0
- data/lib/cfoundry/v2/framework.rb +14 -0
- data/lib/cfoundry/v2/model.rb +148 -0
- data/lib/cfoundry/v2/model_magic.rb +449 -0
- data/lib/cfoundry/v2/organization.rb +16 -0
- data/lib/cfoundry/v2/route.rb +15 -0
- data/lib/cfoundry/v2/runtime.rb +12 -0
- data/lib/cfoundry/v2/service.rb +19 -0
- data/lib/cfoundry/v2/service_auth_token.rb +9 -0
- data/lib/cfoundry/v2/service_binding.rb +10 -0
- data/lib/cfoundry/v2/service_instance.rb +14 -0
- data/lib/cfoundry/v2/service_plan.rb +12 -0
- data/lib/cfoundry/v2/space.rb +18 -0
- data/lib/cfoundry/v2/user.rb +64 -0
- data/lib/cfoundry/validator.rb +39 -0
- data/lib/cfoundry/version.rb +4 -0
- data/lib/cfoundry/zip.rb +56 -0
- data/lib/cfoundry.rb +2 -0
- data/lib/manifests-vmc-plugin/errors.rb +21 -0
- data/lib/manifests-vmc-plugin/loader/builder.rb +34 -0
- data/lib/manifests-vmc-plugin/loader/normalizer.rb +149 -0
- data/lib/manifests-vmc-plugin/loader/resolver.rb +79 -0
- data/lib/manifests-vmc-plugin/loader.rb +31 -0
- data/lib/manifests-vmc-plugin/plugin.rb +145 -0
- data/lib/manifests-vmc-plugin/version.rb +3 -0
- data/lib/manifests-vmc-plugin.rb +313 -0
- data/lib/mothership/base.rb +99 -0
- data/lib/mothership/callbacks.rb +85 -0
- data/lib/mothership/command.rb +146 -0
- data/lib/mothership/errors.rb +38 -0
- data/lib/mothership/help/commands.rb +53 -0
- data/lib/mothership/help/printer.rb +170 -0
- data/lib/mothership/help.rb +64 -0
- data/lib/mothership/inputs.rb +189 -0
- data/lib/mothership/parser.rb +182 -0
- data/lib/mothership/version.rb +3 -0
- data/lib/mothership.rb +64 -0
- data/lib/tunnel-vmc-plugin/plugin.rb +178 -0
- data/lib/tunnel-vmc-plugin/tunnel.rb +308 -0
- data/lib/tunnel-vmc-plugin/version.rb +3 -0
- data/lib/uaa/http.rb +168 -0
- data/lib/uaa/misc.rb +121 -0
- data/lib/uaa/scim.rb +292 -0
- data/lib/uaa/token_coder.rb +196 -0
- data/lib/uaa/token_issuer.rb +255 -0
- data/lib/uaa/util.rb +235 -0
- data/lib/uaa/version.rb +19 -0
- data/lib/uaa.rb +18 -0
- data/lib/vmc/cli/app/app.rb +45 -0
- data/lib/vmc/cli/app/apps.rb +99 -0
- data/lib/vmc/cli/app/base.rb +90 -0
- data/lib/vmc/cli/app/crashes.rb +42 -0
- data/lib/vmc/cli/app/delete.rb +95 -0
- data/lib/vmc/cli/app/deprecated.rb +11 -0
- data/lib/vmc/cli/app/env.rb +78 -0
- data/lib/vmc/cli/app/files.rb +137 -0
- data/lib/vmc/cli/app/health.rb +26 -0
- data/lib/vmc/cli/app/instances.rb +53 -0
- data/lib/vmc/cli/app/logs.rb +76 -0
- data/lib/vmc/cli/app/push/create.rb +165 -0
- data/lib/vmc/cli/app/push/interactions.rb +94 -0
- data/lib/vmc/cli/app/push/sync.rb +64 -0
- data/lib/vmc/cli/app/push.rb +109 -0
- data/lib/vmc/cli/app/rename.rb +35 -0
- data/lib/vmc/cli/app/restart.rb +20 -0
- data/lib/vmc/cli/app/scale.rb +71 -0
- data/lib/vmc/cli/app/start.rb +143 -0
- data/lib/vmc/cli/app/stats.rb +67 -0
- data/lib/vmc/cli/app/stop.rb +27 -0
- data/lib/vmc/cli/help.rb +11 -0
- data/lib/vmc/cli/interactive.rb +105 -0
- data/lib/vmc/cli/route/base.rb +12 -0
- data/lib/vmc/cli/route/map.rb +82 -0
- data/lib/vmc/cli/route/routes.rb +25 -0
- data/lib/vmc/cli/route/unmap.rb +94 -0
- data/lib/vmc/cli/service/base.rb +8 -0
- data/lib/vmc/cli/service/bind.rb +44 -0
- data/lib/vmc/cli/service/create.rb +126 -0
- data/lib/vmc/cli/service/delete.rb +86 -0
- data/lib/vmc/cli/service/rename.rb +35 -0
- data/lib/vmc/cli/service/service.rb +42 -0
- data/lib/vmc/cli/service/services.rb +114 -0
- data/lib/vmc/cli/service/unbind.rb +38 -0
- data/lib/vmc/cli/start/base.rb +94 -0
- data/lib/vmc/cli/start/colors.rb +13 -0
- data/lib/vmc/cli/start/info.rb +126 -0
- data/lib/vmc/cli/start/login.rb +97 -0
- data/lib/vmc/cli/start/logout.rb +17 -0
- data/lib/vmc/cli/start/target.rb +60 -0
- data/lib/vmc/cli/start/target_interactions.rb +37 -0
- data/lib/vmc/cli/start/targets.rb +16 -0
- data/lib/vmc/cli/user/base.rb +29 -0
- data/lib/vmc/cli/user/create.rb +39 -0
- data/lib/vmc/cli/user/delete.rb +27 -0
- data/lib/vmc/cli/user/passwd.rb +50 -0
- data/lib/vmc/cli/user/register.rb +42 -0
- data/lib/vmc/cli/user/users.rb +32 -0
- data/lib/vmc/cli/v2_check_cli.rb +16 -0
- data/lib/vmc/cli.rb +474 -0
- data/lib/vmc/constants.rb +13 -0
- data/lib/vmc/detect.rb +129 -0
- data/lib/vmc/errors.rb +19 -0
- data/lib/vmc/plugin.rb +56 -0
- data/lib/vmc/spacing.rb +89 -0
- data/lib/vmc/spec_helper.rb +1 -0
- data/lib/vmc/test_support.rb +6 -0
- data/lib/vmc/version.rb +3 -0
- data/lib/vmc.rb +8 -0
- data/vendor/errors/v1.yml +189 -0
- data/vendor/errors/v2.yml +360 -0
- metadata +303 -190
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
require "vmc/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module VMC::App
|
|
4
|
+
class Start < Base
|
|
5
|
+
APP_CHECK_LIMIT = 60
|
|
6
|
+
|
|
7
|
+
desc "Start an application"
|
|
8
|
+
group :apps, :manage
|
|
9
|
+
input :apps, :desc => "Applications to start", :argument => :splat,
|
|
10
|
+
:singular => :app, :from_given => by_name(:app)
|
|
11
|
+
input :debug_mode, :desc => "Debug mode to start in", :aliases => "-d"
|
|
12
|
+
input :all, :desc => "Start all applications", :default => false
|
|
13
|
+
def start
|
|
14
|
+
apps = input[:all] ? client.apps : input[:apps]
|
|
15
|
+
fail "No applications given." if apps.empty?
|
|
16
|
+
|
|
17
|
+
spaced(apps) do |app|
|
|
18
|
+
app = filter(:start_app, app)
|
|
19
|
+
|
|
20
|
+
switch_mode(app, input[:debug_mode])
|
|
21
|
+
|
|
22
|
+
if app.started?
|
|
23
|
+
err "Application #{b(app.name)} is already started."
|
|
24
|
+
next
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
log = start_app(app)
|
|
28
|
+
stream_start_log(log) if log
|
|
29
|
+
check_application(app)
|
|
30
|
+
|
|
31
|
+
if app.debug_mode && !quiet?
|
|
32
|
+
line
|
|
33
|
+
invoke :instances, :app => app
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def start_app(app)
|
|
41
|
+
log = nil
|
|
42
|
+
with_progress("Starting #{c(app.name, :name)}") do
|
|
43
|
+
app.start!(true) do |url|
|
|
44
|
+
log = url
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
log
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def stream_start_log(log)
|
|
51
|
+
offset = 0
|
|
52
|
+
|
|
53
|
+
while true
|
|
54
|
+
begin
|
|
55
|
+
client.stream_url(log + "&tail&tail_offset=#{offset}") do |out|
|
|
56
|
+
offset += out.size
|
|
57
|
+
print out
|
|
58
|
+
end
|
|
59
|
+
rescue Timeout::Error
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
rescue CFoundry::APIError
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# set app debug mode, ensuring it's valid, and shutting it down
|
|
66
|
+
def switch_mode(app, mode)
|
|
67
|
+
mode = nil if mode == "none"
|
|
68
|
+
mode = "run" if mode == "" # no value given
|
|
69
|
+
|
|
70
|
+
return false if app.debug == mode
|
|
71
|
+
|
|
72
|
+
if mode.nil?
|
|
73
|
+
with_progress("Removing debug mode") do
|
|
74
|
+
app.debug = nil
|
|
75
|
+
app.stop! if app.started?
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
return true
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
with_progress("Switching mode to #{c(mode, :name)}") do |s|
|
|
82
|
+
app.debug = mode
|
|
83
|
+
app.stop! if app.started?
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def check_application(app)
|
|
88
|
+
if app.debug == "suspend"
|
|
89
|
+
line "Application is in suspended debugging mode."
|
|
90
|
+
line "It will wait for you to attach to it before starting."
|
|
91
|
+
return
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
line "Checking #{c(app.name, :name)}..."
|
|
95
|
+
|
|
96
|
+
seconds = 0
|
|
97
|
+
while instances = app.instances
|
|
98
|
+
indented { print_instances_summary(instances) }
|
|
99
|
+
|
|
100
|
+
if all_instances_running?(instances)
|
|
101
|
+
line "#{c("OK", :good)}"
|
|
102
|
+
return
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if any_instance_flapping?(instances) || seconds == APP_CHECK_LIMIT
|
|
106
|
+
err "Application failed to start."
|
|
107
|
+
return
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
sleep 1
|
|
111
|
+
seconds += 1
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def all_instances_running?(instances)
|
|
116
|
+
instances.all? { |i| i.state == "RUNNING" }
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def any_instance_flapping?(instances)
|
|
120
|
+
instances.any? { |i| i.state == "FLAPPING" }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def print_instances_summary(instances)
|
|
124
|
+
counts = Hash.new { 0 }
|
|
125
|
+
instances.each do |i|
|
|
126
|
+
counts[i.state] += 1
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
states = []
|
|
130
|
+
%w{RUNNING STARTING DOWN FLAPPING}.each do |state|
|
|
131
|
+
if (num = counts[state]) > 0
|
|
132
|
+
states << "#{b(num)} #{c(state.downcase, state_color(state))}"
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
total = instances.count
|
|
137
|
+
running = counts["RUNNING"].to_s.rjust(total.to_s.size)
|
|
138
|
+
|
|
139
|
+
ratio = "#{running}#{d("/")}#{total} instances:"
|
|
140
|
+
line "#{ratio} #{states.join(", ")}"
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require "vmc/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module VMC::App
|
|
4
|
+
class Stats < Base
|
|
5
|
+
desc "Display application instance status"
|
|
6
|
+
group :apps, :info
|
|
7
|
+
input :app, :desc => "Application to get the stats for",
|
|
8
|
+
:argument => true, :from_given => by_name(:app)
|
|
9
|
+
def stats
|
|
10
|
+
app = input[:app]
|
|
11
|
+
|
|
12
|
+
stats =
|
|
13
|
+
with_progress("Getting stats for #{c(app.name, :name)}") do |s|
|
|
14
|
+
begin
|
|
15
|
+
app.stats
|
|
16
|
+
rescue CFoundry::StatsError
|
|
17
|
+
s.fail do
|
|
18
|
+
err "Application #{b(app.name)} is not running."
|
|
19
|
+
return
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
line unless quiet?
|
|
25
|
+
|
|
26
|
+
table(
|
|
27
|
+
%w{instance cpu memory disk},
|
|
28
|
+
stats.sort_by { |idx, _| idx.to_i }.collect { |idx, info|
|
|
29
|
+
idx = c("\##{idx}", :instance)
|
|
30
|
+
|
|
31
|
+
if info[:state] == "DOWN"
|
|
32
|
+
[idx, c("down", :bad)]
|
|
33
|
+
else
|
|
34
|
+
stats = info[:stats]
|
|
35
|
+
usage = stats[:usage]
|
|
36
|
+
|
|
37
|
+
if usage
|
|
38
|
+
[ idx,
|
|
39
|
+
"#{percentage(usage[:cpu])}",
|
|
40
|
+
"#{usage(usage[:mem], stats[:mem_quota])}",
|
|
41
|
+
"#{usage(usage[:disk], stats[:disk_quota])}"
|
|
42
|
+
]
|
|
43
|
+
else
|
|
44
|
+
[idx, c("n/a", :neutral)]
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
})
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def percentage(num, low = 50, mid = 70)
|
|
51
|
+
color =
|
|
52
|
+
if num <= low
|
|
53
|
+
:good
|
|
54
|
+
elsif num <= mid
|
|
55
|
+
:warning
|
|
56
|
+
else
|
|
57
|
+
:bad
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
c(format("%.1f\%", num), color)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def usage(used, limit)
|
|
64
|
+
"#{b(human_size(used))} of #{b(human_size(limit, 0))}"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require "vmc/cli/app/base"
|
|
2
|
+
|
|
3
|
+
module VMC::App
|
|
4
|
+
class Stop < Base
|
|
5
|
+
desc "Stop an application"
|
|
6
|
+
group :apps, :manage
|
|
7
|
+
input :apps, :desc => "Applications to start", :argument => :splat,
|
|
8
|
+
:singular => :app, :from_given => by_name(:app)
|
|
9
|
+
input :all, :desc => "Stop all applications", :default => false
|
|
10
|
+
def stop
|
|
11
|
+
apps = input[:all] ? client.apps : input[:apps]
|
|
12
|
+
fail "No applications given." if apps.empty?
|
|
13
|
+
|
|
14
|
+
apps.each do |app|
|
|
15
|
+
with_progress("Stopping #{c(app.name, :name)}") do |s|
|
|
16
|
+
if app.stopped?
|
|
17
|
+
s.skip do
|
|
18
|
+
err "Application is not running."
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
app.stop!
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/vmc/cli/help.rb
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require "mothership/help"
|
|
2
|
+
|
|
3
|
+
Mothership::Help.groups(
|
|
4
|
+
[:start, "Getting Started"],
|
|
5
|
+
[:apps, "Applications",
|
|
6
|
+
[:manage, "Management"],
|
|
7
|
+
[:info, "Information"]],
|
|
8
|
+
[:services, "Services",
|
|
9
|
+
[:manage, "Management"]],
|
|
10
|
+
[:admin, "Administration",
|
|
11
|
+
[:user, "User Management"]])
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require "interact"
|
|
2
|
+
require "interact/pretty"
|
|
3
|
+
require "interact/progress"
|
|
4
|
+
|
|
5
|
+
module VMC
|
|
6
|
+
module Interactive
|
|
7
|
+
include ::Interactive::Rewindable
|
|
8
|
+
include Interact::Pretty
|
|
9
|
+
include Interact::Progress
|
|
10
|
+
|
|
11
|
+
def ask(question, options = {})
|
|
12
|
+
if force? and options.key?(:default)
|
|
13
|
+
options[:default]
|
|
14
|
+
else
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def list_choices(choices, options = {})
|
|
20
|
+
choices.each_with_index do |o, i|
|
|
21
|
+
puts "#{c(i + 1, :number)}: #{show_choice(o, options)}"
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def input_state(options)
|
|
26
|
+
if options.key? :default
|
|
27
|
+
answer = show_default(options)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
CFState.new(options, answer)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def show_default(options)
|
|
34
|
+
case options[:default]
|
|
35
|
+
when true
|
|
36
|
+
"y"
|
|
37
|
+
when false
|
|
38
|
+
"n"
|
|
39
|
+
when nil
|
|
40
|
+
""
|
|
41
|
+
else
|
|
42
|
+
show_choice(options[:default], options)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def prompt(question, options)
|
|
47
|
+
value = show_default(options)
|
|
48
|
+
|
|
49
|
+
print "#{question}"
|
|
50
|
+
print c("> ", :prompt)
|
|
51
|
+
|
|
52
|
+
unless value.empty?
|
|
53
|
+
print "#{d(value) + "\b" * value.size}"
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def handler(event, state)
|
|
58
|
+
ans = state.answer
|
|
59
|
+
pos = state.position
|
|
60
|
+
|
|
61
|
+
exit if event == :eof
|
|
62
|
+
|
|
63
|
+
if state.default?
|
|
64
|
+
if event.is_a?(Array) and event[0] == :key
|
|
65
|
+
# initial non-movement keypress clears default answer
|
|
66
|
+
clear_input(state)
|
|
67
|
+
else
|
|
68
|
+
# wipe away any coloring
|
|
69
|
+
redraw_input(state)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
state.clear_default!
|
|
73
|
+
|
|
74
|
+
# tab with a default accepts it and moves to the end
|
|
75
|
+
if event == :tab
|
|
76
|
+
state.goto(ans.size)
|
|
77
|
+
else
|
|
78
|
+
super
|
|
79
|
+
end
|
|
80
|
+
else
|
|
81
|
+
super
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
print "\n" if event == :enter
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
class CFState < ::Interactive::InputState
|
|
88
|
+
def initialize(options = {}, answer = nil, position = 0)
|
|
89
|
+
@options = options
|
|
90
|
+
@answer = answer || ""
|
|
91
|
+
@default = options.key? :default
|
|
92
|
+
@position = position
|
|
93
|
+
@done = false
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def clear_default!
|
|
97
|
+
@default = false
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def default?
|
|
101
|
+
@default
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require "vmc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module VMC::Route
|
|
4
|
+
class Map < Base
|
|
5
|
+
def precondition
|
|
6
|
+
fail_on_v2
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
desc "Add a URL mapping"
|
|
10
|
+
group :apps, :info
|
|
11
|
+
input :app, :desc => "Application to add the URL to",
|
|
12
|
+
:argument => :optional, :from_given => by_name(:app)
|
|
13
|
+
input :host, :desc => "Host name for the route",
|
|
14
|
+
:argument => :optional, :default => ""
|
|
15
|
+
input :domain, :desc => "Domain to add the route to",
|
|
16
|
+
:argument => true,
|
|
17
|
+
:from_given => proc { |name, space|
|
|
18
|
+
if v2?
|
|
19
|
+
space.domain_by_name(name) ||
|
|
20
|
+
fail_unknown("domain", name)
|
|
21
|
+
else
|
|
22
|
+
name
|
|
23
|
+
end
|
|
24
|
+
}
|
|
25
|
+
def map
|
|
26
|
+
app = input[:app]
|
|
27
|
+
space = app.space if v2?
|
|
28
|
+
|
|
29
|
+
host = input[:host]
|
|
30
|
+
domain = input[:domain, space]
|
|
31
|
+
|
|
32
|
+
if v2?
|
|
33
|
+
route = find_or_create_route(domain, host, space)
|
|
34
|
+
bind_route(route, app) if app
|
|
35
|
+
else
|
|
36
|
+
with_progress("Updating #{c(app.name, :name)}") do
|
|
37
|
+
app.urls << domain
|
|
38
|
+
app.update!
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def bind_route(route, app)
|
|
46
|
+
with_progress("Binding #{c(route.name, :name)} to #{c(app.name, :name)}") do
|
|
47
|
+
app.add_route(route)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def find_or_create_route(domain, host, space)
|
|
52
|
+
find_route(domain, host) || create_route(domain, host, space)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def find_route(domain, host)
|
|
56
|
+
client.routes_by_host(host, :depth => 0).find { |r| r.domain == domain }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_route(domain, host, space)
|
|
60
|
+
route = client.route
|
|
61
|
+
route.host = host
|
|
62
|
+
route.domain = domain
|
|
63
|
+
route.space = space
|
|
64
|
+
|
|
65
|
+
with_progress("Creating route #{c(route.name, :name)}") do
|
|
66
|
+
route.create!
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
route
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def find_domain(space, name)
|
|
73
|
+
domain = space.domain_by_name(name, :depth => 0)
|
|
74
|
+
fail "Invalid domain '#{name}'" unless domain
|
|
75
|
+
domain
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def ask_app
|
|
79
|
+
ask("Which application?", :choices => client.apps, :display => proc(&:name))
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require "vmc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module VMC::Route
|
|
4
|
+
class Routes < Base
|
|
5
|
+
desc "List routes in a space"
|
|
6
|
+
|
|
7
|
+
def routes
|
|
8
|
+
# TODO: scope to space once space.routes is possible
|
|
9
|
+
routes =
|
|
10
|
+
with_progress("Getting routes") do
|
|
11
|
+
client.routes
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
line unless quiet?
|
|
15
|
+
|
|
16
|
+
table(
|
|
17
|
+
%w{host domain},
|
|
18
|
+
routes.sort_by { |r| "#{r.domain.name} #{r.host}" }.collect { |r|
|
|
19
|
+
[c(r.host, :name),
|
|
20
|
+
r.domain.name
|
|
21
|
+
]
|
|
22
|
+
})
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
require "vmc/cli/route/base"
|
|
2
|
+
|
|
3
|
+
module VMC::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 :delete, :desc => "Delete route", :type => :boolean
|
|
12
|
+
input :all, :desc => "Act on all routes", :type => :boolean
|
|
13
|
+
input :really, :type => :boolean, :forget => true, :hidden => true,
|
|
14
|
+
:default => proc { force? || interact }
|
|
15
|
+
def unmap
|
|
16
|
+
return invoke :v1_unmap, input.inputs, input.given unless v2?
|
|
17
|
+
|
|
18
|
+
if input[:all]
|
|
19
|
+
if input.has?(:app)
|
|
20
|
+
app = target = input[:app]
|
|
21
|
+
return unless !input[:delete] || input[:really, "ALL URLS bound to #{target.name}", :bad]
|
|
22
|
+
else
|
|
23
|
+
target = client
|
|
24
|
+
return unless !input[:delete] || input[:really, "ALL URLS", :bad]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
target.routes.each do |r|
|
|
28
|
+
begin
|
|
29
|
+
invoke :unmap, :delete => input[:delete], :url => r, :really => true, :app => app
|
|
30
|
+
rescue CFoundry::APIError => e
|
|
31
|
+
err "#{e.class}: #{e.message}"
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
return
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
app = input[:app]
|
|
39
|
+
url = input[:url, app ? app.routes : client.routes]
|
|
40
|
+
|
|
41
|
+
if input[:delete]
|
|
42
|
+
with_progress("Deleting route #{c(url.name, :name)}") do
|
|
43
|
+
url.delete!
|
|
44
|
+
end
|
|
45
|
+
elsif app
|
|
46
|
+
with_progress("Unbinding #{c(url.name, :name)} from #{c(app.name, :name)}") do
|
|
47
|
+
app.remove_route(url)
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
fail "Missing either --delete or --app."
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
desc "V1 ONLY UNMAP YOU SHOULD NOT SEE THIS"
|
|
56
|
+
input :url, :desc => "URL to unmap", :argument => :optional,
|
|
57
|
+
:interact => :v1_ask_url
|
|
58
|
+
input :app, :desc => "Application to remove the URL from",
|
|
59
|
+
:argument => :optional, :from_given => by_name(:app)
|
|
60
|
+
input :all, :desc => "Act on all routes", :type => :boolean
|
|
61
|
+
def v1_unmap
|
|
62
|
+
app = input[:app]
|
|
63
|
+
url = input[:url, app.urls] unless input[:all]
|
|
64
|
+
|
|
65
|
+
with_progress("Updating #{c(app.name, :name)}") do |s|
|
|
66
|
+
if input[:all]
|
|
67
|
+
app.urls = []
|
|
68
|
+
else
|
|
69
|
+
simple = url.sub(/^https?:\/\/(.*)\/?/i, '\1')
|
|
70
|
+
|
|
71
|
+
unless app.urls.delete(simple)
|
|
72
|
+
fail "URL #{url} is not mapped to this application."
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
app.update!
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
def ask_url(choices)
|
|
83
|
+
ask("Which URL?", :choices => choices.sort_by(&:name), :display => proc(&:name))
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def v1_ask_url(choices)
|
|
87
|
+
ask("Which URL?", :choices => choices.sort)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def ask_really(name, color)
|
|
91
|
+
ask("Really delete #{c(name, color)}?", :default => false)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
require "vmc/detect"
|
|
2
|
+
|
|
3
|
+
require "vmc/cli/service/base"
|
|
4
|
+
|
|
5
|
+
module VMC::Service
|
|
6
|
+
class Bind < Base
|
|
7
|
+
desc "Bind a service to an application"
|
|
8
|
+
group :services, :manage
|
|
9
|
+
input :service, :desc => "Service to bind", :argument => :optional,
|
|
10
|
+
:from_given => by_name(:service_instance, "service")
|
|
11
|
+
input :app, :desc => "Application to bind to", :argument => :optional,
|
|
12
|
+
:from_given => by_name(:app)
|
|
13
|
+
def bind_service
|
|
14
|
+
app = input[:app]
|
|
15
|
+
service = input[:service, app]
|
|
16
|
+
|
|
17
|
+
with_progress(
|
|
18
|
+
"Binding #{c(service.name, :name)} to #{c(app.name, :name)}") do |s|
|
|
19
|
+
if app.binds?(service)
|
|
20
|
+
s.skip do
|
|
21
|
+
err "App #{b(app.name)} already binds #{b(service.name)}."
|
|
22
|
+
end
|
|
23
|
+
else
|
|
24
|
+
app.bind(service)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
def ask_service(app)
|
|
32
|
+
services = client.service_instances
|
|
33
|
+
fail "No services." if services.empty?
|
|
34
|
+
|
|
35
|
+
ask "Which service?", :choices => services - app.services,
|
|
36
|
+
:display => proc(&:name)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def ask_app
|
|
40
|
+
ask "Which application?", :choices => client.apps,
|
|
41
|
+
:display => proc(&:name)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|