@@ -139,6 +139,42 @@ def _get_pool_request_info(self, pool):
139
139
140
140
return request_info
141
141
142
+ def _get_member_request_info (self , member , create = True ):
143
+ # Validate monitoring options if present
144
+ admin_state_up = None
145
+ if create :
146
+ self ._check_member_monitor_options (member )
147
+ if self ._ip_version_differs (member ):
148
+ raise ovn_exc .IPVersionsMixingNotSupportedError ()
149
+ admin_state_up = member .admin_state_up
150
+ subnet_id = member .subnet_id
151
+ if (isinstance (subnet_id , o_datamodels .UnsetType ) or not subnet_id ):
152
+ subnet_id , subnet_cidr = self ._ovn_helper ._get_subnet_from_pool (
153
+ member .pool_id )
154
+ if not (subnet_id and
155
+ self ._ovn_helper ._check_ip_in_subnet (member .address ,
156
+ subnet_cidr )):
157
+ msg = _ ('Subnet is required, or Loadbalancer associated with '
158
+ 'Pool must have a subnet, for Member creation '
159
+ 'with OVN Provider Driver if it is not the same as '
160
+ 'LB VIP subnet' )
161
+ raise driver_exceptions .UnsupportedOptionError (
162
+ user_fault_string = msg ,
163
+ operator_fault_string = msg )
164
+
165
+ if isinstance (admin_state_up , o_datamodels .UnsetType ):
166
+ admin_state_up = True
167
+ request_info = {'id' : member .member_id ,
168
+ 'address' : member .address ,
169
+ 'protocol_port' : member .protocol_port ,
170
+ 'pool_id' : member .pool_id ,
171
+ 'subnet_id' : subnet_id }
172
+
173
+ if admin_state_up and create :
174
+ request_info ['admin_state_up' ] = admin_state_up
175
+
176
+ return request_info
177
+
142
178
def loadbalancer_create (self , loadbalancer ):
143
179
request = {'type' : ovn_const .REQ_TYPE_LB_CREATE ,
144
180
'info' : self ._get_loadbalancer_request_info (
@@ -648,7 +684,16 @@ def _ensure_loadbalancer(self, loadbalancer):
648
684
status_pool = self ._ovn_helper .pool_create (
649
685
self ._get_pool_request_info (pool ))
650
686
status [constants .POOLS ].append (status_pool )
687
+ for member in pool .members :
688
+ status [constants .MEMBERS ] = []
689
+ if not member .subnet_id :
690
+ member .subnet_id = loadbalancer .vip_subnet_id
691
+ status_member = self ._ovn_helper .member_create (
692
+ self ._get_member_request_info (member ))
693
+ status [constants .MEMBERS ].append (status_member )
694
+
651
695
self ._ovn_helper ._update_status_to_octavia (status )
696
+
652
697
else :
653
698
# Load Balancer found, check LB and listener/pool/member/hms
654
699
# related
@@ -667,8 +712,53 @@ def _ensure_loadbalancer(self, loadbalancer):
667
712
# Pool
668
713
if not isinstance (loadbalancer .pools , o_datamodels .UnsetType ):
669
714
for pool in loadbalancer .pools :
670
- self ._ovn_helper .pool_sync (
671
- self ._get_pool_request_info (pool ), ovn_lb )
715
+ pool_info = self ._get_pool_request_info (pool )
716
+ self ._ovn_helper .pool_sync (pool_info , ovn_lb )
717
+ ovn_pool_key = self ._ovn_helper ._get_pool_key (
718
+ pool_info [constants .ID ],
719
+ is_enabled = pool_info [constants .ADMIN_STATE_UP ])
720
+ member_ids = []
721
+ if not isinstance (pool .members ,
722
+ o_datamodels .UnsetType ):
723
+ for member in pool .members :
724
+ if not member .subnet_id :
725
+ member .subnet_id = (
726
+ loadbalancer .vip_subnet_id
727
+ )
728
+ self ._ovn_helper .member_sync (
729
+ self ._get_member_request_info (member ),
730
+ ovn_lb ,
731
+ ovn_pool_key )
732
+ member_ids .append (member .member_id )
733
+
734
+ for ovn_mb_info in \
735
+ self ._ovn_helper ._get_members_in_ovn_lb (
736
+ ovn_lb , ovn_pool_key ):
737
+ # If member ID not in pool member list,
738
+ # delete it.
739
+ if ovn_mb_info [3 ] not in member_ids :
740
+ LOG .debug (
741
+ "Start deleting extra member "
742
+ f"{ ovn_mb_info [3 ]} from pool "
743
+ "{pool_info[constants.ID]} in OVN."
744
+ )
745
+ mb_delete_info = {
746
+ 'id' : ovn_mb_info [3 ],
747
+ 'subnet_id' : ovn_mb_info [2 ],
748
+ }
749
+ self ._ovn_helper .member_delete (
750
+ mb_delete_info )
751
+
752
+ mb_delete_dvr_info = {
753
+ 'id' : ovn_mb_info [3 ],
754
+ 'address' : ovn_mb_info [0 ],
755
+ 'pool_id' : pool_info [constants .ID ],
756
+ 'subnet_id' : ovn_mb_info [2 ],
757
+ 'action' :
758
+ ovn_const .REQ_INFO_MEMBER_DELETED
759
+ }
760
+ self ._ovn_helper .handle_member_dvr (
761
+ mb_delete_dvr_info )
672
762
status = self ._ovn_helper ._get_current_operating_statuses (
673
763
ovn_lb )
674
764
self ._ovn_helper ._update_status_to_octavia (status )
@@ -691,9 +781,20 @@ def do_sync(self, **lb_filters):
691
781
] if listeners else o_datamodels .Unset
692
782
693
783
pools = provider_lb .pools or []
694
- provider_lb .pools = [
695
- o_datamodels .Pool .from_dict (pool )
696
- for pool in pools
697
- ] if pools else o_datamodels .Unset
698
-
784
+ provider_pools = []
785
+ for pool in pools :
786
+ provider_pool = o_datamodels .Pool .from_dict (pool )
787
+ # format member provider
788
+ members = provider_pool .members
789
+ if not isinstance (members , o_datamodels .UnsetType ) and members :
790
+ provider_pool .members = [
791
+ o_datamodels .Member .from_dict (m )
792
+ for m in members ]
793
+ else :
794
+ provider_pool .members = o_datamodels .Unset
795
+ provider_pools .append (provider_pool )
796
+
797
+ provider_lb .pools = (
798
+ provider_pools if provider_pools else o_datamodels .Unset
799
+ )
699
800
self ._ensure_loadbalancer (provider_lb )
0 commit comments