@@ -11,6 +11,8 @@ import (
1111 "os"
1212 "os/signal"
1313 "path/filepath"
14+ "regexp"
15+ "slices"
1416 "sort"
1517 "strings"
1618 "sync"
@@ -823,8 +825,15 @@ func determineEnvironmentFlags(ctx context.Context, upgrade bool, dryRun bool) (
823825 if apiGroups .Has ("config.openshift.io" ) {
824826 featureGates , err := determineEnabledFeatureGates (ctx , clientConfig )
825827 if err != nil {
826- return nil , errors .WithMessage (err , "couldn't determine feature gates" )
828+ return nil , errors .WithMessage (err , "couldn't determine OpenShift feature gates" )
827829 }
830+ featureGatesAPI , err := getFeatureGatesAPIServerMetrics (ctx , clientConfig )
831+ if err != nil {
832+ return nil , errors .WithMessage (err , "couldn't determine FeatureGates from API /metrics" )
833+ }
834+ featureGates = append (featureGates , featureGatesAPI ... )
835+ slices .Sort (featureGates )
836+ featureGates = slices .Compact (featureGates )
828837 envFlagBuilder .AddFeatureGates (featureGates ... )
829838 }
830839
@@ -902,6 +911,27 @@ func determineEnabledAPIGroups(discoveryClient discovery.AggregatedDiscoveryInte
902911 return apiGroups , nil
903912}
904913
914+ // getFeatureGatesAPIServerMetrics extracts enabled feature gates from the API server metrics endpoint.
915+ // It returns a list of feature gate names that are enabled.
916+ func getFeatureGatesAPIServerMetrics (ctx context.Context , clientConfig * clientconfigv1.Clientset ) ([]string , error ) {
917+ rsp , err := clientConfig .RESTClient ().Get ().AbsPath ("/metrics" ).Do (ctx ).Raw ()
918+ if err != nil {
919+ return nil , err
920+ }
921+ featureGates := sets .NewString ()
922+ lines := strings .Split (string (rsp ), "\n " )
923+ re := regexp .MustCompile (`kubernetes_feature_enabled\{name="([^"]+)".*\} 1` )
924+ for _ , line := range lines {
925+ if strings .HasPrefix (line , "kubernetes_feature_enabled{" ) && strings .HasSuffix (line , "} 1" ) {
926+ matches := re .FindStringSubmatch (line )
927+ if len (matches ) == 2 {
928+ featureGates .Insert (matches [1 ])
929+ }
930+ }
931+ }
932+ return featureGates .List (), nil
933+ }
934+
905935func determineEnabledFeatureGates (ctx context.Context , configClient clientconfigv1.Interface ) ([]string , error ) {
906936 featureGate , err := configClient .ConfigV1 ().FeatureGates ().Get (ctx , "cluster" , metav1.GetOptions {})
907937 if err != nil {
0 commit comments