@@ -583,7 +583,7 @@ func (r *PatternReconciler) finalizeObject(instance *api.Pattern) error {
583583 }
584584
585585 // Check if all child applications are gone from spoke
586- allGone , err := r .checkChildApplicationsGone (qualifiedInstance )
586+ allGone , err := r .checkSpokeChildApplicationsGone (qualifiedInstance )
587587 if err != nil {
588588 return fmt .Errorf ("error checking child applications: %w" , err )
589589 }
@@ -806,62 +806,34 @@ func (r *PatternReconciler) updatePatternCRDetails(input *api.Pattern) (bool, er
806806 return false , nil
807807}
808808
809- // getBearerToken gets a bearer token for authentication, trying multiple methods:
810- // 1. Read from service account token file (in-cluster)
811- // 2. Use BearerToken from rest.Config (local dev with kubeconfig)
812- // 3. Create a token using TokenRequest API (fallback)
813- func (r * PatternReconciler ) getBearerToken (ctx context.Context ) (string , error ) {
814- // Method 1: Try reading from service account token file (in-cluster)
815- tokenPath := "/run/secrets/kubernetes.io/serviceaccount/token"
816- if tokenBytes , err := os .ReadFile (tokenPath ); err == nil {
817- return string (tokenBytes ), nil
818- }
819-
820- // Method 2: Try using BearerToken from rest.Config (local dev)
821- if r .config != nil && r .config .BearerToken != "" {
822- return r .config .BearerToken , nil
823- }
824-
825- // If all methods fail, try to get token from any available service account
826- // This is a fallback for local development
827- return "" , fmt .Errorf ("failed to get bearer token: tried service account file, rest.Config BearerToken, and TokenRequest API" )
828- }
829-
830- // checkChildApplicationsGone checks if all child applications (excluding the app-of-apps) are gone from spoke clusters
809+ // checkSpokeChildApplicationsGone checks if all child applications (excluding the app-of-apps) are gone from spoke clusters
831810// The operator runs on the hub cluster and needs to check spoke clusters through ACM Search Service
832811// Returns true if all child applications are gone, false otherwise
833- func (r * PatternReconciler ) checkChildApplicationsGone (p * api.Pattern ) (bool , error ) {
834- // Determine if we're running in-cluster or locally
835- // Check if service account token file exists (indicates in-cluster)
836- tokenPath := "/run/secrets/kubernetes.io/serviceaccount/token"
837- _ , inCluster := os .Stat (tokenPath )
838-
839- var searchURL string
840- if inCluster == nil {
841- // Running in-cluster: use cluster.local endpoint
812+ func (r * PatternReconciler ) checkSpokeChildApplicationsGone (p * api.Pattern ) (bool , error ) {
813+
814+ // Running locally: use localhost with env var set to "https://localhost:4010/searchapi/graphql" and port-forward
815+ // User should run: kubectl port-forward -n open-cluster-management svc/search-search-api 4010:4010
816+ searchURL := os .Getenv ("ACM_SEARCH_API_URL" )
817+ if searchURL == "" {
842818 searchNamespace := "open-cluster-management" // Default namespace for ACM
843819 searchURL = fmt .Sprintf ("https://search-search-api.%s.svc.cluster.local:4010/searchapi/graphql" , searchNamespace )
844- } else {
845- // Running locally: use localhost with port-forward or environment variable
846- // User should run: kubectl port-forward -n open-cluster-management svc/search-search-api 4010:4010
847- searchURL = os .Getenv ("ACM_SEARCH_API_URL" )
848- if searchURL == "" {
849- // Default to localhost if env var not set (assumes port-forward)
850- searchURL = "https://localhost:4010/searchapi/graphql"
820+ }
821+
822+ token := os .Getenv ("ACM_SEARCH_API_TOKEN" )
823+ if token == "" {
824+ var tokenBytes []byte
825+ var err error
826+
827+ tokenPath := "/run/secrets/kubernetes.io/serviceaccount/token"
828+
829+ if tokenBytes , err = os .ReadFile (tokenPath ); err != nil {
830+ return false , fmt .Errorf ("failed to read serviceaccount token: %w" , err )
851831 }
852- log .Printf ("Using local search API endpoint: %s (set ACM_SEARCH_API_URL env var to override)" , searchURL )
853- }
854- // TODO fix token
855- // the service account token of the operator does not list all applications, only the local cluster ones
856- // the service account token for the search api, works well
857- var token string
858- if r .config != nil && r .config .BearerToken != "" {
859- token = r .config .BearerToken
860- } else {
861- token = os .Getenv ("ACM_SEARCH_API_TOKEN" )
832+ token = string (tokenBytes )
862833 }
863834
864835 // Build GraphQL query to search for Applications
836+ // Filter out local-cluster apps and app of apps (based on namespace)
865837 query := map [string ]any {
866838 "operationName" : "searchResult" ,
867839 "query" : "query searchResult($input: [SearchInput]) { searchResult: search(input: $input) { items related { kind items } } }" ,
@@ -873,11 +845,18 @@ func (r *PatternReconciler) checkChildApplicationsGone(p *api.Pattern) (bool, er
873845 "property" : "apigroup" ,
874846 "values" : []string {"argoproj.io" },
875847 },
876-
877848 {
878849 "property" : "kind" ,
879850 "values" : []string {"Application" },
880851 },
852+ {
853+ "property" : "cluster" ,
854+ "values" : []string {"!local-cluster" },
855+ },
856+ {
857+ "property" : "namespace" ,
858+ "values" : []string {fmt .Sprintf ("!%s" , getClusterWideArgoNamespace ())},
859+ },
881860 },
882861 "relatedKinds" : []string {"Application" },
883862 "limit" : 20000 ,
@@ -905,26 +884,14 @@ func (r *PatternReconciler) checkChildApplicationsGone(p *api.Pattern) (bool, er
905884
906885 // Create HTTP client
907886 // Use insecure TLS (self-signed certs)
908- var client * http.Client
909- if inCluster == nil {
910- // In-cluster: HTTPS with insecure TLS
911- client = & http.Client {
912- Transport : & http.Transport {
913- TLSClientConfig : & tls.Config {
914- InsecureSkipVerify : true ,
915- },
887+ client := & http.Client {
888+ Transport : & http.Transport {
889+ TLSClientConfig : & tls.Config {
890+ InsecureSkipVerify : true ,
916891 },
917- }
918- } else {
919- // Local: HTTPs (no TLS)
920- client = & http.Client {
921- Transport : & http.Transport {
922- TLSClientConfig : & tls.Config {
923- InsecureSkipVerify : true ,
924- },
925- },
926- }
892+ },
927893 }
894+
928895 // Make the request
929896 resp , err := client .Do (req )
930897 if err != nil {
@@ -956,11 +923,7 @@ func (r *PatternReconciler) checkChildApplicationsGone(p *api.Pattern) (bool, er
956923 return i .(map [string ]any )
957924 })
958925
959- // Filter out local-cluster apps and app of apps
960- remote_apps := lo .Filter (items , func (item map [string ]any , _ int ) bool {
961- return item ["cluster" ] != "local-cluster" && item ["namespace" ] != getClusterWideArgoNamespace ()
962- })
963- remote_app_names := lo .Map (remote_apps , func (item map [string ]any , _ int ) string {
926+ remote_app_names := lo .Map (items , func (item map [string ]any , _ int ) string {
964927 return item ["name" ].(string )
965928 })
966929
0 commit comments