95 lines
2.9 KiB
Python
95 lines
2.9 KiB
Python
|
#!/usr/bin/env python
|
||
|
|
||
|
import os
|
||
|
import subprocess
|
||
|
import syslog
|
||
|
import time
|
||
|
|
||
|
from swsscommon.swsscommon import SonicV2Connector
|
||
|
|
||
|
SYSLOG_IDENTIFIER = os.path.basename(__file__)
|
||
|
|
||
|
SONIC_CFGGEN_PATH = '/usr/local/bin/sonic-cfggen'
|
||
|
|
||
|
def log_info(msg):
|
||
|
syslog.openlog(SYSLOG_IDENTIFIER)
|
||
|
syslog.syslog(syslog.LOG_INFO, msg)
|
||
|
syslog.closelog()
|
||
|
|
||
|
def run_command(cmd, return_cmd=False):
|
||
|
log_info("executing cmd = {}".format(cmd))
|
||
|
proc = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE)
|
||
|
out, err = proc.communicate()
|
||
|
if return_cmd:
|
||
|
if err:
|
||
|
return "Unknown"
|
||
|
|
||
|
if len(out) > 0:
|
||
|
return out.strip().decode('utf-8')
|
||
|
|
||
|
def _get_device_type():
|
||
|
"""
|
||
|
Get device type
|
||
|
"""
|
||
|
device_type = run_command([SONIC_CFGGEN_PATH, '-m', '-v', 'DEVICE_METADATA.localhost.type'], return_cmd=True)
|
||
|
return device_type
|
||
|
|
||
|
def _is_storage_device():
|
||
|
"""
|
||
|
Check if the device is a storage device or not
|
||
|
"""
|
||
|
storage_device = run_command([SONIC_CFGGEN_PATH, '-d', '-v', 'DEVICE_METADATA.localhost.storage_device'], return_cmd=True)
|
||
|
return storage_device == "true"
|
||
|
|
||
|
def _is_acl_table_present():
|
||
|
"""
|
||
|
Check if acl table exists
|
||
|
"""
|
||
|
acl_table = run_command([SONIC_CFGGEN_PATH, '-d', '-v', 'ACL_TABLE.DATAACL'], return_cmd=True)
|
||
|
return (acl_table != "Unknown" and bool(acl_table))
|
||
|
|
||
|
def _is_switch_table_present():
|
||
|
state_db = SonicV2Connector(host='127.0.0.1')
|
||
|
state_db.connect(state_db.STATE_DB, False)
|
||
|
table_present = False
|
||
|
wait_time = 0
|
||
|
TIMEOUT = 120
|
||
|
STEP = 10
|
||
|
|
||
|
while wait_time < TIMEOUT:
|
||
|
if state_db.exists(state_db.STATE_DB, 'SWITCH_CAPABILITY|switch'):
|
||
|
table_present = True
|
||
|
break
|
||
|
time.sleep(STEP)
|
||
|
wait_time += STEP
|
||
|
if not table_present:
|
||
|
log_info("Switch table not present")
|
||
|
return table_present
|
||
|
|
||
|
def load_backend_acl(device_type):
|
||
|
"""
|
||
|
Load acl on backend storage device
|
||
|
"""
|
||
|
BACKEND_ACL_TEMPLATE_FILE = os.path.join('/', "usr", "share", "sonic", "templates", "backend_acl.j2")
|
||
|
BACKEND_ACL_FILE = os.path.join('/', "etc", "sonic", "backend_acl.json")
|
||
|
|
||
|
# this acl needs to be loaded only on a storage backend ToR. acl load will fail if the switch table isn't present
|
||
|
if _is_storage_device() and _is_acl_table_present() and _is_switch_table_present():
|
||
|
if os.path.isfile(BACKEND_ACL_TEMPLATE_FILE):
|
||
|
run_command(['sudo', SONIC_CFGGEN_PATH, '-d', '-t', '{},{}'.format(BACKEND_ACL_TEMPLATE_FILE, BACKEND_ACL_FILE)])
|
||
|
if os.path.isfile(BACKEND_ACL_FILE):
|
||
|
run_command(['acl-loader', 'update', 'incremental', BACKEND_ACL_FILE])
|
||
|
else:
|
||
|
log_info("Skipping backend acl load - conditions not met")
|
||
|
|
||
|
def main():
|
||
|
device_type = _get_device_type()
|
||
|
if device_type != "BackEndToRRouter":
|
||
|
log_info("Skipping backend acl load on unsupported device type: {}".format(device_type))
|
||
|
return
|
||
|
|
||
|
load_backend_acl(device_type)
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
main()
|