Random Service port in a specific range.

Now the conductor get a random port for the service in a range of unused ports

Change-Id: Ifa51cc8d7a0459d46a72ea1c285b717932bbc94c
This commit is contained in:
Fabio Verboso 2020-03-02 15:01:04 +01:00
parent d407504102
commit c389793692
7 changed files with 68 additions and 10 deletions

View File

@ -15,6 +15,10 @@ auth_strategy=keystone
# value)
#pecan_debug=false
[conductor]
service_port_min=50000
service_port_max=60000
[wamp]
wamp_transport_url = ws://<host>:<port>/

View File

@ -616,6 +616,10 @@ class ServiceAlreadyExposed(Conflict):
message = _("A Service with UUID %(uuid)s already exposed.")
class NotEnoughPortForService(NotFound):
message = _("No ports available")
class ExposedServiceNotFound(NotFound):
message = _("ExposedService %(uuid)s could not be found.")

View File

@ -43,6 +43,8 @@ serializer = objects_base.IotronicObjectSerializer()
Port = list()
SERVICE_PORT_LIST = None
def versionCompare(v1, v2):
"""Method to compare two versions.
@ -104,8 +106,24 @@ def get_best_agent(ctx):
return agent.hostname
def random_public_port():
return random.randint(50001, 59999)
def random_public_port(ctx=None):
global SERVICE_PORT_LIST
if not SERVICE_PORT_LIST:
# empty, create a cache list
min = cfg.CONF.conductor.service_port_min + 1
max = cfg.CONF.conductor.service_port_max - 1
LOG.debug('recreate service port list cache: min %i max %i', min, max)
full_list = (range(min, max))
exp_list = objects.ExposedService.get_all_ports(ctx)
SERVICE_PORT_LIST = list(set(full_list) - set(exp_list))
if len(SERVICE_PORT_LIST) == 0:
LOG.warning('No more ports available')
return None
else:
num = random.choice(SERVICE_PORT_LIST)
SERVICE_PORT_LIST.remove(num)
return num
def manage_result(res, wamp_rpc_call, board_uuid):
@ -477,6 +495,9 @@ class ConductorEndpoint(object):
except Exception:
public_port = random_public_port()
if not public_port:
return exception.NotEnoughPortForService()
res = self.execute_on_board(ctx, board_uuid, action,
(service, public_port))
result = manage_result(res, action, board_uuid)
@ -504,6 +525,11 @@ class ConductorEndpoint(object):
result = manage_result(res, action, board_uuid)
LOG.debug(res.message)
global SERVICE_PORT_LIST
try:
SERVICE_PORT_LIST.append(exposed.public_port)
except exception:
pass
exposed.destroy()
return result
@ -799,9 +825,10 @@ class ConductorEndpoint(object):
except Exception:
# TO BE CHANGED
https_port = random_public_port()
http_port = random_public_port()
if not https_port or not http_port:
return exception.NotEnoughPortForService()
en_webservice = {
'board_uuid': board.uuid,
@ -918,6 +945,11 @@ class ConductorEndpoint(object):
res = self.execute_on_board(ctx, board.uuid, "ServiceDisable",
(service,), main_req=mreq.uuid)
LOG.debug(res.message)
global SERVICE_PORT_LIST
try:
SERVICE_PORT_LIST.append(exposed.public_port)
except exception:
pass
exposed.destroy()
try:

View File

@ -40,6 +40,12 @@ conductor_opts = [
help='Maximum time (in seconds) since the last check-in '
'of a conductor. A conductor is considered inactive '
'when this time has been exceeded.'),
cfg.IntOpt('service_port_min',
default=50000,
help='Min value for genereting random ports for services'),
cfg.IntOpt('service_port_max',
default=60000,
help='Max value for genereting random ports for services'),
]
CONF = cfg.CONF

View File

@ -911,9 +911,13 @@ class Connection(api.Connection):
raise exception.ExposedServiceNotFound()
def get_exposed_service_list(self, board_uuid):
if board_uuid:
query = model_query(
models.ExposedService).filter_by(
board_uuid=board_uuid)
else:
query = model_query(
models.ExposedService)
return query.all()
def _do_update_exposed_service(self, service_id, values):

View File

@ -31,6 +31,14 @@ class ExposedService(base.IotronicObject):
'public_port': int
}
@base.remotable_classmethod
def get_all_ports(cls, context):
ls = cls.list(context)
ports = []
for x in ls:
ports.append(x.public_port)
return ports
@staticmethod
def _from_db_object(exposed_service, db_exposed_service):
"""Converts a database entity to a formal object."""
@ -96,7 +104,7 @@ class ExposedService(base.IotronicObject):
return exp_service
@base.remotable_classmethod
def list(cls, context, board_uuid):
def list(cls, context, board_uuid=None):
"""Return a list of ExposedService objects.
:param context: Security context.

View File

@ -1,6 +1,6 @@
[tox]
minversion = 2.3.1
envlist = py3,pep8
envlist = py35,pep8
skipsdist = True
[testenv]
@ -22,8 +22,8 @@ commands =
basepython = python2.7
commands = flake8 {posargs}
[testenv:py3]
basepython = python3
[testenv:py35]
basepython = python3.5
[flake8]