Signed-off-by: Madhu Venugopal <madhu@docker.com>
| ... | ... |
@@ -9,6 +9,7 @@ import ( |
| 9 | 9 |
|
| 10 | 10 |
"github.com/docker/libnetwork" |
| 11 | 11 |
"github.com/docker/libnetwork/netlabel" |
| 12 |
+ "github.com/docker/libnetwork/netutils" |
|
| 12 | 13 |
"github.com/docker/libnetwork/types" |
| 13 | 14 |
"github.com/gorilla/mux" |
| 14 | 15 |
) |
| ... | ... |
@@ -459,6 +460,7 @@ func procDeleteNetwork(c libnetwork.NetworkController, vars map[string]string, b |
| 459 | 459 |
*******************/ |
| 460 | 460 |
func procJoinEndpoint(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) {
|
| 461 | 461 |
var ej endpointJoin |
| 462 |
+ var setFctList []libnetwork.EndpointOption |
|
| 462 | 463 |
err := json.Unmarshal(body, &ej) |
| 463 | 464 |
if err != nil {
|
| 464 | 465 |
return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest}
|
| ... | ... |
@@ -477,7 +479,15 @@ func procJoinEndpoint(c libnetwork.NetworkController, vars map[string]string, bo |
| 477 | 477 |
return nil, errRsp |
| 478 | 478 |
} |
| 479 | 479 |
|
| 480 |
- err = ep.Join(sb) |
|
| 480 |
+ for _, str := range ej.Aliases {
|
|
| 481 |
+ name, alias, err := netutils.ParseAlias(str) |
|
| 482 |
+ if err != nil {
|
|
| 483 |
+ return "", convertNetworkError(err) |
|
| 484 |
+ } |
|
| 485 |
+ setFctList = append(setFctList, libnetwork.CreateOptionAlias(name, alias)) |
|
| 486 |
+ } |
|
| 487 |
+ |
|
| 488 |
+ err = ep.Join(sb, setFctList...) |
|
| 481 | 489 |
if err != nil {
|
| 482 | 490 |
return nil, convertNetworkError(err) |
| 483 | 491 |
} |
| ... | ... |
@@ -637,6 +647,7 @@ func procUnpublishService(c libnetwork.NetworkController, vars map[string]string |
| 637 | 637 |
|
| 638 | 638 |
func procAttachBackend(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) {
|
| 639 | 639 |
var bk endpointJoin |
| 640 |
+ var setFctList []libnetwork.EndpointOption |
|
| 640 | 641 |
err := json.Unmarshal(body, &bk) |
| 641 | 642 |
if err != nil {
|
| 642 | 643 |
return nil, &responseStatus{Status: "Invalid body: " + err.Error(), StatusCode: http.StatusBadRequest}
|
| ... | ... |
@@ -653,7 +664,15 @@ func procAttachBackend(c libnetwork.NetworkController, vars map[string]string, b |
| 653 | 653 |
return nil, errRsp |
| 654 | 654 |
} |
| 655 | 655 |
|
| 656 |
- err = sv.Join(sb) |
|
| 656 |
+ for _, str := range bk.Aliases {
|
|
| 657 |
+ name, alias, err := netutils.ParseAlias(str) |
|
| 658 |
+ if err != nil {
|
|
| 659 |
+ return "", convertNetworkError(err) |
|
| 660 |
+ } |
|
| 661 |
+ setFctList = append(setFctList, libnetwork.CreateOptionAlias(name, alias)) |
|
| 662 |
+ } |
|
| 663 |
+ |
|
| 664 |
+ err = sv.Join(sb, setFctList...) |
|
| 657 | 665 |
if err != nil {
|
| 658 | 666 |
return nil, convertNetworkError(err) |
| 659 | 667 |
} |
| ... | ... |
@@ -62,7 +62,8 @@ type sandboxCreate struct {
|
| 62 | 62 |
|
| 63 | 63 |
// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages |
| 64 | 64 |
type endpointJoin struct {
|
| 65 |
- SandboxID string `json:"sandbox_id"` |
|
| 65 |
+ SandboxID string `json:"sandbox_id"` |
|
| 66 |
+ Aliases []string `json:"aliases"` |
|
| 66 | 67 |
} |
| 67 | 68 |
|
| 68 | 69 |
// servicePublish represents the body of the "publish service" http request message |
| ... | ... |
@@ -8,8 +8,10 @@ import ( |
| 8 | 8 |
"strings" |
| 9 | 9 |
"text/tabwriter" |
| 10 | 10 |
|
| 11 |
+ "github.com/docker/docker/opts" |
|
| 11 | 12 |
flag "github.com/docker/docker/pkg/mflag" |
| 12 | 13 |
"github.com/docker/docker/pkg/stringid" |
| 14 |
+ "github.com/docker/libnetwork/netutils" |
|
| 13 | 15 |
) |
| 14 | 16 |
|
| 15 | 17 |
var ( |
| ... | ... |
@@ -319,6 +321,8 @@ func (cli *NetworkCli) CmdServiceInfo(chain string, args ...string) error {
|
| 319 | 319 |
// CmdServiceAttach handles service attach UI |
| 320 | 320 |
func (cli *NetworkCli) CmdServiceAttach(chain string, args ...string) error {
|
| 321 | 321 |
cmd := cli.Subcmd(chain, "attach", "CONTAINER SERVICE[.NETWORK]", "Sets a container as a service backend", false) |
| 322 |
+ flAlias := opts.NewListOpts(netutils.ValidateAlias) |
|
| 323 |
+ cmd.Var(&flAlias, []string{"-alias"}, "Add alias for another container")
|
|
| 322 | 324 |
cmd.Require(flag.Min, 2) |
| 323 | 325 |
err := cmd.ParseFlags(args, true) |
| 324 | 326 |
if err != nil {
|
| ... | ... |
@@ -341,7 +345,7 @@ func (cli *NetworkCli) CmdServiceAttach(chain string, args ...string) error {
|
| 341 | 341 |
return err |
| 342 | 342 |
} |
| 343 | 343 |
|
| 344 |
- nc := serviceAttach{SandboxID: sandboxID}
|
|
| 344 |
+ nc := serviceAttach{SandboxID: sandboxID, Aliases: flAlias.GetAll()}
|
|
| 345 | 345 |
|
| 346 | 346 |
_, _, err = readBody(cli.call("POST", "/services/"+serviceID+"/backend", nc, nil))
|
| 347 | 347 |
|
| ... | ... |
@@ -50,7 +50,8 @@ type serviceCreate struct {
|
| 50 | 50 |
|
| 51 | 51 |
// serviceAttach represents the expected body of the "attach/detach sandbox to/from service" http request messages |
| 52 | 52 |
type serviceAttach struct {
|
| 53 |
- SandboxID string `json:"sandbox_id"` |
|
| 53 |
+ SandboxID string `json:"sandbox_id"` |
|
| 54 |
+ Aliases []string `json:"aliases"` |
|
| 54 | 55 |
} |
| 55 | 56 |
|
| 56 | 57 |
// SandboxCreate is the body of the "post /sandboxes" http request message |
| ... | ... |
@@ -169,3 +169,26 @@ func ReverseIP(IP string) string {
|
| 169 | 169 |
|
| 170 | 170 |
return strings.Join(reverseIP, ".") |
| 171 | 171 |
} |
| 172 |
+ |
|
| 173 |
+// ParseAlias parses and validates the specified string as a alias format (name:alias) |
|
| 174 |
+func ParseAlias(val string) (string, string, error) {
|
|
| 175 |
+ if val == "" {
|
|
| 176 |
+ return "", "", fmt.Errorf("empty string specified for alias")
|
|
| 177 |
+ } |
|
| 178 |
+ arr := strings.Split(val, ":") |
|
| 179 |
+ if len(arr) > 2 {
|
|
| 180 |
+ return "", "", fmt.Errorf("bad format for alias: %s", val)
|
|
| 181 |
+ } |
|
| 182 |
+ if len(arr) == 1 {
|
|
| 183 |
+ return val, val, nil |
|
| 184 |
+ } |
|
| 185 |
+ return arr[0], arr[1], nil |
|
| 186 |
+} |
|
| 187 |
+ |
|
| 188 |
+// ValidateAlias validates that the specified string has a valid alias format (containerName:alias). |
|
| 189 |
+func ValidateAlias(val string) (string, error) {
|
|
| 190 |
+ if _, _, err := ParseAlias(val); err != nil {
|
|
| 191 |
+ return val, err |
|
| 192 |
+ } |
|
| 193 |
+ return val, nil |
|
| 194 |
+} |
| ... | ... |
@@ -233,3 +233,19 @@ function test_single_network_connectivity() {
|
| 233 | 233 |
done |
| 234 | 234 |
|
| 235 | 235 |
} |
| 236 |
+ |
|
| 237 |
+@test "Test bridge network alias support" {
|
|
| 238 |
+ skip_for_circleci |
|
| 239 |
+ dnet_cmd $(inst_id2port 1) network create -d bridge br1 |
|
| 240 |
+ dnet_cmd $(inst_id2port 1) container create container_1 |
|
| 241 |
+ net_connect 1 container_1 br1 container_2:c2 |
|
| 242 |
+ dnet_cmd $(inst_id2port 1) container create container_2 |
|
| 243 |
+ net_connect 1 container_2 br1 |
|
| 244 |
+ runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 container_2" |
|
| 245 |
+ runc $(dnet_container_name 1 bridge) $(get_sbox_id 1 container_1) "ping -c 1 c2" |
|
| 246 |
+ net_disconnect 1 container_1 br1 |
|
| 247 |
+ net_disconnect 1 container_2 br1 |
|
| 248 |
+ dnet_cmd $(inst_id2port 1) container rm container_1 |
|
| 249 |
+ dnet_cmd $(inst_id2port 1) container rm container_2 |
|
| 250 |
+ dnet_cmd $(inst_id2port 1) network rm br1 |
|
| 251 |
+} |
| ... | ... |
@@ -18,8 +18,12 @@ function get_sbox_id() {
|
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 | 20 |
function net_connect() {
|
| 21 |
+ local al |
|
| 22 |
+ if [ -n "$4" ]; then |
|
| 23 |
+ al="--alias=${4}"
|
|
| 24 |
+ fi |
|
| 21 | 25 |
dnet_cmd $(inst_id2port ${1}) service publish ${2}.${3}
|
| 22 |
- dnet_cmd $(inst_id2port ${1}) service attach ${2} ${2}.${3}
|
|
| 26 |
+ dnet_cmd $(inst_id2port ${1}) service attach $al ${2} ${2}.${3}
|
|
| 23 | 27 |
} |
| 24 | 28 |
|
| 25 | 29 |
function net_disconnect() {
|