@@ -20,13 +20,6 @@ use std::{
2020 time:: { Duration , Instant } ,
2121} ;
2222
23- use crate :: {
24- consts:: { GATEWAY_CLASS_CONTROLLER_NAME , GATEWAY_SERVICE_LABEL } ,
25- * ,
26- } ;
27- use gateway_utils:: * ;
28- use route_utils:: set_condition;
29-
3023use chrono:: Utc ;
3124use futures:: StreamExt ;
3225use gateway_api:: apis:: standard:: gateways:: { Gateway , GatewayStatus } ;
@@ -39,33 +32,31 @@ use k8s_openapi::apimachinery::pkg::apis::meta::v1 as metav1;
3932use kube:: {
4033 Resource , ResourceExt ,
4134 api:: { Api , ListParams , Patch , PatchParams } ,
42- runtime:: { Controller , controller:: Action , watcher:: Config } ,
35+ runtime:: {
36+ Controller , controller:: Action , finalizer, finalizer:: Error as FinalizerError ,
37+ finalizer:: Event , watcher:: Config ,
38+ } ,
4339} ;
4440use tracing:: { debug, error, info, warn} ;
4541
42+ use crate :: {
43+ Context , Error , NamespaceName , Result ,
44+ consts:: { CONTROLPLANE_FINALIZER , GATEWAY_CLASS_CONTROLLER_NAME , GATEWAY_SERVICE_LABEL } ,
45+ gateway_utils:: {
46+ create_endpoint_if_not_exists, create_loadbalancer_service, delete_endpoint,
47+ delete_loadbalancer_service, get_accepted_condition, get_ingress_ip_len, get_service_key,
48+ patch_status, set_gateway_status_addresses, set_listener_status,
49+ update_service_for_gateway,
50+ } ,
51+ gatewayclass_utils,
52+ route_utils:: set_condition,
53+ } ;
54+
4655pub async fn reconcile ( gateway : Arc < Gateway > , ctx : Arc < Context > ) -> Result < Action > {
4756 let start = Instant :: now ( ) ;
4857 let client = ctx. client . clone ( ) ;
4958
50- let name = gateway
51- . metadata
52- . name
53- . clone ( )
54- . ok_or ( Error :: InvalidConfigError ( "invalid name" . to_string ( ) ) ) ?;
55-
56- let ns = gateway
57- . metadata
58- . namespace
59- . clone ( )
60- . ok_or ( Error :: InvalidConfigError ( "invalid namespace" . to_string ( ) ) ) ?;
61-
62- let gateway_api: Api < Gateway > = Api :: namespaced ( client. clone ( ) , & ns) ;
63- let mut gw = Gateway {
64- metadata : gateway. metadata . clone ( ) ,
65- spec : gateway. spec . clone ( ) ,
66- status : gateway. status . clone ( ) ,
67- } ;
68-
59+ // check gateway_class
6960 let gateway_class_api = Api :: < GatewayClass > :: all ( client. clone ( ) ) ;
7061 let gateway_class = gateway_class_api
7162 . get ( gateway. spec . gateway_class_name . as_str ( ) )
@@ -90,6 +81,47 @@ pub async fn reconcile(gateway: Arc<Gateway>, ctx: Arc<Context>) -> Result<Actio
9081 return Ok ( Action :: await_change ( ) ) ;
9182 }
9283
84+ let gateway_id = gateway. metadata . namespaced_name ( ) ?;
85+ let gateway_api: Api < Gateway > = Api :: namespaced ( ctx. client . clone ( ) , & gateway_id. namespace ) ;
86+ finalizer (
87+ & gateway_api,
88+ CONTROLPLANE_FINALIZER ,
89+ gateway,
90+ |event| async {
91+ match event {
92+ Event :: Apply ( gateway) => configure_gateway ( gateway, ctx. clone ( ) , start) . await ,
93+ Event :: Cleanup ( gateway) => cleanup_gateway ( gateway, & ctx) . await ,
94+ }
95+ } ,
96+ )
97+ . await
98+ . map_err ( |e| match e {
99+ FinalizerError :: ApplyFailed ( e) | FinalizerError :: CleanupFailed ( e) => e,
100+ FinalizerError :: AddFinalizer ( e) | FinalizerError :: RemoveFinalizer ( e) => e. into ( ) ,
101+ FinalizerError :: UnnamedObject => Error :: MissingResourceName ,
102+ FinalizerError :: InvalidFinalizer => {
103+ Error :: InvalidConfigError ( "InvalidFinalizer" . to_string ( ) )
104+ }
105+ } )
106+ }
107+
108+ pub async fn configure_gateway (
109+ gateway : Arc < Gateway > ,
110+ ctx : Arc < Context > ,
111+ start : Instant ,
112+ ) -> Result < Action > {
113+ let gateway_id = gateway. metadata . namespaced_name ( ) ?;
114+ let ns = gateway_id. namespace . clone ( ) ;
115+ let name = gateway_id. name . clone ( ) ;
116+ let client = ctx. client . clone ( ) ;
117+
118+ let gateway_api: Api < Gateway > = Api :: namespaced ( ctx. client . clone ( ) , & gateway_id. namespace ) ;
119+ let mut gw = Gateway {
120+ metadata : gateway. metadata . clone ( ) ,
121+ spec : gateway. spec . clone ( ) ,
122+ status : gateway. status . clone ( ) ,
123+ } ;
124+
93125 set_listener_status ( & mut gw) ?;
94126 let accepted_cond = get_accepted_condition ( & gw) ;
95127 set_condition ( & mut gw, accepted_cond. clone ( ) ) ;
@@ -154,7 +186,7 @@ pub async fn reconcile(gateway: Arc<Gateway>, ctx: Arc<Context>) -> Result<Actio
154186 }
155187 } else {
156188 info ! ( "creating loadbalancer service" ) ;
157- service = create_svc_for_gateway ( ctx. clone ( ) , gateway. as_ref ( ) ) . await ?;
189+ service = create_loadbalancer_service ( ctx. clone ( ) , gateway. as_ref ( ) ) . await ?;
158190 }
159191
160192 // invalid_lb_condition is a Condition that signifies that the Loadbalancer service is invalid.
@@ -220,6 +252,15 @@ pub async fn reconcile(gateway: Arc<Gateway>, ctx: Arc<Context>) -> Result<Actio
220252 Ok ( Action :: requeue ( Duration :: from_secs ( 60 ) ) )
221253}
222254
255+ async fn cleanup_gateway ( gateway : Arc < Gateway > , ctx : & Context ) -> Result < Action > {
256+ let gateway_id = gateway. metadata . namespaced_name ( ) ?;
257+
258+ delete_endpoint ( ctx. client . clone ( ) , & gateway_id) . await ?;
259+ delete_loadbalancer_service ( ctx. client . clone ( ) , & gateway_id) . await ?;
260+
261+ Ok ( Action :: await_change ( ) )
262+ }
263+
223264pub async fn controller ( ctx : Context ) -> Result < ( ) > {
224265 let gateway = Api :: < Gateway > :: all ( ctx. client . clone ( ) ) ;
225266 gateway
0 commit comments