provisioner: augment Networks config from caller when -unsafe (#411)

Currently container instances are hard-coded to join a single network,
the network associated with the session.

This change allows the caller of CreateInstance to specify which
additional networks should be joined. This is useful, for example, when
a container instance requires access to additional "backend" services
that may be running.

There are security implications associated with this change, hence the
additional networks are only joined when a new -unsafe flag is
specified. It is hoped the name is a sufficient indicator that thought
needs to go into using it.
This commit is contained in:
Paul Jolly
2020-09-04 13:46:31 +01:00
committed by GitHub
parent 78e9689249
commit 681de41e0a
4 changed files with 28 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ package config
import (
"flag"
"os"
"regexp"
"github.com/gorilla/securecookie"
@@ -30,6 +31,11 @@ var ForceTLS bool
var SecureCookie *securecookie.SecureCookie
var AdminToken string
// Unsafe enables a number of unsafe features when set. It is principally
// intended to be used in development. For example, it allows the caller to
// specify the Docker networks to join.
var Unsafe bool
var PlaygroundDomain string
var SegmentId string
@@ -60,6 +66,8 @@ func ParseFlags() {
flag.StringVar(&SegmentId, "segment-id", "", "Segment id to post metrics")
flag.BoolVar(&Unsafe, "unsafe", os.Getenv("PWD_UNSAFE") == "true", "Operate in unsafe mode")
flag.Parse()
SecureCookie = securecookie.New([]byte(CookieHashKey), []byte(CookieBlockKey))

View File

@@ -11,6 +11,7 @@ import (
"strings"
lru "github.com/hashicorp/golang-lru"
"github.com/play-with-docker/play-with-docker/config"
"github.com/play-with-docker/play-with-docker/docker"
"github.com/play-with-docker/play-with-docker/id"
"github.com/play-with-docker/play-with-docker/pwd/types"
@@ -65,6 +66,12 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
}
conf.Hostname = nodeName
}
networks := []string{session.Id}
if config.Unsafe {
networks = append(networks, conf.Networks...)
}
containerName := fmt.Sprintf("%s_%s", session.Id[:8], d.generator.NewId())
opts := docker.CreateContainerOpts{
Image: conf.ImageName,
@@ -76,7 +83,7 @@ func (d *DinD) InstanceNew(session *types.Session, conf types.InstanceConfig) (*
CACert: conf.CACert,
HostFQDN: conf.PlaygroundFQDN,
Privileged: true,
Networks: []string{session.Id},
Networks: networks,
DindVolumeSize: conf.DindVolumeSize,
Envs: conf.Envs,
}

View File

@@ -152,6 +152,15 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
assert.Nil(t, err)
// Switch to unsafe mode in order to test custom networks below
//
// TODO: move config away from being a global in order that we don't
// have to hack setting the context in this way.
config.Unsafe = true
defer func() {
config.Unsafe = false
}()
expectedInstance := types.Instance{
Name: fmt.Sprintf("%s_aaaabbbbcccc", session.Id[:8]),
Hostname: "node1",
@@ -172,14 +181,14 @@ func TestInstanceNew_WithNotAllowedImage(t *testing.T) {
CACert: nil,
Privileged: true,
Envs: []string{"HELLO=WORLD"},
Networks: []string{session.Id},
Networks: []string{session.Id, "arpanet"},
}
_d.On("ContainerCreate", expectedContainerOpts).Return(nil)
_d.On("ContainerIPs", expectedInstance.Name).Return(map[string]string{session.Id: "10.0.0.1"}, nil)
_s.On("InstancePut", mock.AnythingOfType("*types.Instance")).Return(nil)
_e.M.On("Emit", event.INSTANCE_NEW, "aaaabbbbcccc", []interface{}{"aaaabbbb_aaaabbbbcccc", "10.0.0.1", "node1", "ip10-0-0-1-aaaabbbbcccc"}).Return()
instance, err := p.InstanceNew(session, types.InstanceConfig{ImageName: "redis", Envs: []string{"HELLO=WORLD"}})
instance, err := p.InstanceNew(session, types.InstanceConfig{ImageName: "redis", Envs: []string{"HELLO=WORLD"}, Networks: []string{"arpanet"}})
assert.Nil(t, err)
assert.Equal(t, expectedInstance, *instance)

View File

@@ -40,4 +40,5 @@ type InstanceConfig struct {
Type string
DindVolumeSize string
Envs []string
Networks []string
}