Permalink
Cannot retrieve contributors at this time
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
125 lines (108 sloc)
3.89 KB
This file contains 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
| // 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 | |
| } |