github.com/opendevstack/tailor@v1.3.5-0.20220119161809-cab064e60a67/pkg/openshift/filter.go (about) 1 package openshift 2 3 import ( 4 "errors" 5 "fmt" 6 "sort" 7 "strings" 8 9 "github.com/opendevstack/tailor/pkg/utils" 10 ) 11 12 var availableKinds = []string{ 13 "Service", 14 "Route", 15 "DeploymentConfig", 16 "Deployment", 17 "BuildConfig", 18 "ImageStream", 19 "PersistentVolumeClaim", 20 "Template", 21 "ConfigMap", 22 "Secret", 23 "RoleBinding", 24 "ServiceAccount", 25 "CronJob", 26 "Job", 27 "LimitRange", 28 "ResourceQuota", 29 "HorizontalPodAutoscaler", 30 "StatefulSet", 31 } 32 33 type ResourceFilter struct { 34 Kinds []string 35 Name string 36 Label string 37 ExcludedKinds []string 38 ExcludedNames []string 39 ExcludedLabels []string 40 } 41 42 // NewResourceFilter returns a filter based on kinds and flags. 43 // kindArg might be blank, or a list of kinds (e.g. 'pvc,dc') or 44 // a kind/name combination (e.g. 'dc/foo'). 45 // selectorFlag might be blank or a key and a label, e.g. 'name=foo'. 46 func NewResourceFilter(kindArg string, selectorFlag string, excludes []string) (*ResourceFilter, error) { 47 filter := &ResourceFilter{ 48 Kinds: []string{}, 49 Name: "", 50 Label: selectorFlag, 51 } 52 53 if len(kindArg) > 0 { 54 kindArg = strings.ToLower(kindArg) 55 56 if strings.Contains(kindArg, "/") { 57 if strings.Contains(kindArg, ",") { 58 return nil, errors.New( 59 "You cannot target more than one resource name", 60 ) 61 } 62 nameParts := strings.Split(kindArg, "/") 63 filter.Name = KindMapping[nameParts[0]] + "/" + nameParts[1] 64 return filter, nil 65 } 66 67 targetedKinds := make(map[string]bool) 68 unknownKinds := []string{} 69 kinds := strings.Split(kindArg, ",") 70 for _, kind := range kinds { 71 if _, ok := KindMapping[kind]; !ok { 72 unknownKinds = append(unknownKinds, kind) 73 } else { 74 targetedKinds[KindMapping[kind]] = true 75 } 76 } 77 78 if len(unknownKinds) > 0 { 79 return nil, fmt.Errorf( 80 "Unknown resource kinds: %s", 81 strings.Join(unknownKinds, ","), 82 ) 83 } 84 85 for kind := range targetedKinds { 86 filter.Kinds = append(filter.Kinds, kind) 87 } 88 89 sort.Strings(filter.Kinds) 90 } 91 92 unknownKinds := []string{} 93 for _, v := range excludes { 94 v = strings.ToLower(v) 95 if strings.Contains(v, "/") { // Name 96 nameParts := strings.Split(v, "/") 97 k := nameParts[0] 98 if _, ok := KindMapping[k]; !ok { 99 unknownKinds = append(unknownKinds, k) 100 } else { 101 filter.ExcludedNames = append(filter.ExcludedNames, KindMapping[k]+"/"+nameParts[1]) 102 } 103 } else if strings.Contains(v, "=") { // Label 104 filter.ExcludedLabels = append(filter.ExcludedLabels, v) 105 } else { // Kind 106 if _, ok := KindMapping[v]; !ok { 107 unknownKinds = append(unknownKinds, v) 108 } else { 109 filter.ExcludedKinds = append(filter.ExcludedKinds, KindMapping[v]) 110 } 111 } 112 } 113 114 if len(unknownKinds) > 0 { 115 return nil, fmt.Errorf( 116 "Unknown excluded resource kinds: %s", 117 strings.Join(unknownKinds, ","), 118 ) 119 } 120 121 return filter, nil 122 } 123 124 func (f *ResourceFilter) String() string { 125 return fmt.Sprintf("Kinds: %s, Name: %s, Label: %s, ExcludedKinds: %s, ExcludedNames: %s, ExcludedLabels: %s", f.Kinds, f.Name, f.Label, f.ExcludedKinds, f.ExcludedNames, f.ExcludedLabels) 126 } 127 128 func (f *ResourceFilter) SatisfiedBy(item *ResourceItem) bool { 129 if len(f.Name) > 0 && f.Name != item.FullName() { 130 return false 131 } 132 133 if len(f.Kinds) > 0 && !utils.Includes(f.Kinds, item.Kind) { 134 return false 135 } 136 137 if len(f.Label) > 0 { 138 labels := strings.Split(f.Label, ",") 139 for _, label := range labels { 140 if !item.HasLabel(label) { 141 return false 142 } 143 } 144 } 145 146 if len(f.ExcludedNames) > 0 { 147 if utils.Includes(f.ExcludedNames, item.FullName()) { 148 return false 149 } 150 } 151 152 if len(f.ExcludedKinds) > 0 { 153 if utils.Includes(f.ExcludedKinds, item.Kind) { 154 return false 155 } 156 } 157 158 if len(f.ExcludedLabels) > 0 { 159 for _, el := range f.ExcludedLabels { 160 if item.HasLabel(el) { 161 return false 162 } 163 } 164 } 165 166 return true 167 } 168 169 func (f *ResourceFilter) ConvertToTarget() string { 170 if len(f.Name) > 0 { 171 return f.Name 172 } 173 kinds := f.Kinds 174 if len(kinds) == 0 { 175 kinds = availableKinds 176 } 177 return strings.Join(kinds, ",") 178 } 179 180 func (f *ResourceFilter) ConvertToKinds() string { 181 if len(f.Name) > 0 { 182 nameParts := strings.Split(f.Name, "/") 183 return nameParts[0] 184 } 185 kinds := f.Kinds 186 if len(kinds) == 0 { 187 kinds = availableKinds 188 } 189 kindsWithoutExcluded := []string{} 190 for _, k := range kinds { 191 if !utils.Includes(f.ExcludedKinds, k) { 192 kindsWithoutExcluded = append(kindsWithoutExcluded, k) 193 } 194 } 195 return strings.Join(kindsWithoutExcluded, ",") 196 }