@@ -756,10 +756,42 @@ def _check_http2_changed(self, old_listener, listener):
756756 return True
757757 return False
758758
759+ def _check_redirect_changed (self , old_listener , listener ):
760+ LOG .debug (old_listener )
761+ LOG .debug (listener )
762+
763+ if 'redirect_up' not in old_listener or 'redirect_up' not in listener :
764+ return 'none'
765+
766+ old_redirect_up = old_listener .get ('redirect_up' )
767+ new_redirect_up = listener .get ('redirect_up' )
768+
769+ if new_redirect_up and not old_redirect_up :
770+ LOG .debug ('enabling' )
771+ return 'enable'
772+ elif old_redirect_up and not new_redirect_up :
773+ LOG .debug ('disabling' )
774+ return 'disable'
775+ elif old_redirect_up and new_redirect_up :
776+ old_num = old_listener .get ('redirect_port' )
777+ new_num = listener .get ('redirect_port' )
778+ LOG .debug ('old_num:' )
779+ LOG .debug (old_num )
780+ LOG .debug ('new_num:' )
781+ LOG .debug (new_num )
782+ if old_num != new_num :
783+ LOG .debug ('modifying' )
784+ return 'modify'
785+
786+ LOG .debug ('nothing' )
787+ return 'none'
788+
759789 def _update_needed (self , payload , old_listener , listener ):
760790 if self ._check_tls_changed (old_listener , listener ) or \
761791 self ._check_customized_changed (old_listener , listener ) or \
792+ self ._check_redirect_changed (old_listener , listener ) != 'none' or \
762793 self ._check_http2_changed (old_listener , listener ):
794+ LOG .info ('true here' )
763795 return True
764796 return super (ListenerManager , self )._update_needed (
765797 payload , old_listener , listener )
@@ -1098,6 +1130,22 @@ def _detach_profile(self, bigip, vs, profile):
10981130 LOG .debug ("Profile %s is not attached to vs %s" ,
10991131 profile ['name' ], vs ['name' ])
11001132
1133+ def _create_redirect_irule_payload (self , vs , loadbalancer , listener ):
1134+ # create the redirect irule
1135+ irule = {}
1136+ irule ['partition' ] = self .driver .service_adapter .\
1137+ get_folder_name (loadbalancer ['tenant_id' ])
1138+ irule ['name' ] = 'redirect_irule_' + listener ['id' ]
1139+
1140+ redi_port = listener .get ('redirect_port' )
1141+ if redi_port is None :
1142+ LOG .error ('redirect port is none, seems safe to neglect now' )
1143+
1144+ irule ['apiAnonymous' ] = 'when HTTP_REQUEST {\n \
1145+ HTTP::redirect https://[getfield [HTTP::host] ":" 1]:' + \
1146+ str (redi_port ) + '[HTTP::uri]\n }'
1147+ return irule
1148+
11011149 def _create_websocket_irule (self , bigip , vs ):
11021150 # Websocket iRule is shared across all partitions. Needn't delete it.
11031151 irule = {
@@ -1120,6 +1168,36 @@ def _create_websocket_irule(self, bigip, vs):
11201168 bigip , irule , None , None , type = "irule" , helper = self .irule_helper )
11211169 vs ['rules' ].append ("/Common/websocket_irule" )
11221170
1171+ def try_create_redirect_irule (self , bigip , vs , loadbalancer , listener ):
1172+ LOG .debug ('vs here is:' )
1173+ LOG .debug (vs )
1174+ the_payload = self ._create_redirect_irule_payload (
1175+ vs , loadbalancer , listener
1176+ )
1177+ super (ListenerManager , self )._create (
1178+ bigip , the_payload , None , None , type = "irule" ,
1179+ helper = self .irule_helper , overwrite = True
1180+ )
1181+
1182+ def try_del_redirect_irule (self , bigip , vs , loadbalancer , listener ):
1183+ LOG .debug ('inside try_del_redirect_irule' )
1184+ LOG .debug ('vs here:' )
1185+ LOG .debug (vs )
1186+
1187+ LOG .debug ('loadbalancer here:' )
1188+ LOG .debug (loadbalancer )
1189+
1190+ LOG .debug ('listener here:' )
1191+ LOG .debug (listener )
1192+
1193+ payload = self ._create_redirect_irule_payload (
1194+ vs , loadbalancer , listener
1195+ )
1196+ super (ListenerManager , self ).\
1197+ _delete (bigip , payload , None , None ,
1198+ type = "irule" ,
1199+ helper = self .irule_helper )
1200+
11231201 def _create (self , bigip , vs , listener , service ):
11241202 tls = self .driver .service_adapter .get_tls (service )
11251203 if tls :
@@ -1154,6 +1232,23 @@ def _create(self, bigip, vs, listener, service):
11541232 bwc_policy = LoadBalancerManager .get_bwc_policy_name (
11551233 self .driver .service_adapter , loadbalancer )
11561234 vs ['bwcPolicy' ] = bwc_policy
1235+
1236+ # redirect_up, redirect_protocol, redirect_port
1237+ if vs .get ('redirect_up' ):
1238+ LOG .debug ('at redirect_up' )
1239+ self .try_create_redirect_irule (
1240+ bigip , vs , loadbalancer , listener
1241+ )
1242+ # use full name
1243+ # redirect_irule_name = 'redirect_irule_' + listener['id']
1244+ redi_irule_full_name = self .get_redirect_irule_full_name (
1245+ self .driver .service_adapter ,
1246+ loadbalancer , listener ['id' ]
1247+ )
1248+ vs ['rules' ].append (redi_irule_full_name )
1249+
1250+ LOG .debug ('vs details:' )
1251+ LOG .debug (vs )
11571252 super (ListenerManager , self )._create (bigip , vs , listener , service )
11581253
11591254 def __get_profiles_from_bigip (self , bigip , vs ):
@@ -1166,6 +1261,13 @@ def __get_profiles_from_bigip(self, bigip, vs):
11661261 profiles = v .profilesReference
11671262 return profiles
11681263
1264+ @staticmethod
1265+ def get_redirect_irule_full_name (adapter , loadbalancer , listener_id ):
1266+ irule_name = '/' + adapter .\
1267+ get_folder_name (loadbalancer ['tenant_id' ]) + '/redirect_irule_' \
1268+ + listener_id
1269+ return irule_name
1270+
11691271 def _update (self , bigip , vs , old_listener , listener , service ):
11701272 # Add conditions here for more update requests via vs['profiles']
11711273 extended_profile_updated = False
@@ -1222,7 +1324,74 @@ def _update(self, bigip, vs, old_listener, listener, service):
12221324 old_service = {"listener" : old_listener }
12231325 self ._delete_ssl_profiles (bigip , vs , old_service )
12241326
1327+ LOG .debug ('checking redirect here' )
1328+ # enable, disable, modify, none
1329+ redirect_ret = self ._check_redirect_changed (old_listener , listener )
1330+ LOG .debug ('redirect_ret here is:' )
1331+ LOG .debug (redirect_ret )
1332+ loadbalancer = service .get ('loadbalancer' , dict ())
1333+
1334+ # redirect_irule_name = 'redirect_irule_' + listener['id']
1335+ redi_irule_full_name = self .get_redirect_irule_full_name (
1336+ self .driver .service_adapter ,
1337+ loadbalancer , listener ['id' ]
1338+ )
1339+
1340+ the_vs_payload = self .driver .service_adapter .\
1341+ _init_virtual_name (loadbalancer , listener )
1342+ the_vs = self .resource_helper .load (
1343+ bigip , name = the_vs_payload ['name' ],
1344+ partition = the_vs_payload ['partition' ]
1345+ )
1346+
1347+ the_vs_payload ['rules' ] = the_vs .rules
1348+
1349+ if redirect_ret == 'enable' :
1350+ LOG .debug ('to redirect' )
1351+ self .try_create_redirect_irule (
1352+ bigip , the_vs_payload ,
1353+ loadbalancer , listener
1354+ )
1355+ the_vs_payload ['rules' ].append (redi_irule_full_name )
1356+
1357+ elif redirect_ret == 'disable' :
1358+ LOG .debug ('to reverse redirect' )
1359+ # not able to delete here because it is still in use by listener
1360+ # self.try_del_redirect_irule(bigip,vs,loadbalancer,old_listener)
1361+
1362+ if redi_irule_full_name in the_vs_payload ['rules' ]:
1363+ LOG .debug ('remove from rules' )
1364+ LOG .debug (redi_irule_full_name )
1365+ the_vs_payload ['rules' ].remove (redi_irule_full_name )
1366+
1367+ elif redirect_ret == 'modify' :
1368+ LOG .debug ('to redirect elsewhere' )
1369+ # self.try_del_redirect_irule(bigip, the_vs_payload,
1370+ # loadbalancer,old_listener)
1371+ LOG .debug ('creating new:' )
1372+ self .try_create_redirect_irule (
1373+ bigip , the_vs_payload , loadbalancer , listener
1374+ )
1375+
1376+ if redi_irule_full_name not in the_vs_payload ['rules' ]:
1377+ LOG .info ('add to rules' )
1378+ the_vs_payload ['rules' ].append (redi_irule_full_name )
1379+ else :
1380+ LOG .debug ('no redirect change here' )
1381+
1382+ if redirect_ret in ('enable' , 'disable' , 'modify' ):
1383+ LOG .debug ('calling _update' )
1384+ self .resource_helper .update (bigip , the_vs_payload )
1385+
1386+ if redirect_ret == 'disable' :
1387+ LOG .debug ('delete the irule here.' )
1388+ self .try_del_redirect_irule (
1389+ bigip , the_vs_payload , loadbalancer , old_listener
1390+ )
1391+
12251392 def _delete (self , bigip , vs , listener , service ):
1393+ loadbalancer = service .get ("loadbalancer" , None )
1394+
12261395 super (ListenerManager , self )._delete (bigip , vs , listener , service )
12271396 self ._delete_persist_profile (bigip , vs )
12281397 self ._delete_ssl_profiles (bigip , vs , service )
@@ -1231,6 +1400,8 @@ def _delete(self, bigip, vs, listener, service):
12311400 if ftp_enable :
12321401 self .ftp_helper .remove_profile (service , vs , bigip )
12331402
1403+ self .try_del_redirect_irule (bigip , vs , loadbalancer , listener )
1404+
12341405 @serialized ('ListenerManager.create' )
12351406 @log_helpers .log_method_call
12361407 def create (self , listener , service , ** kwargs ):
0 commit comments