Skip to content
Permalink
d7d63f4b62
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
125 lines (108 sloc) 3.89 KB
// Copyright 2020 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package ordering
import (
"sort"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/resource"
"sigs.k8s.io/cli-utils/pkg/object"
)
type SortableInfos []*resource.Info
var _ sort.Interface = SortableInfos{}
func (a SortableInfos) Len() int { return len(a) }
func (a SortableInfos) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortableInfos) Less(i, j int) bool {
first, err := object.InfoToObjMeta(a[i])
if err != nil {
return false
}
second, err := object.InfoToObjMeta(a[j])
if err != nil {
return false
}
return less(first, second)
}
type SortableUnstructureds []*unstructured.Unstructured
var _ sort.Interface = SortableUnstructureds{}
func (a SortableUnstructureds) Len() int { return len(a) }
func (a SortableUnstructureds) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortableUnstructureds) Less(i, j int) bool {
first := object.UnstructuredToObjMetadata(a[i])
second := object.UnstructuredToObjMetadata(a[j])
return less(first, second)
}
type SortableMetas []object.ObjMetadata
var _ sort.Interface = SortableMetas{}
func (a SortableMetas) Len() int { return len(a) }
func (a SortableMetas) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a SortableMetas) Less(i, j int) bool {
return less(a[i], a[j])
}
func less(i, j object.ObjMetadata) bool {
if !Equals(i.GroupKind, j.GroupKind) {
return IsLessThan(i.GroupKind, j.GroupKind)
}
// In case of tie, compare the namespace and name combination so that the output
// order is consistent irrespective of input order
if i.Namespace != j.Namespace {
return i.Namespace < j.Namespace
}
return i.Name < j.Name
}
var groupKind2index = computeGroupKind2index()
func computeGroupKind2index() map[schema.GroupKind]int {
// An attempt to order things to help k8s, e.g.
// a Service should come before things that refer to it.
// Namespace should be first.
// In some cases order just specified to provide determinism.
orderFirst := []schema.GroupKind{
{Group: "", Kind: "Namespace"},
{Group: "", Kind: "ResourceQuota"},
{Group: "storage.k8s.io", Kind: "StorageClass"},
{Group: "apiextensions.k8s.io", Kind: "CustomResourceDefinition"},
{Group: "admissionregistration.k8s.io", Kind: "MutatingWebhookConfiguration"},
{Group: "", Kind: "ServiceAccount"},
{Group: "extensions", Kind: "PodSecurityPolicy"}, // deprecated=1.11, removed=1.16
{Group: "policy", Kind: "PodSecurityPolicy"}, // deprecated=1.21, removed=1.25
{Group: "rbac.authorization.k8s.io", Kind: "Role"},
{Group: "rbac.authorization.k8s.io", Kind: "ClusterRole"},
{Group: "rbac.authorization.k8s.io", Kind: "RoleBinding"},
{Group: "rbac.authorization.k8s.io", Kind: "ClusterRoleBinding"},
{Group: "", Kind: "ConfigMap"},
{Group: "", Kind: "Secret"},
{Group: "", Kind: "Service"},
{Group: "", Kind: "LimitRange"},
{Group: "scheduling.k8s.io", Kind: "PriorityClass"},
{Group: "extensions", Kind: "Deployment"}, // deprecated=1.8, removed=1.16
{Group: "apps", Kind: "Deployment"},
{Group: "apps", Kind: "StatefulSet"},
{Group: "batch", Kind: "CronJob"},
{Group: "policy", Kind: "PodDisruptionBudget"},
}
orderLast := []schema.GroupKind{
{Group: "admissionregistration.k8s.io", Kind: "ValidatingWebhookConfiguration"},
}
kind2indexResult := make(map[schema.GroupKind]int, len(orderFirst)+len(orderLast))
for i, n := range orderFirst {
kind2indexResult[n] = -len(orderFirst) + i
}
for i, n := range orderLast {
kind2indexResult[n] = 1 + i
}
return kind2indexResult
}
func Equals(i, j schema.GroupKind) bool {
return i.Group == j.Group && i.Kind == j.Kind
}
func IsLessThan(i, j schema.GroupKind) bool {
indexI := groupKind2index[i]
indexJ := groupKind2index[j]
if indexI != indexJ {
return indexI < indexJ
}
if i.Group != j.Group {
return i.Group < j.Group
}
return i.Kind < j.Kind
}