Simplify gvk, speed up cluster-scoped checks.

This commit is contained in:
monopole
2021-05-02 10:23:07 -07:00
parent 48d16f877b
commit 660847225d
20 changed files with 167 additions and 335 deletions

View File

@@ -16,13 +16,26 @@ type Gvk struct {
Group string `json:"group,omitempty" yaml:"group,omitempty"`
Version string `json:"version,omitempty" yaml:"version,omitempty"`
Kind string `json:"kind,omitempty" yaml:"kind,omitempty"`
// isClusterScoped is true if the object is known, per the openapi
// data in use, to be cluster scoped, and false otherwise.
isClusterScoped bool
}
func NewGvk(g, v, k string) Gvk {
result := Gvk{Group: g, Version: v, Kind: k}
result.isClusterScoped =
openapi.IsCertainlyClusterScoped(result.AsTypeMeta())
return result
}
func GvkFromNode(r *yaml.RNode) Gvk {
g, v := ParseGroupVersion(r.GetApiVersion())
return NewGvk(g, v, r.GetKind())
}
// FromKind makes a Gvk with only the kind specified.
func FromKind(k string) Gvk {
return Gvk{
Kind: k,
}
return NewGvk("", "", k)
}
// ParseGroupVersion parses a KRM metadata apiVersion field.
@@ -56,11 +69,7 @@ func GvkFromString(s string) Gvk {
if k == noKind {
k = ""
}
return Gvk{
Group: g,
Version: v,
Kind: k,
}
return NewGvk(g, v, k)
}
// Values that are brief but meaningful in logs.
@@ -90,10 +99,13 @@ func (x Gvk) String() string {
// ApiVersion returns the combination of Group and Version
func (x Gvk) ApiVersion() string {
if x.Group == "" {
return x.Version
var sb strings.Builder
if x.Group != "" {
sb.WriteString(x.Group)
sb.WriteString("/")
}
return x.Group + "/" + x.Version
sb.WriteString(x.Version)
return sb.String()
}
// StringWoEmptyField returns a string representation of the GVK. Non-exist
@@ -207,26 +219,16 @@ func (x Gvk) IsSelected(selector *Gvk) bool {
return true
}
// toKyamlTypeMeta returns a yaml.TypeMeta from x's information.
func (x Gvk) toKyamlTypeMeta() yaml.TypeMeta {
var apiVersion strings.Builder
if x.Group != "" {
apiVersion.WriteString(x.Group)
apiVersion.WriteString("/")
}
apiVersion.WriteString(x.Version)
// AsTypeMeta returns a yaml.TypeMeta from x's information.
func (x Gvk) AsTypeMeta() yaml.TypeMeta {
return yaml.TypeMeta{
APIVersion: apiVersion.String(),
APIVersion: x.ApiVersion(),
Kind: x.Kind,
}
}
// IsNamespaceableKind returns true if x is a namespaceable Gvk,
// e.g. instances of Pod and Deployment are namespaceable,
// but instances of Node and Namespace are not namespaceable.
// Alternative name for this method: IsNotClusterScoped.
// Implements https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#not-all-objects-are-in-a-namespace
func (x Gvk) IsNamespaceableKind() bool {
isNamespaceScoped, found := openapi.IsNamespaceScoped(x.toKyamlTypeMeta())
return !found || isNamespaceScoped
// IsClusterScoped returns true if the Gvk is certainly cluster scoped
// with respect to the available openapi data.
func (x Gvk) IsClusterScoped() bool {
return x.isClusterScoped
}