2
2
# -*- coding: utf-8 -*-
3
3
4
4
import os
5
+ import re
5
6
import sys
6
7
import subprocess
7
8
import syslog
@@ -22,6 +23,15 @@ TACPLUS_SERVER_TIMEOUT_DEFAULT = "5"
22
23
TACPLUS_SERVER_AUTH_TYPE_DEFAULT = "pap"
23
24
24
25
26
+ def is_valid_hostname (name ):
27
+ if hostname [- 1 ] == "." :
28
+ hostname = hostname [:- 1 ] # strip exactly one dot from the right, if present
29
+ if len (hostname ) > 253 :
30
+ return False
31
+ allowed = re .compile ("(?!-)[A-Z\d-]{1,63}(?<!-)$" , re .IGNORECASE )
32
+ return all (allowed .match (x ) for x in hostname .split ("." ))
33
+
34
+
25
35
def is_true (val ):
26
36
if val == 'True' or val == 'true' :
27
37
return True
@@ -148,6 +158,7 @@ class HostConfigDaemon:
148
158
tacacs_server = self .config_db .get_table ('TACPLUS_SERVER' )
149
159
self .aaacfg = AaaCfg ()
150
160
self .aaacfg .load (aaa , tacacs_global , tacacs_server )
161
+ self .hostname_cache = ""
151
162
152
163
def aaa_handler (self , key , data ):
153
164
self .aaacfg .aaa_update (key , data )
@@ -166,10 +177,49 @@ class HostConfigDaemon:
166
177
log_data ['passkey' ] = obfuscate (log_data ['passkey' ])
167
178
syslog .syslog (syslog .LOG_INFO , 'value of {} changed to {}' .format (key , log_data ))
168
179
180
+ def hostname_handler (self , key , data ):
181
+ if key != "localhost" :
182
+ return
183
+
184
+ hostname = data .get ("hostname" )
185
+
186
+ if not hostname :
187
+ syslog .syslog (syslog .LOG_WARNING , "hostname key is missing" )
188
+ return
189
+ if not is_valid_hostname (hostname ):
190
+ return
191
+ if hostname == self .hostname_cache :
192
+ return
193
+
194
+ syslog .syslog (syslog .LOG_INFO , "Get all running containers" )
195
+ cmd = 'docker ps --format "{{.Names}}"'
196
+ try :
197
+ containers = subprocess .check_output (cmd , shell = True ).split ("\n " )[:- 1 ]
198
+ except subprocess .CalledProcessError as err :
199
+ syslog .syslog (syslog .LOG_ERR , "{} - failed: return code - {}, output:\n {}"
200
+ .format (err .cmd , err .returncode , err .output ))
201
+
202
+ for name in containers :
203
+ script = '/usr/bin/{}.sh' .format (name )
204
+ exists = os .path .isfile (script )
205
+ if not exists :
206
+ syslog .syslog (syslog .LOG_ERR , "Can't find control script for {}" .format (name ))
207
+ continue
208
+
209
+ cmd = "{} updateHostName {}" .format (script , hostname )
210
+ try :
211
+ subprocess .check_call (cmd , shell = True )
212
+ except subprocess .CalledProcessError as err :
213
+ syslog .syslog (syslog .LOG_ERR , "{} - failed: return code - {}, output:\n {}"
214
+ .format (err .cmd , err .returncode , err .output ))
215
+
216
+ self .hostname_cache = hostname
217
+
169
218
def start (self ):
170
219
self .config_db .subscribe ('AAA' , lambda table , key , data : self .aaa_handler (key , data ))
171
220
self .config_db .subscribe ('TACPLUS_SERVER' , lambda table , key , data : self .tacacs_server_handler (key , data ))
172
221
self .config_db .subscribe ('TACPLUS' , lambda table , key , data : self .tacacs_global_handler (key , data ))
222
+ self .config_db .subscribe ('DEVICE_METADATA' , lambda table , key , data : self .hostname_handler (key , data ))
173
223
self .config_db .listen ()
174
224
175
225
0 commit comments