@@ -164,77 +164,77 @@ func SigMigrate(cmd *cobra.Command, _ []string) error {
164164func collectAllObjects (discoveryClient discovery.DiscoveryInterface , dynamicClient dynamic.Interface , logLevel string ) (map [string ]ObjectRef , error ) {
165165 objects := make (map [string ]ObjectRef )
166166
167- // Get all API resources
168- apiResourceLists , err := discoveryClient .ServerPreferredResources ()
167+ // Get all API groups first (similar to kubectl api- resources)
168+ apiGroupList , err := discoveryClient .ServerGroups ()
169169 if err != nil {
170- // Ignore group discovery errors
171- if ! discovery .IsGroupDiscoveryFailedError (err ) {
172- return nil , fmt .Errorf ("failed to discover API resources: %w" , err )
173- }
170+ return nil , fmt .Errorf ("failed to discover API groups: %w" , err )
174171 }
175172
176173 namespacedResources := []schema.GroupVersionResource {}
177174 clusterResources := []schema.GroupVersionResource {}
178175
179- // Track resources by name to prefer core API versions over metrics/extensions
176+ // Track resources by GVR to collect all unique API versions
177+ // This allows us to process both core API resources and custom resources (like apps.kruise.io)
180178 type resourceInfo struct {
181179 gvr schema.GroupVersionResource
182180 namespaced bool
183181 }
184182 resourceMap := make (map [string ]resourceInfo )
185183
186- for _ , apiResourceList := range apiResourceLists {
187- gv , err := schema .ParseGroupVersion (apiResourceList .GroupVersion )
188- if err != nil {
189- continue
190- }
191-
192- // Skip metrics and other API groups that don't support standard operations
193- // These groups typically only support read operations
194- if gv .Group == "metrics.k8s.io" || gv .Group == "custom.metrics.k8s.io" || gv .Group == "external.metrics.k8s.io" {
195- continue
196- }
197-
198- for _ , apiResource := range apiResourceList .APIResources {
199- // Skip subresources
200- if strings .Contains (apiResource .Name , "/" ) {
184+ // Iterate through all API groups and their versions (like kubectl api-resources does)
185+ for _ , group := range apiGroupList .Groups {
186+ for _ , version := range group .Versions {
187+ // Get resources for this specific group version
188+ apiResourceList , err := discoveryClient .ServerResourcesForGroupVersion (version .GroupVersion )
189+ if err != nil {
190+ // Log but continue - some groups may fail (e.g., metrics)
191+ if logLevel == "TRACE" {
192+ fmt .Printf ("Warning: failed to get resources for %s: %v\n " , version .GroupVersion , err )
193+ }
201194 continue
202195 }
203196
204- // Skip resources that don't support list
205- if ! contains ( apiResource . Verbs , "list" ) {
197+ gv , err := schema . ParseGroupVersion ( apiResourceList . GroupVersion )
198+ if err != nil {
206199 continue
207200 }
208201
209- // Skip resources that don't support patch (needed for annotations)
210- if ! contains (apiResource .Verbs , "patch" ) {
202+ // Skip metrics and other API groups that don't support standard operations
203+ // These groups typically only support read operations
204+ if gv .Group == "metrics.k8s.io" || gv .Group == "custom.metrics.k8s.io" || gv .Group == "external.metrics.k8s.io" {
211205 continue
212206 }
213207
214- gvr := schema.GroupVersionResource {
215- Group : gv .Group ,
216- Version : gv .Version ,
217- Resource : apiResource .Name ,
218- }
208+ for _ , apiResource := range apiResourceList .APIResources {
209+ // Skip subresources
210+ if strings .Contains (apiResource .Name , "/" ) {
211+ continue
212+ }
213+
214+ // Skip resources that don't support list
215+ if ! contains (apiResource .Verbs , "list" ) {
216+ continue
217+ }
219218
220- // Use resource name as key (e.g., "pods")
221- resourceKey := apiResource .Name
219+ // Skip resources that don't support patch (needed for annotations)
220+ if ! contains (apiResource .Verbs , "patch" ) {
221+ continue
222+ }
222223
223- // Prefer core API versions (empty group or v1) over extensions
224- // If we already have this resource, prefer the one with empty group or v1
225- if existingInfo , exists := resourceMap [resourceKey ]; exists {
226- // Prefer core API (empty group) over extensions
227- if gv .Group == "" && existingInfo .gvr .Group != "" {
224+ gvr := schema.GroupVersionResource {
225+ Group : gv .Group ,
226+ Version : gv .Version ,
227+ Resource : apiResource .Name ,
228+ }
229+
230+ // Use full GVR string as key to collect all unique API versions
231+ // This allows us to process both core API (apps/v1/daemonsets) and custom resources (apps.kruise.io/v1alpha1/daemonsets)
232+ resourceKey := gvr .String ()
233+
234+ // Only add if we haven't seen this exact GVR before
235+ if _ , exists := resourceMap [resourceKey ]; ! exists {
228236 resourceMap [resourceKey ] = resourceInfo {gvr : gvr , namespaced : apiResource .Namespaced }
229- } else if gv .Group == "" && existingInfo .gvr .Group == "" {
230- // Both are core, prefer v1 over other versions
231- if gv .Version == "v1" && existingInfo .gvr .Version != "v1" {
232- resourceMap [resourceKey ] = resourceInfo {gvr : gvr , namespaced : apiResource .Namespaced }
233- }
234237 }
235- // Otherwise keep the existing one
236- } else {
237- resourceMap [resourceKey ] = resourceInfo {gvr : gvr , namespaced : apiResource .Namespaced }
238238 }
239239 }
240240 }
0 commit comments