35
35
from neutron .plugins .ml2 .drivers .ovn .mech_driver .ovsdb .extensions import qos \
36
36
as ovn_qos
37
37
from neutron .plugins .ml2 .drivers .ovn .mech_driver .ovsdb import ovn_client
38
+ from neutron .services .logapi .drivers .ovn import driver as log_driver
38
39
from neutron .services .segments import db as segments_db
39
40
40
41
@@ -82,6 +83,18 @@ def __init__(self, core_plugin, ovn_api, sb_ovn, mode, ovn_driver):
82
83
self .segments_plugin = (
83
84
manager .NeutronManager .load_class_for_provider (
84
85
'neutron.service_plugins' , 'segments' )())
86
+ self .log_plugin = directory .get_plugin (plugin_constants .LOG_API )
87
+ if not self .log_plugin :
88
+ self .log_plugin = (
89
+ manager .NeutronManager .load_class_for_provider (
90
+ 'neutron.service_plugins' , 'log' )())
91
+ directory .add_plugin (plugin_constants .LOG_API , self .log_plugin )
92
+ for driver in self .log_plugin .driver_manager .drivers :
93
+ if driver .name == "ovn" :
94
+ self .ovn_log_driver = driver
95
+ if not hasattr (self , 'ovn_log_driver' ):
96
+ self .ovn_log_driver = log_driver .OVNDriver ()
97
+ self .log_plugin .driver_manager .register_driver (self .ovn_log_driver )
85
98
86
99
def stop (self ):
87
100
if utils .is_ovn_l3 (self .l3_plugin ):
@@ -233,6 +246,9 @@ def sync_port_groups(self, ctx):
233
246
234
247
def _get_acls_from_port_groups (self ):
235
248
ovn_acls = []
249
+ # Options and label columns are only present for OVN >= 22.03.
250
+ # Furthermore label is a randint so it cannot be compared with any
251
+ # expected neutron value. They are added later on the ACL addition.
236
252
acl_columns = (self .ovn_api ._tables ['ACL' ].columns .keys () &
237
253
set (ovn_const .ACL_EXPECTED_COLUMNS_NBDB ))
238
254
acl_columns .discard ('external_ids' )
@@ -244,7 +260,16 @@ def _get_acls_from_port_groups(self):
244
260
acl_string ['port_group' ] = pg .name
245
261
if id_key in acl .external_ids :
246
262
acl_string [id_key ] = acl .external_ids [id_key ]
263
+ # This properties are present as lists of one item,
264
+ # converting them to string.
265
+ if acl_string ['name' ]:
266
+ acl_string ['name' ] = acl_string ['name' ][0 ]
267
+ if acl_string ['meter' ]:
268
+ acl_string ['meter' ] = acl_string ['meter' ][0 ]
269
+ if acl_string ['severity' ]:
270
+ acl_string ['severity' ] = acl_string ['severity' ][0 ]
247
271
ovn_acls .append (acl_string )
272
+
248
273
return ovn_acls
249
274
250
275
def sync_acls (self , ctx ):
@@ -274,6 +299,10 @@ def sync_acls(self, ctx):
274
299
neutron_default_acls = acl_utils .add_acls_for_drop_port_group (
275
300
ovn_const .OVN_DROP_PORT_GROUP_NAME )
276
301
302
+ # Add logging options
303
+ self .ovn_log_driver .add_logging_options_to_acls (neutron_acls , ctx )
304
+ self .ovn_log_driver .add_logging_options_to_acls (neutron_default_acls ,
305
+ ctx )
277
306
ovn_acls = self ._get_acls_from_port_groups ()
278
307
# Sort the acls in the ovn database according to the security
279
308
# group rule id for easy comparison in the future.
@@ -304,14 +333,24 @@ def sync_acls(self, ctx):
304
333
o_index += 1
305
334
elif n_id == o_id :
306
335
if any (item not in na .items () for item in oa .items ()):
336
+ for item in oa .items ():
337
+ if item not in na .items ():
338
+ LOG .warning ('Property %(item)s from OVN ACL not '
339
+ 'found in Neutron ACL: %(n_acl)s' ,
340
+ {'item' : item ,
341
+ 'n_acl' : na })
307
342
add_acls .append (na )
308
343
remove_acls .append (oa )
309
344
n_index += 1
310
345
o_index += 1
311
346
elif n_id > o_id :
347
+ LOG .warning ('ACL should not be present in OVN, removing'
348
+ '%(acl)s' , {'acl' : oa })
312
349
remove_acls .append (oa )
313
350
o_index += 1
314
351
else :
352
+ LOG .warning ('ACL should be present in OVN but is not, adding:'
353
+ '%(acl)s' , {'acl' : na })
315
354
add_acls .append (na )
316
355
n_index += 1
317
356
@@ -351,15 +390,41 @@ def get_num_acls(ovn_acls):
351
390
if (self .mode == ovn_const .OVN_DB_SYNC_MODE_REPAIR and
352
391
(num_acls_to_add or num_acls_to_remove )):
353
392
one_time_pg_resync = True
393
+ with self .ovn_api .transaction (check_error = True ) as txn :
394
+ for aclr in ovn_acls :
395
+ LOG .warning ('ACLs found in OVN NB DB but not in '
396
+ 'Neutron for port group %s' ,
397
+ aclr ['port_group' ])
398
+ txn .add (self .ovn_api .pg_acl_del (aclr ['port_group' ],
399
+ aclr ['direction' ],
400
+ aclr ['priority' ],
401
+ aclr ['match' ]))
402
+ for aclr in ovn_acls_from_ls :
403
+ # Remove all the ACLs from any Logical Switch if they have
404
+ # any. Elements are (lswitch_name, list_of_acls).
405
+ if len (aclr [1 ]) > 0 :
406
+ LOG .warning ('Removing ACLs from OVN from Logical '
407
+ 'Switch %s' , aclr [0 ])
408
+ txn .add (self .ovn_api .acl_del (aclr [0 ]))
354
409
while True :
355
410
try :
356
411
with self .ovn_api .transaction (check_error = True ) as txn :
357
412
for acla in neutron_acls :
358
413
LOG .warning ('ACL found in Neutron but not in '
359
414
'OVN NB DB for port group %s' ,
360
415
acla ['port_group' ])
361
- txn .add (self .ovn_api .pg_acl_add (
362
- ** acla , may_exist = True ))
416
+ acl = txn .add (self .ovn_api .pg_acl_add (** acla ,
417
+ may_exist = True ))
418
+ # We need to do this now since label should be
419
+ # random and not 0. We can use options as a way
420
+ # to see if label is supported or not.
421
+ if acla .get ('log' ):
422
+ self .ovn_log_driver .add_label_related (acla ,
423
+ ctx )
424
+ txn .add (self .ovn_api .db_set ('ACL' , acl ,
425
+ label = acla ['label' ],
426
+ options = acla ['options' ]))
427
+
363
428
except idlutils .RowNotFound as row_err :
364
429
if row_err .msg .startswith ("Cannot find Port_Group" ):
365
430
if one_time_pg_resync :
@@ -377,23 +442,6 @@ def get_num_acls(ovn_acls):
377
442
raise
378
443
break
379
444
380
- with self .ovn_api .transaction (check_error = True ) as txn :
381
- for aclr in ovn_acls :
382
- LOG .warning ('ACLs found in OVN NB DB but not in '
383
- 'Neutron for port group %s' ,
384
- aclr ['port_group' ])
385
- txn .add (self .ovn_api .pg_acl_del (aclr ['port_group' ],
386
- aclr ['direction' ],
387
- aclr ['priority' ],
388
- aclr ['match' ]))
389
- for aclr in ovn_acls_from_ls :
390
- # Remove all the ACLs from any Logical Switch if they have
391
- # any. Elements are (lswitch_name, list_of_acls).
392
- if len (aclr [1 ]) > 0 :
393
- LOG .warning ('Removing ACLs from OVN from Logical '
394
- 'Switch %s' , aclr [0 ])
395
- txn .add (self .ovn_api .acl_del (aclr [0 ]))
396
-
397
445
LOG .debug ('OVN-NB Sync ACLs completed @ %s' , str (datetime .now ()))
398
446
399
447
def _calculate_routes_differences (self , ovn_routes , db_routes ):
0 commit comments