2
# Programmer: Chris Bunch
5
require 'soap/rpc/driver'
8
IP_REGEX = /\d+\.\d+\.\d+\.\d+/
9
FQDN_REGEX = /[\w\d\.\-]+/
10
IP_OR_FQDN = /#{IP_REGEX}|#{FQDN_REGEX}/
16
class AppControllerClient
17
attr_reader :conn, :ip, :secret
19
def initialize(ip, secret)
23
@conn = SOAP::RPC::Driver.new("https://#{@ip}:17443")
24
@conn.add_method("set_parameters", "djinn_locations", "database_credentials", "app_names", "secret")
25
@conn.add_method("status", "secret")
26
@conn.add_method("update", "app_names", "secret")
27
@conn.add_method("stop_app", "app_name", "secret")
28
@conn.add_method("get_all_public_ips", "secret")
29
@conn.add_method("backup_appscale", "backup_in_info", "secret")
30
@conn.add_method("kill", "secret")
33
def make_call(time, retry_on_except)
38
Timeout::timeout(time) {
41
rescue Errno::ECONNREFUSED
42
if refused_count > max
43
abort("Connection was refused. Is the AppController running?")
49
rescue OpenSSL::SSL::SSLError, NotImplementedError, Timeout::Error
51
rescue Exception => except
55
abort("We saw an unexpected error of the type #{except.class} with the following message:\n#{except}.")
60
def get_userappserver_ip(verbose_level="low")
61
userappserver_ip, status, state, new_state = "", "", "", ""
65
new_state = status.scan(/Current State: ([\w\s\d\.,]+)\n/).flatten.to_s.chomp
66
if verbose_level == "high" and new_state != state
71
if status == "false: bad secret"
72
abort("\nWe were unable to verify your secret key with the head node specified in your locations file. Are you sure you have the correct secret key and locations file?\n\nSecret provided: [#{@secret}]\nHead node IP address: [#{@ip}]\n")
75
if status =~ /Database is at (#{IP_OR_FQDN})/ and $1 != "not-up-yet"
83
return userappserver_ip
86
def set_parameters(locations, creds, apps_to_start)
88
make_call(10, ABORT_ON_FAIL) {
89
result = conn.set_parameters(locations, creds, apps_to_start, @secret)
91
abort(result) if result =~ /Error:/
94
def status(print_output=true)
98
puts "Status of node at #{ip}:"
106
make_call(10, RETRY_ON_FAIL) { @conn.status(@secret) }
109
def stop_app(app_name)
110
make_call(30, RETRY_ON_FAIL) { @conn.stop_app(app_name, @secret) }
113
def update(app_names)
114
make_call(30, RETRY_ON_FAIL) { @conn.update(app_names, @secret) }
117
def get_all_public_ips()
118
make_call(30, RETRY_ON_FAIL) { @conn.get_all_public_ips(@secret) }
121
def backup_appscale(backup_info)
122
make_call(NO_TIMEOUT, RETRY_ON_FAIL) { @conn.backup_appscale(backup_info, @secret) }
126
make_call(NO_TIMEOUT, RETRY_ON_FAIL) { @conn.kill(@secret) }