lds-cf-plugin 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,5 @@
|
|
1
1
|
require "cf/cli"
|
2
|
-
require "
|
2
|
+
require "json"
|
3
3
|
|
4
4
|
module LdsCfPlugin
|
5
5
|
class CustomService < CF::CLI
|
@@ -8,7 +8,7 @@ module LdsCfPlugin
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "Create a custom service"
|
11
|
-
group :lds
|
11
|
+
group :lds, :services
|
12
12
|
input :name, :desc => "Name for your service", :argument => :optional
|
13
13
|
input :credentials, :desc => "The service credentials JSON string to be passed to the application", :argument => :optional
|
14
14
|
input :plan, :desc => "Service plan",
|
@@ -49,7 +49,7 @@ module LdsCfPlugin
|
|
49
49
|
credentials = ask("Service credentials JSON string")
|
50
50
|
end
|
51
51
|
|
52
|
-
creds =
|
52
|
+
creds = JSON.parse(credentials)
|
53
53
|
|
54
54
|
# Register custom service with gateway
|
55
55
|
|
@@ -59,7 +59,7 @@ module LdsCfPlugin
|
|
59
59
|
:credentials => creds
|
60
60
|
}
|
61
61
|
options = {
|
62
|
-
:payload =>
|
62
|
+
:payload => JSON.generate(payload)
|
63
63
|
}
|
64
64
|
request, response = rest_client.request("POST", "/register", options)
|
65
65
|
if response[:status].to_i != 200
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require "cf/cli"
|
2
|
-
require "
|
2
|
+
require "json"
|
3
3
|
|
4
4
|
module LdsCfPlugin
|
5
5
|
class CustomService < CF::CLI
|
@@ -8,7 +8,7 @@ module LdsCfPlugin
|
|
8
8
|
end
|
9
9
|
|
10
10
|
desc "Create an Oracle service"
|
11
|
-
group :lds
|
11
|
+
group :lds, :services
|
12
12
|
input :name, :desc => "Name for your service", :argument => :optional
|
13
13
|
input :service, :desc => "The Oracle database to connect to", :argument => :optional
|
14
14
|
input :schema, :desc => "The schema (user) to use", :argument => :optional
|
@@ -71,11 +71,11 @@ module LdsCfPlugin
|
|
71
71
|
:password => password
|
72
72
|
}
|
73
73
|
options = {
|
74
|
-
:payload =>
|
74
|
+
:payload => JSON.generate(payload)
|
75
75
|
}
|
76
76
|
request, response = rest_client.request("POST", "/register", options)
|
77
77
|
if response[:status].to_i != 200
|
78
|
-
fail "Error registering Oracle service with gateway
|
78
|
+
fail "Error registering Oracle service with gateway:\n#{response[:body]}"
|
79
79
|
end
|
80
80
|
|
81
81
|
|
data/lib/lds-cf-plugin/plugin.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require "mothership/help"
|
2
2
|
|
3
3
|
Mothership::Help.groups(
|
4
|
-
[:lds, "LDS Specific"
|
4
|
+
[:lds, "LDS Specific",
|
5
|
+
[:services, "Services"],
|
6
|
+
[:diagnostics, "Diagnostics"]]
|
5
7
|
)
|
6
8
|
|
7
9
|
require "lds-cf-plugin/custom_service"
|
8
10
|
require "lds-cf-plugin/oracle_service"
|
9
|
-
|
11
|
+
require "lds-cf-plugin/tunnel"
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require 'eventmachine'
|
2
|
+
require 'interact/pretty'
|
3
|
+
|
4
|
+
module TunnelClient
|
5
|
+
|
6
|
+
PROTOCOL_VERSION = '1'.freeze
|
7
|
+
|
8
|
+
FRAME_HEADER_LENGTH = 5
|
9
|
+
|
10
|
+
extend Interact::Pretty
|
11
|
+
|
12
|
+
def self.tunnel(token, tunnel_server_host, tunnel_server_port, app, instance_id, port = 'debug', local_host = '127.0.0.1', local_port = 1847, use_tls = true)
|
13
|
+
EventMachine::start_server(local_host, local_port, TunnelListener, token, tunnel_server_host, tunnel_server_port, app.guid, instance_id, port, use_tls)
|
14
|
+
end
|
15
|
+
|
16
|
+
class TunnelListener < EventMachine::Connection
|
17
|
+
|
18
|
+
attr_reader :token
|
19
|
+
attr_reader :app_guid
|
20
|
+
attr_reader :instance_id
|
21
|
+
attr_reader :port
|
22
|
+
attr_reader :use_tls
|
23
|
+
|
24
|
+
def initialize(token, tunnel_server_host, tunnel_server_port, app_guid, instance_id, port, use_tls)
|
25
|
+
@token, @app_guid, @instance_id, @port, @use_tls = token, app_guid, instance_id, port, use_tls
|
26
|
+
|
27
|
+
@tunnel_server_host = tunnel_server_host
|
28
|
+
@tunnel_server_port = tunnel_server_port
|
29
|
+
end
|
30
|
+
|
31
|
+
def post_init
|
32
|
+
puts 'Opening new connection to server...'
|
33
|
+
pause
|
34
|
+
@connection = EventMachine.connect(@tunnel_server_host, @tunnel_server_port, TunnelConnection, self)
|
35
|
+
end
|
36
|
+
|
37
|
+
def unbind
|
38
|
+
puts "Connection closed"
|
39
|
+
@connection.close_connection_after_writing
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
class TunnelConnection < EventMachine::Connection
|
45
|
+
|
46
|
+
def initialize(listener)
|
47
|
+
@listener = listener
|
48
|
+
end
|
49
|
+
|
50
|
+
def post_init
|
51
|
+
puts "Connection opened"
|
52
|
+
if @listener.use_tls
|
53
|
+
start_tls
|
54
|
+
else
|
55
|
+
send_initialization
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def ssl_handshake_completed
|
60
|
+
send_initialization
|
61
|
+
end
|
62
|
+
|
63
|
+
def receive_data(data)
|
64
|
+
(@buf ||= '') << data
|
65
|
+
|
66
|
+
while @buf.bytesize >= FRAME_HEADER_LENGTH
|
67
|
+
frame_type, frame_length = @buf.unpack("A1N")
|
68
|
+
if @buf.bytesize >= FRAME_HEADER_LENGTH + frame_length
|
69
|
+
@buf.slice!(0,FRAME_HEADER_LENGTH)
|
70
|
+
frame_body = @buf.slice!(0,frame_length)
|
71
|
+
case frame_type
|
72
|
+
when 'E', 'e'
|
73
|
+
# Error
|
74
|
+
close_connection
|
75
|
+
raise frame_body
|
76
|
+
when 'R', 'r'
|
77
|
+
@listener.resume
|
78
|
+
proxy_incoming_to @listener
|
79
|
+
@listener.proxy_incoming_to self
|
80
|
+
else
|
81
|
+
close_connection
|
82
|
+
raise "Received invalid frame type '#{frame_type}' from Tunnel Server"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def unbind
|
89
|
+
@listener.close_connection_after_writing
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def send_initialization
|
95
|
+
frame_body = "#{PROTOCOL_VERSION} #{@listener.token} #{@listener.app_guid} #{@listener.instance_id} #{@listener.port}"
|
96
|
+
frame = ['I', frame_body.bytesize, frame_body]
|
97
|
+
send_data frame.pack("A1NA*")
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require "cf/cli"
|
2
|
+
require "cf/constants"
|
3
|
+
require 'eventmachine'
|
4
|
+
require "lds-cf-plugin/tunnel/tunnelclient"
|
5
|
+
require "open-uri"
|
6
|
+
require "uri"
|
7
|
+
|
8
|
+
module LdsCfPlugin
|
9
|
+
|
10
|
+
JMXMP_JAR_NAME = "jmxremote_optional-repackaged-4.0.jar".freeze
|
11
|
+
JMXMP_JAR_FILE = File.expand_path("#{CF::CONFIG_DIR}/jmxremote_optional-repackaged-4.0.jar").freeze
|
12
|
+
JMXMP_JAR_URL = "http://search.maven.org/remotecontent?filepath=org/glassfish/main/external/jmxremote_optional-repackaged/4.0/#{JMXMP_JAR_NAME}".freeze
|
13
|
+
|
14
|
+
class Tunnel < CF::CLI
|
15
|
+
def precondition
|
16
|
+
check_target
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Open tunnel to application's debug port"
|
20
|
+
group :lds, :diagnostics
|
21
|
+
input :app, :desc => "Application to debug", :argument => :optional,
|
22
|
+
:from_given => by_name(:app)
|
23
|
+
input :instance, :desc => "Application instance", :argument => :optional
|
24
|
+
input :host, :desc => "The local host to bind to for tunneling connections",
|
25
|
+
:default => "127.0.0.1", :aliases => "--host"
|
26
|
+
input :port, :desc => "The local port to listen on for tunneling connections",
|
27
|
+
:default => 1847, :aliases => "--port"
|
28
|
+
input :tunnel_server, :desc => "The server to connect to for tunneling to the application",
|
29
|
+
:aliases => "--server"
|
30
|
+
input :tunnel_server_port, :desc => "The port to connect to on the tunnel server",
|
31
|
+
:aliases => "--server-port", :default => 2014
|
32
|
+
input :use_tls, :desc => "Indicates if TLS should be used", :default => true
|
33
|
+
def tunnel_debug
|
34
|
+
app = input[:app]
|
35
|
+
instances = get_instances(app)
|
36
|
+
|
37
|
+
filter_debug_instances(app, instances)
|
38
|
+
|
39
|
+
unless instances.size > 0
|
40
|
+
if ask("Restart application #{c(app.name, :name)} in debug mode?", :default => true)
|
41
|
+
invoke :restart, :app => app, :debug_mode => ""
|
42
|
+
|
43
|
+
instances = get_instances(app)
|
44
|
+
filter_debug_instances(app, instances)
|
45
|
+
else
|
46
|
+
fail "Unable to debug #{c(app.name, :name)} because it is not running in debug mode."
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
fail "Debugger information for #{c(app.name, :name)} still not available." unless instances.size > 0
|
51
|
+
|
52
|
+
tunnel(app, instances, "debug")
|
53
|
+
end
|
54
|
+
|
55
|
+
def filter_debug_instances(app, instances)
|
56
|
+
instances.keep_if do |instance|
|
57
|
+
debugger = instance.debugger
|
58
|
+
puts "#{c('Debugger information for instance', :error)} ##{c(instance.id, :number)} #{c('of', :error)} #{c(app.name, :name)} #{c('not available', :error)}" unless debugger
|
59
|
+
debugger
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc "Open tunnel to application's console port"
|
64
|
+
group :lds, :diagnostics
|
65
|
+
input :app, :desc => "Application to connect the console to", :argument => :optional,
|
66
|
+
:from_given => by_name(:app)
|
67
|
+
input :instance, :desc => "Application instance", :argument => :optional
|
68
|
+
input :host, :desc => "The local host to bind to for tunneling connections",
|
69
|
+
:default => "127.0.0.1", :aliases => "--host"
|
70
|
+
input :port, :desc => "The local port to listen on for tunneling connections",
|
71
|
+
:default => 1830, :aliases => "--port"
|
72
|
+
input :tunnel_server, :desc => "The server to connect to for tunneling to the application",
|
73
|
+
:aliases => "--server"
|
74
|
+
input :tunnel_server_port, :desc => "The port to connect to on the tunnel server",
|
75
|
+
:aliases => "--server-port", :default => 2014
|
76
|
+
input :use_tls, :desc => "Indicates if TLS should be used", :default => true
|
77
|
+
def tunnel_console(&post_tunnel)
|
78
|
+
app = input[:app]
|
79
|
+
instances = get_instances(app)
|
80
|
+
|
81
|
+
instances.keep_if do |instance|
|
82
|
+
console = instance.console
|
83
|
+
puts "#{c('Console information for instance', :error)} ##{c(instance.id, :number)} #{c('of', :error)} #{c(app.name, :name)} #{c(' not available', :error)}" unless console
|
84
|
+
console
|
85
|
+
end
|
86
|
+
|
87
|
+
fail "Console information for #{c(app.name, :name)} not available." unless instances.size > 0
|
88
|
+
|
89
|
+
tunnel(app, instances, "console", &post_tunnel)
|
90
|
+
end
|
91
|
+
|
92
|
+
desc "Launch VisualVM and connect to each instance of application"
|
93
|
+
group :lds, :diagnostics
|
94
|
+
input :app, :desc => "Application VisualVM will connect to", :argument => :optional,
|
95
|
+
:from_given => by_name(:app)
|
96
|
+
input :instance, :desc => "Application instance", :argument => :optional
|
97
|
+
input :host, :desc => "The local host to bind to for tunneling connections",
|
98
|
+
:default => "127.0.0.1", :aliases => "--host"
|
99
|
+
input :port, :desc => "The local port to listen on for tunneling connections",
|
100
|
+
:default => 1830, :aliases => "--port"
|
101
|
+
input :tunnel_server, :desc => "The server to connect to for tunneling to the application",
|
102
|
+
:aliases => "--server"
|
103
|
+
input :tunnel_server_port, :desc => "The port to connect to on the tunnel server",
|
104
|
+
:aliases => "--server-port", :default => 2014
|
105
|
+
input :use_tls, :desc => "Indicates if TLS should be used", :default => true
|
106
|
+
input :jvisualvm, :desc => "The location of the jvisualvm executable to be used", :aliases => "--jvisualvm"
|
107
|
+
def visualvm
|
108
|
+
if !File::exist?(JMXMP_JAR_FILE)
|
109
|
+
with_progress("Downloading JMXMP extension") do
|
110
|
+
File.open(JMXMP_JAR_FILE, "wb") do |saved_file|
|
111
|
+
open(JMXMP_JAR_URL, 'rb') do |read_file|
|
112
|
+
saved_file.write(read_file.read)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
tunnel_console do |instances|
|
118
|
+
visualvm = input[:jvisualvm] ? input[:jvisualvm] : "jvisualvm"
|
119
|
+
EventMachine::defer do
|
120
|
+
if system("#{visualvm} -cp:a #{JMXMP_JAR_FILE}") == nil
|
121
|
+
fail("Unable to run '#{visualvm}'. Is it in your PATH?")
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
EventMachine::defer do
|
126
|
+
# Give jvisualvm time to start up
|
127
|
+
sleep(5)
|
128
|
+
host = input[:host]
|
129
|
+
port = input[:port]
|
130
|
+
|
131
|
+
instances.each do |instance|
|
132
|
+
jmxurl = "service:jmx:jmxmp://#{host}:#{port}"
|
133
|
+
puts "Adding instance #{c('#' + instance.id, :instance)} to VisualVM (#{c(jmxurl, :instance)})"
|
134
|
+
system("#{visualvm} --openjmx #{jmxurl}")
|
135
|
+
port = port + 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def tunnel(app, instances, mode, &post_tunnel)
|
142
|
+
server = input[:tunnel_server] ? input[:tunnel_server] : URI(client.target).host
|
143
|
+
server_port = input[:tunnel_server_port]
|
144
|
+
|
145
|
+
host = input[:host]
|
146
|
+
port = input[:port]
|
147
|
+
|
148
|
+
line
|
149
|
+
|
150
|
+
EventMachine.error_handler do |e|
|
151
|
+
EventMachine.stop_event_loop
|
152
|
+
|
153
|
+
log_error(e)
|
154
|
+
end
|
155
|
+
|
156
|
+
EventMachine.run do
|
157
|
+
instances.each do |instance|
|
158
|
+
TunnelClient::tunnel(client.token.auth_header, server, server_port, app, instance.id, mode, host, port, input[:use_tls])
|
159
|
+
puts "Listening on #{c(host + ':' + port.to_s, :number)} for #{c(mode, :warning)} connections to forward to #{c(app.name, :name)} instance #{c('#' + instance.id, :instance)}."
|
160
|
+
port = port + 1
|
161
|
+
end
|
162
|
+
yield instances if post_tunnel
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
private
|
167
|
+
|
168
|
+
def ask_app
|
169
|
+
ask "Which application?", :choices => client.apps,
|
170
|
+
:display => proc(&:name)
|
171
|
+
end
|
172
|
+
|
173
|
+
def get_instances(app)
|
174
|
+
instances = with_progress ("Getting instances for #{c(app.name, :name)}") do
|
175
|
+
app.instances
|
176
|
+
end
|
177
|
+
|
178
|
+
fail "No instances of #{c(app.name, :name)} are running." if instances.length == 0
|
179
|
+
|
180
|
+
instances.sort! { |a, b| a.id.to_i <=> b.id.to_i }
|
181
|
+
|
182
|
+
if input[:instance]
|
183
|
+
instance = input[:instance].to_i
|
184
|
+
instances = [ instances[instance] ]
|
185
|
+
end
|
186
|
+
|
187
|
+
instances
|
188
|
+
end
|
189
|
+
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
metadata
CHANGED
@@ -1,69 +1,100 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: lds-cf-plugin
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.2.3
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Mike Heath
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2013-07-17 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: cfoundry
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.5.1
|
22
|
+
type: :runtime
|
17
23
|
prerelease: false
|
18
|
-
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
25
|
none: false
|
20
|
-
requirements:
|
21
|
-
- -
|
22
|
-
- !ruby/object:Gem::Version
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
23
29
|
version: 1.5.1
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: eventmachine
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '1.0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: json_pure
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '1.6'
|
24
54
|
type: :runtime
|
25
|
-
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.6'
|
26
62
|
description:
|
27
|
-
email:
|
63
|
+
email:
|
28
64
|
- heathma@ldschurch.org
|
29
65
|
executables: []
|
30
|
-
|
31
66
|
extensions: []
|
32
|
-
|
33
67
|
extra_rdoc_files: []
|
34
|
-
|
35
|
-
files:
|
68
|
+
files:
|
36
69
|
- Rakefile
|
37
70
|
- lib/lds-cf-plugin/custom_service.rb
|
38
71
|
- lib/lds-cf-plugin/oracle_service.rb
|
72
|
+
- lib/lds-cf-plugin/tunnel.rb
|
39
73
|
- lib/lds-cf-plugin/version.rb
|
40
74
|
- lib/lds-cf-plugin/plugin.rb
|
41
|
-
|
75
|
+
- lib/lds-cf-plugin/tunnel/tunnelclient.rb
|
76
|
+
homepage: http://ui.app.lds.org/
|
42
77
|
licenses: []
|
43
|
-
|
44
78
|
post_install_message:
|
45
79
|
rdoc_options: []
|
46
|
-
|
47
|
-
require_paths:
|
80
|
+
require_paths:
|
48
81
|
- lib
|
49
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
82
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
50
83
|
none: false
|
51
|
-
requirements:
|
52
|
-
- -
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version:
|
55
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
89
|
none: false
|
57
|
-
requirements:
|
58
|
-
- -
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version:
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
61
94
|
requirements: []
|
62
|
-
|
63
95
|
rubyforge_project:
|
64
|
-
rubygems_version: 1.8.
|
96
|
+
rubygems_version: 1.8.23
|
65
97
|
signing_key:
|
66
98
|
specification_version: 3
|
67
99
|
summary: Cloud Foundry commands for LDS PaaS.
|
68
100
|
test_files: []
|
69
|
-
|