1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
|
package common
import (
"errors"
"fmt"
"gitlab.com/gitlab-org/gitlab-runner/helpers"
)
type logger interface {
Println(args ...interface{})
Warningln(args ...interface{})
}
type SecretsResolver interface {
Resolve(secrets Secrets) (JobVariables, error)
}
type SecretResolverRegistry interface {
Register(f secretResolverFactory)
GetFor(secret Secret) (SecretResolver, error)
}
type secretResolverFactory func(secret Secret) SecretResolver
type SecretResolver interface {
Name() string
IsSupported() bool
Resolve() (string, error)
}
var (
secretResolverRegistry = new(defaultSecretResolverRegistry)
ErrMissingLogger = errors.New("logger not provided")
ErrMissingSecretResolver = errors.New("no resolver that can handle the secret")
)
func GetSecretResolverRegistry() SecretResolverRegistry {
return secretResolverRegistry
}
type defaultSecretResolverRegistry struct {
factories []secretResolverFactory
}
func (r *defaultSecretResolverRegistry) Register(f secretResolverFactory) {
r.factories = append(r.factories, f)
}
func (r *defaultSecretResolverRegistry) GetFor(secret Secret) (SecretResolver, error) {
for _, f := range r.factories {
sr := f(secret)
if sr.IsSupported() {
return sr, nil
}
}
return nil, ErrMissingSecretResolver
}
func newSecretsResolver(l logger, registry SecretResolverRegistry) (SecretsResolver, error) {
if l == nil {
return nil, ErrMissingLogger
}
sr := &defaultSecretsResolver{
logger: l,
secretResolverRegistry: registry,
}
return sr, nil
}
type defaultSecretsResolver struct {
logger logger
secretResolverRegistry SecretResolverRegistry
}
func (r *defaultSecretsResolver) Resolve(secrets Secrets) (JobVariables, error) {
if secrets == nil {
return nil, nil
}
msg := fmt.Sprintf(
"%sResolving secrets%s",
helpers.ANSI_BOLD_CYAN,
helpers.ANSI_RESET,
)
r.logger.Println(msg)
variables := make(JobVariables, 0)
for variableKey, secret := range secrets {
r.logger.Println(fmt.Sprintf("Resolving secret %q...", variableKey))
v, err := r.handleSecret(variableKey, secret)
if err != nil {
return nil, err
}
if v != nil {
variables = append(variables, *v)
}
}
return variables, nil
}
func (r *defaultSecretsResolver) handleSecret(variableKey string, secret Secret) (*JobVariable, error) {
sr, err := r.secretResolverRegistry.GetFor(secret)
if err != nil {
r.logger.Warningln(fmt.Sprintf("Not resolved: %v", err))
return nil, nil
}
r.logger.Println(fmt.Sprintf("Using %q secret resolver...", sr.Name()))
value, err := sr.Resolve()
if err != nil {
return nil, err
}
variable := &JobVariable{
Key: variableKey,
Value: value,
File: secret.IsFile(),
}
return variable, nil
}
|