Commit 88d5383f authored by Jérome Perrin's avatar Jérome Perrin

proxy: bypass simple frontend requests by returning URL

When slapproxy is not using multi-master, shared frontend requests
were never fulfilled. This is problematic because several promises (for
example monitor ones) assert that frontend is instanciated and properly
responding to HTTP requests.
Better-than-nothing approach is to return the URL provided as input,
ie: "Give me a frontend for $URL" -> "OK, just use $URL".
parent 8c3860de
......@@ -44,6 +44,7 @@ from slapos.util import loads, dumps
import six
from six.moves import range
from six.moves.urllib.parse import urlparse
app = Flask(__name__)
......@@ -391,12 +392,32 @@ def supplySupply():
@app.route('/requestComputerPartition', methods=['POST'])
def requestComputerPartition():
parsed_request_dict = parseRequestComputerPartitionForm(request.form)
# Is it a slave instance?
slave = loads(request.form.get('shared_xml', EMPTY_DICT_XML).encode('utf-8'))
# Check first if instance is already allocated
if slave:
# slapproxy cannot request frontends, but if client request a "simple" frontend for an URL
# we can tell this client to use the URL directly.
apache_frontend_sr_url_list = (
'http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg',
)
if not isRequestToBeForwardedToExternalMaster(parsed_request_dict)\
and parsed_request_dict['software_release'] in apache_frontend_sr_url_list \
and parsed_request_dict.get('software_type', '') in ('', 'RootSoftwareInstance', 'default'):
url = parsed_request_dict['partition_parameter_kw'].get('url')
if url:
app.logger.warning("Bypassing frontend for %s => %s", parsed_request_dict, url)
partition = ComputerPartition('', 'Fake frontend for {}'.format(url))
partition.slap_computer_id = ''
partition.slap_computer_partition_id = ''
partition._parameter_dict = {}
partition._connection_dict = {
'secure_access': url,
'domain': urlparse(url).netloc,
}
return dumps(partition)
# XXX: change schema to include a simple "partition_reference" which
# is name of the instance. Then, no need to do complex search here.
slave_reference = parsed_request_dict['partition_id'] + '_' + parsed_request_dict['partition_reference']
......
......@@ -682,6 +682,22 @@ class TestRequest(MasterMixin):
partition_new = self.request('http://sr//', None, 'myinstance', 'slappart0')
self.assertEqual(partition_new.getConnectionParameter('foo'), '1')
def test_request_frontend(self):
# slapproxy tells client to bypass "simple" frontends by just using the URL.
request = self.request(
'http://git.erp5.org/gitweb/slapos.git/blob_plain/HEAD:/software/apache-frontend/software.cfg',
None,
self.id(),
'slappart0',
shared=True,
partition_parameter_kw={'url': 'https://[::1]:123/', })
self.assertEqual(
'https://[::1]:123/',
request.getConnectionParameterDict()['secure_access'])
self.assertEqual(
'[::1]:123',
request.getConnectionParameterDict()['domain'])
class TestSlaveRequest(MasterMixin):
"""
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment