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 "yajl"
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 = Yajl::Parser.new.parse(credentials)
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 => Yajl::Encoder.encode(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 "yajl"
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 => Yajl::Encoder.encode(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. See details below:\n#{response[:body]}"
78
+ fail "Error registering Oracle service with gateway:\n#{response[:body]}"
79
79
  end
80
80
 
81
81
 
@@ -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
@@ -1,3 +1,3 @@
1
1
  module LdsCfPlugin
2
- VERSION = "0.2.3".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  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
- date: 2013-06-27 00:00:00 Z
14
- dependencies:
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
- requirement: &id001 !ruby/object:Gem::Requirement
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
- version_requirements: *id001
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
- homepage: http://cloudfoundry.com/
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: "0"
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: "0"
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
61
94
  requirements: []
62
-
63
95
  rubyforge_project:
64
- rubygems_version: 1.8.24
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
-