18
18
DB_CONNECTOR = None
19
19
COUNTER_TABLE = None
20
20
21
+ class MACsecCfgMeta (object ):
22
+ def __init__ (self , * args ) -> None :
23
+ SEPARATOR = DB_CONNECTOR .get_db_separator (DB_CONNECTOR .CONFIG_DB )
24
+ self .key = self .__class__ .get_cfg_table_name () + SEPARATOR + \
25
+ SEPARATOR .join (args )
26
+ self .cfgMeta = DB_CONNECTOR .get_all (
27
+ DB_CONNECTOR .CONFIG_DB , self .key )
28
+ if len (self .cfgMeta ) == 0 :
29
+ raise ValueError ("No such MACsecCfgMeta: {}" .format (self .key ))
30
+ for k , v in self .cfgMeta .items ():
31
+ setattr (self , k , v )
21
32
22
33
class MACsecAppMeta (object ):
23
34
def __init__ (self , * args ) -> None :
@@ -126,23 +137,55 @@ def get_header(self):
126
137
return "MACsec Egress SC ({})\n " .format (self .sci )
127
138
128
139
129
- class MACsecPort (MACsecAppMeta ):
140
+ class MACsecPort (MACsecAppMeta , MACsecCfgMeta ):
130
141
def __init__ (self , port_name : str ) -> None :
131
142
self .port_name = port_name
132
- super (MACsecPort , self ).__init__ (port_name )
143
+ MACsecAppMeta .__init__ (self , port_name )
144
+ MACsecCfgMeta .__init__ (self , port_name )
133
145
134
146
@classmethod
135
147
def get_appl_table_name (cls ) -> str :
136
148
return "MACSEC_PORT_TABLE"
137
149
150
+ @classmethod
151
+ def get_cfg_table_name (cls ) -> str :
152
+ return "PORT"
153
+
138
154
def dump_str (self , cache = None ) -> str :
139
155
buffer = self .get_header ()
156
+
157
+ # Add the profile information to the meta dict from config meta dict
158
+ self .meta ["profile" ] = self .cfgMeta ["macsec" ]
159
+
140
160
buffer += tabulate (sorted (self .meta .items (), key = lambda x : x [0 ]))
141
161
return buffer
142
162
143
163
def get_header (self ) -> str :
144
164
return "MACsec port({})\n " .format (self .port_name )
145
165
166
+ class MACsecProfile (MACsecCfgMeta ):
167
+ def __init__ (self , profile_name : str ) -> None :
168
+ self .profile_name = profile_name
169
+ super (MACsecProfile , self ).__init__ (profile_name )
170
+
171
+ @classmethod
172
+ def get_cfg_table_name (cls ) -> str :
173
+ return "MACSEC_PROFILE"
174
+
175
+ def dump_str (self , cache = None ) -> str :
176
+ buffer = self .get_header ()
177
+
178
+ # Don't display the primary and fallback CAK
179
+ if 'primary_cak' in self .cfgMeta : del self .cfgMeta ['primary_cak' ]
180
+ if 'fallback_cak' in self .cfgMeta : del self .cfgMeta ['fallback_cak' ]
181
+
182
+ t_buffer = tabulate (sorted (self .cfgMeta .items (), key = lambda x : x [0 ]))
183
+ t_buffer = "\n " .join (["\t " + line for line in t_buffer .splitlines ()])
184
+ buffer += t_buffer
185
+ return buffer
186
+
187
+ def get_header (self ) -> str :
188
+ return "MACsec profile : {}\n " .format (self .profile_name )
146
189
147
190
def create_macsec_obj (key : str ) -> MACsecAppMeta :
148
191
attr = key .split (":" )
@@ -161,6 +204,14 @@ def create_macsec_obj(key: str) -> MACsecAppMeta:
161
204
except ValueError as e :
162
205
return None
163
206
207
+ def create_macsec_profile_obj (key : str ) -> MACsecCfgMeta :
208
+ attr = key .split ("|" )
209
+ try :
210
+ if attr [0 ] == MACsecProfile .get_cfg_table_name ():
211
+ return MACsecProfile (attr [1 ])
212
+ raise TypeError ("Unknown MACsec object type" )
213
+ except ValueError as e :
214
+ return None
164
215
165
216
def create_macsec_objs (interface_name : str ) -> typing .List [MACsecAppMeta ]:
166
217
objs = []
@@ -192,6 +243,12 @@ def create_macsec_objs(interface_name: str) -> typing.List[MACsecAppMeta]:
192
243
return objs
193
244
194
245
246
+ def create_macsec_profiles_objs (profile_name : str ) -> typing .List [MACsecCfgMeta ]:
247
+ objs = []
248
+ objs .append (create_macsec_profile_obj (MACsecProfile .get_cfg_table_name () + "|" + profile_name ))
249
+ return objs
250
+
251
+
195
252
def cache_find (cache : dict , target : MACsecAppMeta ) -> MACsecAppMeta :
196
253
if not cache or not cache ["objs" ]:
197
254
return None
@@ -207,34 +264,51 @@ def cache_find(cache: dict, target: MACsecAppMeta) -> MACsecAppMeta:
207
264
208
265
@click .command ()
209
266
@click .argument ('interface_name' , required = False )
210
- @click .option ('--dump-file' , is_flag = True , required = False , default = False )
267
+ @click .option ('--profile' , is_flag = True , required = False , default = False , help = "show all macsec profiles" )
268
+ @click .option ('--dump-file' , is_flag = True , required = False , default = False , help = "store show output to a file" )
211
269
@multi_asic_util .multi_asic_click_options
212
- def macsec (interface_name , dump_file , namespace , display ):
213
- MacsecContext (namespace , display ).show (interface_name , dump_file )
270
+ def macsec (interface_name , dump_file , namespace , display , profile ):
271
+ if interface_name is not None and profile :
272
+ click .echo ('Interface name is not valid with profile option' )
273
+ return
274
+ MacsecContext (namespace , display ).show (interface_name , dump_file , profile )
214
275
215
276
class MacsecContext (object ):
216
277
217
278
def __init__ (self , namespace_option , display_option ):
218
279
self .db = None
219
280
self .multi_asic = multi_asic_util .MultiAsic (
220
281
display_option , namespace_option )
282
+ self .macsec_profiles = []
221
283
222
284
@multi_asic_util .run_on_multi_asic
223
- def show (self , interface_name , dump_file ):
285
+ def show (self , interface_name , dump_file , profile ):
224
286
global DB_CONNECTOR
225
287
global COUNTER_TABLE
226
288
DB_CONNECTOR = self .db
227
- COUNTER_TABLE = CounterTable (self .db .get_redis_client (self .db .COUNTERS_DB ))
228
289
229
- interface_names = [name .split (":" )[1 ] for name in self .db .keys (self .db .APPL_DB , "MACSEC_PORT*" )]
230
- if interface_name is not None :
231
- if interface_name not in interface_names :
232
- return
233
- interface_names = [interface_name ]
234
- objs = []
290
+ if not profile :
291
+ COUNTER_TABLE = CounterTable (self .db .get_redis_client (self .db .COUNTERS_DB ))
292
+
293
+ interface_names = [name .split (":" )[1 ] for name in self .db .keys (self .db .APPL_DB , "MACSEC_PORT*" )]
294
+ if interface_name is not None :
295
+ if interface_name not in interface_names :
296
+ return
297
+ interface_names = [interface_name ]
298
+ objs = []
235
299
236
- for interface_name in natsorted (interface_names ):
237
- objs += create_macsec_objs (interface_name )
300
+ for interface_name in natsorted (interface_names ):
301
+ objs += create_macsec_objs (interface_name )
302
+ else :
303
+ profile_names = [name .split ("|" )[1 ] for name in self .db .keys (self .db .CONFIG_DB , "MACSEC_PROFILE*" )]
304
+ objs = []
305
+
306
+ for profile_name in natsorted (profile_names ):
307
+ # Check if this macsec profile is already added to profile list. This is in case of
308
+ # multi-asic devices where all namespaces will have the same macsec profile defined.
309
+ if profile_name not in self .macsec_profiles and not dump_file :
310
+ self .macsec_profiles .append (profile_name )
311
+ objs += create_macsec_profiles_objs (profile_name )
238
312
239
313
cache = {}
240
314
if os .path .isfile (CACHE_FILE .format (self .multi_asic .current_namespace )):
0 commit comments