jdc 0.2.1.pre → 0.2.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/LICENSE +24 -1277
- data/README.md +102 -0
- data/bin/jdc +2 -12
- data/{lib/tunnel/helper-app → caldecott_helper}/server.rb +5 -5
- data/{lib/tunnel/config → config}/clients.yml +2 -2
- data/config/micro/paths.yml +22 -0
- data/config/micro/refresh_ip.rb +20 -0
- data/lib/cli/commands/admin.rb +58 -0
- data/lib/cli/commands/apps.rb +1129 -0
- data/lib/cli/commands/base.rb +228 -0
- data/lib/cli/commands/manifest.rb +56 -0
- data/lib/cli/commands/micro.rb +115 -0
- data/lib/cli/commands/misc.rb +126 -0
- data/lib/cli/commands/services.rb +178 -0
- data/lib/cli/commands/user.rb +14 -0
- data/lib/cli/config.rb +173 -0
- data/lib/cli/console_helper.rb +170 -0
- data/lib/cli/core_ext.rb +122 -0
- data/lib/cli/errors.rb +19 -0
- data/lib/cli/frameworks.rb +265 -0
- data/lib/cli/manifest_helper.rb +300 -0
- data/lib/cli/runner.rb +505 -0
- data/lib/cli/services_helper.rb +84 -0
- data/lib/cli/tunnel_helper.rb +332 -0
- data/lib/cli/usage.rb +86 -0
- data/lib/cli/version.rb +7 -0
- data/lib/cli/zip_util.rb +77 -0
- data/lib/cli.rb +53 -0
- data/lib/jdc/client.rb +457 -0
- data/lib/jdc/const.rb +25 -0
- data/lib/jdc/micro/switcher/base.rb +97 -0
- data/lib/{micro → jdc/micro}/switcher/darwin.rb +3 -5
- data/lib/{micro → jdc/micro}/switcher/dummy.rb +1 -1
- data/lib/jdc/micro/switcher/linux.rb +16 -0
- data/lib/{micro → jdc/micro}/switcher/windows.rb +5 -5
- data/lib/{micro → jdc/micro}/vmrun.rb +19 -26
- data/lib/{micro → jdc}/micro.rb +15 -15
- data/lib/jdc/signature/version.rb +27 -0
- data/lib/jdc/signer.rb +13 -0
- data/lib/jdc/timer.rb +12 -0
- data/lib/jdc.rb +2 -15
- metadata +210 -360
- data/Rakefile +0 -13
- data/lib/admin/README.md +0 -15
- data/lib/admin/curl.rb +0 -60
- data/lib/admin/guid.rb +0 -89
- data/lib/admin/plugin.rb +0 -6
- data/lib/admin/service_auth_token.rb +0 -94
- data/lib/admin/service_broker/add.rb +0 -47
- data/lib/admin/service_broker/service_brokers.rb +0 -24
- data/lib/admin/set_quota.rb +0 -44
- data/lib/console/README.md +0 -8
- data/lib/console/console.rb +0 -187
- data/lib/console/plugin.rb +0 -33
- data/lib/jdc/cli/app/app.rb +0 -43
- data/lib/jdc/cli/app/apps.rb +0 -87
- data/lib/jdc/cli/app/base.rb +0 -72
- data/lib/jdc/cli/app/delete.rb +0 -95
- data/lib/jdc/cli/app/deprecated.rb +0 -11
- data/lib/jdc/cli/app/env.rb +0 -78
- data/lib/jdc/cli/app/events.rb +0 -45
- data/lib/jdc/cli/app/files.rb +0 -137
- data/lib/jdc/cli/app/health.rb +0 -26
- data/lib/jdc/cli/app/instances.rb +0 -53
- data/lib/jdc/cli/app/logs.rb +0 -76
- data/lib/jdc/cli/app/push/create.rb +0 -108
- data/lib/jdc/cli/app/push/interactions.rb +0 -86
- data/lib/jdc/cli/app/push/sync.rb +0 -57
- data/lib/jdc/cli/app/push.rb +0 -103
- data/lib/jdc/cli/app/rename.rb +0 -35
- data/lib/jdc/cli/app/restart.rb +0 -31
- data/lib/jdc/cli/app/scale.rb +0 -63
- data/lib/jdc/cli/app/start.rb +0 -161
- data/lib/jdc/cli/app/stats.rb +0 -67
- data/lib/jdc/cli/app/stop.rb +0 -27
- data/lib/jdc/cli/domain/base.rb +0 -9
- data/lib/jdc/cli/domain/domains.rb +0 -40
- data/lib/jdc/cli/domain/map.rb +0 -55
- data/lib/jdc/cli/domain/unmap.rb +0 -56
- data/lib/jdc/cli/help.rb +0 -15
- data/lib/jdc/cli/interactive.rb +0 -105
- data/lib/jdc/cli/login_requirements.rb +0 -15
- data/lib/jdc/cli/organization/base.rb +0 -14
- data/lib/jdc/cli/organization/create.rb +0 -37
- data/lib/jdc/cli/organization/delete.rb +0 -63
- data/lib/jdc/cli/organization/org.rb +0 -45
- data/lib/jdc/cli/organization/orgs.rb +0 -30
- data/lib/jdc/cli/organization/rename.rb +0 -37
- data/lib/jdc/cli/populators/base.rb +0 -16
- data/lib/jdc/cli/populators/organization.rb +0 -32
- data/lib/jdc/cli/populators/populator_methods.rb +0 -64
- data/lib/jdc/cli/populators/space.rb +0 -33
- data/lib/jdc/cli/populators/target.rb +0 -13
- data/lib/jdc/cli/route/base.rb +0 -9
- data/lib/jdc/cli/route/delete.rb +0 -28
- data/lib/jdc/cli/route/map.rb +0 -68
- data/lib/jdc/cli/route/routes.rb +0 -26
- data/lib/jdc/cli/route/unmap.rb +0 -56
- data/lib/jdc/cli/service/base.rb +0 -9
- data/lib/jdc/cli/service/bind.rb +0 -44
- data/lib/jdc/cli/service/create.rb +0 -159
- data/lib/jdc/cli/service/delete.rb +0 -83
- data/lib/jdc/cli/service/rename.rb +0 -36
- data/lib/jdc/cli/service/service.rb +0 -42
- data/lib/jdc/cli/service/service_instance_helper.rb +0 -99
- data/lib/jdc/cli/service/services.rb +0 -111
- data/lib/jdc/cli/service/unbind.rb +0 -37
- data/lib/jdc/cli/space/base.rb +0 -29
- data/lib/jdc/cli/space/create.rb +0 -67
- data/lib/jdc/cli/space/delete.rb +0 -56
- data/lib/jdc/cli/space/rename.rb +0 -38
- data/lib/jdc/cli/space/space.rb +0 -66
- data/lib/jdc/cli/space/spaces.rb +0 -57
- data/lib/jdc/cli/space/switch.rb +0 -19
- data/lib/jdc/cli/start/base.rb +0 -41
- data/lib/jdc/cli/start/colors.rb +0 -13
- data/lib/jdc/cli/start/target.rb +0 -50
- data/lib/jdc/cli/start/target_prettifier.rb +0 -17
- data/lib/jdc/cli/start/targets.rb +0 -16
- data/lib/jdc/cli/user/base.rb +0 -30
- data/lib/jdc/cli/user/create.rb +0 -52
- data/lib/jdc/cli/user/passwd.rb +0 -37
- data/lib/jdc/cli/user/register.rb +0 -43
- data/lib/jdc/cli/user/users.rb +0 -32
- data/lib/jdc/cli.rb +0 -556
- data/lib/jdc/constants.rb +0 -11
- data/lib/jdc/errors.rb +0 -19
- data/lib/jdc/object_extensions.rb +0 -15
- data/lib/jdc/plugin.rb +0 -56
- data/lib/jdc/spacing.rb +0 -89
- data/lib/jdc/spec_helper.rb +0 -1
- data/lib/jdc/test_support.rb +0 -6
- data/lib/jdc/version.rb +0 -3
- data/lib/manifests/errors.rb +0 -35
- data/lib/manifests/loader/builder.rb +0 -39
- data/lib/manifests/loader/normalizer.rb +0 -145
- data/lib/manifests/loader/resolver.rb +0 -79
- data/lib/manifests/loader.rb +0 -31
- data/lib/manifests/manifests.rb +0 -344
- data/lib/manifests/plugin.rb +0 -140
- data/lib/micro/README.md +0 -9
- data/lib/micro/errors.rb +0 -4
- data/lib/micro/plugin.rb +0 -197
- data/lib/micro/switcher/base.rb +0 -79
- data/lib/micro/switcher/linux.rb +0 -16
- data/lib/tasks/gem_release.rake +0 -42
- data/lib/tunnel/README.md +0 -29
- data/lib/tunnel/helper-app/Gemfile +0 -10
- data/lib/tunnel/helper-app/Gemfile.lock +0 -48
- data/lib/tunnel/plugin.rb +0 -183
- data/lib/tunnel/tunnel.rb +0 -295
data/lib/micro/switcher/base.rb
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
require "micro/errors"
|
|
2
|
-
|
|
3
|
-
module JDCMicro::Switcher
|
|
4
|
-
class Base
|
|
5
|
-
|
|
6
|
-
def initialize(config)
|
|
7
|
-
@config = config
|
|
8
|
-
|
|
9
|
-
@vmrun = JDCMicro::VMrun.new(config)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
#wrapper methods
|
|
13
|
-
def vmx
|
|
14
|
-
@vmrun.vmx
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def domain
|
|
18
|
-
@vmrun.domain
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def ip
|
|
22
|
-
@vmrun.ip
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def running?
|
|
26
|
-
@vmrun.running?
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def start!
|
|
30
|
-
@vmrun.start!
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def ready?
|
|
34
|
-
@vmrun.ready?
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def offline?
|
|
38
|
-
@vmrun.offline?
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def nat?
|
|
42
|
-
@config['online_connection_type'] ||= @vmrun.connection_type
|
|
43
|
-
@config["online_connection_type"] == "nat"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def reset_to_nat!
|
|
47
|
-
@vmrun.connection_type = 'nat'
|
|
48
|
-
@vmrun.reset
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def set_host_dns!
|
|
52
|
-
@config['domain'] ||= @vmrun.domain
|
|
53
|
-
@config['ip'] ||= @vmrun.ip
|
|
54
|
-
set_nameserver(@config['domain'], @config['ip'])
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def unset_host_dns!
|
|
58
|
-
@config['domain'] ||= @vmrun.domain
|
|
59
|
-
@config['ip'] ||= @vmrun.ip
|
|
60
|
-
unset_nameserver(@config['domain'], @config['ip'])
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def offline!
|
|
64
|
-
if @vmrun.offline?
|
|
65
|
-
raise JDCMicro::MCFError, "Micro Cloud Foundry VM already in offline mode"
|
|
66
|
-
else
|
|
67
|
-
@vmrun.offline!
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
def online!
|
|
72
|
-
if @vmrun.offline?
|
|
73
|
-
@vmrun.online!
|
|
74
|
-
else
|
|
75
|
-
raise JDCMirco::MCFError, "Micro Cloud Foundry already in online mode"
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
data/lib/micro/switcher/linux.rb
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
module JDCMicro::Switcher
|
|
2
|
-
|
|
3
|
-
class Linux < Base
|
|
4
|
-
def set_nameserver(domain, ip)
|
|
5
|
-
JDCMicro.run_command("sudo", "sed -i'.backup' '1 i nameserver #{ip}' /etc/resolv.conf")
|
|
6
|
-
# lock resolv.conf so Network Manager doesn't clear out the file when offline
|
|
7
|
-
JDCMicro.run_command("sudo", "chattr +i /etc/resolv.conf")
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def unset_nameserver(domain, ip)
|
|
11
|
-
JDCMicro.run_command("sudo", "chattr -i /etc/resolv.conf")
|
|
12
|
-
JDCMicro.run_command("sudo", "sed -i'.backup' '/#{ip}/d' /etc/resolv.conf")
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
end
|
data/lib/tasks/gem_release.rake
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require 'active_support/core_ext'
|
|
2
|
-
|
|
3
|
-
namespace :gem do
|
|
4
|
-
desc "Bump gem version, push to RubyGems, push to Github, add release notes"
|
|
5
|
-
task :release, [:version] do |_, args|
|
|
6
|
-
version = args[:version] || 'rc'
|
|
7
|
-
old_version = gem_version
|
|
8
|
-
|
|
9
|
-
sh! "gem bump --version #{version} --no-commit"
|
|
10
|
-
sh! "git add lib/jdc/version.rb"
|
|
11
|
-
|
|
12
|
-
print_with_purpose "Bumping to version #{gem_version}"
|
|
13
|
-
#generate_release_notes(old_version)
|
|
14
|
-
sh!("git commit -m 'Bumping to version #{gem_version}.'")
|
|
15
|
-
sh!("git push")
|
|
16
|
-
sh!("gem release --tag")
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
private
|
|
20
|
-
def generate_release_notes(old_version)
|
|
21
|
-
print_with_purpose "Generating release notes..."
|
|
22
|
-
file_name = "release_#{gem_version}"
|
|
23
|
-
sh!("anchorman notes --name=#{file_name} --from=v#{old_version}")
|
|
24
|
-
sh!("git add release_notes")
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def sh!(cmd)
|
|
28
|
-
`#{cmd}`
|
|
29
|
-
raise "borked with #{$?}" unless $?.success?
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def print_with_purpose(text)
|
|
33
|
-
puts "\033[34m#{text}\033[0m"
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def gem_version
|
|
37
|
-
silence_warnings do
|
|
38
|
-
load "lib/jdc/version.rb"
|
|
39
|
-
end
|
|
40
|
-
Gem::Specification.load("jdc.gemspec").version.to_s
|
|
41
|
-
end
|
|
42
|
-
end
|
data/lib/tunnel/README.md
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
[](https://travis-ci.org/cloudfoundry/tunnel-cf-plugin)
|
|
2
|
-
[](http://badge.fury.io/rb/tunnel-cf-plugin)
|
|
3
|
-
|
|
4
|
-
## Tunnel
|
|
5
|
-
### Info
|
|
6
|
-
This plugin allows you to connect to a Cloud Foundry service using your own command line client. By default, the plugin supports *redis*, *mysql*, *mongodb*, and *postgresql*.
|
|
7
|
-
|
|
8
|
-
### Installation
|
|
9
|
-
```
|
|
10
|
-
gem install tunnel-cf-plugin
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
### Usage
|
|
14
|
-
```
|
|
15
|
-
tunnel [INSTANCE] [CLIENT] Create a local tunnel to a service.
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
You can add support for other command-line clients by providing a `~/.cf/clients.yml` file with the following format:
|
|
19
|
-
|
|
20
|
-
```yaml
|
|
21
|
-
service_name:
|
|
22
|
-
client_program_name: command line arguments
|
|
23
|
-
client_program_name_2:
|
|
24
|
-
command: command line arguments
|
|
25
|
-
environment:
|
|
26
|
-
- ENV_VAR_NAME=env_var_value
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
GEM
|
|
2
|
-
remote: http://rubygems.org/
|
|
3
|
-
specs:
|
|
4
|
-
addressable (2.2.6)
|
|
5
|
-
async_sinatra (0.5.0)
|
|
6
|
-
rack (>= 1.2.1)
|
|
7
|
-
sinatra (>= 1.0)
|
|
8
|
-
caldecott (0.0.3)
|
|
9
|
-
addressable (= 2.2.6)
|
|
10
|
-
async_sinatra (= 0.5.0)
|
|
11
|
-
em-http-request (= 0.3.0)
|
|
12
|
-
em-websocket (= 0.3.1)
|
|
13
|
-
json (= 1.6.1)
|
|
14
|
-
uuidtools (= 2.1.2)
|
|
15
|
-
daemons (1.1.8)
|
|
16
|
-
em-http-request (0.3.0)
|
|
17
|
-
addressable (>= 2.0.0)
|
|
18
|
-
escape_utils
|
|
19
|
-
eventmachine (>= 0.12.9)
|
|
20
|
-
em-websocket (0.3.1)
|
|
21
|
-
addressable (>= 2.1.1)
|
|
22
|
-
eventmachine (>= 0.12.9)
|
|
23
|
-
escape_utils (0.2.4)
|
|
24
|
-
eventmachine (0.12.10)
|
|
25
|
-
json (1.6.1)
|
|
26
|
-
rack (1.2.5)
|
|
27
|
-
sinatra (1.2.8)
|
|
28
|
-
rack (~> 1.1)
|
|
29
|
-
tilt (>= 1.2.2, < 2.0)
|
|
30
|
-
thin (1.4.1)
|
|
31
|
-
daemons (>= 1.0.9)
|
|
32
|
-
eventmachine (>= 0.12.6)
|
|
33
|
-
rack (>= 1.0.0)
|
|
34
|
-
tilt (1.3.3)
|
|
35
|
-
uuidtools (2.1.2)
|
|
36
|
-
|
|
37
|
-
PLATFORMS
|
|
38
|
-
ruby
|
|
39
|
-
|
|
40
|
-
DEPENDENCIES
|
|
41
|
-
async_sinatra
|
|
42
|
-
bundler
|
|
43
|
-
caldecott (= 0.0.3)
|
|
44
|
-
em-websocket
|
|
45
|
-
json
|
|
46
|
-
rack (~> 1.2.0)
|
|
47
|
-
thin
|
|
48
|
-
uuidtools
|
data/lib/tunnel/plugin.rb
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
require "jdc/cli"
|
|
2
|
-
require "tunnel/tunnel"
|
|
3
|
-
|
|
4
|
-
module JDCTunnelPlugin
|
|
5
|
-
class Tunnel < JDC::CLI
|
|
6
|
-
CLIENTS_FILE = "tunnel-clients.yml"
|
|
7
|
-
STOCK_CLIENTS = File.expand_path("../config/clients.yml", __FILE__)
|
|
8
|
-
|
|
9
|
-
desc "Create a local tunnel to a service."
|
|
10
|
-
group :services, :manage
|
|
11
|
-
input(:instance, :argument => :optional,
|
|
12
|
-
:from_given => find_by_name("service instance"),
|
|
13
|
-
:desc => "Service instance to tunnel to") { |instances|
|
|
14
|
-
ask("Which service instance?", :choices => instances,
|
|
15
|
-
:display => proc(&:name))
|
|
16
|
-
}
|
|
17
|
-
input(:client, :argument => :optional,
|
|
18
|
-
:desc => "Client to automatically launch") { |clients|
|
|
19
|
-
if clients.empty?
|
|
20
|
-
"none"
|
|
21
|
-
else
|
|
22
|
-
ask("Which client would you like to start?",
|
|
23
|
-
:choices => clients.keys.unshift("none"))
|
|
24
|
-
end
|
|
25
|
-
}
|
|
26
|
-
input(:port, :default => 10000, :desc => "Port to bind the tunnel to")
|
|
27
|
-
def tunnel
|
|
28
|
-
instances = client.service_instances
|
|
29
|
-
fail "No services available for tunneling." if instances.empty?
|
|
30
|
-
|
|
31
|
-
instance = input[:instance, instances.sort_by(&:name)]
|
|
32
|
-
vendor = instance.service_plan.service.label
|
|
33
|
-
clients = tunnel_clients[vendor] || {}
|
|
34
|
-
client_name = input[:client, clients]
|
|
35
|
-
|
|
36
|
-
tunnel = JDCTunnel.new(client, instance)
|
|
37
|
-
port = tunnel.pick_port!(input[:port])
|
|
38
|
-
|
|
39
|
-
conn_info =
|
|
40
|
-
with_progress("Opening tunnel on port #{c(port, :name)}") do
|
|
41
|
-
tunnel.open!
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
if client_name == "none"
|
|
45
|
-
unless quiet?
|
|
46
|
-
line
|
|
47
|
-
display_tunnel_connection_info(conn_info)
|
|
48
|
-
|
|
49
|
-
line
|
|
50
|
-
line "Open another shell to run command-line clients or"
|
|
51
|
-
line "use a UI tool to connect using the displayed information."
|
|
52
|
-
line "Press Ctrl-C to exit..."
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
tunnel.wait_for_end
|
|
56
|
-
else
|
|
57
|
-
with_progress("Waiting for local tunnel to become available") do
|
|
58
|
-
tunnel.wait_for_start
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
unless start_local_prog(clients, client_name, conn_info, port)
|
|
62
|
-
fail "'#{client_name}' execution failed; is it in your $PATH?"
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def tunnel_clients
|
|
68
|
-
return @tunnel_clients if @tunnel_clients
|
|
69
|
-
stock_config = YAML.load_file(STOCK_CLIENTS)
|
|
70
|
-
custom_config_file = config_file_path
|
|
71
|
-
|
|
72
|
-
if File.exists?(custom_config_file)
|
|
73
|
-
custom_config = YAML.load_file(custom_config_file)
|
|
74
|
-
@tunnel_clients = deep_merge(stock_config, custom_config)
|
|
75
|
-
else
|
|
76
|
-
@tunnel_clients = stock_config
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
private
|
|
81
|
-
|
|
82
|
-
def config_file_path
|
|
83
|
-
File.expand_path("#{JDC::CONFIG_DIR}/.jdc/#{CLIENTS_FILE}")
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def display_tunnel_connection_info(info)
|
|
87
|
-
line "Service connection info:"
|
|
88
|
-
|
|
89
|
-
to_show = [nil, nil, nil] # reserved for user, pass, db name
|
|
90
|
-
info.keys.each do |k|
|
|
91
|
-
case k
|
|
92
|
-
when "host", "hostname", "port", "node_id"
|
|
93
|
-
# skip
|
|
94
|
-
when "user", "username"
|
|
95
|
-
# prefer "username" over "user"
|
|
96
|
-
to_show[0] = k unless to_show[0] == "username"
|
|
97
|
-
when "password"
|
|
98
|
-
to_show[1] = k
|
|
99
|
-
when "name"
|
|
100
|
-
to_show[2] = k
|
|
101
|
-
else
|
|
102
|
-
to_show << k
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
to_show.compact!
|
|
106
|
-
|
|
107
|
-
align_len = to_show.collect(&:size).max + 1
|
|
108
|
-
|
|
109
|
-
indented do
|
|
110
|
-
to_show.each do |k|
|
|
111
|
-
# TODO: modify the server services rest call to have explicit knowledge
|
|
112
|
-
# about the items to return. It should return all of them if
|
|
113
|
-
# the service is unknown so that we don't have to do this weird
|
|
114
|
-
# filtering.
|
|
115
|
-
line "#{k.ljust align_len}: #{b(info[k])}"
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
line
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def start_local_prog(clients, command, info, port)
|
|
123
|
-
client = clients[File.basename(command)]
|
|
124
|
-
|
|
125
|
-
cmdline = "#{command} "
|
|
126
|
-
|
|
127
|
-
case client
|
|
128
|
-
when Hash
|
|
129
|
-
cmdline << resolve_symbols(client["command"], info, port)
|
|
130
|
-
client["environment"].each do |e|
|
|
131
|
-
if e =~ /([^=]+)=(["']?)([^"']*)\2/
|
|
132
|
-
ENV[$1] = resolve_symbols($3, info, port)
|
|
133
|
-
else
|
|
134
|
-
fail "Invalid environment variable: #{e}"
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
when String
|
|
138
|
-
cmdline << resolve_symbols(client, info, port)
|
|
139
|
-
else
|
|
140
|
-
raise "Unknown client info: #{client.inspect}."
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
if verbose?
|
|
144
|
-
line
|
|
145
|
-
line "Launching '#{cmdline}'"
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
system(cmdline)
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def resolve_symbols(str, info, local_port)
|
|
152
|
-
str.gsub(/\$\{\s*([^\}]+)\s*\}/) do
|
|
153
|
-
sym = $1
|
|
154
|
-
|
|
155
|
-
case sym
|
|
156
|
-
when "host"
|
|
157
|
-
# TODO: determine proper host
|
|
158
|
-
"localhost"
|
|
159
|
-
when "port"
|
|
160
|
-
local_port
|
|
161
|
-
when "user", "username"
|
|
162
|
-
info["username"]
|
|
163
|
-
when /^ask (.+)/
|
|
164
|
-
ask($1)
|
|
165
|
-
else
|
|
166
|
-
info[sym] || raise("Unknown symbol in config: #{sym}")
|
|
167
|
-
end
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def deep_merge(a, b)
|
|
172
|
-
merge = proc { |_, old, new|
|
|
173
|
-
if old.is_a?(Hash) && new.is_a?(Hash)
|
|
174
|
-
old.merge(new, &merge)
|
|
175
|
-
else
|
|
176
|
-
new
|
|
177
|
-
end
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
a.merge(b, &merge)
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
data/lib/tunnel/tunnel.rb
DELETED
|
@@ -1,295 +0,0 @@
|
|
|
1
|
-
require "addressable/uri"
|
|
2
|
-
require "restclient"
|
|
3
|
-
require "uuidtools"
|
|
4
|
-
|
|
5
|
-
require "caldecott-client"
|
|
6
|
-
|
|
7
|
-
class JDCTunnel
|
|
8
|
-
HELPER_NAME = "caldecott"
|
|
9
|
-
HELPER_APP = File.expand_path("../helper-app", __FILE__)
|
|
10
|
-
|
|
11
|
-
# bump this AND the version info reported by HELPER_APP/server.rb
|
|
12
|
-
# this is to keep the helper in sync with any updates here
|
|
13
|
-
HELPER_VERSION = "0.0.4"
|
|
14
|
-
|
|
15
|
-
def initialize(client, service, port = 10000)
|
|
16
|
-
@client = client
|
|
17
|
-
@service = service
|
|
18
|
-
@port = port
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def open!
|
|
22
|
-
if helper
|
|
23
|
-
auth = helper_auth
|
|
24
|
-
|
|
25
|
-
unless helper_healthy?(auth)
|
|
26
|
-
delete_helper
|
|
27
|
-
auth = create_helper
|
|
28
|
-
end
|
|
29
|
-
else
|
|
30
|
-
auth = create_helper
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
bind_to_helper if @service && !helper_already_binds?
|
|
34
|
-
|
|
35
|
-
info = get_connection_info(auth)
|
|
36
|
-
|
|
37
|
-
start_tunnel(info, auth)
|
|
38
|
-
|
|
39
|
-
info
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def wait_for_start
|
|
43
|
-
10.times do |n|
|
|
44
|
-
begin
|
|
45
|
-
TCPSocket.open("localhost", @port).close
|
|
46
|
-
return true
|
|
47
|
-
rescue => e
|
|
48
|
-
sleep 1
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
raise "Could not connect to local tunnel."
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def wait_for_end
|
|
56
|
-
if @local_tunnel_thread
|
|
57
|
-
@local_tunnel_thread.join
|
|
58
|
-
else
|
|
59
|
-
raise "Tunnel wasn't started!"
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
PORT_RANGE = 10
|
|
64
|
-
def pick_port!(port = @port)
|
|
65
|
-
original = port
|
|
66
|
-
|
|
67
|
-
PORT_RANGE.times do |n|
|
|
68
|
-
begin
|
|
69
|
-
TCPSocket.open("localhost", port)
|
|
70
|
-
port += 1
|
|
71
|
-
rescue
|
|
72
|
-
return @port = port
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
@port = grab_ephemeral_port
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
private
|
|
80
|
-
|
|
81
|
-
def helper
|
|
82
|
-
@helper ||= @client.app_by_name(HELPER_NAME)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def create_helper
|
|
86
|
-
auth = UUIDTools::UUID.random_create.to_s
|
|
87
|
-
push_helper(auth)
|
|
88
|
-
start_helper
|
|
89
|
-
auth
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def helper_auth
|
|
93
|
-
helper.env["CALDECOTT_AUTH"]
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
def helper_healthy?(token)
|
|
97
|
-
return false unless helper.healthy?
|
|
98
|
-
|
|
99
|
-
begin
|
|
100
|
-
response = RestClient.get(
|
|
101
|
-
"#{helper_url}/info",
|
|
102
|
-
"Auth-Token" => token
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
info = JSON.parse(response)
|
|
106
|
-
if info["version"] == HELPER_VERSION
|
|
107
|
-
true
|
|
108
|
-
else
|
|
109
|
-
stop_helper
|
|
110
|
-
false
|
|
111
|
-
end
|
|
112
|
-
rescue RestClient::Exception
|
|
113
|
-
stop_helper
|
|
114
|
-
false
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def helper_already_binds?
|
|
119
|
-
helper.binds? @service
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def push_helper(token)
|
|
123
|
-
app = @client.app
|
|
124
|
-
app.name = HELPER_NAME
|
|
125
|
-
app.command = "bundle exec ruby server.rb"
|
|
126
|
-
app.total_instances = 1
|
|
127
|
-
app.memory = 128
|
|
128
|
-
app.env = {"CALDECOTT_AUTH" => token}
|
|
129
|
-
|
|
130
|
-
space = app.space = @client.current_space
|
|
131
|
-
app.create!
|
|
132
|
-
|
|
133
|
-
app.bind(@service) if @service
|
|
134
|
-
|
|
135
|
-
domain = @client.domains.find { |d| d.owning_organization == nil }
|
|
136
|
-
|
|
137
|
-
app.create_route(:domain => domain, :space => space, :host => random_helper_url)
|
|
138
|
-
|
|
139
|
-
begin
|
|
140
|
-
app.upload(HELPER_APP)
|
|
141
|
-
invalidate_tunnel_app_info
|
|
142
|
-
rescue
|
|
143
|
-
app.delete!
|
|
144
|
-
raise
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
def delete_helper
|
|
149
|
-
helper.delete!
|
|
150
|
-
invalidate_tunnel_app_info
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
def stop_helper
|
|
154
|
-
helper.stop!
|
|
155
|
-
invalidate_tunnel_app_info
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
TUNNEL_CHECK_LIMIT = 60
|
|
159
|
-
def start_helper
|
|
160
|
-
helper.start!
|
|
161
|
-
|
|
162
|
-
seconds = 0
|
|
163
|
-
until helper.healthy?
|
|
164
|
-
sleep 1
|
|
165
|
-
seconds += 1
|
|
166
|
-
if seconds == TUNNEL_CHECK_LIMIT
|
|
167
|
-
raise "Helper application failed to start."
|
|
168
|
-
end
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
invalidate_tunnel_app_info
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def bind_to_helper
|
|
175
|
-
helper.bind(@service)
|
|
176
|
-
helper.restart!
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def invalidate_tunnel_app_info
|
|
180
|
-
@helper_url = nil
|
|
181
|
-
@helper = nil
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
def helper_url
|
|
185
|
-
return @helper_url if @helper_url
|
|
186
|
-
|
|
187
|
-
tun_url = helper.url
|
|
188
|
-
|
|
189
|
-
["https", "http"].each do |scheme|
|
|
190
|
-
url = "#{scheme}://#{tun_url}"
|
|
191
|
-
begin
|
|
192
|
-
RestClient.get(url)
|
|
193
|
-
|
|
194
|
-
# https failed
|
|
195
|
-
rescue Errno::ECONNREFUSED
|
|
196
|
-
|
|
197
|
-
# we expect a 404 since this request isn't auth'd
|
|
198
|
-
rescue RestClient::ResourceNotFound
|
|
199
|
-
return @helper_url = url
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
raise "Cannot determine URL for #{tun_url}"
|
|
204
|
-
end
|
|
205
|
-
|
|
206
|
-
def get_connection_info(token)
|
|
207
|
-
response = nil
|
|
208
|
-
10.times do
|
|
209
|
-
begin
|
|
210
|
-
response =
|
|
211
|
-
RestClient.get(
|
|
212
|
-
helper_url + "/" + safe_path("services", @service.name),
|
|
213
|
-
"Auth-Token" => token)
|
|
214
|
-
|
|
215
|
-
break
|
|
216
|
-
rescue RestClient::Exception => e
|
|
217
|
-
sleep 1
|
|
218
|
-
end
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
unless response
|
|
222
|
-
raise "Remote tunnel helper is unaware of #{@service.name}!"
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
is_v2 = @client.is_a?(JFoundry::V2::Client)
|
|
226
|
-
|
|
227
|
-
info = JSON.parse(response)
|
|
228
|
-
case (is_v2 ? @service.service_plan.service.label : @service.vendor)
|
|
229
|
-
when "rabbitmq"
|
|
230
|
-
uri = Addressable::URI.parse info["url"]
|
|
231
|
-
info["hostname"] = uri.host
|
|
232
|
-
info["port"] = uri.port
|
|
233
|
-
info["vhost"] = uri.path[1..-1]
|
|
234
|
-
info["user"] = uri.user
|
|
235
|
-
info["password"] = uri.password
|
|
236
|
-
info.delete "url"
|
|
237
|
-
|
|
238
|
-
# we use "db" as the "name" for mongo
|
|
239
|
-
# existing "name" is junk
|
|
240
|
-
when "mongodb"
|
|
241
|
-
info["name"] = info["db"]
|
|
242
|
-
info.delete "db"
|
|
243
|
-
|
|
244
|
-
# our "name" is irrelevant for redis
|
|
245
|
-
when "redis"
|
|
246
|
-
info.delete "name"
|
|
247
|
-
|
|
248
|
-
when "filesystem"
|
|
249
|
-
raise "Tunneling is not supported for this type of service"
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
["hostname", "port", "password"].each do |k|
|
|
253
|
-
raise "Could not determine #{k} for #{@service.name}" if info[k].nil?
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
info
|
|
257
|
-
end
|
|
258
|
-
|
|
259
|
-
def start_tunnel(conn_info, auth)
|
|
260
|
-
@local_tunnel_thread = Thread.new do
|
|
261
|
-
Caldecott::Client.start({
|
|
262
|
-
:local_port => @port,
|
|
263
|
-
:tun_url => helper_url,
|
|
264
|
-
:dst_host => conn_info["hostname"],
|
|
265
|
-
:dst_port => conn_info["port"],
|
|
266
|
-
:log_file => STDOUT,
|
|
267
|
-
:log_level => ENV["JDC_TUNNEL_DEBUG"] || "ERROR",
|
|
268
|
-
:auth_token => auth,
|
|
269
|
-
:quiet => true
|
|
270
|
-
})
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
at_exit { @local_tunnel_thread.kill }
|
|
274
|
-
end
|
|
275
|
-
|
|
276
|
-
def random_helper_url
|
|
277
|
-
random = sprintf("%x", rand(1000000))
|
|
278
|
-
"caldecott-#{random}"
|
|
279
|
-
end
|
|
280
|
-
|
|
281
|
-
def safe_path(*segments)
|
|
282
|
-
segments.flatten.collect { |x|
|
|
283
|
-
URI.encode x.to_s, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]")
|
|
284
|
-
}.join("/")
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
def grab_ephemeral_port
|
|
288
|
-
socket = TCPServer.new("0.0.0.0", 0)
|
|
289
|
-
socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
|
290
|
-
Socket.do_not_reverse_lookup = true
|
|
291
|
-
socket.addr[1]
|
|
292
|
-
ensure
|
|
293
|
-
socket.close
|
|
294
|
-
end
|
|
295
|
-
end
|