Ping monitor ignores retry parameter

Now Tacker ping monitor do not retry even in 'retry' parameter is
specified like described in [1]. In addition, description about ping
monitor in [1] is incorrect.

This patch fixes above problems.

[1] https://docs.openstack.org/tacker/latest/contributor/vnfd_template_description.html

Change-Id: I8e7cc4367002724f9ff00a623f7722e915ca1333
Closes-Bug: #1861774
This commit is contained in:
JO Hiroyuki 2020-02-04 05:51:03 +00:00
parent 55319282f3
commit 364ce6921e
4 changed files with 139 additions and 68 deletions

View File

@ -52,10 +52,13 @@ Following methods need to be overridden in the new driver:
This method must return the url of vnf to monitor.
``def monitor_call(self, vnf, kwargs)``
This method must either return boolean value 'True', if VNF is healthy.
Otherwise it should return an event string like 'failure' or
'calls-capacity-reached' based on specific VNF health condition. More
details on these event is given in below section.
This method is called cyclically each time a monitoring is
triggered. **kwagrs** is a dict object given under **parameters** in
the target VDU template. This method must either return boolean
value 'True', if VNF is healthy. Otherwise it should return an event
string like 'failure' or 'calls-capacity-reached' based on specific
VNF health condition. More details on these event is given in below
section.
Custom events
--------------
@ -67,13 +70,15 @@ For example:
::
vdu1:
monitoring_policy:
ping:
VDU1:
properties:
...
monitoring_policy:
name: ping
actions:
failure: respawn
In this example, we have an event called 'failure'. So whenever monitor_call
In this example, we have an event called 'failure'. So whenever monitor_call
returns 'failure' tacker will respawn the VNF.
@ -85,31 +90,32 @@ occurs.
#. respawn
In case of OpenStack VIM, when any VDU monitoring fails, it will delete
the entire VNF and create a new one.
#. log
#. vdu_autoheal
In case of OpenStack VIM, when any VDU monitoring fails, it will delete
only that specific VDU resource and create a new one alone with it's
dependent resources like CP.
#. log
#. log_and_kill
How to write TOSCA template to monitor VNF entities
----------------------------------------------------
In the vdus section, under vdu you can specify the monitors details with
corresponding actions and parameters.The syntax for writing monitor policy
is as follows:
In the vdus section, you can specify the monitor details with
corresponding actions and parameters. The syntax for writing monitor
policy is as follows:
::
vduN:
monitoring_policy:
<monitoring-driver-name>:
monitoring_params:
properties:
...
monitoring_policy:
name: <monitoring-driver-name>:
parameters:
<param-name>: <param-value>
...
actions:
<event>: <action-name>
...
...
<event-name>: <action-name>
Example Template
@ -117,32 +123,32 @@ Example Template
::
vdu1:
monitoring_policy:
ping:
VDU1:
properties:
...
monitoring_policy:
name: ping
actions:
failure: respawn
vdu2:
monitoring_policy:
http-ping:
monitoring_params:
VDU2:
properties:
...
monitoring_policy:
name: http-ping
parameters:
port: 8080
url: ping.cgi
actions:
failure: respawn
vdu_scaling_driver:
monitoring_params:
resource: cpu
threshold: 10000
actions:
max_foo_reached: scale_up
min_foo_reached: scale_down
vdu3:
monitoring_policy:
ping:
actions:
failure: vdu_autoheal
VDU3:
properties:
...
monitoring_policy:
name: <your-driver-name>
parameters:
<param1>: <value1>
<param2>: <value2>
actions:
<event1>: <action>
<event2>: <action>

View File

@ -110,10 +110,15 @@ a VNFD, **flavor** setting will take precedence.
Monitoring the VDU
""""""""""""""""""
A VDU can be monitored by pinging it on port 22 for 3 times at an interval of
2 seconds every 20 seconds. Number of retries be 6 and timeout of 2 seconds.
It can be re-spawned in case ping fails. This is described under
**monitoring_policy**.
A VDU can be monitored by pinging it. The following VNFD pings VDU1 with
3 ECHO packet counts, 0.2 second intervals and 2 second timeout options
per monitoring trigger. Ping is attempted up to 6 times unless it
returns an exit code 0. On VDU2, Tacker tries to open
http://<VDU2_mgmt_ip>:80 with 2 second timeout and 6 retries. Both VDUs
have 20 second delay time from creation or respawning to start
monitoring. The VDUs can be re-spawned in case of failure. See
:doc:`monitor-api` for more information.
::
@ -123,15 +128,27 @@ It can be re-spawned in case ping fails. This is described under
properties:
monitoring_policy:
name: ping
parameters:
monitoring_delay: 20
count: 3
interval: 2
timeout: 2
actions:
failure: respawn
retry: 6
port: 22
parameters:
monitoring_delay: 20
count: 3
interval: 0.2
timeout: 2
retry: 6
actions:
failure: respawn
VDU2:
type: tosca.nodes.nfv.VDU.Tacker
properties:
monitoring_policy:
name: http-ping
parameters:
monitoring_delay: 20
timeout: 2
retry: 6
port: 80
actions:
failure: respawn
Providing user data
"""""""""""""""""""

View File

@ -32,8 +32,8 @@ class TestVNFMonitorPing(testtools.TestCase):
}
mock_ping_cmd = ['ping',
'-c', 5,
'-W', 1,
'-i', '0.2',
'-W', 5.0,
'-i', 1.0,
'a.b.c.d']
self.monitor_ping.monitor_call(test_vnf,
test_kwargs)
@ -59,3 +59,39 @@ class TestVNFMonitorPing(testtools.TestCase):
mock.ANY,
test_vnf)
self.assertEqual('a.b.c.d', test_monitor_url)
@mock.patch('tacker.agent.linux.utils.execute')
def test_monitor_call_with_params(self, mock_utils_execute):
check_ping_counts = 2
check_ping_timeout = 5.0
check_ping_interval = 0.5
test_vnf = {}
test_kwargs = {
'mgmt_ip': 'a:b:c:d:e:f:1:2',
'count': check_ping_counts,
'timeout': check_ping_timeout,
'interval': check_ping_interval
}
mock_ping_cmd = ['ping6',
'-c', check_ping_counts,
'-W', check_ping_timeout,
'-i', check_ping_interval,
'a:b:c:d:e:f:1:2']
self.monitor_ping.monitor_call(test_vnf,
test_kwargs)
mock_utils_execute.assert_called_once_with(mock_ping_cmd,
check_exit_code=True)
@mock.patch('tacker.agent.linux.utils.execute')
def test_monitor_call_for_counts(self, mock_utils_execute):
check_retury_counts = 5
mock_utils_execute.side_effect = RuntimeError()
test_vnf = {}
test_kwargs = {
'mgmt_ip': 'a:b:c:d:e:f:1:2',
'retry': check_retury_counts
}
self.monitor_ping.monitor_call(test_vnf,
test_kwargs)
self.assertEqual(check_retury_counts,
mock_utils_execute.call_count)

View File

@ -25,12 +25,14 @@ from tacker.vnfm.monitor_drivers import abstract_driver
LOG = logging.getLogger(__name__)
OPTS = [
cfg.StrOpt('count', default='1',
cfg.IntOpt('count', default=5,
help=_('Number of ICMP packets to send')),
cfg.StrOpt('timeout', default='1',
cfg.FloatOpt('timeout', default=5,
help=_('Number of seconds to wait for a response')),
cfg.StrOpt('interval', default='1',
help=_('Number of seconds to wait between packets'))
cfg.FloatOpt('interval', default=1,
help=_('Number of seconds to wait between packets')),
cfg.IntOpt('retry', default=1,
help=_('Number of ping retries'))
]
cfg.CONF.register_opts(OPTS, 'monitor_ping')
@ -53,12 +55,12 @@ class VNFMonitorPing(abstract_driver.VNFMonitorAbstractDriver):
LOG.debug('monitor_url %s', vnf)
return vnf.get('monitor_url', '')
def _is_pingable(self, mgmt_ip="", count=5, timeout=1, interval='0.2',
**kwargs):
def _is_pingable(self, mgmt_ip="", count=None, timeout=None,
interval=None, retry=None, **kwargs):
"""Checks whether an IP address is reachable by pinging.
Use linux utils to execute the ping (ICMP ECHO) command.
Sends 5 packets with an interval of 0.2 seconds and timeout of 1
Sends 5 packets with an interval of 1 seconds and timeout of 1
seconds. Runtime error implies unreachability else IP is pingable.
:param ip: IP to check
:return: bool - True or string 'failure' depending on pingability.
@ -67,18 +69,28 @@ class VNFMonitorPing(abstract_driver.VNFMonitorAbstractDriver):
if netaddr.valid_ipv6(mgmt_ip):
cmd_ping = 'ping6'
if not count:
count = cfg.CONF.monitor_ping.count
if not timeout:
timeout = cfg.CONF.monitor_ping.timeout
if not interval:
interval = cfg.CONF.monitor_ping.interval
if not retry:
retry = cfg.CONF.monitor_ping.retry
ping_cmd = [cmd_ping,
'-c', count,
'-W', timeout,
'-i', interval,
mgmt_ip]
try:
linux_utils.execute(ping_cmd, check_exit_code=True)
return True
except RuntimeError:
LOG.warning("Cannot ping ip address: %s", mgmt_ip)
return 'failure'
for retry_range in range(int(retry)):
try:
linux_utils.execute(ping_cmd, check_exit_code=True)
return True
except RuntimeError:
LOG.warning("Cannot ping ip address: %s", mgmt_ip)
return 'failure'
@log.log
def monitor_call(self, vnf, kwargs):