NSX-V: Add support for log level in router flavors
Add the ability to configure routing log level in syslog section of router flavor. For that purpose, move log level configuration modifiers to edge_utils from nsx-admin code. Change-Id: Ic8ea0def221b48ac592b81424cdab7c9cafe0c2b
This commit is contained in:
parent
04730c324c
commit
a966ca0708
@ -808,6 +808,12 @@ class EdgeApplianceDriver(object):
|
||||
router_id)
|
||||
return
|
||||
|
||||
loglevel = syslog_config.get('log_level')
|
||||
if loglevel and loglevel not in edge_utils.SUPPORTED_EDGE_LOG_LEVELS:
|
||||
LOG.warning(_LW("Invalid loglevel in syslog config for %s"),
|
||||
router_id)
|
||||
return
|
||||
|
||||
server_ip = syslog_config['server_ip']
|
||||
request = {'featureType': 'syslog',
|
||||
'protocol': protocol,
|
||||
@ -820,3 +826,8 @@ class EdgeApplianceDriver(object):
|
||||
syslog_config['server2_ip'])
|
||||
|
||||
self.vcns.update_edge_syslog(edge_id, request)
|
||||
|
||||
# update log level for routing in separate API call
|
||||
if loglevel:
|
||||
edge_utils.update_edge_loglevel(self.vcns, edge_id,
|
||||
'routing', loglevel)
|
||||
|
@ -57,6 +57,12 @@ LOG = logging.getLogger(__name__)
|
||||
_uuid = uuidutils.generate_uuid
|
||||
|
||||
|
||||
SUPPORTED_EDGE_LOG_MODULES = ('routing', 'highavailability',
|
||||
'dhcp', 'loadbalancer', 'dns')
|
||||
|
||||
SUPPORTED_EDGE_LOG_LEVELS = ('none', 'debug', 'info', 'warning', 'error')
|
||||
|
||||
|
||||
def _get_vdr_transit_network_ipobj():
|
||||
transit_net = cfg.CONF.nsxv.vdr_transit_network
|
||||
return netaddr.IPNetwork(transit_net)
|
||||
@ -2396,6 +2402,63 @@ def check_network_in_use_at_backend(context, network_id):
|
||||
LOG.error(_LE('NSXv: network is still in use at the backend'))
|
||||
|
||||
|
||||
def default_loglevel_modifier(config, level):
|
||||
"""Modify log level settings in edge config bulk (standard syntax)"""
|
||||
|
||||
if 'logging' not in config:
|
||||
LOG.error(_LE("Logging section missing in configuration"))
|
||||
return False
|
||||
|
||||
enable = True
|
||||
if level == 'none':
|
||||
enable = False
|
||||
level = 'info' # default
|
||||
|
||||
config['logging']['enable'] = enable
|
||||
config['logging']['logLevel'] = level
|
||||
return True
|
||||
|
||||
|
||||
def routing_loglevel_modifier(config, level):
|
||||
"""Modify log level in routing global settings"""
|
||||
|
||||
if 'routingGlobalConfig' not in config:
|
||||
LOG.error(_LE("routingGlobalConfig section missing in config"))
|
||||
return False
|
||||
|
||||
return default_loglevel_modifier(config['routingGlobalConfig'],
|
||||
level)
|
||||
|
||||
|
||||
def get_loglevel_modifier(module, level):
|
||||
"""Pick modifier according to module and set log level"""
|
||||
special_modifiers = {'routing': routing_loglevel_modifier}
|
||||
|
||||
modifier = default_loglevel_modifier
|
||||
if module in special_modifiers.keys():
|
||||
modifier = special_modifiers[module]
|
||||
|
||||
def wrapper(config):
|
||||
return modifier(config, level)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def update_edge_loglevel(vcns, edge_id, module, level):
|
||||
"""Update loglevel on edge for specified module"""
|
||||
if module not in SUPPORTED_EDGE_LOG_MODULES:
|
||||
LOG.error(_LE("Unrecognized logging module %s - ignored"), module)
|
||||
return
|
||||
|
||||
if level not in SUPPORTED_EDGE_LOG_LEVELS:
|
||||
LOG.error(_LE("Unrecognized log level %s - ignored"), level)
|
||||
return
|
||||
|
||||
vcns.update_edge_config_with_modifier(edge_id, module,
|
||||
get_loglevel_modifier(module,
|
||||
level))
|
||||
|
||||
|
||||
class NsxVCallbacks(object):
|
||||
"""Edge callback implementation Callback functions for
|
||||
asynchronous tasks.
|
||||
|
@ -17,6 +17,7 @@ import logging
|
||||
import pprint
|
||||
import textwrap
|
||||
|
||||
from vmware_nsx.plugins.nsx_v.vshield import edge_utils
|
||||
from vmware_nsx.shell.admin.plugins.common import constants
|
||||
from vmware_nsx.shell.admin.plugins.common import formatters
|
||||
|
||||
@ -222,47 +223,6 @@ def delete_edge_syslog(edge_id):
|
||||
LOG.error(_LE("%s"), str(e))
|
||||
|
||||
|
||||
def default_loglevel_modifier(config, level):
|
||||
"""Modify log level settings in edge config bulk (standard syntax)"""
|
||||
|
||||
if 'logging' not in config:
|
||||
LOG.error(_LE("Logging section missing in configuration"))
|
||||
return False
|
||||
|
||||
enable = True
|
||||
if level == 'none':
|
||||
enable = False
|
||||
level = 'info' # default
|
||||
|
||||
config['logging']['enable'] = enable
|
||||
config['logging']['logLevel'] = level
|
||||
return True
|
||||
|
||||
|
||||
def routing_loglevel_modifier(config, level):
|
||||
"""Modify log level in routing global settings"""
|
||||
|
||||
if 'routingGlobalConfig' not in config:
|
||||
LOG.error(_LE("routingGlobalConfig section missing in configuration"))
|
||||
return False
|
||||
|
||||
return default_loglevel_modifier(config['routingGlobalConfig'], level)
|
||||
|
||||
|
||||
def get_loglevel_modifier(module, level):
|
||||
"""This function picks modifier according to module and sets log level"""
|
||||
special_modifiers = {'routing': routing_loglevel_modifier}
|
||||
|
||||
modifier = default_loglevel_modifier
|
||||
if module in special_modifiers.keys():
|
||||
modifier = special_modifiers[module]
|
||||
|
||||
def wrapper(config):
|
||||
return modifier(config, level)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def change_edge_loglevel(properties):
|
||||
"""Update log level on edge
|
||||
|
||||
@ -272,34 +232,17 @@ def change_edge_loglevel(properties):
|
||||
succeeded)
|
||||
"""
|
||||
|
||||
supported_modules = ('routing', 'highavailability',
|
||||
'dhcp', 'loadbalancer', 'dns')
|
||||
supported_levels = ('none', 'debug', 'info', 'warning', 'error')
|
||||
|
||||
modules = {}
|
||||
if properties.get('log-level'):
|
||||
level = properties.get('log-level')
|
||||
if level in supported_levels:
|
||||
# change log level for all modules
|
||||
modules = {k: level for k in supported_modules}
|
||||
else:
|
||||
LOG.info(_LI("Skipping unrecognized level (%s)"), level)
|
||||
return True
|
||||
# change log level for all modules
|
||||
modules = {k: level for k in edge_utils.SUPPORTED_EDGE_LOG_MODULES}
|
||||
else:
|
||||
# check for log level settings for specific modules
|
||||
for k, v in properties.items():
|
||||
if k.endswith('-log-level'):
|
||||
module = k[:-10] # module is in parameter prefix
|
||||
if module in supported_modules:
|
||||
if v in supported_levels:
|
||||
modules[module] = v
|
||||
else:
|
||||
LOG.info(_LI("Skipping unrecognized level (%s)"), v)
|
||||
return True
|
||||
|
||||
else:
|
||||
LOG.info(_LI("Skipping unrecognized module (%s)"), k)
|
||||
return True
|
||||
modules[module] = v
|
||||
|
||||
if not modules:
|
||||
# no log level properties
|
||||
@ -308,15 +251,13 @@ def change_edge_loglevel(properties):
|
||||
edge_id = properties.get('edge-id')
|
||||
|
||||
for module, level in modules.items():
|
||||
if level == 'none':
|
||||
LOG.info(_LI("Disabling logging for %s"), module)
|
||||
else:
|
||||
LOG.info(_LI("Enabling logging for %(m)s with level %(l)s"),
|
||||
{'m': module, 'l': level})
|
||||
try:
|
||||
if level == 'none':
|
||||
LOG.info(_LI("Disabling logging for %s"), module)
|
||||
else:
|
||||
LOG.info(_LI("Enabling logging for %(m)s with level %(l)s"),
|
||||
{'m': module, 'l': level})
|
||||
|
||||
nsxv.update_edge_config_with_modifier(edge_id, module,
|
||||
get_loglevel_modifier(module, level))
|
||||
edge_utils.update_edge_loglevel(nsxv, edge_id, module, level)
|
||||
|
||||
except nsxv_exceptions.ResourceNotFound as e:
|
||||
LOG.error(_LE("Edge %s not found"), edge_id)
|
||||
|
@ -4891,10 +4891,10 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase,
|
||||
# and needs to be validated separately
|
||||
if 'syslog' in expected_data.keys():
|
||||
self.assertSyslogConfig(expected_data['syslog'])
|
||||
del expected_data['syslog']
|
||||
|
||||
for key, expected_val in expected_data.items():
|
||||
self.assertEqual(expected_val, router[key])
|
||||
if key != 'syslog':
|
||||
self.assertEqual(expected_val, router[key])
|
||||
|
||||
def test_router_create_with_flavor_different_sizes(self):
|
||||
"""Create exclusive router with size in flavor
|
||||
@ -4975,20 +4975,22 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase,
|
||||
self._test_router_create_with_flavor(
|
||||
metainfo, expected_router)
|
||||
|
||||
# Advanced config - secondary server IP and protocol
|
||||
# Advanced config - secondary server IP, protocol and loglevel
|
||||
ip2 = '1.1.1.11'
|
||||
for protocol in ['tcp', 'udp']:
|
||||
expected_router = {'router_type': 'exclusive',
|
||||
'syslog': {'protocol': protocol,
|
||||
'server_ip': ip, 'server2_ip': ip2}}
|
||||
for loglevel in ['none', 'debug', 'info', 'warning', 'error']:
|
||||
expected_router = {'router_type': 'exclusive',
|
||||
'syslog': {'protocol': protocol,
|
||||
'server_ip': ip, 'server2_ip': ip2}}
|
||||
|
||||
metainfo = ("{'router_type':'exclusive',"
|
||||
"'syslog':{'server_ip':'%s', 'server2_ip':'%s',"
|
||||
"'protocol':'%s'}}" % (ip, ip2, protocol))
|
||||
metainfo = ("{'router_type':'exclusive',"
|
||||
"'syslog':{'server_ip':'%s', 'server2_ip':'%s',"
|
||||
"'protocol':'%s', 'log_level':'%s'}}" %
|
||||
(ip, ip2, protocol, loglevel))
|
||||
|
||||
self._iteration += 1
|
||||
self._test_router_create_with_flavor(
|
||||
metainfo, expected_router)
|
||||
self._iteration += 1
|
||||
self._test_router_create_with_flavor(
|
||||
metainfo, expected_router)
|
||||
|
||||
def test_router_create_with_syslog_flavor_error(self):
|
||||
"""Create router based on flavor with badly formed syslog metadata
|
||||
@ -5001,7 +5003,9 @@ class TestRouterFlavorTestCase(extension.ExtensionTestCase,
|
||||
self._iteration = 0
|
||||
bad_defs = ("'server_ip':'1.1.1.1', 'protocol':'http2'",
|
||||
"'server2_ip':'2.2.2.2'",
|
||||
"'protocol':'tcp'")
|
||||
"'protocol':'tcp'",
|
||||
"'server_ip':'1.1.1.1', 'protocol':'udp','log_level':'pro'",
|
||||
"'log_level':'error'")
|
||||
for meta in bad_defs:
|
||||
metainfo = "{'router_type':'exclusive', 'syslog': {%s}}" % meta
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user