mirror of https://github.com/docker/cli.git
moving opts to cli repo
Signed-off-by: Abhinandan Prativadi <abhi@docker.com>
This commit is contained in:
parent
2e07636e5e
commit
0893ab8560
|
@ -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
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue