-
Notifications
You must be signed in to change notification settings - Fork 18.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from abhinandanpb/master
Adding network specific option in csv format for service create/update
- Loading branch information
Showing
29 changed files
with
767 additions
and
778 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.