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

Add Redis ACL support [First Draft] #144

Closed
Closed
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
4 changes: 3 additions & 1 deletion src/swsssdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

if ('unittest' not in sys.modules.keys() and
'mockredis' not in sys.modules.keys() and
'mock' not in sys.modules.keys()):
'mock' not in sys.modules.keys() and
'netq_agent' not in sys.modules.keys()):
# netq_agent temporary fix until move to swsscommon lib.
msg = "sonic-py-swsssdk been deprecated, please switch to sonic-swss-common."
logger.exception(msg)
raise ImportError("sonic-py-swsssdk been deprecated, please switch to sonic-swss-common.")
Expand Down
11 changes: 10 additions & 1 deletion src/swsssdk/interface.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import time
from functools import wraps
from . import util

import redis
from redis import RedisError
Expand Down Expand Up @@ -143,6 +144,8 @@ class DBInterface(object):
ACS Redis db mainly uses hash, therefore h is selected.
"""

ACL_PW_PATH = '/etc/shadow_redis_dir/shadow_redis_admin'

def __init__(self, **kwargs):

super(DBInterface, self).__init__()
Expand All @@ -151,7 +154,13 @@ def __init__(self, **kwargs):
self.redis_kwargs = kwargs
if len(self.redis_kwargs) == 0:
self.redis_kwargs['unix_socket_path'] = self.REDIS_UNIX_SOCKET_PATH

self.redis_kwargs['username'] = 'admin'
if 'password' not in self.redis_kwargs:
self.redis_kwargs['password'] = util.read_from_file(self.ACL_PW_PATH)
redis_shadow_tls_ca="/etc/shadow_redis_dir/certs_redis/ca.crt"
self.redis_kwargs['ssl'] = True
self.redis_kwargs['ssl_cert_reqs'] = None
self.redis_kwargs['ssl_ca_certs'] = redis_shadow_tls_ca
# For thread safety as recommended by python-redis
# Create a separate client for each database
self.redis_clients = DBRegistry()
Expand Down
1 change: 1 addition & 0 deletions src/swsssdk/sonic_db_dump_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ def do_load(options, args):
usage += "\nfrom standard input."
parser = optparse.OptionParser(usage=usage)
parser.add_option('-w', '--password', help='connect with PASSWORD')
parser.add_option('-u', '--username', help='connect with USERNAME')
if help == DUMP:
parser.add_option('-n', '--dbname', help='dump DATABASE (APPL_DB/ASIC_DB...)')
parser.add_option('-t', '--conntype', help='indicate redis connection type (tcp[default] or unix_socket)', default='tcp')
Expand Down
24 changes: 24 additions & 0 deletions src/swsssdk/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,27 @@ def setup_logging(config_file_path, log_level=logging.INFO):
logging.root.exception(
"Could not load specified logging configuration '{}'. Verify the filepath exists and is compliant with: "
"[https://docs.python.org/3/library/logging.config.html#object-connections]".format(config_file_path))


def read_from_file(file_path, target_type=str):
"""
Read content from file and convert to target type
:param file_path: File path
:param target_type: target type
:return: content of the file according the target type.
"""
value = None
try:
with open(file_path, 'r') as f:
value = f.read()
if value is None:
# None return value is not allowed in any case, so we log error here for further debug.
logging.error('Failed to read from {}, value is None, errno is {}'.format(file_path, ctypes.get_errno()))
# Raise ValueError for the except statement to handle this as a normal exception
raise ValueError('File content of {} is None'.format(file_path))
else:
value = target_type(value.strip())
except (ValueError, IOError) as e:
logging.error('Failed to read from {}, errno is {}'.format(file_path, str(e)))

return value
Loading