1515class StandardEnv (object ):
1616 def __init__ (self , redisBinaryPath , port = 6379 , modulePath = None , moduleArgs = None , outputFilesFormat = None ,
1717 dbDirPath = None , useSlaves = False , serverId = 1 , password = None , libPath = None , clusterEnabled = False ,
18- useAof = False , debugger = None , noCatch = False , unix = False , verbose = False ):
18+ useAof = False , debugger = None , noCatch = False , unix = False , verbose = False , useTLS = False , tlsCertFile = None , tlsKeyFile = None , tlsCaCertFile = None ):
1919 self .uuid = uuid .uuid4 ().hex
2020 self .redisBinaryPath = os .path .expanduser (redisBinaryPath ) if redisBinaryPath .startswith ('~/' ) else redisBinaryPath
2121 self .modulePath = os .path .abspath (modulePath ) if modulePath else None
@@ -38,6 +38,10 @@ def __init__(self, redisBinaryPath, port=6379, modulePath=None, moduleArgs=None,
3838 self .slaveExitCode = None
3939 self .verbose = verbose
4040 self .role = MASTER
41+ self .useTLS = useTLS
42+ self .tlsCertFile = tlsCertFile
43+ self .tlsKeyFile = tlsKeyFile
44+ self .tlsCaCertFile = tlsCaCertFile
4145
4246 if port > 0 :
4347 self .port = port
@@ -57,6 +61,22 @@ def __init__(self, redisBinaryPath, port=6379, modulePath=None, moduleArgs=None,
5761 if self .has_interactive_debugger :
5862 assert self .noCatch and not self .useSlaves and not self .clusterEnabled
5963
64+ if self .useTLS :
65+ if self .useUnix :
66+ raise ValueError ('Unix sockets cannot be used with TLS enabled mode' )
67+ if self .tlsCertFile is None :
68+ raise ValueError ('When useTLS option is True tlsCertFile must be defined' )
69+ if os .path .isfile (self .tlsCertFile ) is False :
70+ raise ValueError ('When useTLS option is True tlsCertFile must exist. specified path {}' .format (self .tlsCertFile ))
71+ if self .tlsKeyFile is None :
72+ raise ValueError ('When useTLS option is True tlsKeyFile must be defined' )
73+ if os .path .isfile (self .tlsKeyFile ) is False :
74+ raise ValueError ('When useTLS option is True tlsKeyFile must exist. specified path {}' .format (self .tlsKeyFile ))
75+ if self .tlsCaCertFile is None :
76+ raise ValueError ('When useTLS option is True tlsCaCertFile must be defined' )
77+ if os .path .isfile (self .tlsCaCertFile ) is False :
78+ raise ValueError ('When useTLS option is True tlsCaCertFile must exist. specified path {}' .format (self .tlsCaCertFile ))
79+
6080 if libPath :
6181 self .libPath = os .path .expanduser (libPath ) if libPath .startswith ('~/' ) else libPath
6282 else :
@@ -88,6 +108,15 @@ def getUnixPath(self, role):
88108 basename = '{}-{}.sock' .format (self .uuid , role )
89109 return os .path .abspath (os .path .join (self .dbDirPath , basename ))
90110
111+ def getTLSCertFile (self ):
112+ return os .path .abspath (self .tlsCertFile )
113+
114+ def getTLSKeyFile (self ):
115+ return os .path .abspath (self .tlsKeyFile )
116+
117+ def getTLSCACertFile (self ):
118+ return os .path .abspath (self .tlsCaCertFile )
119+
91120 @property
92121 def has_interactive_debugger (self ):
93122 return self .debugger and self .debugger .is_interactive
@@ -98,8 +127,11 @@ def createCmdArgs(self, role):
98127 cmdArgs += self .debugger .generate_command (self ._getVlgrindFilePath (role ) if not self .noCatch else None )
99128
100129 cmdArgs += [self .redisBinaryPath ]
101- if self .port > - 1 :
102- cmdArgs += ['--port' , str (self .getPort (role ))]
130+ if self .port > - 1 :
131+ if self .useTLS :
132+ cmdArgs += ['--port' , str (0 ), '--tls-port' , str (self .getPort (role ))]
133+ else :
134+ cmdArgs += ['--port' , str (self .getPort (role ))]
103135 else :
104136 cmdArgs += ['--port' , str (0 ), '--unixsocket' , self .getUnixPath (role )]
105137 if self .modulePath :
@@ -121,11 +153,18 @@ def createCmdArgs(self, role):
121153 if self .clusterEnabled and role is not SLAVE :
122154 cmdArgs += ['--cluster-enabled' , 'yes' , '--cluster-config-file' , self ._getFileName (role , '.cluster.conf' ),
123155 '--cluster-node-timeout' , '5000' ]
156+ if self .useTLS :
157+ cmdArgs += ['--tls-cluster' , 'yes' ]
124158 if self .useAof :
125159 cmdArgs += ['--appendonly yes' ]
126160 cmdArgs += ['--appendfilename' , self ._getFileName (role , '.aof' )]
127161 cmdArgs += ['--aof-use-rdb-preamble' , 'yes' ]
128162
163+ if self .useTLS :
164+ cmdArgs += ['--tls-cert-file' , self .getTLSCertFile ()]
165+ cmdArgs += ['--tls-key-file' , self .getTLSKeyFile ()]
166+ cmdArgs += ['--tls-ca-cert-file' , self .getTLSCACertFile ()]
167+
129168 return cmdArgs
130169
131170 def waitForRedisToStart (self , con ):
@@ -160,6 +199,10 @@ def _printEnvData(self, prefix='', role=MASTER):
160199 print (Colors .Yellow (prefix + 'db dir path: %s' % (self .dbDirPath )))
161200 if self .libPath :
162201 print (Colors .Yellow (prefix + 'library path: %s' % (self .libPath )))
202+ if self .useTLS :
203+ print (Colors .Yellow (prefix + 'TLS Cert File: %s' % (self .getTLSCertFile ())))
204+ print (Colors .Yellow (prefix + 'TLS Key File: %s' % (self .getTLSKeyFile ())))
205+ print (Colors .Yellow (prefix + 'TLS CA Cert File: %s' % (self .getTLSCACertFile ())))
163206
164207 def printEnvData (self , prefix = '' ):
165208 print (Colors .Yellow (prefix + 'master:' ))
@@ -258,6 +301,15 @@ def _getConnection(self, role):
258301 if self .useUnix :
259302 return redis .StrictRedis (unix_socket_path = self .getUnixPath (role ),
260303 password = self .password )
304+ elif self .useTLS :
305+ return redis .StrictRedis ('localhost' , self .getPort (role ),
306+ password = self .password ,
307+ ssl = self .useTLS ,
308+ ssl_keyfile = self .getTLSKeyFile (),
309+ ssl_certfile = self .getTLSCertFile (),
310+ ssl_cert_reqs = 'required' ,
311+ ssl_ca_certs = self .getTLSCACertFile (),
312+ )
261313 else :
262314 return redis .StrictRedis ('localhost' , self .getPort (role ),
263315 password = self .password )
@@ -347,6 +399,9 @@ def isUnixSocket(self):
347399 def isTcp (self ):
348400 return not (self .useUnix )
349401
402+ def isTLS (self ):
403+ return self .useTLS
404+
350405 def exists (self , val ):
351406 return self .getConnection ().exists (val )
352407
0 commit comments