moving opts to cli repo

Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
master
Abhinandan Prativadi 2017-05-15 17:02:04 -07:00
parent 2e07636e5e
commit 0893ab8560
2 changed files with 206 additions and 0 deletions

106
opts/network.go Normal file
View File

@ -0,0 +1,106 @@
package opts
import (
"encoding/csv"
"fmt"
"regexp"
"strings"
)
const (
networkOptName = "name"
networkOptAlias = "alias"
driverOpt = "driver-opt"
)
// NetworkAttachmentOpts represents the network options for endpoint creation
type NetworkAttachmentOpts struct {
Target string
Aliases []string
DriverOpts map[string]string
}
// NetworkOpt represents a network config in swarm mode.
type NetworkOpt struct {
options []NetworkAttachmentOpts
}
// Set networkopts value
func (n *NetworkOpt) Set(value string) error {
longSyntax, err := regexp.MatchString(`\w+=\w+(,\w+=\w+)*`, value)
if err != nil {
return err
}
var netOpt NetworkAttachmentOpts
if longSyntax {
csvReader := csv.NewReader(strings.NewReader(value))
fields, err := csvReader.Read()
if err != nil {
return err
}
netOpt.Aliases = []string{}
for _, field := range fields {
parts := strings.SplitN(field, "=", 2)
if len(parts) < 2 {
return fmt.Errorf("invalid field %s", field)
}
key := strings.TrimSpace(strings.ToLower(parts[0]))
value := strings.TrimSpace(strings.ToLower(parts[1]))
switch key {
case networkOptName:
netOpt.Target = value
case networkOptAlias:
netOpt.Aliases = append(netOpt.Aliases, value)
case driverOpt:
key, value, err = parseDriverOpt(value)
if err == nil {
if netOpt.DriverOpts == nil {
netOpt.DriverOpts = make(map[string]string)
}
netOpt.DriverOpts[key] = value
} else {
return err
}
default:
return fmt.Errorf("invalid field key %s", key)
}
}
if len(netOpt.Target) == 0 {
return fmt.Errorf("network name/id is not specified")
}
} else {
netOpt.Target = value
}
n.options = append(n.options, netOpt)
return nil
}
// Type returns the type of this option
func (n *NetworkOpt) Type() string {
return "network"
}
// Value returns the networkopts
func (n *NetworkOpt) Value() []NetworkAttachmentOpts {
return n.options
}
// String returns the network opts as a string
func (n *NetworkOpt) String() string {
return ""
}
func parseDriverOpt(driverOpt string) (key string, value string, err error) {
parts := strings.SplitN(driverOpt, "=", 2)
if len(parts) != 2 {
err = fmt.Errorf("invalid key value pair format in driver options")
}
key = strings.TrimSpace(strings.ToLower(parts[0]))
value = strings.TrimSpace(strings.ToLower(parts[1]))
return
}

100
opts/network_test.go Normal file
View File

@ -0,0 +1,100 @@
package opts
import (
"testing"
"github.com/docker/docker/pkg/testutil"
"github.com/stretchr/testify/assert"
)
func TestNetworkOptLegacySyntax(t *testing.T) {
testCases := []struct {
value string
expected []NetworkAttachmentOpts
}{
{
value: "docknet1",
expected: []NetworkAttachmentOpts{
{
Target: "docknet1",
},
},
},
}
for _, tc := range testCases {
var network NetworkOpt
assert.NoError(t, network.Set(tc.value))
assert.Equal(t, tc.expected, network.Value())
}
}
func TestNetworkOptCompleteSyntax(t *testing.T) {
testCases := []struct {
value string
expected []NetworkAttachmentOpts
}{
{
value: "name=docknet1,alias=web,driver-opt=field1=value1",
expected: []NetworkAttachmentOpts{
{
Target: "docknet1",
Aliases: []string{"web"},
DriverOpts: map[string]string{
"field1": "value1",
},
},
},
},
{
value: "name=docknet1,alias=web1,alias=web2,driver-opt=field1=value1,driver-opt=field2=value2",
expected: []NetworkAttachmentOpts{
{
Target: "docknet1",
Aliases: []string{"web1", "web2"},
DriverOpts: map[string]string{
"field1": "value1",
"field2": "value2",
},
},
},
},
{
value: "name=docknet1",
expected: []NetworkAttachmentOpts{
{
Target: "docknet1",
Aliases: []string{},
},
},
},
}
for _, tc := range testCases {
var network NetworkOpt
assert.NoError(t, network.Set(tc.value))
assert.Equal(t, tc.expected, network.Value())
}
}
func TestNetworkOptInvalidSyntax(t *testing.T) {
testCases := []struct {
value string
expectedError string
}{
{
value: "invalidField=docknet1",
expectedError: "invalid field",
},
{
value: "network=docknet1,invalid=web",
expectedError: "invalid field",
},
{
value: "driver-opt=field1=value1,driver-opt=field2=value2",
expectedError: "network name/id is not specified",
},
}
for _, tc := range testCases {
var network NetworkOpt
testutil.ErrorContains(t, network.Set(tc.value), tc.expectedError)
}
}