github.com/appscode/helm@v3.0.0-alpha.1+incompatible/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 "sort"
    20  
    21  // KindSortOrder is an ordering of Kinds.
    22  type KindSortOrder []string
    23  
    24  // InstallOrder is the order in which manifests should be installed (by Kind).
    25  //
    26  // Those occurring earlier in the list get installed before those occurring later in the list.
    27  var InstallOrder KindSortOrder = []string{
    28  	"Namespace",
    29  	"ResourceQuota",
    30  	"LimitRange",
    31  	"Secret",
    32  	"ConfigMap",
    33  	"StorageClass",
    34  	"PersistentVolume",
    35  	"PersistentVolumeClaim",
    36  	"ServiceAccount",
    37  	"CustomResourceDefinition",
    38  	"ClusterRole",
    39  	"ClusterRoleBinding",
    40  	"Role",
    41  	"RoleBinding",
    42  	"Service",
    43  	"DaemonSet",
    44  	"Pod",
    45  	"ReplicationController",
    46  	"ReplicaSet",
    47  	"Deployment",
    48  	"StatefulSet",
    49  	"Job",
    50  	"CronJob",
    51  	"Ingress",
    52  	"APIService",
    53  }
    54  
    55  // UninstallOrder is the order in which manifests should be uninstalled (by Kind).
    56  //
    57  // Those occurring earlier in the list get uninstalled before those occurring later in the list.
    58  var UninstallOrder KindSortOrder = []string{
    59  	"APIService",
    60  	"Ingress",
    61  	"Service",
    62  	"CronJob",
    63  	"Job",
    64  	"StatefulSet",
    65  	"Deployment",
    66  	"ReplicaSet",
    67  	"ReplicationController",
    68  	"Pod",
    69  	"DaemonSet",
    70  	"RoleBinding",
    71  	"Role",
    72  	"ClusterRoleBinding",
    73  	"ClusterRole",
    74  	"CustomResourceDefinition",
    75  	"ServiceAccount",
    76  	"PersistentVolumeClaim",
    77  	"PersistentVolume",
    78  	"StorageClass",
    79  	"ConfigMap",
    80  	"Secret",
    81  	"LimitRange",
    82  	"ResourceQuota",
    83  	"Namespace",
    84  }
    85  
    86  // sortByKind does an in-place sort of manifests by Kind.
    87  //
    88  // Results are sorted by 'ordering'
    89  func sortByKind(manifests []Manifest, ordering KindSortOrder) []Manifest {
    90  	ks := newKindSorter(manifests, ordering)
    91  	sort.Sort(ks)
    92  	return ks.manifests
    93  }
    94  
    95  type kindSorter struct {
    96  	ordering  map[string]int
    97  	manifests []Manifest
    98  }
    99  
   100  func newKindSorter(m []Manifest, s KindSortOrder) *kindSorter {
   101  	o := make(map[string]int, len(s))
   102  	for v, k := range s {
   103  		o[k] = v
   104  	}
   105  
   106  	return &kindSorter{
   107  		manifests: m,
   108  		ordering:  o,
   109  	}
   110  }
   111  
   112  func (k *kindSorter) Len() int { return len(k.manifests) }
   113  
   114  func (k *kindSorter) Swap(i, j int) { k.manifests[i], k.manifests[j] = k.manifests[j], k.manifests[i] }
   115  
   116  func (k *kindSorter) Less(i, j int) bool {
   117  	a := k.manifests[i]
   118  	b := k.manifests[j]
   119  	first, aok := k.ordering[a.Head.Kind]
   120  	second, bok := k.ordering[b.Head.Kind]
   121  	// if same kind (including unknown) sub sort alphanumeric
   122  	if first == second {
   123  		// if both are unknown and of different kind sort by kind alphabetically
   124  		if !aok && !bok && a.Head.Kind != b.Head.Kind {
   125  			return a.Head.Kind < b.Head.Kind
   126  		}
   127  		return a.Name < b.Name
   128  	}
   129  	// unknown kind is last
   130  	if !aok {
   131  		return false
   132  	}
   133  	if !bok {
   134  		return true
   135  	}
   136  	// sort different kinds
   137  	return first < second
   138  }