Skip to content

Commit

Permalink
Communicate with ejabberd using private IP address
Browse files Browse the repository at this point in the history
  • Loading branch information
cdonati committed Dec 6, 2018
1 parent 719dcf5 commit 9bb5986
Show file tree
Hide file tree
Showing 19 changed files with 124 additions and 68 deletions.
3 changes: 2 additions & 1 deletion AdminServer/appscale/admin/instance_manager/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ def create_java_start_cmd(app_name, port, load_balancer_host, max_heap,
"--APP_NAME=" + app_name,
"--NGINX_ADDRESS=" + load_balancer_host,
"--TQ_PROXY=" + options.tq_proxy,
"--xmpp_path=" + options.load_balancer_ip,
"--pidfile={}".format(pidfile),
"--external_api_port={}".format(api_server_port),
"--api_using_python_stub=app_identity_service",
Expand Down Expand Up @@ -163,7 +164,7 @@ def create_python27_start_cmd(app_name, login_ip, port, pidfile, revision_key,
"--nginx_host " + str(login_ip),
"--require_indexes",
"--enable_sendmail",
"--xmpp_path " + login_ip,
"--xmpp_path " + options.load_balancer_ip,
"--php_executable_path=" + str(PHP_CGI_LOCATION),
"--uaserver_path " + options.db_proxy + ":" + str(UA_SERVER_PORT),
"--datastore_path " + options.db_proxy + ":" + str(DB_SERVER_PORT),
Expand Down
1 change: 1 addition & 0 deletions AdminServer/appscale/admin/instance_manager/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def main():
options.define('private_ip', appscale_info.get_private_ip())
options.define('syslog_server', appscale_info.get_headnode_ip())
options.define('db_proxy', appscale_info.get_db_proxy())
options.define('load_balancer_ip', appscale_info.get_load_balancer_ips()[0])
options.define('tq_proxy', appscale_info.get_tq_proxy())
options.define('secret', appscale_info.get_secret())

Expand Down
1 change: 1 addition & 0 deletions AdminServer/tests/test_instance_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
options.define('private_ip', '<private_ip>')

options.define('db_proxy', '<private_ip>')
options.define('load_balancer_ip', '<private_ip>')
options.define('tq_proxy', '<private_ip>')


Expand Down
9 changes: 5 additions & 4 deletions AppController/djinn.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4066,7 +4066,6 @@ def regenerate_routing_config
Djinn.log_debug("Regenerating nginx and haproxy config files for apps.")
my_public = my_node.public_ip
my_private = my_node.private_ip
login_ip = @options['login']

@versions_loaded.each { |version_key|
project_id, service_id, version_id = version_key.split(
Expand Down Expand Up @@ -4154,7 +4153,8 @@ def regenerate_routing_config

Nginx.write_fullproxy_version_config(
version_key, http_port, https_port, my_public, my_private,
proxy_port, static_handlers, login_ip, app_language)
proxy_port, static_handlers, get_load_balancer.private_ip,
app_language)
end
}
Djinn.log_debug("Done updating nginx and haproxy config files.")
Expand Down Expand Up @@ -4438,7 +4438,7 @@ def start_ejabberd
@state = "Starting up XMPP server"
my_public = my_node.public_ip
Djinn.log_run("rm -f /var/lib/ejabberd/*")
Ejabberd.write_config_file(my_public)
Ejabberd.write_config_file(my_public, my_node.private_ip)
Ejabberd.update_ctl_config

# Monit does not have an entry for ejabberd yet. This allows a restart
Expand Down Expand Up @@ -5663,7 +5663,8 @@ def start_xmpp_for_app(app)

if Ejabberd.does_app_need_receive?(app)
start_cmd = "#{PYTHON27} #{APPSCALE_HOME}/XMPPReceiver/" \
"xmpp_receiver.py #{app} #{login_ip} #{@@secret}"
"xmpp_receiver.py #{app} #{login_ip} " \
"#{get_load_balancer.private_ip} #{@@secret}"
MonitInterface.start(watch_name, start_cmd)
Djinn.log_debug("App #{app} does need xmpp receive functionality")
else
Expand Down
11 changes: 9 additions & 2 deletions AppController/lib/ejabberd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def self.update_ctl_config
end
end

def self.write_config_file(my_private_ip)
def self.write_config_file(domain, my_private_ip)
config_file = 'ejabberd.yml'
begin
ejabberd_version = get_ejabberd_version
Expand All @@ -133,7 +133,14 @@ def self.write_config_file(my_private_ip)
template = "#{APPSCALE_HOME}/AppController/templates/#{config_file}"
config = File.read(template)

config.gsub!('APPSCALE-HOST', my_private_ip)
config.gsub!('APPSCALE-HOST', domain)
if config_file == 'ejabberd.yml'
config.gsub!('APPSCALE-PRIVATE-IP', my_private_ip)
else
# Convert IP address to Erlang tuple.
ip_tuple = "{#{my_private_ip.gsub('.', ',')}}"
config.gsub!('APPSCALE-PRIVATE-IP', ip_tuple)
end
config.gsub!('APPSCALE-CERTFILE',
"#{Djinn::APPSCALE_CONFIG_DIR}/ejabberd.pem")
config.gsub!('APPSCALE-AUTH-SCRIPT', AUTH_SCRIPT_LOCATION)
Expand Down
6 changes: 3 additions & 3 deletions AppController/lib/nginx.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def self.check_config
# Returns:
# boolean: indicates if the nginx configuration has been written.
def self.write_fullproxy_version_config(version_key, http_port, https_port,
my_public_ip, my_private_ip, proxy_port, static_handlers, login_ip,
my_public_ip, my_private_ip, proxy_port, static_handlers, load_balancer_ip,
language)

parsing_log = "Writing proxy for #{version_key} with language " \
Expand Down Expand Up @@ -284,7 +284,7 @@ def self.write_fullproxy_version_config(version_key, http_port, https_port,
proxy_buffering off;
tcp_nodelay on;
keepalive_timeout 600;
proxy_pass http://#{login_ip}:#{CHANNELSERVER_PORT}/http-bind;
proxy_pass http://#{load_balancer_ip}:#{CHANNELSERVER_PORT}/http-bind;
proxy_read_timeout 120;
}
}
Expand Down Expand Up @@ -323,7 +323,7 @@ def self.write_fullproxy_version_config(version_key, http_port, https_port,
proxy_buffering off;
tcp_nodelay on;
keepalive_timeout 600;
proxy_pass http://#{login_ip}:#{CHANNELSERVER_PORT}/http-bind;
proxy_pass http://#{load_balancer_ip}:#{CHANNELSERVER_PORT}/http-bind;
proxy_read_timeout 120;
}
}
Expand Down
3 changes: 3 additions & 0 deletions AppController/templates/ejabberd.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@
{listen,
[
{5222, ejabberd_c2s, [
{ip, APPSCALE-PRIVATE-IP},
{access, c2s},
{shaper, c2s_shaper},
{max_stanza_size, 65536},
Expand All @@ -132,6 +133,7 @@
%% ]},

{5269, ejabberd_s2s_in, [
{ip, APPSCALE-PRIVATE-IP},
{shaper, s2s_shaper},
{max_stanza_size, 131072}
]},
Expand Down Expand Up @@ -187,6 +189,7 @@
%% ]},

{5280, ejabberd_http, [
{ip, APPSCALE-PRIVATE-IP},
%%{request_handlers,
%% [
%% {["pub", "archive"], mod_http_fileserver}
Expand Down
6 changes: 3 additions & 3 deletions AppController/templates/ejabberd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ hosts:
listen:
-
port: 5222
ip: "::"
ip: "APPSCALE-PRIVATE-IP"
module: ejabberd_c2s
##
## If TLS is compiled in and you installed a SSL
Expand All @@ -127,7 +127,7 @@ listen:
resend_on_timeout: if_offline
-
port: 5269
ip: "::"
ip: "APPSCALE-PRIVATE-IP"
module: ejabberd_s2s_in
##
## ejabberd_service: Interact with external components (transports, ...)
Expand Down Expand Up @@ -161,7 +161,7 @@ listen:
## access_commands: {}
-
port: 5280
ip: "::"
ip: "APPSCALE-PRIVATE-IP"
module: ejabberd_http
request_handlers:
"/websocket": ejabberd_http_ws
Expand Down
16 changes: 10 additions & 6 deletions AppServer/google/appengine/api/xmpp/test/test_xmpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ def setUp(self):
# and set up some instance variables to clean up our tests
self.appid = "my-app"
self.domain = "domain"
self.ejabberd_ip = 'ejabberd_ip'
self.xmpp_port = 5222
self.uasecret = "boo"
self.message = "the message"
self.message_type = 'chat'
Expand Down Expand Up @@ -55,8 +57,8 @@ def test_send_xmpp_message(self):

# set up a fake xmpp client
fake_xmpp_client = flexmock(name='xmpp')
fake_xmpp_client.should_receive('connect').with_args(secure=False) \
.and_return()
fake_xmpp_client.should_receive('connect').with_args(
(self.ejabberd_ip, self.xmpp_port), secure=False)
fake_xmpp_client.should_receive('auth').with_args(self.appid, self.uasecret,
resource='').and_return()
fake_xmpp_client.should_receive('send').with_args(
Expand All @@ -66,7 +68,8 @@ def test_send_xmpp_message(self):
xmpppy.should_receive('Client').with_args(self.domain, debug=[]) \
.and_return(fake_xmpp_client)

xmpp = xmpp_service_real.XmppService(log=logging.info, service_name='xmpp',
xmpp = xmpp_service_real.XmppService(
self.ejabberd_ip, log=logging.info, service_name='xmpp',
domain=self.domain, uaserver='public-ip', uasecret=self.uasecret)

# Set up a mocked XMPPRequest, that contains the message we want to send and
Expand Down Expand Up @@ -104,8 +107,8 @@ def test_send_channel_message(self):

# set up a fake xmpp client
fake_xmpp_client = flexmock(name='xmpp')
fake_xmpp_client.should_receive('connect').with_args(secure=False) \
.and_return()
fake_xmpp_client.should_receive('connect').with_args(
(self.ejabberd_ip, self.xmpp_port), secure=False)
fake_xmpp_client.should_receive('auth').with_args(self.appid, self.uasecret,
resource='').and_return()
fake_xmpp_client.should_receive('send').with_args(
Expand All @@ -115,7 +118,8 @@ def test_send_channel_message(self):
xmpppy.should_receive('Client').with_args(self.domain, debug=[]) \
.and_return(fake_xmpp_client)

xmpp = xmpp_service_real.XmppService(log=logging.info, service_name='xmpp',
xmpp = xmpp_service_real.XmppService(
self.ejabberd_ip, log=logging.info, service_name='xmpp',
domain=self.domain, uaserver='public-ip', uasecret=self.uasecret)

# Set up a mocked XMPPRequest, that contains the message we want to send and
Expand Down
24 changes: 16 additions & 8 deletions AppServer/google/appengine/api/xmpp/xmpp_service_real.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,23 @@ class XmppService(apiproxy_stub.APIProxyStub):
support is also in this file.
"""

def __init__(self,
log=logging.info,
service_name='xmpp',
domain="localhost",
uaserver="localhost",
uasecret=""):
# The port that ejabberd uses for the XMPP API.
PORT = 5222

def __init__(self, xmpp_location, log=logging.info, service_name='xmpp',
domain="localhost", uaserver="localhost", uasecret=""):
"""Initializer.
Args:
xmpp_location: A string specifying the private IP of the ejabberd node
to use.
log: A logger, used for dependency injection.
service_name: Service name expected for all calls.
domain: A string specifying the domain of the xmpp user used to
authenticate.
uaserver: A string specifying the private IP address of the UAServer.
uasecret: A string specifying the key used to authenticate UAServer
requests.
"""
super(XmppService, self).__init__(service_name)
self.log = log
Expand All @@ -70,6 +76,8 @@ def __init__(self,

self.uasecret = uasecret

self._xmpp_location = xmpp_location

def _Dynamic_GetPresence(self, request, response):
"""Implementation of XmppService::GetPresence.
Expand Down Expand Up @@ -109,7 +117,7 @@ def _Dynamic_SendMessage(self, request, response):

my_jid = xmpppy.protocol.JID(xmpp_username)
client = xmpppy.Client(my_jid.getDomain(), debug=[])
client.connect(secure=False)
client.connect((self._xmpp_location, self.PORT), secure=False)
client.auth(my_jid.getNode(), self.uasecret, resource=my_jid.getResource())

for jid in request.jid_list():
Expand Down Expand Up @@ -242,7 +250,7 @@ def _Dynamic_SendChannelMessage(self, request, response):
xmpp_username = appname + "@" + self.xmpp_domain
my_jid = xmpppy.protocol.JID(xmpp_username)
client = xmpppy.Client(my_jid.getDomain(), debug=[])
client.connect(secure=False)
client.connect((self._xmpp_location, self.PORT), secure=False)
client.auth(my_jid.getNode(), self.uasecret, resource=my_jid.getResource())

message = xmpppy.protocol.Message(frm=xmpp_username, to=jid,
Expand Down
3 changes: 2 additions & 1 deletion AppServer/google/appengine/tools/dev_appserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -3616,7 +3616,8 @@ def SetupStubs(app_id, **config):

apiproxy_stub_map.apiproxy.RegisterStub(
'xmpp',
xmpp_service_real.XmppService(domain=xmpp_path, uaserver=uaserver_path))
xmpp_service_real.XmppService(xmpp_path, domain=login_server,
uaserver=uaserver_path))

apiproxy_stub_map.apiproxy.RegisterStub(
'logservice',
Expand Down
13 changes: 9 additions & 4 deletions AppServer/google/appengine/tools/devappserver2/api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,8 @@ def setup_stubs(
user_logout_url,
default_gcs_bucket_name,
uaserver_path,
xmpp_path):
xmpp_path,
xmpp_domain):
"""Configures the APIs hosted by this server.
Args:
Expand Down Expand Up @@ -292,6 +293,7 @@ def setup_stubs(
of the machine that runs a UserAppServer.
xmpp_path: (AppScale-specific) A str containing the FQDN or IP address of
the machine that runs ejabberd, where XMPP clients should connect to.
xmpp_domain: A string specifying the domain portion of the XMPP user.
"""

identity_stub = app_identity_stub.AppIdentityServiceStub()
Expand Down Expand Up @@ -396,7 +398,8 @@ def setup_stubs(

apiproxy_stub_map.apiproxy.RegisterStub(
'xmpp',
xmpp_service_real.XmppService(domain=xmpp_path, uaserver=uaserver_path))
xmpp_service_real.XmppService(xmpp_path, domain=xmpp_domain,
uaserver=uaserver_path))

apiproxy_stub_map.apiproxy.RegisterStub(
'matcher',
Expand Down Expand Up @@ -488,7 +491,8 @@ def test_setup_stubs(
user_logout_url='/_ah/login?continue=%s',
default_gcs_bucket_name=None,
uaserver_path='localhost',
xmpp_path='localhost'):
xmpp_path='localhost',
xmpp_domain='localhost'):
"""Similar to setup_stubs with reasonable test defaults and recallable."""

# Reset the stub map between requests because a stub map only allows a
Expand Down Expand Up @@ -524,7 +528,8 @@ def test_setup_stubs(
user_logout_url,
default_gcs_bucket_name,
uaserver_path,
xmpp_path)
xmpp_path,
xmpp_domain)


def cleanup_stubs():
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,8 @@ def start(self, options):
user_logout_url=user_logout_url,
default_gcs_bucket_name=options.default_gcs_bucket_name,
uaserver_path=options.uaserver_path,
xmpp_path=options.xmpp_path)
xmpp_path=options.xmpp_path,
xmpp_domain=options.login_server)

# The APIServer must bind to localhost because that is what the runtime
# instances talk to.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ public ApiBasePb.VoidProto sendChannelMessage(LocalRpcService.Status status, Cha
String domain = getDomain();
String applicationKey = request.getApplicationKey();
String from = appId + "@" + domain;
String xmppPath = System.getProperty("XMPP_PATH");

AppScaleXMPPClient xmppClient = new AppScaleXMPPClient(appId, secret, domain, XMPP_PORT);
AppScaleXMPPClient xmppClient = new AppScaleXMPPClient(appId, secret, xmppPath, XMPP_PORT, domain);

String uniqueAppId = getSha1AsString(appId + applicationKey);
String toJid = "channel~" + uniqueAppId + "~" + applicationKey + "@" + domain;
Expand Down
Loading

0 comments on commit 9bb5986

Please sign in to comment.