Skip to content

Commit 8dd3dd7

Browse files
committed
fix: Cleanup token, url, logic, vars around spoke child app check
1 parent 4297c73 commit 8dd3dd7

1 file changed

Lines changed: 36 additions & 73 deletions

File tree

internal/controller/pattern_controller.go

Lines changed: 36 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)