mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
3b8d36d064
Updating swarmkit dependencies. Add more parameters for the secret driver API. Signed-off-by: Liron Levin <liron@twistlock.com>
162 lines
4.4 KiB
Go
162 lines
4.4 KiB
Go
package template
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/docker/swarmkit/agent/exec"
|
|
"github.com/docker/swarmkit/api"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// ExpandContainerSpec expands templated fields in the runtime using the task
|
|
// state and the node where it is scheduled to run.
|
|
// Templating is all evaluated on the agent-side, before execution.
|
|
//
|
|
// Note that these are projected only on runtime values, since active task
|
|
// values are typically manipulated in the manager.
|
|
func ExpandContainerSpec(n *api.NodeDescription, t *api.Task) (*api.ContainerSpec, error) {
|
|
container := t.Spec.GetContainer()
|
|
if container == nil {
|
|
return nil, errors.Errorf("task missing ContainerSpec to expand")
|
|
}
|
|
|
|
container = container.Copy()
|
|
ctx := NewContext(n, t)
|
|
|
|
var err error
|
|
container.Env, err = expandEnv(ctx, container.Env)
|
|
if err != nil {
|
|
return container, errors.Wrap(err, "expanding env failed")
|
|
}
|
|
|
|
// For now, we only allow templating of string-based mount fields
|
|
container.Mounts, err = expandMounts(ctx, container.Mounts)
|
|
if err != nil {
|
|
return container, errors.Wrap(err, "expanding mounts failed")
|
|
}
|
|
|
|
container.Hostname, err = ctx.Expand(container.Hostname)
|
|
return container, errors.Wrap(err, "expanding hostname failed")
|
|
}
|
|
|
|
func expandMounts(ctx Context, mounts []api.Mount) ([]api.Mount, error) {
|
|
if len(mounts) == 0 {
|
|
return mounts, nil
|
|
}
|
|
|
|
expanded := make([]api.Mount, len(mounts))
|
|
for i, mount := range mounts {
|
|
var err error
|
|
mount.Source, err = ctx.Expand(mount.Source)
|
|
if err != nil {
|
|
return mounts, errors.Wrapf(err, "expanding mount source %q", mount.Source)
|
|
}
|
|
|
|
mount.Target, err = ctx.Expand(mount.Target)
|
|
if err != nil {
|
|
return mounts, errors.Wrapf(err, "expanding mount target %q", mount.Target)
|
|
}
|
|
|
|
if mount.VolumeOptions != nil {
|
|
mount.VolumeOptions.Labels, err = expandMap(ctx, mount.VolumeOptions.Labels)
|
|
if err != nil {
|
|
return mounts, errors.Wrap(err, "expanding volume labels")
|
|
}
|
|
|
|
if mount.VolumeOptions.DriverConfig != nil {
|
|
mount.VolumeOptions.DriverConfig.Options, err = expandMap(ctx, mount.VolumeOptions.DriverConfig.Options)
|
|
if err != nil {
|
|
return mounts, errors.Wrap(err, "expanding volume driver config")
|
|
}
|
|
}
|
|
}
|
|
|
|
expanded[i] = mount
|
|
}
|
|
|
|
return expanded, nil
|
|
}
|
|
|
|
func expandMap(ctx Context, m map[string]string) (map[string]string, error) {
|
|
var (
|
|
n = make(map[string]string, len(m))
|
|
err error
|
|
)
|
|
|
|
for k, v := range m {
|
|
v, err = ctx.Expand(v)
|
|
if err != nil {
|
|
return m, errors.Wrapf(err, "expanding map entry %q=%q", k, v)
|
|
}
|
|
|
|
n[k] = v
|
|
}
|
|
|
|
return n, nil
|
|
}
|
|
|
|
func expandEnv(ctx Context, values []string) ([]string, error) {
|
|
var result []string
|
|
for _, value := range values {
|
|
var (
|
|
parts = strings.SplitN(value, "=", 2)
|
|
entry = parts[0]
|
|
)
|
|
|
|
if len(parts) > 1 {
|
|
expanded, err := ctx.Expand(parts[1])
|
|
if err != nil {
|
|
return values, errors.Wrapf(err, "expanding env %q", value)
|
|
}
|
|
|
|
entry = fmt.Sprintf("%s=%s", entry, expanded)
|
|
}
|
|
|
|
result = append(result, entry)
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func expandPayload(ctx *PayloadContext, payload []byte) ([]byte, error) {
|
|
result, err := ctx.Expand(string(payload))
|
|
if err != nil {
|
|
return payload, err
|
|
}
|
|
return []byte(result), nil
|
|
}
|
|
|
|
// ExpandSecretSpec expands the template inside the secret payload, if any.
|
|
// Templating is evaluated on the agent-side.
|
|
func ExpandSecretSpec(s *api.Secret, node *api.NodeDescription, t *api.Task, dependencies exec.DependencyGetter) (*api.SecretSpec, error) {
|
|
if s.Spec.Templating == nil {
|
|
return &s.Spec, nil
|
|
}
|
|
if s.Spec.Templating.Name == "golang" {
|
|
ctx := NewPayloadContextFromTask(node, t, dependencies)
|
|
secretSpec := s.Spec.Copy()
|
|
|
|
var err error
|
|
secretSpec.Data, err = expandPayload(&ctx, secretSpec.Data)
|
|
return secretSpec, err
|
|
}
|
|
return &s.Spec, errors.New("unrecognized template type")
|
|
}
|
|
|
|
// ExpandConfigSpec expands the template inside the config payload, if any.
|
|
// Templating is evaluated on the agent-side.
|
|
func ExpandConfigSpec(c *api.Config, node *api.NodeDescription, t *api.Task, dependencies exec.DependencyGetter) (*api.ConfigSpec, bool, error) {
|
|
if c.Spec.Templating == nil {
|
|
return &c.Spec, false, nil
|
|
}
|
|
if c.Spec.Templating.Name == "golang" {
|
|
ctx := NewPayloadContextFromTask(node, t, dependencies)
|
|
configSpec := c.Spec.Copy()
|
|
|
|
var err error
|
|
configSpec.Data, err = expandPayload(&ctx, configSpec.Data)
|
|
return configSpec, ctx.sensitive, err
|
|
}
|
|
return &c.Spec, false, errors.New("unrecognized template type")
|
|
}
|