github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/process/sort.go (about)

     1  package process
     2  
     3  import (
     4  	"sort"
     5  
     6  	"github.com/grafana/tanka/pkg/kubernetes/manifest"
     7  )
     8  
     9  // Order in which install different kinds of Kubernetes objects.
    10  // Inspired by https://github.com/helm/helm/blob/8c84a0bc0376650bc3d7334eef0c46356c22fa36/pkg/releaseutil/kind_sorter.go
    11  var kindOrder = []string{
    12  	"Namespace",
    13  	"NetworkPolicy",
    14  	"ResourceQuota",
    15  	"LimitRange",
    16  	"PodSecurityPolicy",
    17  	"PodDisruptionBudget",
    18  	"ServiceAccount",
    19  	"Secret",
    20  	"ConfigMap",
    21  	"StorageClass",
    22  	"PersistentVolume",
    23  	"PersistentVolumeClaim",
    24  	"CustomResourceDefinition",
    25  	"ClusterRole",
    26  	"ClusterRoleList",
    27  	"ClusterRoleBinding",
    28  	"ClusterRoleBindingList",
    29  	"Role",
    30  	"RoleList",
    31  	"RoleBinding",
    32  	"RoleBindingList",
    33  	"Service",
    34  	"DaemonSet",
    35  	"Pod",
    36  	"ReplicationController",
    37  	"ReplicaSet",
    38  	"Deployment",
    39  	"HorizontalPodAutoscaler",
    40  	"StatefulSet",
    41  	"Job",
    42  	"CronJob",
    43  	"Ingress",
    44  	"APIService",
    45  }
    46  
    47  // Sort orders manifests in a stable order, taking order-dependencies of these
    48  // into consideration. This is best-effort based:
    49  // - Use the static kindOrder list if possible
    50  // - Sort alphabetically by kind otherwise
    51  // - If kind equal, sort alphabetically by name
    52  func Sort(list manifest.List) {
    53  	sort.SliceStable(list, func(i int, j int) bool {
    54  		var io, jo int
    55  
    56  		// anything that is not in kindOrder will get to the end of the install list.
    57  		for io = 0; io < len(kindOrder); io++ {
    58  			if list[i].Kind() == kindOrder[io] {
    59  				break
    60  			}
    61  		}
    62  
    63  		for jo = 0; jo < len(kindOrder); jo++ {
    64  			if list[j].Kind() == kindOrder[jo] {
    65  				break
    66  			}
    67  		}
    68  
    69  		// If Kind of both objects are at different indexes of kindOrder, sort by them
    70  		if io != jo {
    71  			return io < jo
    72  		}
    73  
    74  		// If the Kinds themselves are different (e.g. both of the Kinds are not in
    75  		// the kindOrder), order alphabetically.
    76  		if list[i].Kind() != list[j].Kind() {
    77  			return list[i].Kind() < list[j].Kind()
    78  		}
    79  
    80  		// If namespaces differ, sort by the namespace.
    81  		if list[i].Metadata().Namespace() != list[j].Metadata().Namespace() {
    82  			return list[i].Metadata().Namespace() < list[j].Metadata().Namespace()
    83  		}
    84  
    85  		// Otherwise, order the objects by name.
    86  		return list[i].Metadata().Name() < list[j].Metadata().Name()
    87  	})
    88  }