Skip to content

Commit 6b70d66

Browse files
committed
patch for sdn-base
For differences between sdn-base and 9.8-stable branch(commit 46e2320). Note: version in __init__.py is modified to be 5.0.0 here.
1 parent 14d8557 commit 6b70d66

14 files changed

Lines changed: 475 additions & 109 deletions

f5_openstack_agent/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
# actually patched to 46e2320 of 9.8-stable althougn it is 5.0.0 here
12
__version__ = "5.0.0"

f5_openstack_agent/lbaasv2/drivers/bigip/agent.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@
1616

1717
import errno
1818
import inspect
19+
import service_launcher
1920
import sys
2021

2122
import f5_openstack_agent.lbaasv2.drivers.bigip.exceptions as exceptions
2223

2324
try:
2425
from oslo_config import cfg
2526
from oslo_log import log as oslo_logging
26-
from oslo_service import service
2727
except ImportError as CriticalError:
2828
frame = inspect.getframeinfo(inspect.currentframe())
2929
CriticalError = \
@@ -77,14 +77,12 @@ def main():
7777
"""F5 LBaaS agent for OpenStack."""
7878
cfg.CONF.register_opts(OPTS)
7979
cfg.CONF.register_opts(manager.OPTS)
80-
# pzhang(NOTE): may not be used anywhere, needs to check
8180
cfg.CONF.register_opts(INTERFACE_OPTS)
8281

8382
config.register_agent_state_opts_helper(cfg.CONF)
8483
config.register_root_helper(cfg.CONF)
8584

8685
common_config.init(sys.argv[1:])
87-
# alias for common_config.setup_logging()...
8886
config.setup_logging()
8987

9088
mgr = manager.LbaasAgentManager(cfg.CONF)
@@ -94,7 +92,18 @@ def main():
9492
topic=f5constants.TOPIC_LOADBALANCER_AGENT_V2,
9593
manager=mgr
9694
)
97-
service.launch(cfg.CONF, svc).wait()
95+
96+
def handler(*args):
97+
LOG.info("receive signal to refresh ESD files!")
98+
if mgr.lbdriver.esd_processor:
99+
mgr.lbdriver.init_esd()
100+
LOG.info("ESD has been refreshed")
101+
102+
service_launch = service_launcher.F5ServiceLauncher(cfg.CONF)
103+
104+
service_launch.signal_handler.add_handler('SIGUSR1', handler)
105+
service_launch.launch_service(svc)
106+
service_launch.wait()
98107

99108

100109
if __name__ == '__main__':

f5_openstack_agent/lbaasv2/drivers/bigip/agent_manager.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@
129129
default=60,
130130
help=(
131131
'Amount of time to wait for a errored service to become active')
132+
),
133+
cfg.BoolOpt(
134+
'password_cipher_mode',
135+
default=False,
136+
help='The flag indicating the password is plain text or not.'
137+
),
138+
cfg.BoolOpt(
139+
'esd_auto_refresh',
140+
default=True,
141+
help='Enable ESD file periodic refresh'
132142
)
133143
]
134144

@@ -324,6 +334,9 @@ def __init__(self, conf):
324334
self._report_state)
325335
heartbeat.start(interval=report_interval)
326336

337+
if self.lbdriver:
338+
self.lbdriver.connect()
339+
327340
def _load_driver(self, conf):
328341
self.lbdriver = None
329342

@@ -489,6 +502,13 @@ def connect_driver(self, context):
489502
if self.lbdriver:
490503
self.lbdriver.connect()
491504

505+
@periodic_task.periodic_task(spacing=PERIODIC_TASK_INTERVAL)
506+
def refresh_esd(self, context):
507+
"""Refresh ESD files."""
508+
if self.lbdriver.esd_processor and self.conf.esd_auto_refresh:
509+
LOG.info("refresh ESD files automatically")
510+
self.lbdriver.init_esd()
511+
492512
@periodic_task.periodic_task(spacing=PERIODIC_TASK_INTERVAL)
493513
def recover_errored_devices(self, context):
494514
"""Try to reconnect to errored devices."""

f5_openstack_agent/lbaasv2/drivers/bigip/esd_filehandler.py

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515
#
1616

17+
import copy
1718
import glob
1819
import json
1920
import os
@@ -31,56 +32,50 @@
3132
LOG = logging.getLogger(__name__)
3233

3334

34-
class EsdJSONValidation(object):
35-
"""Class reads the json file(s)
35+
class EsdTagProcessor(object):
36+
"""Class processes json dictionary
3637
37-
It checks and parses the content of json file(s) to a dictionary
38+
It checks compares the tags from esdjson dictionary to list of valid tags
3839
"""
39-
def __init__(self, esddir):
40-
self.esdJSONFileList = glob.glob(os.path.join(esddir, '*.json'))
41-
self.esdJSONDict = {}
42-
43-
def read_json(self):
44-
for fileList in self.esdJSONFileList:
40+
_instance = None
41+
esd_dict = {}
42+
43+
def __new__(cls, *args, **kwargs):
44+
if not isinstance(cls._instance, cls):
45+
cls._instance = object.__new__(cls, *args, **kwargs)
46+
return cls._instance
47+
48+
def read_json(self, esddir):
49+
esdJSONFileList = glob.glob(os.path.join(esddir, '*.json'))
50+
esdJSONDict = {}
51+
for fileList in esdJSONFileList:
4552
try:
4653
with open(fileList) as json_file:
4754
# Reading each file to a dictionary
4855
fileJSONDict = json.load(json_file)
4956
# Combine all dictionaries to one
50-
self.esdJSONDict.update(fileJSONDict)
57+
esdJSONDict.update(fileJSONDict)
5158

5259
except ValueError as err:
5360
LOG.error('ESD JSON File is invalid: %s', err)
5461
raise f5_ex.esdJSONFileInvalidException()
5562

56-
return self.esdJSONDict
57-
58-
59-
class EsdTagProcessor(EsdJSONValidation):
60-
"""Class processes json dictionary
61-
62-
It checks compares the tags from esdjson dictionary to list of valid tags
63-
"""
64-
def __init__(self, esddir):
65-
super(EsdTagProcessor, self).__init__(esddir)
66-
67-
# this function will return intersection of known valid esd tags
68-
# and the ones that user provided
69-
def valid_tag_key_subset(self):
70-
self.validtags = list(set(self.esdJSONDict.keys()) &
71-
set(self.valid_esd_tags.keys()))
72-
if not self.validtags:
73-
LOG.error("Intersect of valid esd tags and user esd tags is empty")
74-
75-
if set(self.validtags) != set(self.esdJSONDict.keys()):
76-
LOG.error("invalid tags in the user esd tags")
63+
return esdJSONDict
7764

78-
def process_esd(self, bigips):
65+
def process_esd(self, bigips, esddir):
66+
esd_json_backup = {}
67+
esd_json_backup = copy.deepcopy(self.esd_dict)
7968
try:
80-
dict = self.read_json()
69+
dict = self.read_json(esddir)
8170
self.esd_dict = self.verify_esd_dict(bigips, dict)
8271
except f5_ex.esdJSONFileInvalidException:
83-
self.esd_dict = {}
72+
# if error happens, we set backup esd.
73+
self.esd_dict = copy.deepcopy(esd_json_backup)
74+
LOG.warning(
75+
"ESD JSON File is invalid, "
76+
"ESD JSON Dict is restored to %s",
77+
esd_json_backup
78+
)
8479
raise
8580

8681
def get_esd(self, name):

f5_openstack_agent/lbaasv2/drivers/bigip/icontrol_driver.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# limitations under the License.
1515
#
1616

17+
import base64
1718
import datetime
1819
import hashlib
1920
import json
@@ -334,7 +335,7 @@ class iControlDriver(LBaaSBaseDriver):
334335
def __init__(self, conf, registerOpts=True):
335336
# The registerOpts parameter allows a test to
336337
# turn off config option handling so that it can
337-
# set the options manually instead. """
338+
# set the options manually instead.
338339
super(iControlDriver, self).__init__(conf)
339340
self.conf = conf
340341
if registerOpts:
@@ -368,6 +369,7 @@ def __init__(self, conf, registerOpts=True):
368369

369370
# to store the verified esd names
370371
self.esd_names = []
372+
self.esd_processor = None
371373

372374
# service component managers
373375
self.tenant_manager = None
@@ -389,6 +391,12 @@ def __init__(self, conf, registerOpts=True):
389391
self.pool_manager = resource_helper.BigIPResourceHelper(
390392
resource_helper.ResourceType.pool)
391393

394+
if self.conf.password_cipher_mode:
395+
self.conf.icontrol_password = \
396+
base64.b64decode(self.conf.icontrol_password)
397+
if self.conf.os_password:
398+
self.conf.os_password = base64.b64decode(self.conf.os_password)
399+
392400
try:
393401

394402
# debug logging of service requests recieved by driver
@@ -493,6 +501,11 @@ def _init_bigip_managers(self):
493501
self.system_helper = SystemHelper()
494502
self.lbaas_builder = LBaaSBuilder(self.conf, self)
495503

504+
# Set esd_processor object as soon as ServiceModelAdapter and
505+
# LBaaSBuilder class instantiated, otherwise manager RPC exception
506+
# will break setting esd_porcessor procedure.
507+
self.init_esd()
508+
496509
if self.conf.f5_global_routed_mode:
497510
self.network_builder = None
498511
else:
@@ -668,7 +681,7 @@ def _init_errored_bigips(self):
668681
raise
669682

670683
def _open_bigip(self, hostname):
671-
# Open bigip connection """
684+
# Open bigip connection
672685
try:
673686
bigip = self.__bigips[hostname]
674687
if bigip.status not in ['creating', 'error']:
@@ -824,27 +837,37 @@ def _post_init(self):
824837
if self.network_builder:
825838
self.network_builder.post_init()
826839

827-
# read enhanced services definitions
840+
self._set_agent_status(False)
841+
842+
def init_esd(self):
843+
# read all esd file from esd dir
844+
# init esd object in lbaas_builder
845+
# init esd object in service_adapter
828846
esd_dir = os.path.join(self.get_config_dir(), 'esd')
829-
esd = EsdTagProcessor(esd_dir)
847+
# EsdTagProcessor is a singleton, so nothing new
848+
self.esd_processor = EsdTagProcessor()
830849
try:
831-
esd.process_esd(self.get_all_bigips())
832-
self.lbaas_builder.init_esd(esd)
833-
self.service_adapter.init_esd(esd)
834-
835-
LOG.debug('esd details here after process_esd(): ')
836-
LOG.debug(esd)
837-
self.esd_names = esd.esd_dict.keys() or []
838-
LOG.debug('##### self.esd_names obtainded here:')
839-
LOG.debug(self.esd_names)
850+
self.esd_processor.process_esd(self.get_all_bigips(), esd_dir)
851+
self.lbaas_builder.init_esd(self.esd_processor)
852+
self.service_adapter.init_esd(self.esd_processor)
853+
840854
except f5ex.esdJSONFileInvalidException as err:
841855
LOG.error("unable to initialize ESD. Error: %s.", err.message)
842-
self._set_agent_status(False)
856+
except IOError as ioe:
857+
LOG.error("unable to process ESD file. Error: %s.", ioe.message)
858+
except Exception as exc:
859+
LOG.error("unknown Error happens. Error: %s.", exc.message)
860+
861+
LOG.debug('ESD details here after process_esd(): ')
862+
LOG.debug(self.esd_processor)
863+
self.esd_names = self.esd_processor.esd_dict.keys() or []
864+
LOG.debug('self.esd_names obtainded here:')
865+
LOG.debug(self.esd_names)
843866

844867
def _validate_ha(self, bigip):
845868
# if there was only one address supplied and
846869
# this is not a standalone device, get the
847-
# devices trusted by this device. """
870+
# devices trusted by this device.
848871
device_group_name = None
849872
if self.conf.f5_ha_type == 'standalone':
850873
if len(self.hostnames) != 1:

0 commit comments

Comments
 (0)