runtime: support for dynamic secrets (#1861)
* runtime: replace CreateCredentials with CreateSecret * runtime/kubernetes: secrets support * runtime: CreateSecret => WithSecret * runtime: use map[string]string for secrets * runtime/kubernetes: update to use kv secrets * Fix merge conflict (missing import) Co-authored-by: Asim Aslam <asim@aslam.me>
This commit is contained in:
parent
3d1ba914fc
commit
006bbefaf3
@ -3,7 +3,6 @@ package kubernetes
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
@ -450,9 +449,8 @@ func (k *kubernetes) Create(s *runtime.Service, opts ...runtime.CreateOption) er
|
||||
options.Image = k.getImage(s, options)
|
||||
|
||||
// create a secret for the credentials if some where provided
|
||||
if len(options.Credentials) > 0 {
|
||||
secret, err := k.createCredentials(s, options)
|
||||
if err != nil {
|
||||
if len(options.Secrets) > 0 {
|
||||
if err := k.createCredentials(s, options); err != nil {
|
||||
if logger.V(logger.WarnLevel, logger.DefaultLogger) {
|
||||
logger.Warnf("Error generating auth credentials for service: %v", err)
|
||||
}
|
||||
@ -462,9 +460,6 @@ func (k *kubernetes) Create(s *runtime.Service, opts ...runtime.CreateOption) er
|
||||
if logger.V(logger.DebugLevel, logger.DefaultLogger) {
|
||||
logger.Debugf("Generated auth credentials for service %v", s.Name)
|
||||
}
|
||||
|
||||
// pass the secret name to the client via the credentials option
|
||||
options.Credentials = secret
|
||||
}
|
||||
|
||||
// create new service
|
||||
@ -689,33 +684,27 @@ func (k *kubernetes) getImage(s *runtime.Service, options runtime.CreateOptions)
|
||||
|
||||
return ""
|
||||
}
|
||||
func (k *kubernetes) createCredentials(service *runtime.Service, options runtime.CreateOptions) (string, error) {
|
||||
// validate the creds
|
||||
comps := strings.Split(options.Credentials, ":")
|
||||
if len(comps) != 2 {
|
||||
return "", errors.New("Invalid credentials, expected format 'user:pass'")
|
||||
func (k *kubernetes) createCredentials(service *runtime.Service, options runtime.CreateOptions) error {
|
||||
data := make(map[string]string, len(options.Secrets))
|
||||
for key, value := range options.Secrets {
|
||||
data[key] = base64.StdEncoding.EncodeToString([]byte(value))
|
||||
}
|
||||
|
||||
// construct the k8s secret object
|
||||
secret := &client.Secret{
|
||||
Type: "Opaque",
|
||||
Data: map[string]string{
|
||||
"id": base64.StdEncoding.EncodeToString([]byte(comps[0])),
|
||||
"secret": base64.StdEncoding.EncodeToString([]byte(comps[1])),
|
||||
},
|
||||
Data: data,
|
||||
Metadata: &client.Metadata{
|
||||
Name: credentialsName(service),
|
||||
Namespace: options.Namespace,
|
||||
},
|
||||
}
|
||||
|
||||
// create options specify the namespace
|
||||
ns := client.CreateNamespace(options.Namespace)
|
||||
|
||||
// crete the secret in kubernetes
|
||||
name := credentialsName(service)
|
||||
err := k.client.Create(&client.Resource{Kind: "secret", Name: name, Value: secret}, ns)
|
||||
return name, err
|
||||
return k.client.Create(&client.Resource{
|
||||
Kind: "secret", Name: name, Value: secret,
|
||||
}, client.CreateNamespace(options.Namespace))
|
||||
}
|
||||
|
||||
func credentialsName(service *runtime.Service) string {
|
||||
|
@ -75,22 +75,14 @@ func newService(s *runtime.Service, c runtime.CreateOptions) *service {
|
||||
env = append(env, client.EnvVar{Name: evarPair[0], Value: evarPair[1]})
|
||||
}
|
||||
|
||||
// if credentials were provided, pass them to the service
|
||||
if len(c.Credentials) > 0 {
|
||||
// if secrets were provided, pass them to the service
|
||||
for key := range c.Secrets {
|
||||
env = append(env, client.EnvVar{
|
||||
Name: "MICRO_AUTH_ID",
|
||||
Name: key,
|
||||
ValueFrom: &client.EnvVarSource{
|
||||
SecretKeyRef: &client.SecretKeySelector{
|
||||
Name: c.Credentials, Key: "id",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
env = append(env, client.EnvVar{
|
||||
Name: "MICRO_AUTH_SECRET",
|
||||
ValueFrom: &client.EnvVarSource{
|
||||
SecretKeyRef: &client.SecretKeySelector{
|
||||
Name: c.Credentials, Key: "secret",
|
||||
Name: credentialsName(s),
|
||||
Key: key,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
@ -270,16 +270,9 @@ func (r *localRuntime) Create(s *runtime.Service, opts ...runtime.CreateOption)
|
||||
options.Args = []string{"run", "."}
|
||||
}
|
||||
|
||||
// pass credentials as env vars
|
||||
if len(options.Credentials) > 0 {
|
||||
// validate the creds
|
||||
comps := strings.Split(options.Credentials, ":")
|
||||
if len(comps) != 2 {
|
||||
return errors.New("Invalid credentials, expected format 'user:pass'")
|
||||
}
|
||||
|
||||
options.Env = append(options.Env, "MICRO_AUTH_ID", comps[0])
|
||||
options.Env = append(options.Env, "MICRO_AUTH_SECRET", comps[1])
|
||||
// pass secrets as env vars
|
||||
for key, value := range options.Secrets {
|
||||
options.Env = append(options.Env, key, value)
|
||||
}
|
||||
|
||||
if _, ok := r.namespaces[options.Namespace]; !ok {
|
||||
|
@ -82,8 +82,8 @@ type CreateOptions struct {
|
||||
Namespace string
|
||||
// Specify the context to use
|
||||
Context context.Context
|
||||
// Credentials for the service to use
|
||||
Credentials string
|
||||
// Secrets to use
|
||||
Secrets map[string]string
|
||||
}
|
||||
|
||||
// ReadOptions queries runtime services
|
||||
@ -128,10 +128,14 @@ func CreateContext(ctx context.Context) CreateOption {
|
||||
}
|
||||
}
|
||||
|
||||
// CreateCredentials sets the credentials to start the service with
|
||||
func CreateCredentials(user, pass string) CreateOption {
|
||||
// WithSecret sets a secret to provide the service with
|
||||
func WithSecret(key, value string) CreateOption {
|
||||
return func(o *CreateOptions) {
|
||||
o.Credentials = user + ":" + pass
|
||||
if o.Secrets == nil {
|
||||
o.Secrets = map[string]string{key: value}
|
||||
} else {
|
||||
o.Secrets[key] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user