4
4
import ast
5
5
import os
6
6
import time
7
+ import threading
7
8
import sys
8
9
import subprocess
9
10
import syslog
@@ -25,6 +26,20 @@ TACPLUS_SERVER_PASSKEY_DEFAULT = ""
25
26
TACPLUS_SERVER_TIMEOUT_DEFAULT = "5"
26
27
TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap"
27
28
29
+ global_lock = None
30
+
31
+ class lock_mgr :
32
+ def __init__ (self ):
33
+ self .lock = global_lock
34
+
35
+ def __enter__ ( self ):
36
+ if self .lock :
37
+ self .lock .acquire ()
38
+
39
+ def __exit__ ( self , exc_type , exc_value , traceback ):
40
+ if self .lock :
41
+ self .lock .release ()
42
+
28
43
29
44
def is_true (val ):
30
45
if val == 'True' or val == 'true' :
@@ -123,7 +138,7 @@ class Iptables(object):
123
138
.format (err .cmd , err .returncode , err .output ))
124
139
125
140
class AaaCfg (object ):
126
- def __init__ (self ):
141
+ def __init__ (self , config_db ):
127
142
self .auth_default = {
128
143
'login' : 'local' ,
129
144
}
@@ -136,49 +151,42 @@ class AaaCfg(object):
136
151
self .tacplus_global = {}
137
152
self .tacplus_servers = {}
138
153
self .debug = False
154
+ self .config_db = config_db
139
155
140
156
# Load conf from ConfigDb
141
- def load (self , aaa_conf , tac_global_conf , tacplus_conf ):
142
- for row in aaa_conf :
143
- self .aaa_update (row , aaa_conf [row ], modify_conf = False )
144
- for row in tac_global_conf :
145
- self .tacacs_global_update (row , tac_global_conf [row ], modify_conf = False )
146
- for row in tacplus_conf :
147
- self .tacacs_server_update (row , tacplus_conf [row ], modify_conf = False )
157
+ def load (self ):
148
158
self .modify_conf_file ()
149
159
150
- def aaa_update (self , key , data , modify_conf = True ):
160
+ def aaa_update (self , key ):
151
161
if key == 'authentication' :
152
- self .auth = data
153
- if 'failthrough' in data :
154
- self .auth ['failthrough' ] = is_true (data ['failthrough' ])
155
- if 'debug' in data :
156
- self .debug = is_true (data ['debug' ])
157
- if modify_conf :
158
162
self .modify_conf_file ()
159
163
160
- def tacacs_global_update (self , key , data , modify_conf = True ):
164
+ def tacacs_global_update (self , key ):
161
165
if key == 'global' :
162
- self .tacplus_global = data
163
- if modify_conf :
164
- self .modify_conf_file ()
165
-
166
- def tacacs_server_update (self , key , data , modify_conf = True ):
167
- if data == {}:
168
- if key in self .tacplus_servers :
169
- del self .tacplus_servers [key ]
170
- else :
171
- self .tacplus_servers [key ] = data
172
-
173
- if modify_conf :
174
166
self .modify_conf_file ()
175
167
168
+ def tacacs_server_update (self , key ):
169
+ self .modify_conf_file ()
170
+
176
171
def modify_single_file (self , filename , operations = None ):
177
172
if operations :
178
173
cmd = "sed -e {0} {1} > {1}.new; mv -f {1} {1}.old; mv -f {1}.new {1}" .format (' -e ' .join (operations ), filename )
179
174
os .system (cmd )
180
175
181
176
def modify_conf_file (self ):
177
+ with lock_mgr ():
178
+ self .auth = self .config_db .get_table ('AAA' ).get ("authentication" , {})
179
+ if 'failthrough' in self .auth :
180
+ self .auth ['failthrough' ] = is_true (self .auth ['failthrough' ])
181
+ if 'debug' in self .auth :
182
+ self .debug = is_true (self .auth ['debug' ])
183
+
184
+ self .tacplus_global = self .config_db .get_table ('TACPLUS' ).get (
185
+ "global" , {})
186
+ self .tacplus_servers = self .config_db .get_table ('TACPLUS_SERVER' )
187
+ self ._modify_conf_file ()
188
+
189
+ def _modify_conf_file (self ):
182
190
auth = self .auth_default .copy ()
183
191
auth .update (self .auth )
184
192
tacplus_global = self .tacplus_global_default .copy ()
@@ -224,6 +232,11 @@ class AaaCfg(object):
224
232
with open (NSS_TACPLUS_CONF , 'w' ) as f :
225
233
f .write (nss_tacplus_conf )
226
234
235
+ if 'passkey' in tacplus_global :
236
+ tacplus_global ['passkey' ] = obfuscate (tacplus_global ['passkey' ])
237
+ syslog .syslog (syslog .LOG_INFO , 'pam.d files updated auth={} global={}' .
238
+ format (auth , tacplus_global ))
239
+
227
240
class MultiAsicBgpMonCfg (object ):
228
241
def __init__ (self ):
229
242
self .ns_for_bgp_mon = 'asic4'
@@ -343,7 +356,7 @@ class HostConfigDaemon:
343
356
self .config_db .connect (wait_for_init = True , retry_on = True )
344
357
syslog .syslog (syslog .LOG_INFO , 'ConfigDB connect success' )
345
358
346
- self .aaacfg = AaaCfg ()
359
+ self .aaacfg = AaaCfg (self . config_db )
347
360
self .iptables = Iptables ()
348
361
# Cache the values of 'state' field in 'FEATURE' table of each container
349
362
self .cached_feature_states = {}
@@ -355,11 +368,19 @@ class HostConfigDaemon:
355
368
if self .is_multi_npu :
356
369
self .masicBgpMonCfg = MultiAsicBgpMonCfg ()
357
370
371
+
372
+ def timer_load (self ):
373
+ global global_lock
374
+
375
+ syslog .syslog (syslog .LOG_INFO , 'reloading tacacs from timer thread' )
376
+ self .aaacfg .load ()
377
+
378
+ # Remove lock as timer is one shot
379
+ global_lock = None
380
+
381
+
358
382
def load (self ):
359
- aaa = self .config_db .get_table ('AAA' )
360
- tacacs_global = self .config_db .get_table ('TACPLUS' )
361
- tacacs_server = self .config_db .get_table ('TACPLUS_SERVER' )
362
- self .aaacfg .load (aaa , tacacs_global , tacacs_server )
383
+ self .aaacfg .load ()
363
384
364
385
lpbk_table = self .config_db .get_table ('LOOPBACK_INTERFACE' )
365
386
self .iptables .load (lpbk_table )
@@ -468,17 +489,18 @@ class HostConfigDaemon:
468
489
self .update_feature_state (feature_name , state , feature_table )
469
490
470
491
def aaa_handler (self , key , data ):
471
- self .aaacfg .aaa_update (key , data )
492
+ self .aaacfg .aaa_update (key )
493
+ syslog .syslog (syslog .LOG_INFO , 'value of {} changed to {}' .format (key , data ))
472
494
473
495
def tacacs_server_handler (self , key , data ):
474
- self .aaacfg .tacacs_server_update (key , data )
496
+ self .aaacfg .tacacs_server_update (key )
475
497
log_data = copy .deepcopy (data )
476
498
if 'passkey' in log_data :
477
499
log_data ['passkey' ] = obfuscate (log_data ['passkey' ])
478
500
syslog .syslog (syslog .LOG_INFO , 'value of {} changed to {}' .format (key , log_data ))
479
501
480
502
def tacacs_global_handler (self , key , data ):
481
- self .aaacfg .tacacs_global_update (key , data )
503
+ self .aaacfg .tacacs_global_update (key )
482
504
log_data = copy .deepcopy (data )
483
505
if 'passkey' in log_data :
484
506
log_data ['passkey' ] = obfuscate (log_data ['passkey' ])
@@ -515,6 +537,7 @@ class HostConfigDaemon:
515
537
self .update_feature_state (feature_name , state , feature_table )
516
538
517
539
def start (self ):
540
+ global global_lock
518
541
519
542
self .config_db .subscribe ('AAA' , lambda table , key , data : self .aaa_handler (key , data ))
520
543
self .config_db .subscribe ('TACPLUS_SERVER' , lambda table , key , data : self .tacacs_server_handler (key , data ))
@@ -537,6 +560,10 @@ class HostConfigDaemon:
537
560
# Defer load until subscribe
538
561
self .load ()
539
562
563
+ global_lock = threading .Lock ()
564
+ self .tmr_thread = threading .Timer (30 , self .timer_load )
565
+ self .tmr_thread .start ()
566
+
540
567
self .config_db .listen ()
541
568
542
569
0 commit comments