Created
November 2, 2025 20:09
-
-
Save yati-sagade/d792238d20c785120fd10716a372dbaf to your computer and use it in GitHub Desktop.
discovery -> fallback to object.metadata field check
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "bytes" | |
| "fmt" | |
| "os" | |
| "strings" | |
| "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" | |
| "k8s.io/apimachinery/pkg/runtime" | |
| "k8s.io/apimachinery/pkg/runtime/schema" | |
| "k8s.io/apimachinery/pkg/runtime/serializer/yaml" | |
| utilyaml "k8s.io/apimachinery/pkg/util/yaml" | |
| "k8s.io/client-go/discovery" | |
| "k8s.io/client-go/rest" | |
| "k8s.io/client-go/tools/clientcmd" | |
| ) | |
| func main() { | |
| yamlManifest, err := os.ReadFile(os.Args[1]) | |
| if err != nil { | |
| panic(fmt.Sprintf("failed to read file: %v", err)) | |
| } | |
| decoder := utilyaml.NewYAMLOrJSONDecoder(bytes.NewReader([]byte(yamlManifest)), 1024) | |
| decUnstructured := yaml.NewDecodingSerializer(unstructured.UnstructuredJSONScheme) | |
| for { | |
| var rawObj runtime.RawExtension | |
| if err := decoder.Decode(&rawObj); err != nil { | |
| if err.Error() == "EOF" { | |
| fmt.Println("Finished processing YAML document") | |
| break | |
| } | |
| panic(fmt.Sprintf("failed to decode YAML: %v", err)) | |
| } | |
| if len(rawObj.Raw) == 0 { | |
| fmt.Println("Skipping empty document") | |
| continue | |
| } | |
| obj := &unstructured.Unstructured{} | |
| _, err := decodeToUnstructured(rawObj.Raw, obj, decUnstructured) | |
| if err != nil { | |
| panic(fmt.Sprintf("decode error: %v", err)) | |
| } | |
| out, err := obj.MarshalJSON() | |
| if err != nil { | |
| panic(fmt.Sprintf("failed to marshal object: %v", err)) | |
| } | |
| fmt.Printf("---\n%s\n", string(out)) | |
| config, err := clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile) | |
| if err != nil { | |
| panic(fmt.Sprintf("error building config: %v", err)) | |
| } | |
| supports, err := CheckLabelSupport(obj, config) | |
| if err != nil { | |
| panic(fmt.Sprintf("error checking label support: %v", err)) | |
| } | |
| fmt.Printf("%s supports labels: %+v", obj.GetKind(), supports) | |
| fmt.Println("----") | |
| } | |
| } | |
| type supportsLabelsResult struct { | |
| ok bool | |
| source string | |
| } | |
| func CheckLabelSupport(obj *unstructured.Unstructured, config *rest.Config) (supportsLabelsResult, error) { | |
| if ok, err := DiscoverySupportsLabels(obj, config); err == nil { | |
| return supportsLabelsResult{ok: ok, source: "discovery"}, nil | |
| } | |
| if ok, err := LocalSupportsLabels(obj); err == nil { | |
| return supportsLabelsResult{ok: ok, source: "local"}, nil | |
| } | |
| return supportsLabelsResult{}, fmt.Errorf("could not determine label support") | |
| } | |
| func LocalSupportsLabels(obj *unstructured.Unstructured) (bool, error) { | |
| // Check if the object has metadata | |
| if obj.Object["metadata"] != nil { | |
| return true, nil | |
| } | |
| return false, nil | |
| } | |
| func DiscoverySupportsLabels(obj *unstructured.Unstructured, config *rest.Config) (bool, error) { | |
| // Create discovery client | |
| discClient, err := discovery.NewDiscoveryClientForConfig(config) | |
| if err != nil { | |
| return false, err | |
| } | |
| // Get GVK from the object | |
| gvk := obj.GroupVersionKind() | |
| // Get API resources for this group/version | |
| resources, err := discClient.ServerResourcesForGroupVersion(gvk.GroupVersion().String()) | |
| if err != nil { | |
| return false, err | |
| } | |
| // Find the resource | |
| for _, r := range resources.APIResources { | |
| if r.Kind == gvk.Kind { | |
| // If the resource has metadata, it supports labels | |
| if strings.Contains(r.Name, "/metadata") || strings.Contains(r.Name, "metadata") { | |
| return true, nil | |
| } | |
| return true, nil | |
| } | |
| } | |
| return false, fmt.Errorf("resource kind %s not found", gvk.Kind) | |
| } | |
| func decodeToUnstructured(raw []byte, obj *unstructured.Unstructured, dec runtime.Decoder) (*schema.GroupVersionKind, error) { | |
| out, gvk, err := dec.Decode(raw, nil, obj) | |
| if err != nil { | |
| return nil, err | |
| } | |
| _, ok := out.(*unstructured.Unstructured) | |
| if !ok { | |
| return nil, fmt.Errorf("object is not Unstructured") | |
| } | |
| return gvk, nil | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment