@@ -17,10 +17,10 @@ use kube::api::{
1717use kube:: client:: scope;
1818use kube:: runtime:: watcher:: { self , Config } ;
1919use kube:: { Api , Client } ;
20- use kube:: { Resource , api:: ResourceExt , runtime:: controller:: Action } ;
20+ use kube:: { Resource , api:: { ResourceExt , Patch } , runtime:: controller:: Action } ;
2121use serde:: Serialize ;
22- use serde_json:: Value ;
23- use tracing:: info;
22+ use serde_json:: { Value , json } ;
23+ use tracing:: { info, debug } ;
2424
2525use std:: sync:: Arc ;
2626
@@ -30,6 +30,7 @@ use super::controller::{
3030use super :: { BundleResult , ClusterSyncError , ClusterSyncResult } ;
3131
3232pub static CONTROLPLANE_READY_CONDITION : & str = "ControlPlaneReady" ;
33+ pub static FLEET_WORKSPACE_ANNOTATION : & str = "field.cattle.io/allow-fleetworkspace-creation-for-existing-namespace" ;
3334
3435pub struct FleetClusterBundle {
3536 template_sources : TemplateSources ,
@@ -176,6 +177,19 @@ impl FleetBundle for FleetClusterBundle {
176177 }
177178 }
178179
180+ // Ensure the fleet workspace annotation is present.
181+ let patch = json ! ( {
182+ "metadata" : {
183+ "annotations" : {
184+ FLEET_WORKSPACE_ANNOTATION : "true"
185+ }
186+ }
187+ } ) ;
188+ let namespace_name = self . fleet . namespace ( ) . unwrap_or_default ( ) ;
189+ let namespaces = Api :: < Namespace > :: all ( ctx. client . clone ( ) ) ;
190+ namespaces. patch_metadata ( & namespace_name, & PatchParams :: default ( ) , & Patch :: Merge ( & patch) ) . await ?;
191+ debug ! ( "Added fleet annotation to namespace {}." , namespace_name) ;
192+
179193 Ok ( Action :: await_change ( ) )
180194 }
181195
@@ -205,6 +219,26 @@ impl FleetBundle for FleetClusterBundle {
205219 . await ?;
206220 }
207221
222+ // List all other clusters in this namespace
223+ let namespaces = Api :: < Namespace > :: all ( ctx. client . clone ( ) ) ;
224+ let namespace_name = self . fleet . namespace ( ) . unwrap_or_default ( ) ;
225+ let clusters = Api :: < Cluster > :: namespaced ( ctx. client . clone ( ) , & namespace_name) ;
226+ let other_clusters = clusters
227+ . list ( & ListParams :: default ( ) . fields ( & format ! ( "metadata.namespace={},metadata.name!={}" , namespace_name, self . fleet. name_any( ) ) ) )
228+ . await ?;
229+ // If no other clusters are found in this namespace, remove the fleet workspace annotation.
230+ if other_clusters. items . is_empty ( ) {
231+ let patch = json ! ( {
232+ "metadata" : {
233+ "annotations" : {
234+ FLEET_WORKSPACE_ANNOTATION : null
235+ }
236+ }
237+ } ) ;
238+ namespaces. patch_metadata ( & namespace_name, & PatchParams :: default ( ) , & Patch :: Merge ( & patch) ) . await ?;
239+ debug ! ( "Removed fleet annotation from namespace {}." , namespace_name) ;
240+ }
241+
208242 Ok ( Action :: await_change ( ) )
209243 }
210244}
@@ -285,4 +319,4 @@ impl Cluster {
285319
286320 Ok ( Action :: await_change ( ) )
287321 }
288- }
322+ }
0 commit comments