Repository: derailed/k9s
File: internal/dao/registry.go (Go)

Code before:
		var crd apiext.CustomResourceDefinition
		err = runtime.DefaultUnstructuredConverter.FromUnstructured(o.(*unstructured.Unstructured).Object, &crd)
		if err != nil {
			log.Err(err).Msg("boom")
			continue
		}

		var meta metav1.APIResource
		meta.Kind = crd.Spec.Names.Kind
		meta.Group = crd.Spec.Group
		// Since CRD names are cluster scoped they need to be unique, however, it is allowed
		// to have the CRDs with the same names in different groups. Because of that, the
		// returned `crd.Name` values have the group as a suffix, for example
		// "ciliumnetworkpolicies.cilium.io".
		//
		// `Name` field of `meta/v1/APIResource` is supposed to be the plural name of the
		// resource, without the group. Because of that we need to trim the group suffix.
		meta.Name = strings.TrimSuffix(crd.Name, "."+meta.Group)

		meta.SingularName = crd.Spec.Names.Singular
		meta.ShortNames = crd.Spec.Names.ShortNames
		meta.Namespaced = crd.Spec.Scope == apiext.NamespaceScoped
		for _, v := range crd.Spec.Versions {
			if v.Served && !v.Deprecated {
				meta.Version = v.Name
				break
			}
		}

		meta.Categories = append(meta.Categories, crdCat)
		gvr := client.NewGVRFromMeta(meta)
		m[gvr] = meta
	}
}

func extractMeta(o runtime.Object) (metav1.APIResource, []error) {
	var (
		m    metav1.APIResource
		errs []error
	)

	crd, ok := o.(*unstructured.Unstructured)
	if !ok {
		return m, append(errs, fmt.Errorf("expected unstructured, but got %T", o))
	}

	var spec map[string]interface{}
	spec, errs = extractMap(crd.Object, "spec", errs)

	var meta map[string]interface{}
	meta, errs = extractMap(crd.Object, "metadata", errs)

Review comment (suggestion):
This should use Names.Singular. 
Also I think the crd name needs to be unique ie crd.Name+"."+meta.Group

Code after:
		if err != nil {
			log.Err(err).Msg("boom")
			continue
		}

		if gvr, version, ok := newGVRFromCRD(&crd); ok {
			if meta, ok := m[gvr]; ok && version.Subresources != nil && version.Subresources.Scale != nil {
				if !slices.Contains(meta.Categories, scaleCat) {
					meta.Categories = append(meta.Categories, scaleCat)
					m[gvr] = meta
				}
			}
		}
	}
}

func newGVRFromCRD(crd *apiext.CustomResourceDefinition) (client.GVR, apiext.CustomResourceDefinitionVersion, bool) {
	for _, v := range crd.Spec.Versions {
		if v.Served && !v.Deprecated {
			return client.NewGVRFromMeta(metav1.APIResource{
				Kind:         crd.Spec.Names.Kind,
				Group:        crd.Spec.Group,
				Name:         crd.Spec.Names.Plural,
				Version:      v.Name,
				ShortNames:   crd.Spec.Names.ShortNames,
				SingularName: crd.Spec.Names.Plural,
				Namespaced:   crd.Spec.Scope == apiext.NamespaceScoped,
			}), v, true
		}
	}

	return client.GVR{}, apiext.CustomResourceDefinitionVersion{}, false
}

func extractMeta(o runtime.Object) (metav1.APIResource, []error) {
	var (
		m    metav1.APIResource
		errs []error
	)

	crd, ok := o.(*unstructured.Unstructured)
	if !ok {
		return m, append(errs, fmt.Errorf("expected unstructured, but got %T", o))
	}

	var spec map[string]interface{}
	spec, errs = extractMap(crd.Object, "spec", errs)

	var meta map[string]interface{}
	meta, errs = extractMap(crd.Object, "metadata", errs)
	m.Name, errs = extractStr(meta, "name", errs)