-
Notifications
You must be signed in to change notification settings - Fork 0
/
tomcat_manager_by_curl.rb
143 lines (122 loc) · 2.87 KB
/
tomcat_manager_by_curl.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env ruby
# vim:ai:sw=2:ts=2
# Provides a ruby wrapper for accessing the Tomcat management REST API through Curl.
# The reason for using Curl instead of direct net/http access is to allow this library
# to be used with Capistrano (or net/ssh).
# Interface to create Curl commands agains the Tomcat endpoint.
class Curl
def initialize(host, port, user, password)
@host, @port, @user, @password = host, port, user, password
end
def command(name, options = {})
base = "curl -s -u #{@user}:#{@password} http://#{@host}:#{@port}/manager/#{name}"
unless options.empty?
base << "?" + options.map{|k,v| "#{k}=#{v}"}.join('&')
end
return Command.new(name, base)
end
# Wraps the command-line for Curl, and the concrete Command class that can handle the output from the command.
class Command
attr_reader :name, :command_line
def initialize(name, command_line)
@name, @command_line = name, command_line
end
def run_local
puts "Executing #{@command_line}"
return response(`#{@command_line}`)
end
def response(curl_output)
klass = case @name
when 'list'
ListResponse
when 'roles'
RolesResponse
when 'resources'
ResourcesResponse
when 'serverinfo'
ServerInfoResponse
else
Response
end
klass.new(curl_output)
end
class Response
attr_reader :summary, :lines
def initialize(curl_output)
@summary = curl_output
@lines = curl_output.split("\n").map{|l| l.strip}
prepare unless fail?
end
def message
@lines.first
end
def fail?
message =~ /^FAIL/ ? true : false
end
protected
def prepare
# 'Abstract' method impl. by subclasses.
end
end
class TupleResponse < Response
attr_reader :tuples
def find_by(key, value)
@tuples.select do |tuple|
tuple[key] == value
end
end
def prepare
@tuples = []
keys = partitions() # Get partitions.
if keys
@lines[1..-1].each do |line|
tuple = line.split(":")
hash = {}
keys.each do |k|
hash[k] = tuple[keys.index(k)]
end
@tuples << hash
end
end
end
def partitions
nil # Override in subclasses.
end
end
class ListResponse < TupleResponse
def partitions
[:path, :status, :sessions, :name]
end
end
class RolesResponse < TupleResponse
def partitions
[:name, :description]
end
end
class ResourcesResponse < TupleResponse
def partitions
[:name, :type]
end
end
class ServerInfoResponse < TupleResponse
def partitions
[:property, :value]
end
end
end
end
if __FILE__ == $0
require 'pp'
command = ARGV.shift
options = {}
ARGV.map{|pair| pair.split("=", 2)}.each do |k,v|
options[k.to_sym] = v
end
curl = Curl.new('localhost', 8080, 'admin', 'admin')
curl_command = curl.command(command, options)
response = curl_command.run_local
pp response
puts "Command Failed: #{response.fail?}"
puts "Summary:"
puts response.summary
end