/
driver.py
587 lines (526 loc) · 27.4 KB
/
driver.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
# Copyright 2020 Red Hat, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import copy
import netaddr
from octavia_lib.api.drivers import data_models as o_datamodels
from octavia_lib.api.drivers import exceptions as driver_exceptions
from octavia_lib.api.drivers import provider_base as driver_base
from octavia_lib.common import constants
from oslo_log import log as logging
from ovn_octavia_provider.common import config as ovn_conf
# TODO(mjozefcz): Start consuming const and utils
# from neutron-lib once released.
from ovn_octavia_provider.common import constants as ovn_const
from ovn_octavia_provider.common import exceptions as ovn_exc
from ovn_octavia_provider import helper as ovn_helper
from ovn_octavia_provider.i18n import _
LOG = logging.getLogger(__name__)
class OvnProviderDriver(driver_base.ProviderDriver):
def __init__(self):
super().__init__()
# NOTE (froyo): Move inside init method in order to
# avoid the issues on test scope colliding with Neutron
# already registered options when this register was
# called from outside of the class a soon this module
# was imported, also to cover requirement from
# OvnProviderHelper and intra references modules
ovn_conf.register_opts()
self._ovn_helper = ovn_helper.OvnProviderHelper(notifier=False)
def __del__(self):
self._ovn_helper.shutdown()
def _is_health_check_supported(self):
return self._ovn_helper.ovn_nbdb_api.is_col_present(
'Load_Balancer', 'health_check')
def _check_for_supported_protocols(self, protocol):
if protocol not in ovn_const.OVN_NATIVE_LB_PROTOCOLS:
msg = _('OVN provider does not support %s protocol') % protocol
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def _check_for_supported_algorithms(self, algorithm):
if algorithm not in ovn_const.OVN_NATIVE_LB_ALGORITHMS:
msg = _('OVN provider does not support %s algorithm') % algorithm
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def _check_for_supported_session_persistence(self, session):
if (session and
session.get("type") not in
ovn_const.OVN_NATIVE_SESSION_PERSISTENCE):
msg = _('OVN provider does not support %s session persistence. '
'Only SOURCE_IP type is supported.') % session.type
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def _check_for_allowed_cidrs(self, allowed_cidrs):
# TODO(haleyb): add support for this
if isinstance(allowed_cidrs, o_datamodels.UnsetType):
allowed_cidrs = []
if allowed_cidrs:
msg = _('OVN provider does not support allowed_cidrs option')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def loadbalancer_create(self, loadbalancer):
admin_state_up = loadbalancer.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': loadbalancer.loadbalancer_id,
'vip_address': loadbalancer.vip_address,
'vip_network_id': loadbalancer.vip_network_id,
'admin_state_up': admin_state_up}
if not isinstance(loadbalancer.additional_vips,
o_datamodels.UnsetType):
request_info[constants.ADDITIONAL_VIPS] = \
loadbalancer.additional_vips
request = {'type': ovn_const.REQ_TYPE_LB_CREATE,
'info': request_info}
self._ovn_helper.add_request(request)
if not isinstance(loadbalancer.listeners, o_datamodels.UnsetType):
for listener in loadbalancer.listeners:
self.listener_create(listener)
if not isinstance(loadbalancer.pools, o_datamodels.UnsetType):
for pool in loadbalancer.pools:
self.pool_create(pool)
for member in pool.members:
if not member.subnet_id:
member.subnet_id = loadbalancer.vip_network_id
self.member_create(member)
def loadbalancer_delete(self, loadbalancer, cascade=False):
request_info = {'id': loadbalancer.loadbalancer_id,
'cascade': cascade}
request = {'type': ovn_const.REQ_TYPE_LB_DELETE,
'info': request_info}
self._ovn_helper.add_request(request)
def loadbalancer_failover(self, loadbalancer_id):
msg = _('OVN provider does not support loadbalancer failover')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def loadbalancer_update(self, old_loadbalancer, new_loadbalancer):
request_info = {'id': new_loadbalancer.loadbalancer_id}
if not isinstance(
new_loadbalancer.admin_state_up, o_datamodels.UnsetType):
request_info['admin_state_up'] = new_loadbalancer.admin_state_up
request = {'type': ovn_const.REQ_TYPE_LB_UPDATE,
'info': request_info}
self._ovn_helper.add_request(request)
# Pool
def pool_create(self, pool):
self._check_for_supported_protocols(pool.protocol)
self._check_for_supported_algorithms(pool.lb_algorithm)
admin_state_up = pool.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': pool.pool_id,
'loadbalancer_id': pool.loadbalancer_id,
'protocol': pool.protocol,
'lb_algorithm': pool.lb_algorithm,
'listener_id': pool.listener_id,
'admin_state_up': admin_state_up}
request = {'type': ovn_const.REQ_TYPE_POOL_CREATE,
'info': request_info}
if not isinstance(
pool.session_persistence, o_datamodels.UnsetType):
self._check_for_supported_session_persistence(
pool.session_persistence)
request['info']['session_persistence'] = pool.session_persistence
self._ovn_helper.add_request(request)
if pool.healthmonitor is not None and not isinstance(
pool.healthmonitor, o_datamodels.UnsetType):
self.health_monitor_create(pool.healthmonitor)
def pool_delete(self, pool):
if pool.healthmonitor:
self.health_monitor_delete(pool.healthmonitor)
for member in pool.members:
self.member_delete(member)
request_info = {'id': pool.pool_id,
'protocol': pool.protocol,
'loadbalancer_id': pool.loadbalancer_id}
request = {'type': ovn_const.REQ_TYPE_POOL_DELETE,
'info': request_info}
self._ovn_helper.add_request(request)
def pool_update(self, old_pool, new_pool):
if not isinstance(new_pool.protocol, o_datamodels.UnsetType):
self._check_for_supported_protocols(new_pool.protocol)
if not isinstance(new_pool.lb_algorithm, o_datamodels.UnsetType):
self._check_for_supported_algorithms(new_pool.lb_algorithm)
request_info = {'id': old_pool.pool_id,
'protocol': old_pool.protocol,
'loadbalancer_id': old_pool.loadbalancer_id}
if not isinstance(new_pool.admin_state_up, o_datamodels.UnsetType):
request_info['admin_state_up'] = new_pool.admin_state_up
if not isinstance(
new_pool.session_persistence, o_datamodels.UnsetType):
self._check_for_supported_session_persistence(
new_pool.session_persistence)
request_info['session_persistence'] = (
new_pool.session_persistence)
request = {'type': ovn_const.REQ_TYPE_POOL_UPDATE,
'info': request_info}
self._ovn_helper.add_request(request)
def listener_create(self, listener):
self._check_for_supported_protocols(listener.protocol)
self._check_for_allowed_cidrs(listener.allowed_cidrs)
admin_state_up = listener.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': listener.listener_id,
'protocol': listener.protocol,
'loadbalancer_id': listener.loadbalancer_id,
'protocol_port': listener.protocol_port,
'default_pool_id': listener.default_pool_id,
'admin_state_up': admin_state_up}
request = {'type': ovn_const.REQ_TYPE_LISTENER_CREATE,
'info': request_info}
self._ovn_helper.add_request(request)
def listener_delete(self, listener):
request_info = {'id': listener.listener_id,
'loadbalancer_id': listener.loadbalancer_id,
'protocol_port': listener.protocol_port,
'protocol': listener.protocol}
request = {'type': ovn_const.REQ_TYPE_LISTENER_DELETE,
'info': request_info}
self._ovn_helper.add_request(request)
def listener_update(self, old_listener, new_listener):
self._check_for_allowed_cidrs(new_listener.allowed_cidrs)
request_info = {'id': new_listener.listener_id,
'loadbalancer_id': old_listener.loadbalancer_id,
'protocol': old_listener.protocol,
'protocol_port': old_listener.protocol_port}
if not isinstance(new_listener.admin_state_up, o_datamodels.UnsetType):
request_info['admin_state_up'] = new_listener.admin_state_up
if not isinstance(new_listener.default_pool_id,
o_datamodels.UnsetType):
request_info['default_pool_id'] = new_listener.default_pool_id
request = {'type': ovn_const.REQ_TYPE_LISTENER_UPDATE,
'info': request_info}
self._ovn_helper.add_request(request)
# Member
def _check_monitor_options(self, member):
if (isinstance(member.monitor_address, o_datamodels.UnsetType) and
isinstance(member.monitor_port, o_datamodels.UnsetType)):
return False
if member.monitor_address or member.monitor_port:
return True
return False
def _check_member_monitor_options(self, member):
if self._check_monitor_options(member):
msg = _('OVN Load Balancer does not support different member '
'monitor address or port.')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def _ip_version_differs(self, member):
_, ovn_lb = self._ovn_helper._find_ovn_lb_by_pool_id(member.pool_id)
if not ovn_lb:
return False
lb_vips = [ovn_lb.external_ids.get(
ovn_const.LB_EXT_IDS_VIP_KEY)]
if ovn_const.LB_EXT_IDS_ADDIT_VIP_KEY in ovn_lb.external_ids:
lb_vips.extend(ovn_lb.external_ids.get(
ovn_const.LB_EXT_IDS_ADDIT_VIP_KEY).split(','))
# NOTE(froyo): Allow mixing member IP version when VIP LB and any
# additional vip is also mixing version
vip_version = netaddr.IPNetwork(lb_vips[0]).version
vips_mixed = any(netaddr.IPNetwork(vip).version != vip_version
for vip in lb_vips if vip)
if vips_mixed:
return False
else:
return vip_version != (netaddr.IPNetwork(member.address).version)
def member_create(self, member):
# Validate monitoring options if present
self._check_member_monitor_options(member)
if self._ip_version_differs(member):
raise ovn_exc.IPVersionsMixingNotSupportedError()
admin_state_up = member.admin_state_up
subnet_id = member.subnet_id
if (isinstance(subnet_id, o_datamodels.UnsetType) or not subnet_id):
subnet_id, subnet_cidr = self._ovn_helper._get_subnet_from_pool(
member.pool_id)
if not (subnet_id and
self._ovn_helper._check_ip_in_subnet(member.address,
subnet_cidr)):
msg = _('Subnet is required, or Loadbalancer associated with '
'Pool must have a subnet, for Member creation '
'with OVN Provider Driver if it is not the same as '
'LB VIP subnet')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': member.member_id,
'address': member.address,
'protocol_port': member.protocol_port,
'pool_id': member.pool_id,
'subnet_id': subnet_id,
'admin_state_up': admin_state_up}
request = {'type': ovn_const.REQ_TYPE_MEMBER_CREATE,
'info': request_info}
self._ovn_helper.add_request(request)
# NOTE(mjozefcz): If LB has FIP on VIP
# and member has FIP we need to centralize
# traffic for member.
request_info = {'id': member.member_id,
'address': member.address,
'pool_id': member.pool_id,
'subnet_id': subnet_id,
'action': ovn_const.REQ_INFO_MEMBER_ADDED}
request = {'type': ovn_const.REQ_TYPE_HANDLE_MEMBER_DVR,
'info': request_info}
self._ovn_helper.add_request(request)
def member_delete(self, member):
# NOTE(froyo): OVN provider allow to create member without param
# subnet_id, in that case the driver search it according to the
# pool_id, but it is not propagated to Octavia. In this case, if
# the member is deleted, Octavia send the object without subnet_id.
subnet_id = member.subnet_id
if (isinstance(subnet_id, o_datamodels.UnsetType) or not subnet_id):
subnet_id, subnet_cidr = self._ovn_helper._get_subnet_from_pool(
member.pool_id)
if not (subnet_id and
self._ovn_helper._check_ip_in_subnet(member.address,
subnet_cidr)):
msg = _('Subnet is required, or Loadbalancer associated with '
'Pool must have a subnet, for Member deletion if it is'
'with OVN Provider Driver if it is not the same as '
'LB VIP subnet')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
request_info = {'id': member.member_id,
'address': member.address,
'protocol_port': member.protocol_port,
'pool_id': member.pool_id,
'subnet_id': subnet_id}
request = {'type': ovn_const.REQ_TYPE_MEMBER_DELETE,
'info': request_info}
self._ovn_helper.add_request(request)
# NOTE(mjozefcz): If LB has FIP on VIP
# and member had FIP we can decentralize
# the traffic now.
request_info = {'id': member.member_id,
'address': member.address,
'pool_id': member.pool_id,
'subnet_id': subnet_id,
'action': ovn_const.REQ_INFO_MEMBER_DELETED}
request = {'type': ovn_const.REQ_TYPE_HANDLE_MEMBER_DVR,
'info': request_info}
self._ovn_helper.add_request(request)
def member_update(self, old_member, new_member):
# Validate monitoring options if present
self._check_member_monitor_options(new_member)
if new_member.address and self._ip_version_differs(new_member):
raise ovn_exc.IPVersionsMixingNotSupportedError()
request_info = {'id': new_member.member_id,
'address': old_member.address,
'protocol_port': old_member.protocol_port,
'pool_id': old_member.pool_id,
'old_admin_state_up': old_member.admin_state_up}
if not isinstance(new_member.admin_state_up, o_datamodels.UnsetType):
request_info['admin_state_up'] = new_member.admin_state_up
request = {'type': ovn_const.REQ_TYPE_MEMBER_UPDATE,
'info': request_info}
self._ovn_helper.add_request(request)
def member_batch_update(self, pool_id, members):
request_list = []
pool_key, ovn_lb = self._ovn_helper._find_ovn_lb_by_pool_id(pool_id)
external_ids = copy.deepcopy(ovn_lb.external_ids)
pool = external_ids[pool_key]
existing_members = pool.split(',') if pool else []
members_to_delete = copy.copy(existing_members)
pool_subnet_id = None
pool_subnet_cidr = None
for member in members:
# NOTE(froyo): in order to keep sync with Octavia DB, we raise
# not supporting exceptions as soon as posible, considering the
# full request as not valid
if (self._check_monitor_options(member)):
msg = 'OVN provider does not support monitor options'
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
if (member.address and self._ip_version_differs(member)):
raise ovn_exc.IPVersionsMixingNotSupportedError()
# NOTE(froyo): if subnet_id not provided, lets try to get it
# from the member pool_id
subnet_id = member.subnet_id
if (isinstance(subnet_id, o_datamodels.UnsetType) or
not subnet_id):
if not pool_subnet_id:
pool_subnet_id, pool_subnet_cidr = (
self._ovn_helper._get_subnet_from_pool(pool_id))
if pool_subnet_id:
if (self._ovn_helper._check_ip_in_subnet(
member.address, pool_subnet_cidr)):
member.subnet_id = pool_subnet_id
# NOTE(mjozefcz): We need to have subnet_id information.
if not member.subnet_id:
msg = _('Subnet is required, or Loadbalancer associated '
'with Pool must have a subnet, for Member '
'batch update with OVN Provider Driver if it is '
'not the same as LB VIP subnet')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
admin_state_up = member.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
member_info = self._ovn_helper._get_member_info(member)
if member_info not in existing_members:
req_type = ovn_const.REQ_TYPE_MEMBER_CREATE
else:
# If member exists in pool, then Update
req_type = ovn_const.REQ_TYPE_MEMBER_UPDATE
# Remove all updating members so only deleted ones are left
members_to_delete.remove(member_info)
request_info = {'id': member.member_id,
'address': member.address,
'protocol_port': member.protocol_port,
'pool_id': member.pool_id,
'subnet_id': member.subnet_id,
'admin_state_up': admin_state_up}
request = {'type': req_type,
'info': request_info}
request_list.append(request)
for member in members_to_delete:
member_info = member.split('_')
member_ip, member_port, subnet_id, member_id = (
self._ovn_helper._extract_member_info(member)[0])
request_info = {'id': member_info[1],
'address': member_ip,
'protocol_port': member_port,
'pool_id': pool_id}
if len(member_info) == 4:
request_info['subnet_id'] = subnet_id
request = {'type': ovn_const.REQ_TYPE_MEMBER_DELETE,
'info': request_info}
request_list.append(request)
# NOTE(mjozefcz): If LB has FIP on VIP
# and member had FIP we can decentralize
# the traffic now.
request_info = {'id': member_id,
'address': member_ip,
'pool_id': pool_id,
'action': ovn_const.REQ_INFO_MEMBER_DELETED}
if len(member_info) == 4:
request_info['subnet_id'] = subnet_id
request = {'type': ovn_const.REQ_TYPE_HANDLE_MEMBER_DVR,
'info': request_info}
request_list.append(request)
for request in request_list:
self._ovn_helper.add_request(request)
def create_vip_port(self, lb_id, project_id, vip_dict,
additional_vip_dicts=None):
"""Create the VIP port of a load balancer
:param lb_id: The ID of the load balancer
:param project_id: The ID of the project that owns the load balancer
:param vip_dict: A dict that contains the provider VIP information
('network_id', 'port_id', 'subnet_id' and/or 'ip_address')
:param additional_vip_dicts: An optional list of dicts of additional
VIP. An additional VIP dict might contain the 'ip_address',
'network_id', 'port_id' and/or 'subnet_id' of the secondary
VIPs.
:return: a tuple that contains the VIP provider dictionary and a list
of additional VIP dictionaries
"""
try:
port, additional_ports = self._ovn_helper.create_vip_port(
project_id, lb_id, vip_dict, additional_vip_dicts)
vip_dict[constants.VIP_PORT_ID] = port.id
vip_dict[constants.VIP_ADDRESS] = (
port['fixed_ips'][0]['ip_address'])
additional_vip_port_dict = []
for additional_port in additional_ports:
additional_vip_port_dict.append({
'port_id': additional_port['id'],
constants.NETWORK_ID:
additional_port[constants.NETWORK_ID],
constants.SUBNET_ID:
additional_port['fixed_ips'][0]['subnet_id'],
'ip_address': additional_port['fixed_ips'][0]['ip_address']
})
except Exception as e:
kwargs = {}
for attr in ('details', 'message'):
if hasattr(e, attr):
value = getattr(e, attr)
kwargs = {'user_fault_string': value,
'operator_fault_string': value}
break
raise driver_exceptions.DriverError(
**kwargs)
return vip_dict, additional_vip_port_dict
def _validate_hm_support(self, hm, action='create'):
if not self._is_health_check_supported():
msg = _('OVN Load Balancer supports Health Check provider '
'from version 2.12. Upgrade OVN in order to use it.')
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
# type is only required for create
if action == 'create':
if isinstance(hm.type, o_datamodels.UnsetType):
msg = _('OVN provider health monitor type not specified.')
# seems this should be other than "unsupported"?
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
if hm.type not in ovn_const.SUPPORTED_HEALTH_MONITOR_TYPES:
msg = (_('OVN provider does not support %s '
'health monitor type. Supported types: %s') %
(hm.type,
', '.join(ovn_const.SUPPORTED_HEALTH_MONITOR_TYPES)))
raise driver_exceptions.UnsupportedOptionError(
user_fault_string=msg,
operator_fault_string=msg)
def health_monitor_create(self, healthmonitor):
self._validate_hm_support(healthmonitor)
admin_state_up = healthmonitor.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': healthmonitor.healthmonitor_id,
'pool_id': healthmonitor.pool_id,
'type': healthmonitor.type,
'interval': healthmonitor.delay,
'timeout': healthmonitor.timeout,
'failure_count': healthmonitor.max_retries_down,
'success_count': healthmonitor.max_retries,
'admin_state_up': admin_state_up}
request = {'type': ovn_const.REQ_TYPE_HM_CREATE,
'info': request_info}
self._ovn_helper.add_request(request)
def health_monitor_update(self, old_healthmonitor, new_healthmonitor):
self._validate_hm_support(new_healthmonitor, action='update')
admin_state_up = new_healthmonitor.admin_state_up
if isinstance(admin_state_up, o_datamodels.UnsetType):
admin_state_up = True
request_info = {'id': new_healthmonitor.healthmonitor_id,
'pool_id': old_healthmonitor.pool_id,
'interval': new_healthmonitor.delay,
'timeout': new_healthmonitor.timeout,
'failure_count': new_healthmonitor.max_retries_down,
'success_count': new_healthmonitor.max_retries,
'admin_state_up': admin_state_up}
request = {'type': ovn_const.REQ_TYPE_HM_UPDATE,
'info': request_info}
self._ovn_helper.add_request(request)
def health_monitor_delete(self, healthmonitor):
request_info = {'id': healthmonitor.healthmonitor_id,
'pool_id': healthmonitor.pool_id}
request = {'type': ovn_const.REQ_TYPE_HM_DELETE,
'info': request_info}
self._ovn_helper.add_request(request)