github.com/secure-build/gitlab-runner@v12.5.0+incompatible/executors/kubernetes/overwrites.go (about) 1 package kubernetes 2 3 import ( 4 "fmt" 5 "regexp" 6 "strings" 7 8 "gitlab.com/gitlab-org/gitlab-runner/common" 9 ) 10 11 const ( 12 // NamespaceOverwriteVariableName is the key for the JobVariable containing user overwritten Namespace 13 NamespaceOverwriteVariableName = "KUBERNETES_NAMESPACE_OVERWRITE" 14 // ServiceAccountOverwriteVariableName is the key for the JobVariable containing user overwritten ServiceAccount 15 ServiceAccountOverwriteVariableName = "KUBERNETES_SERVICE_ACCOUNT_OVERWRITE" 16 // BearerTokenOverwriteVariableValue is the key for the JobVariable containing user overwritten BearerToken 17 BearerTokenOverwriteVariableValue = "KUBERNETES_BEARER_TOKEN" 18 // PodAnnotationsOverwriteVariablePrefix is the prefix for all the JobVariable keys containing user overwritten PodAnnotations 19 PodAnnotationsOverwriteVariablePrefix = "KUBERNETES_POD_ANNOTATIONS_" 20 ) 21 22 type overwrites struct { 23 namespace string 24 serviceAccount string 25 bearerToken string 26 podAnnotations map[string]string 27 } 28 29 func createOverwrites(config *common.KubernetesConfig, variables common.JobVariables, logger common.BuildLogger) (*overwrites, error) { 30 var err error 31 o := &overwrites{} 32 33 namespaceOverwrite := variables.Expand().Get(NamespaceOverwriteVariableName) 34 o.namespace, err = o.evaluateOverwrite("Namespace", config.Namespace, config.NamespaceOverwriteAllowed, namespaceOverwrite, logger) 35 if err != nil { 36 return nil, err 37 } 38 39 serviceAccountOverwrite := variables.Expand().Get(ServiceAccountOverwriteVariableName) 40 o.serviceAccount, err = o.evaluateOverwrite("ServiceAccount", config.ServiceAccount, config.ServiceAccountOverwriteAllowed, serviceAccountOverwrite, logger) 41 if err != nil { 42 return nil, err 43 } 44 45 bearerTokenOverwrite := variables.Expand().Get(BearerTokenOverwriteVariableValue) 46 o.bearerToken, err = o.evaluateBoolControlledOverwrite("BearerToken", config.BearerToken, config.BearerTokenOverwriteAllowed, bearerTokenOverwrite, logger) 47 if err != nil { 48 return nil, err 49 } 50 51 o.podAnnotations, err = o.evaluateMapOverwrite("PodAnnotations", config.PodAnnotations, config.PodAnnotationsOverwriteAllowed, variables, PodAnnotationsOverwriteVariablePrefix, logger) 52 if err != nil { 53 return nil, err 54 } 55 56 return o, nil 57 } 58 59 func (o *overwrites) evaluateBoolControlledOverwrite(fieldName, value string, canOverride bool, overwriteValue string, logger common.BuildLogger) (string, error) { 60 if canOverride { 61 return o.evaluateOverwrite(fieldName, value, ".+", overwriteValue, logger) 62 } 63 return o.evaluateOverwrite(fieldName, value, "", overwriteValue, logger) 64 } 65 66 func (o *overwrites) evaluateOverwrite(fieldName, value, regex, overwriteValue string, logger common.BuildLogger) (string, error) { 67 if regex == "" { 68 logger.Debugln("Regex allowing overrides for", fieldName, "is empty, disabling override.") 69 return value, nil 70 } 71 72 if overwriteValue == "" { 73 return value, nil 74 } 75 76 if err := overwriteRegexCheck(regex, overwriteValue); err != nil { 77 return value, err 78 } 79 80 logValue := overwriteValue 81 if fieldName == "BearerToken" { 82 logValue = "XXXXXXXX..." 83 } 84 85 logger.Println(fmt.Sprintf("%q overwritten with %q", fieldName, logValue)) 86 87 return overwriteValue, nil 88 } 89 90 func overwriteRegexCheck(regex, value string) error { 91 var err error 92 var r *regexp.Regexp 93 if r, err = regexp.Compile(regex); err != nil { 94 return err 95 } 96 if match := r.MatchString(value); !match { 97 return fmt.Errorf("Provided value %q does not match regex %q", value, regex) 98 } 99 return nil 100 } 101 102 // splitMapOverwrite splits provided string on the first "=" and returns (key, value, nil). 103 // If the argument cannot be split an error is returned 104 func splitMapOverwrite(str string) (string, string, error) { 105 if split := strings.SplitN(str, "=", 2); len(split) > 1 { 106 return split[0], split[1], nil 107 } 108 109 return "", "", fmt.Errorf("Provided value %q is malformed, does not match k=v", str) 110 } 111 112 func (o *overwrites) evaluateMapOverwrite(fieldName string, values map[string]string, regex string, variables common.JobVariables, variablesSelector string, logger common.BuildLogger) (map[string]string, error) { 113 if regex == "" { 114 logger.Debugln("Regex allowing overrides for", fieldName, "is empty, disabling override.") 115 return values, nil 116 } 117 118 finalValues := make(map[string]string) 119 for k, v := range values { 120 finalValues[k] = v 121 } 122 123 for _, variable := range variables { 124 if strings.HasPrefix(variable.Key, variablesSelector) { 125 if err := overwriteRegexCheck(regex, variable.Value); err != nil { 126 return nil, err 127 } 128 129 key, value, err := splitMapOverwrite(variable.Value) 130 if err != nil { 131 return nil, err 132 } 133 134 finalValues[key] = value 135 logger.Println(fmt.Sprintf("%q %q overwritten with %q", fieldName, key, value)) 136 } 137 } 138 return finalValues, nil 139 }