github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/releaseutil/kind_sorter.go (about)

     1  /*
     2  Copyright The Helm Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package releaseutil
    18  
    19  import (
    20  	"sort"
    21  
    22  	"github.com/stefanmcshane/helm/pkg/release"
    23  )
    24  
    25  // KindSortOrder is an ordering of Kinds.
    26  type KindSortOrder []string
    27  
    28  // InstallOrder is the order in which manifests should be installed (by Kind).
    29  //
    30  // Those occurring earlier in the list get installed before those occurring later in the list.
    31  var InstallOrder KindSortOrder = []string{
    32  	"Namespace",
    33  	"NetworkPolicy",
    34  	"ResourceQuota",
    35  	"LimitRange",
    36  	"PodSecurityPolicy",
    37  	"PodDisruptionBudget",
    38  	"ServiceAccount",
    39  	"Secret",
    40  	"SecretList",
    41  	"ConfigMap",
    42  	"StorageClass",
    43  	"PersistentVolume",
    44  	"PersistentVolumeClaim",
    45  	"CustomResourceDefinition",
    46  	"ClusterRole",
    47  	"ClusterRoleList",
    48  	"ClusterRoleBinding",
    49  	"ClusterRoleBindingList",
    50  	"Role",
    51  	"RoleList",
    52  	"RoleBinding",
    53  	"RoleBindingList",
    54  	"Service",
    55  	"DaemonSet",
    56  	"Pod",
    57  	"ReplicationController",
    58  	"ReplicaSet",
    59  	"Deployment",
    60  	"HorizontalPodAutoscaler",
    61  	"StatefulSet",
    62  	"Job",
    63  	"CronJob",
    64  	"IngressClass",
    65  	"Ingress",
    66  	"APIService",
    67  }
    68  
    69  // UninstallOrder is the order in which manifests should be uninstalled (by Kind).
    70  //
    71  // Those occurring earlier in the list get uninstalled before those occurring later in the list.
    72  var UninstallOrder KindSortOrder = []string{
    73  	"APIService",
    74  	"Ingress",
    75  	"IngressClass",
    76  	"Service",
    77  	"CronJob",
    78  	"Job",
    79  	"StatefulSet",
    80  	"HorizontalPodAutoscaler",
    81  	"Deployment",
    82  	"ReplicaSet",
    83  	"ReplicationController",
    84  	"Pod",
    85  	"DaemonSet",
    86  	"RoleBindingList",
    87  	"RoleBinding",
    88  	"RoleList",
    89  	"Role",
    90  	"ClusterRoleBindingList",
    91  	"ClusterRoleBinding",
    92  	"ClusterRoleList",
    93  	"ClusterRole",
    94  	"CustomResourceDefinition",
    95  	"PersistentVolumeClaim",
    96  	"PersistentVolume",
    97  	"StorageClass",
    98  	"ConfigMap",
    99  	"SecretList",
   100  	"Secret",
   101  	"ServiceAccount",
   102  	"PodDisruptionBudget",
   103  	"PodSecurityPolicy",
   104  	"LimitRange",
   105  	"ResourceQuota",
   106  	"NetworkPolicy",
   107  	"Namespace",
   108  }
   109  
   110  // sort manifests by kind.
   111  //
   112  // Results are sorted by 'ordering', keeping order of items with equal kind/priority
   113  func sortManifestsByKind(manifests []Manifest, ordering KindSortOrder) []Manifest {
   114  	sort.SliceStable(manifests, func(i, j int) bool {
   115  		return lessByKind(manifests[i], manifests[j], manifests[i].Head.Kind, manifests[j].Head.Kind, ordering)
   116  	})
   117  
   118  	return manifests
   119  }
   120  
   121  // sort hooks by kind, using an out-of-place sort to preserve the input parameters.
   122  //
   123  // Results are sorted by 'ordering', keeping order of items with equal kind/priority
   124  func sortHooksByKind(hooks []*release.Hook, ordering KindSortOrder) []*release.Hook {
   125  	h := hooks
   126  	sort.SliceStable(h, func(i, j int) bool {
   127  		return lessByKind(h[i], h[j], h[i].Kind, h[j].Kind, ordering)
   128  	})
   129  
   130  	return h
   131  }
   132  
   133  func lessByKind(a interface{}, b interface{}, kindA string, kindB string, o KindSortOrder) bool {
   134  	ordering := make(map[string]int, len(o))
   135  	for v, k := range o {
   136  		ordering[k] = v
   137  	}
   138  
   139  	first, aok := ordering[kindA]
   140  	second, bok := ordering[kindB]
   141  
   142  	if !aok && !bok {
   143  		// if both are unknown then sort alphabetically by kind, keep original order if same kind
   144  		if kindA != kindB {
   145  			return kindA < kindB
   146  		}
   147  		return first < second
   148  	}
   149  	// unknown kind is last
   150  	if !aok {
   151  		return false
   152  	}
   153  	if !bok {
   154  		return true
   155  	}
   156  	// sort different kinds, keep original order if same priority
   157  	return first < second
   158  }