github.com/ali-iotechsys/cli@v20.10.0+incompatible/opts/capabilities.go (about) 1 package opts 2 3 import ( 4 "sort" 5 "strings" 6 ) 7 8 const ( 9 // AllCapabilities is a special value to add or drop all capabilities 10 AllCapabilities = "ALL" 11 12 // ResetCapabilities is a special value to reset capabilities when updating. 13 // This value should only be used when updating, not used on "create". 14 ResetCapabilities = "RESET" 15 ) 16 17 // NormalizeCapability normalizes a capability by upper-casing, trimming white space 18 // and adding a CAP_ prefix (if not yet present). This function also accepts the 19 // "ALL" magic-value, as used by CapAdd/CapDrop. 20 // 21 // This function only handles rudimentary formatting; no validation is performed, 22 // as the list of available capabilities can be updated over time, thus should be 23 // handled by the daemon. 24 func NormalizeCapability(cap string) string { 25 cap = strings.ToUpper(strings.TrimSpace(cap)) 26 if cap == AllCapabilities || cap == ResetCapabilities { 27 return cap 28 } 29 if !strings.HasPrefix(cap, "CAP_") { 30 cap = "CAP_" + cap 31 } 32 return cap 33 } 34 35 // CapabilitiesMap normalizes the given capabilities and converts them to a map. 36 func CapabilitiesMap(caps []string) map[string]bool { 37 normalized := make(map[string]bool) 38 for _, c := range caps { 39 normalized[NormalizeCapability(c)] = true 40 } 41 return normalized 42 } 43 44 // EffectiveCapAddCapDrop normalizes and sorts capabilities to "add" and "drop", 45 // and returns the effective capabilities to include in both. 46 // 47 // "CapAdd" takes precedence over "CapDrop", so capabilities included in both 48 // lists are removed from the list of capabilities to drop. The special "ALL" 49 // capability is also taken into account. 50 // 51 // Note that the special "RESET" value is only used when updating an existing 52 // service, and will be ignored. 53 // 54 // Duplicates are removed, and the resulting lists are sorted. 55 func EffectiveCapAddCapDrop(add, drop []string) (capAdd, capDrop []string) { 56 var ( 57 addCaps = CapabilitiesMap(add) 58 dropCaps = CapabilitiesMap(drop) 59 ) 60 61 if addCaps[AllCapabilities] { 62 // Special case: "ALL capabilities" trumps any other capability added. 63 addCaps = map[string]bool{AllCapabilities: true} 64 } 65 if dropCaps[AllCapabilities] { 66 // Special case: "ALL capabilities" trumps any other capability added. 67 dropCaps = map[string]bool{AllCapabilities: true} 68 } 69 for c := range dropCaps { 70 if addCaps[c] { 71 // Adding a capability takes precedence, so skip dropping 72 continue 73 } 74 if c != ResetCapabilities { 75 capDrop = append(capDrop, c) 76 } 77 } 78 79 for c := range addCaps { 80 if c != ResetCapabilities { 81 capAdd = append(capAdd, c) 82 } 83 } 84 85 sort.Strings(capAdd) 86 sort.Strings(capDrop) 87 88 return capAdd, capDrop 89 }