Commit 12bff817 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 7f49065e
......@@ -70,10 +70,6 @@ md5sum = 9741fbc99aaf768e9cc3ab48925dfee5
_update_hash_filename_ = ru/lopcomm/software.jinja2.py
md5sum = 2b08bb666c5f3ab287cdddbfdb4c9249
[ru_lopcomm_supervision.jinja2.py]
_update_hash_filename_ = ru/lopcomm/supervision.jinja2.py
md5sum = da233439ca2b4978ea57bf8c6d628965
[ru_tapsplit]
_update_hash_filename_ = ru/tapsplit
md5sum = 2b8b57c5771b2a2203c0e7767e629e55
......
......@@ -303,7 +303,6 @@ extra-context =
raw ru_lopcomm_stats_template ${ru_lopcomm_stats.jinja2.py:target}
raw ru_lopcomm_config_template ${ru_lopcomm_config.jinja2.py:target}
raw ru_lopcomm_software_template ${ru_lopcomm_software.jinja2.py:target}
raw ru_lopcomm_supervision_template ${ru_lopcomm_supervision.jinja2.py:target}
raw ru_lopcomm_reset_info_template ${ru_lopcomm_reset-info.jinja2.py:target}
raw ru_lopcomm_reset_template ${ru_lopcomm_reset.jinja2.py:target}
raw ru_lopcomm_CreateProcessingEle_template ${ru_lopcomm_CreateProcessingEle.jinja2.xml:target}
......
......@@ -22,9 +22,6 @@ parts +=
[ru_lopcomm_software.jinja2.py]
<= download-base
[ru_lopcomm_supervision.jinja2.py]
<= download-base
[ru_lopcomm_ncclient_common.py]
<= download-base
destination = ${buildout:directory}/ncclient_common.py
......
......@@ -17,44 +17,10 @@ promise = check_socket_listening
config-host = ${vtap.{{ru.cpri_link._tap}}:gateway}
config-port = 830
{#- monitor state of netconf connection + keep on touching RU watchdog #}
[{{ru_ref}}-supervision-template]
recipe = slapos.recipe.template:jinja2
extensions = jinja2.ext.do
_logbase = ${directory:var}/log/{{ru_ref}}-supervision
log-output = ${:_logbase}.log
supervision-reply-json-log-output = ${:_logbase}-reply.json.log
is_netconf_connected = ${directory:etc}/{{ru_ref}}.is_netconf_connected
context =
section directory directory
section vtap vtap.{{ ru.cpri_link._tap }}
key slapparameter_dict slap-configuration:configuration
key log_file :log-output
key supervision_reply_json_log_file :supervision-reply-json-log-output
raw testing {{ slapparameter_dict.get("testing", False) }}
raw python_path {{ buildout_directory}}/bin/pythonwitheggs
raw buildout_directory_path {{ buildout_directory }}
key is_netconf_connected :is_netconf_connected
import netaddr netaddr
mode = 0775
url = {{ ru_lopcomm_supervision_template }}
output = ${directory:bin}/{{ru_ref}}-supervision.py
{{ part('%s-supervision-service' % ru_ref) }}
recipe = slapos.cookbook:wrapper
command-line = ${ {{- ru_ref}}-supervision-template:output}
wrapper-path = ${directory:service}/{{ru_ref}}-supervision
mode = 0775
hash-files =
${:command-line}
{{ promise('%s-netconf-connection' % ru_ref) }}
promise = check_command_execute
config-command = [ -f ${ {{-ru_ref}}-supervision-template:is_netconf_connected} ]
{#- push firmware to RU #}
[{{ru_ref}}-software-template]
......@@ -134,7 +100,7 @@ promise = check_lopcomm_config_log
config-config-log = ${ {{- ru_ref}}-config-template:log-output}
{#- handle notifications from RU #}
{#- handle notifications from RU + keep on touching RU watchdog #}
[{{ru_ref}}-stats-template]
recipe = slapos.recipe.template:jinja2
......@@ -146,6 +112,8 @@ cfg-json-log-output = ${:_logbase}-config.json.log
supervision-json-log-output = ${:_logbase}-supervision.json.log
ncsession-json-log-output = ${:_logbase}-ncsession.json.log
software-json-log-output = ${:_logbase}-software.json.log
supervision-reply-json-log-output = ${:_logbase}-supervision-reply.json.log
is_netconf_connected = ${directory:etc}/{{ru_ref}}.is_netconf_connected
context =
section directory directory
section vtap vtap.{{ ru.cpri_link._tap }}
......@@ -154,6 +122,8 @@ context =
key json_log_file :json-log-output
key cfg_json_log_file :cfg-json-log-output
key supervision_json_log_file :supervision-json-log-output
key supervision_reply_json_log_file :supervision-reply-json-log-output
key is_netconf_connected :is_netconf_connected
key ncsession_json_log_file :ncsession-json-log-output
key software_json_log_file :software-json-log-output
raw testing {{ slapparameter_dict.get("testing", False) }}
......
......@@ -103,24 +103,24 @@ class LopcommNetconfClient:
sub = self.conn.create_subscription()
self.logger.info('Subscription to %s successful' % (self.address,))
def get_notification(self):
result = None
while result == None:
self.logger.debug('Waiting for notification from %s...' % (self.address,))
result = self.conn.take_notification(block=True)
if result:
self.logger.debug('Got new notification from %s...' % (self.address,))
result_in_xml = result._raw
data_dict = xmltodict.parse(result_in_xml)
if 'alarm-notif' in data_dict['notification']:
self.json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'supervision-notification' in data_dict['notification']:
self.supervision_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'netconf-session-start' in data_dict['notification'] or 'netconf-session-end' in data_dict['notification']:
self.ncsession_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif any(event in data_dict['notification'] for event in ['install-event', 'activation-event', 'download-event']):
self.software_json_logger.info('', extra={'data': json.dumps(data_dict)})
else:
self.cfg_json_logger.info('', extra={'data': json.dumps(data_dict)})
self.logger.debug('Waiting for notification from %s...' % (self.address,))
result = self.conn.take_notification(block=True, timeout=120)
if result:
self.logger.debug('Got new notification from %s...' % (self.address,))
result_in_xml = result._raw
data_dict = xmltodict.parse(result_in_xml)
if 'alarm-notif' in data_dict['notification']:
self.json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'supervision-notification' in data_dict['notification']:
self.supervision_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif 'netconf-session-start' in data_dict['notification'] or 'netconf-session-end' in data_dict['notification']:
self.ncsession_json_logger.info('', extra={'data': json.dumps(data_dict)})
elif any(event in data_dict['notification'] for event in ['install-event', 'activation-event', 'download-event']):
self.software_json_logger.info('', extra={'data': json.dumps(data_dict)})
else:
self.cfg_json_logger.info('', extra={'data': json.dumps(data_dict)})
else:
raise TimeoutError
def edit_config(self, config_files):
for config_file in config_files:
with open(config_file) as f:
......@@ -199,6 +199,23 @@ class LopcommNetconfClient:
"running_slot_name_build_version": running_slot_name_build_version
}
def supervision_reset(self, interval=60, margin=10):
self.logger.info("NETCONF server supervision replying...")
supervision_watchdog_rpc_xml = f"""
<supervision-watchdog-reset xmlns="urn:o-ran:supervision:1.0">
<supervision-notification-interval>{interval}</supervision-notification-interval>
<guard-timer-overhead>{margin}</guard-timer-overhead>
</supervision-watchdog-reset>
"""
supervision_watchdog_reply_xml = self.custom_rpc_request(supervision_watchdog_rpc_xml)
replied = False
if supervision_watchdog_reply_xml:
replied = True
self.logger.info("NETCONF server supervision replied")
supervision_watchdog_data = xmltodict.parse(supervision_watchdog_reply_xml)
self.supervision_reply_json_logger.info('', extra={'data': json.dumps(supervision_watchdog_data)})
return replied
def close(self):
# Close not compatible between ncclient and netconf server
#self.conn.close()
......
#!{{ python_path }}
import time
import sys
import os
import threading
sys.path.append({{ repr(buildout_directory_path) }})
from ncclient_common import LopcommNetconfClient
# Shared variable to indicate error occurred
error_occurred = False
lock = threading.Lock()
def get_notification_continuously(nc):
global error_occurred
try:
while not error_occurred:
nc.get_notification()
pass
except Exception as e:
with lock:
error_occurred = True
nc.logger.error(f'Error in get_notification_continuously: {e}')
# supervision watchdog keeps on
def run_supervision_reset_continuously(nc):
global error_occurred
netconf_check_file = '{{ is_netconf_connected }}'
interval = 60
margin = 10
try:
while not error_occurred:
t0 = time.time()
replied = nc.supervision_reset(interval, margin)
if replied:
with open(netconf_check_file, "w") as f:
f.write('')
elif os.path.exists(netconf_check_file):
os.remove(netconf_check_file)
t1 = time.time()
time.sleep(interval - (t1 - t0))
except Exception as e:
with lock:
error_occurred = True
nc.logger.error(f'Error in run_supervision_reset_continuously: {e}')
if __name__ == '__main__':
nc = LopcommNetconfClient(
log_file="{{ log_file }}",
json_log_file="{{ json_log_file }}",
cfg_json_log_file="{{ cfg_json_log_file }}",
supervision_json_log_file="{{ supervision_json_log_file }}",
ncsession_json_log_file="{{ ncsession_json_log_file }}",
software_json_log_file="{{ software_json_log_file }}"
nc = LopcommNetconfClient(
log_file="{{ log_file }}",
json_log_file="{{ json_log_file }}",
cfg_json_log_file="{{ cfg_json_log_file }}",
supervision_json_log_file="{{ supervision_json_log_file }}",
ncsession_json_log_file="{{ ncsession_json_log_file }}",
software_json_log_file="{{ software_json_log_file }}",
supervision_reply_json_log_file="{{ supervision_reply_json_log_file }}"
)
while True:
threads = []
try:
nc.connect("{{ netaddr.IPAddress(vtap.gateway) }}", 830, "oranuser", "oranpassword")
nc.subscribe()
while True:
nc.get_notification()
notification_thread = threading.Thread(target=get_notification_continuously, args=(nc,))
supervision_thread = threading.Thread(target=run_supervision_reset_continuously, args=(nc,))
threads.append(notification_thread)
threads.append(supervision_thread)
for thread in threads:
thread.start()
for thread in threads:
thread.join()
except Exception as e:
nc.logger.debug('Got exception, waiting 10 seconds before reconnecting...')
nc.logger.debug(e)
......
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