github.com/zhyoulun/cilium@v1.6.12/pkg/labels/oplabels.go (about) 1 // Copyright 2016-2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package labels 16 17 import ( 18 "fmt" 19 20 "github.com/cilium/cilium/pkg/logging/logfields" 21 22 "github.com/sirupsen/logrus" 23 ) 24 25 type keepMarks map[string]struct{} 26 27 // set marks the label with 'key' to not be deleted. 28 func (k keepMarks) set(key string) { 29 k[key] = struct{}{} // marked for keeping 30 } 31 32 // OpLabels represents the the possible types. 33 type OpLabels struct { 34 // Active labels that are enabled and disabled but not deleted 35 Custom Labels 36 37 // Labels derived from orchestration system 38 OrchestrationIdentity Labels 39 40 // orchestrationIdentity labels which have been disabled 41 Disabled Labels 42 43 // orchestrationInfo - labels from orchestration which are not used in determining a security identity 44 OrchestrationInfo Labels 45 } 46 47 // NewOpLabels creates new initialized OpLabels 48 func NewOpLabels() OpLabels { 49 return OpLabels{ 50 Custom: Labels{}, 51 Disabled: Labels{}, 52 OrchestrationIdentity: Labels{}, 53 OrchestrationInfo: Labels{}, 54 } 55 } 56 57 // SplitUserLabelChanges returns labels to 'add' and 'del'ete to make 58 // the custom labels match 'lbls' 59 // FIXME: Somewhere in the code we crash if the returned maps are non-nil 60 // but length 0. We retain this behaviour here because it's easier. 61 func (o *OpLabels) SplitUserLabelChanges(lbls Labels) (add, del Labels) { 62 for key, lbl := range lbls { 63 if _, found := o.Custom[key]; !found { 64 if add == nil { 65 add = Labels{} 66 } 67 add[key] = lbl 68 } 69 } 70 71 for key, lbl := range o.Custom { 72 if _, found := lbls[key]; !found { 73 if del == nil { 74 del = Labels{} 75 } 76 del[key] = lbl 77 } 78 } 79 80 return add, del 81 } 82 83 // IdentityLabels returns map of labels that are used when determining a 84 // security identity. 85 func (o *OpLabels) IdentityLabels() Labels { 86 enabled := make(Labels, len(o.Custom)+len(o.OrchestrationIdentity)) 87 88 for k, v := range o.Custom { 89 enabled[k] = v 90 } 91 92 for k, v := range o.OrchestrationIdentity { 93 enabled[k] = v 94 } 95 96 return enabled 97 } 98 99 // GetIdentityLabel returns the value of the given Key from all IdentityLabels. 100 func (o *OpLabels) GetIdentityLabel(key string) (l Label, found bool) { 101 l, found = o.OrchestrationIdentity[key] 102 if !found { 103 l, found = o.Custom[key] 104 } 105 return l, found 106 } 107 108 // AllLabels returns all Labels within the provided OpLabels. 109 func (o *OpLabels) AllLabels() Labels { 110 all := make(Labels, len(o.Custom)+len(o.OrchestrationInfo)+len(o.OrchestrationIdentity)+len(o.Disabled)) 111 112 for k, v := range o.Custom { 113 all[k] = v 114 } 115 116 for k, v := range o.Disabled { 117 all[k] = v 118 } 119 120 for k, v := range o.OrchestrationIdentity { 121 all[k] = v 122 } 123 124 for k, v := range o.OrchestrationInfo { 125 all[k] = v 126 } 127 return all 128 } 129 130 func (o *OpLabels) ReplaceInformationLabels(l Labels, logger *logrus.Entry) bool { 131 changed := false 132 keepers := make(keepMarks) 133 for _, v := range l { 134 keepers.set(v.Key) 135 if o.OrchestrationInfo.upsertLabel(v) { 136 changed = true 137 logger.WithField(logfields.Object, logfields.Repr(v)).Debug("Assigning information label") 138 } 139 } 140 o.OrchestrationInfo.deleteUnMarked(keepers) 141 142 return changed 143 } 144 145 func (o *OpLabels) ReplaceIdentityLabels(l Labels, logger *logrus.Entry) bool { 146 changed := false 147 148 keepers := make(keepMarks) 149 disabledKeepers := make(keepMarks) 150 151 for k, v := range l { 152 // A disabled identity label stays disabled without value updates 153 if _, found := o.Disabled[k]; found { 154 disabledKeepers.set(k) 155 } else if keepers.set(v.Key); o.OrchestrationIdentity.upsertLabel(v) { 156 logger.WithField(logfields.Object, logfields.Repr(v)).Debug("Assigning security relevant label") 157 changed = true 158 } 159 } 160 161 if o.OrchestrationIdentity.deleteUnMarked(keepers) || o.Disabled.deleteUnMarked(disabledKeepers) { 162 changed = true 163 } 164 165 return changed 166 } 167 168 func (o *OpLabels) ModifyIdentityLabels(addLabels, delLabels Labels) (changed bool, err error) { 169 for k := range delLabels { 170 // The change request is accepted if the label is on 171 // any of the lists. If the label is already disabled, 172 // we will simply ignore that change. 173 if _, found := o.Custom[k]; !found { 174 if _, found := o.OrchestrationIdentity[k]; !found { 175 if _, found := o.Disabled[k]; !found { 176 return false, fmt.Errorf("label %s not found", k) 177 } 178 } 179 } 180 } 181 182 // Will not fail after this point 183 for k := range delLabels { 184 if v, found := o.OrchestrationIdentity[k]; found { 185 delete(o.OrchestrationIdentity, k) 186 o.Disabled[k] = v 187 changed = true 188 } 189 190 if _, found := o.Custom[k]; found { 191 delete(o.Custom, k) 192 changed = true 193 } 194 } 195 196 for k, v := range addLabels { 197 if _, found := o.Disabled[k]; found { // Restore label. 198 delete(o.Disabled, k) 199 o.OrchestrationIdentity[k] = v 200 changed = true 201 } else if _, found := o.OrchestrationIdentity[k]; found { // Replace label's source and value. 202 o.OrchestrationIdentity[k] = v 203 changed = true 204 } else { 205 o.Custom[k] = v 206 changed = true 207 } 208 } 209 return changed, nil 210 } 211 212 // upsertLabel updates or inserts 'label' in 'l', but only if exactly the same label 213 // was not already in 'l'. Returns 'true' if a label was added, or an old label was 214 // updated, 'false' otherwise. 215 func (l Labels) upsertLabel(label Label) bool { 216 oldLabel, found := l[label.Key] 217 if found { 218 // Key is the same, check if Value and Source are also the same 219 if label.Value == oldLabel.Value && label.Source == oldLabel.Source { 220 return false // No change 221 } 222 } 223 // Insert or replace old label 224 l[label.Key] = label 225 return true 226 } 227 228 // deleteUnMarked deletes the labels which have not been marked for keeping. 229 // Returns true if any of them were deleted. 230 func (l Labels) deleteUnMarked(marks keepMarks) bool { 231 deleted := false 232 for k := range l { 233 if _, keep := marks[k]; !keep { 234 delete(l, k) 235 deleted = true 236 } 237 } 238 239 return deleted 240 }