Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[action] [PR:14229] [storage_backend] Add backend acl service #14281

Merged
merged 1 commit into from
Mar 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions files/build_templates/sonic_debian_extension.j2
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,11 @@ sudo cp $IMAGE_CONFIGS/config-chassisdb/config-chassisdb $FILESYSTEM_ROOT/usr/bi
echo "config-chassisdb.service" | sudo tee -a $GENERATED_SERVICE_FILE
sudo LANG=C chroot $FILESYSTEM_ROOT systemctl enable config-chassisdb.service

# Copy backend-acl script and service file
sudo cp $IMAGE_CONFIGS/backend_acl/backend-acl.service $FILESYSTEM_ROOT_USR_LIB_SYSTEMD_SYSTEM/backend-acl.service
sudo cp $IMAGE_CONFIGS/backend_acl/backend_acl.py $FILESYSTEM_ROOT/usr/bin/backend_acl.py
echo "backend-acl.service" | sudo tee -a $GENERATED_SERVICE_FILE

# Copy SNMP configuration files
sudo cp $IMAGE_CONFIGS/snmp/snmp.yml $FILESYSTEM_ROOT/etc/sonic/

Expand Down
12 changes: 12 additions & 0 deletions files/image_config/backend_acl/backend-acl.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Unit]
Description=Enable backend acl on storage backend ToRs
After=swss.service
BindsTo=sonic.target
After=sonic.target

[Service]
Type=oneshot
ExecStart=/usr/bin/backend_acl.py

[Install]
WantedBy=sonic.target
94 changes: 94 additions & 0 deletions files/image_config/backend_acl/backend_acl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/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()