- To the same level of Network cli
and to make use of the new service
rest apis
Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -96,6 +96,7 @@ func (h *httpHandler) initRouter() {
|
| 96 | 96 |
{"/services", []string{"partial-id", epPID}, procGetServices},
|
| 97 | 97 |
{"/services", nil, procGetServices},
|
| 98 | 98 |
{"/services/" + epID, nil, procGetService},
|
| 99 |
+ {"/services/" + epID + "/backend", nil, procGetContainers},
|
|
| 99 | 100 |
}, |
| 100 | 101 |
"POST": {
|
| 101 | 102 |
{"/networks", nil, procCreateNetwork},
|
| ... | ... |
@@ -184,6 +185,14 @@ func buildEndpointResource(ep libnetwork.Endpoint) *endpointResource {
|
| 184 | 184 |
return r |
| 185 | 185 |
} |
| 186 | 186 |
|
| 187 |
+func buildContainerResource(ci libnetwork.ContainerInfo) *containerResource {
|
|
| 188 |
+ r := &containerResource{}
|
|
| 189 |
+ if ci != nil {
|
|
| 190 |
+ r.ID = ci.ID() |
|
| 191 |
+ } |
|
| 192 |
+ return r |
|
| 193 |
+} |
|
| 194 |
+ |
|
| 187 | 195 |
/**************** |
| 188 | 196 |
Options Parsers |
| 189 | 197 |
*****************/ |
| ... | ... |
@@ -527,6 +536,19 @@ func procGetService(c libnetwork.NetworkController, vars map[string]string, body |
| 527 | 527 |
return buildEndpointResource(sv), &successResponse |
| 528 | 528 |
} |
| 529 | 529 |
|
| 530 |
+func procGetContainers(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) {
|
|
| 531 |
+ epT, epBy := detectEndpointTarget(vars) |
|
| 532 |
+ sv, errRsp := findService(c, epT, epBy) |
|
| 533 |
+ if !errRsp.isOK() {
|
|
| 534 |
+ return nil, endpointToService(errRsp) |
|
| 535 |
+ } |
|
| 536 |
+ var list []*containerResource |
|
| 537 |
+ if sv.ContainerInfo() != nil {
|
|
| 538 |
+ list = append(list, buildContainerResource(sv.ContainerInfo())) |
|
| 539 |
+ } |
|
| 540 |
+ return list, &successResponse |
|
| 541 |
+} |
|
| 542 |
+ |
|
| 530 | 543 |
func procPublishService(c libnetwork.NetworkController, vars map[string]string, body []byte) (interface{}, *responseStatus) {
|
| 531 | 544 |
var sp servicePublish |
| 532 | 545 |
|
| ... | ... |
@@ -70,6 +70,14 @@ func i2nL(i interface{}) []*networkResource {
|
| 70 | 70 |
return s |
| 71 | 71 |
} |
| 72 | 72 |
|
| 73 |
+func i2cL(i interface{}) []*containerResource {
|
|
| 74 |
+ s, ok := i.([]*containerResource) |
|
| 75 |
+ if !ok {
|
|
| 76 |
+ panic(fmt.Sprintf("Failed i2cL for %v", i))
|
|
| 77 |
+ } |
|
| 78 |
+ return s |
|
| 79 |
+} |
|
| 80 |
+ |
|
| 73 | 81 |
func createTestNetwork(t *testing.T, network string) (libnetwork.NetworkController, libnetwork.Network) {
|
| 74 | 82 |
c, err := libnetwork.New("")
|
| 75 | 83 |
if err != nil {
|
| ... | ... |
@@ -904,6 +912,14 @@ func TestAttachDetachBackend(t *testing.T) {
|
| 904 | 904 |
t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
|
| 905 | 905 |
} |
| 906 | 906 |
|
| 907 |
+ _, errRsp = procGetContainers(c, vars, nil) |
|
| 908 |
+ if errRsp.isOK() {
|
|
| 909 |
+ t.Fatalf("Expected failure. Got %v", errRsp)
|
|
| 910 |
+ } |
|
| 911 |
+ if errRsp.StatusCode != http.StatusNotFound {
|
|
| 912 |
+ t.Fatalf("Expected %d. Got: %v", http.StatusNotFound, errRsp)
|
|
| 913 |
+ } |
|
| 914 |
+ |
|
| 907 | 915 |
vars[urlEpName] = "db" |
| 908 | 916 |
_, errRsp = procAttachBackend(c, vars, bad) |
| 909 | 917 |
if errRsp == &successResponse {
|
| ... | ... |
@@ -925,6 +941,26 @@ func TestAttachDetachBackend(t *testing.T) {
|
| 925 | 925 |
t.Fatalf("Unexpected failure, got: %v", errRsp)
|
| 926 | 926 |
} |
| 927 | 927 |
|
| 928 |
+ cli, errRsp := procGetContainers(c, vars, nil) |
|
| 929 |
+ if errRsp != &successResponse {
|
|
| 930 |
+ t.Fatalf("Unexpected failure, got: %v", errRsp)
|
|
| 931 |
+ } |
|
| 932 |
+ cl := i2cL(cli) |
|
| 933 |
+ if len(cl) != 1 {
|
|
| 934 |
+ t.Fatalf("Did not find expected number of containers attached to the service: %d", len(cl))
|
|
| 935 |
+ } |
|
| 936 |
+ if cl[0].ID != cid {
|
|
| 937 |
+ t.Fatalf("Did not find expected container attached to the service: %v", cl[0])
|
|
| 938 |
+ } |
|
| 939 |
+ |
|
| 940 |
+ _, errRsp = procUnpublishService(c, vars, nil) |
|
| 941 |
+ if errRsp.isOK() {
|
|
| 942 |
+ t.Fatalf("Expected failure but succeeded")
|
|
| 943 |
+ } |
|
| 944 |
+ if errRsp.StatusCode != http.StatusForbidden {
|
|
| 945 |
+ t.Fatalf("Expected %d. Got: %v", http.StatusForbidden, errRsp)
|
|
| 946 |
+ } |
|
| 947 |
+ |
|
| 928 | 948 |
vars[urlEpName] = "endpoint" |
| 929 | 949 |
_, errRsp = procDetachBackend(c, vars, nil) |
| 930 | 950 |
if errRsp == &successResponse {
|
| ... | ... |
@@ -949,6 +985,15 @@ func TestAttachDetachBackend(t *testing.T) {
|
| 949 | 949 |
t.Fatalf("Unexpected failure, got: %v", errRsp)
|
| 950 | 950 |
} |
| 951 | 951 |
|
| 952 |
+ cli, errRsp = procGetContainers(c, vars, nil) |
|
| 953 |
+ if errRsp != &successResponse {
|
|
| 954 |
+ t.Fatalf("Unexpected failure, got: %v", errRsp)
|
|
| 955 |
+ } |
|
| 956 |
+ cl = i2cL(cli) |
|
| 957 |
+ if len(cl) != 0 {
|
|
| 958 |
+ t.Fatalf("Did not find expected number of containers attached to the service: %d", len(cl))
|
|
| 959 |
+ } |
|
| 960 |
+ |
|
| 952 | 961 |
err = ep1.Delete() |
| 953 | 962 |
if err != nil {
|
| 954 | 963 |
t.Fatal(err) |
| ... | ... |
@@ -21,6 +21,12 @@ type endpointResource struct {
|
| 21 | 21 |
Network string `json:"network"` |
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 |
+// containerResource is the body of "get service backend" response message |
|
| 25 |
+type containerResource struct {
|
|
| 26 |
+ ID string `json:"id"` |
|
| 27 |
+ // will add more fields once labels change is in |
|
| 28 |
+} |
|
| 29 |
+ |
|
| 24 | 30 |
/*********** |
| 25 | 31 |
Body types |
| 26 | 32 |
************/ |
| ... | ... |
@@ -55,7 +61,7 @@ type endpointJoin struct {
|
| 55 | 55 |
// servicePublish represents the body of the "publish service" http request message |
| 56 | 56 |
type servicePublish struct {
|
| 57 | 57 |
Name string `json:"name"` |
| 58 |
- Network string `json:"network"` |
|
| 58 |
+ Network string `json:"network_name"` |
|
| 59 | 59 |
ExposedPorts []types.TransportPort `json:"exposed_ports"` |
| 60 | 60 |
PortMapping []types.PortBinding `json:"port_mapping"` |
| 61 | 61 |
} |
| ... | ... |
@@ -7,7 +7,7 @@ import ( |
| 7 | 7 |
_ "github.com/docker/libnetwork/netutils" |
| 8 | 8 |
) |
| 9 | 9 |
|
| 10 |
-func TestClientNetworkServiceInvalidCommand(t *testing.T) {
|
|
| 10 |
+func TestClientServiceInvalidCommand(t *testing.T) {
|
|
| 11 | 11 |
var out, errOut bytes.Buffer |
| 12 | 12 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 13 | 13 |
|
| ... | ... |
@@ -17,73 +17,73 @@ func TestClientNetworkServiceInvalidCommand(t *testing.T) {
|
| 17 | 17 |
} |
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 |
-func TestClientNetworkServiceCreate(t *testing.T) {
|
|
| 20 |
+func TestClientServiceCreate(t *testing.T) {
|
|
| 21 | 21 |
var out, errOut bytes.Buffer |
| 22 | 22 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 23 | 23 |
|
| 24 |
- err := cli.Cmd("docker", "service", "create", mockServiceName, mockNwName)
|
|
| 24 |
+ err := cli.Cmd("docker", "service", "publish", "-net="+mockNwName, mockServiceName)
|
|
| 25 | 25 |
if err != nil {
|
| 26 |
- t.Fatal(err.Error()) |
|
| 26 |
+ t.Fatal(err) |
|
| 27 | 27 |
} |
| 28 | 28 |
} |
| 29 | 29 |
|
| 30 |
-func TestClientNetworkServiceRm(t *testing.T) {
|
|
| 30 |
+func TestClientServiceRm(t *testing.T) {
|
|
| 31 | 31 |
var out, errOut bytes.Buffer |
| 32 | 32 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 33 | 33 |
|
| 34 |
- err := cli.Cmd("docker", "service", "rm", mockServiceName, mockNwName)
|
|
| 34 |
+ err := cli.Cmd("docker", "service", "unpublish", "-net="+mockNwName, mockServiceName)
|
|
| 35 | 35 |
if err != nil {
|
| 36 |
- t.Fatal(err.Error()) |
|
| 36 |
+ t.Fatal(err) |
|
| 37 | 37 |
} |
| 38 | 38 |
} |
| 39 | 39 |
|
| 40 |
-func TestClientNetworkServiceLs(t *testing.T) {
|
|
| 40 |
+func TestClientServiceLs(t *testing.T) {
|
|
| 41 | 41 |
var out, errOut bytes.Buffer |
| 42 | 42 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 43 | 43 |
|
| 44 |
- err := cli.Cmd("docker", "service", "ls", mockNwName)
|
|
| 44 |
+ err := cli.Cmd("docker", "service", "ls")
|
|
| 45 | 45 |
if err != nil {
|
| 46 |
- t.Fatal(err.Error()) |
|
| 46 |
+ t.Fatal(err) |
|
| 47 | 47 |
} |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
-func TestClientNetworkServiceInfo(t *testing.T) {
|
|
| 50 |
+func TestClientServiceInfo(t *testing.T) {
|
|
| 51 | 51 |
var out, errOut bytes.Buffer |
| 52 | 52 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 53 | 53 |
|
| 54 |
- err := cli.Cmd("docker", "service", "info", mockServiceName, mockNwName)
|
|
| 54 |
+ err := cli.Cmd("docker", "service", "info", "-net="+mockNwName, mockServiceName)
|
|
| 55 | 55 |
if err != nil {
|
| 56 |
- t.Fatal(err.Error()) |
|
| 56 |
+ t.Fatal(err) |
|
| 57 | 57 |
} |
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 |
-func TestClientNetworkServiceInfoById(t *testing.T) {
|
|
| 60 |
+func TestClientServiceInfoById(t *testing.T) {
|
|
| 61 | 61 |
var out, errOut bytes.Buffer |
| 62 | 62 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 63 | 63 |
|
| 64 |
- err := cli.Cmd("docker", "service", "info", mockServiceID, mockNwID)
|
|
| 64 |
+ err := cli.Cmd("docker", "service", "info", "-net="+mockNwName, mockServiceID)
|
|
| 65 | 65 |
if err != nil {
|
| 66 |
- t.Fatal(err.Error()) |
|
| 66 |
+ t.Fatal(err) |
|
| 67 | 67 |
} |
| 68 | 68 |
} |
| 69 | 69 |
|
| 70 |
-func TestClientNetworkServiceJoin(t *testing.T) {
|
|
| 70 |
+func TestClientServiceJoin(t *testing.T) {
|
|
| 71 | 71 |
var out, errOut bytes.Buffer |
| 72 | 72 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 73 | 73 |
|
| 74 |
- err := cli.Cmd("docker", "service", "join", mockContainerID, mockServiceName, mockNwName)
|
|
| 74 |
+ err := cli.Cmd("docker", "service", "attach", "-net="+mockNwName, mockContainerID, mockServiceName)
|
|
| 75 | 75 |
if err != nil {
|
| 76 |
- t.Fatal(err.Error()) |
|
| 76 |
+ t.Fatal(err) |
|
| 77 | 77 |
} |
| 78 | 78 |
} |
| 79 | 79 |
|
| 80 |
-func TestClientNetworkServiceLeave(t *testing.T) {
|
|
| 80 |
+func TestClientServiceLeave(t *testing.T) {
|
|
| 81 | 81 |
var out, errOut bytes.Buffer |
| 82 | 82 |
cli := NewNetworkCli(&out, &errOut, callbackFunc) |
| 83 | 83 |
|
| 84 |
- err := cli.Cmd("docker", "service", "leave", mockContainerID, mockServiceName, mockNwName)
|
|
| 84 |
+ err := cli.Cmd("docker", "service", "detach", "-net="+mockNwName, mockContainerID, mockServiceName)
|
|
| 85 | 85 |
if err != nil {
|
| 86 |
- t.Fatal(err.Error()) |
|
| 86 |
+ t.Fatal(err) |
|
| 87 | 87 |
} |
| 88 | 88 |
} |
| 89 | 89 |
|
| ... | ... |
@@ -39,8 +39,8 @@ func setupMockHTTPCallback() {
|
| 39 | 39 |
list = append(list, nw) |
| 40 | 40 |
mockNwListJSON, _ = json.Marshal(list) |
| 41 | 41 |
|
| 42 |
- var srvList []endpointResource |
|
| 43 |
- ep := endpointResource{Name: mockServiceName, ID: mockServiceID, Network: mockNwName}
|
|
| 42 |
+ var srvList []serviceResource |
|
| 43 |
+ ep := serviceResource{Name: mockServiceName, ID: mockServiceID, Network: mockNwName}
|
|
| 44 | 44 |
mockServiceJSON, _ = json.Marshal(ep) |
| 45 | 45 |
srvList = append(srvList, ep) |
| 46 | 46 |
mockServiceListJSON, _ = json.Marshal(srvList) |
| ... | ... |
@@ -61,26 +61,26 @@ func setupMockHTTPCallback() {
|
| 61 | 61 |
rsp = string(mockNwListJSON) |
| 62 | 62 |
} else if strings.HasSuffix(path, "networks/"+mockNwID) {
|
| 63 | 63 |
rsp = string(mockNwJSON) |
| 64 |
- } else if strings.Contains(path, fmt.Sprintf("endpoints?name=%s", mockServiceName)) {
|
|
| 64 |
+ } else if strings.Contains(path, fmt.Sprintf("services?name=%s", mockServiceName)) {
|
|
| 65 | 65 |
rsp = string(mockServiceListJSON) |
| 66 |
- } else if strings.Contains(path, "endpoints?name=") {
|
|
| 66 |
+ } else if strings.Contains(path, "services?name=") {
|
|
| 67 | 67 |
rsp = "[]" |
| 68 |
- } else if strings.Contains(path, fmt.Sprintf("endpoints?partial-id=%s", mockServiceID)) {
|
|
| 68 |
+ } else if strings.Contains(path, fmt.Sprintf("services?partial-id=%s", mockServiceID)) {
|
|
| 69 | 69 |
rsp = string(mockServiceListJSON) |
| 70 |
- } else if strings.Contains(path, "endpoints?partial-id=") {
|
|
| 70 |
+ } else if strings.Contains(path, "services?partial-id=") {
|
|
| 71 | 71 |
rsp = "[]" |
| 72 |
- } else if strings.HasSuffix(path, "endpoints") {
|
|
| 72 |
+ } else if strings.HasSuffix(path, "services") {
|
|
| 73 | 73 |
rsp = string(mockServiceListJSON) |
| 74 |
- } else if strings.HasSuffix(path, "endpoints/"+mockServiceID) {
|
|
| 74 |
+ } else if strings.HasSuffix(path, "services/"+mockServiceID) {
|
|
| 75 | 75 |
rsp = string(mockServiceJSON) |
| 76 | 76 |
} |
| 77 | 77 |
case "POST": |
| 78 | 78 |
var data []byte |
| 79 | 79 |
if strings.HasSuffix(path, "networks") {
|
| 80 | 80 |
data, _ = json.Marshal(mockNwID) |
| 81 |
- } else if strings.HasSuffix(path, "endpoints") {
|
|
| 81 |
+ } else if strings.HasSuffix(path, "services") {
|
|
| 82 | 82 |
data, _ = json.Marshal(mockServiceID) |
| 83 |
- } else if strings.HasSuffix(path, "containers") {
|
|
| 83 |
+ } else if strings.HasSuffix(path, "backend") {
|
|
| 84 | 84 |
data, _ = json.Marshal(mockContainerID) |
| 85 | 85 |
} |
| 86 | 86 |
rsp = string(data) |
| ... | ... |
@@ -177,10 +177,10 @@ func (cli *NetworkCli) CmdNetworkInfo(chain string, args ...string) error {
|
| 177 | 177 |
fmt.Fprintf(cli.out, "Network Id: %s\n", networkResource.ID) |
| 178 | 178 |
fmt.Fprintf(cli.out, "Name: %s\n", networkResource.Name) |
| 179 | 179 |
fmt.Fprintf(cli.out, "Type: %s\n", networkResource.Type) |
| 180 |
- if networkResource.Endpoints != nil {
|
|
| 181 |
- for _, endpointResource := range networkResource.Endpoints {
|
|
| 182 |
- fmt.Fprintf(cli.out, " Service Id: %s\n", endpointResource.ID) |
|
| 183 |
- fmt.Fprintf(cli.out, "\tName: %s\n", endpointResource.Name) |
|
| 180 |
+ if networkResource.Services != nil {
|
|
| 181 |
+ for _, serviceResource := range networkResource.Services {
|
|
| 182 |
+ fmt.Fprintf(cli.out, " Service Id: %s\n", serviceResource.ID) |
|
| 183 |
+ fmt.Fprintf(cli.out, "\tName: %s\n", serviceResource.Name) |
|
| 184 | 184 |
} |
| 185 | 185 |
} |
| 186 | 186 |
|
| ... | ... |
@@ -13,64 +13,77 @@ import ( |
| 13 | 13 |
|
| 14 | 14 |
var ( |
| 15 | 15 |
serviceCommands = []command{
|
| 16 |
- {"create", "Create a service endpoint"},
|
|
| 17 |
- {"rm", "Remove a service endpoint"},
|
|
| 18 |
- {"join", "Join a container to a service endpoint"},
|
|
| 19 |
- {"leave", "Leave a container from a service endpoint"},
|
|
| 20 |
- {"ls", "Lists all service endpoints on a network"},
|
|
| 21 |
- {"info", "Display information of a service endpoint"},
|
|
| 16 |
+ {"publish", "Publish a service"},
|
|
| 17 |
+ {"unpublish", "Remove a service"},
|
|
| 18 |
+ {"attach", "Attach a provider (container) to the service"},
|
|
| 19 |
+ {"detach", "Detach the provider from the service"},
|
|
| 20 |
+ {"ls", "Lists all services"},
|
|
| 21 |
+ {"info", "Display information about a service"},
|
|
| 22 | 22 |
} |
| 23 | 23 |
) |
| 24 | 24 |
|
| 25 |
-func lookupServiceID(cli *NetworkCli, networkID string, nameID string) (string, error) {
|
|
| 26 |
- obj, statusCode, err := readBody(cli.call("GET", fmt.Sprintf("/networks/%s/endpoints?name=%s", networkID, nameID), nil, nil))
|
|
| 25 |
+func lookupServiceID(cli *NetworkCli, nwName, svNameID string) (string, error) {
|
|
| 26 |
+ // Sanity Check |
|
| 27 |
+ obj, _, err := readBody(cli.call("GET", fmt.Sprintf("/networks?name=%s", nwName), nil, nil))
|
|
| 28 |
+ if err != nil {
|
|
| 29 |
+ return "", err |
|
| 30 |
+ } |
|
| 31 |
+ var nwList []networkResource |
|
| 32 |
+ if err = json.Unmarshal(obj, &nwList); err != nil {
|
|
| 33 |
+ return "", err |
|
| 34 |
+ } |
|
| 35 |
+ if len(nwList) == 0 {
|
|
| 36 |
+ return "", fmt.Errorf("Network %s does not exist", nwName)
|
|
| 37 |
+ } |
|
| 38 |
+ |
|
| 39 |
+ // Query service by name |
|
| 40 |
+ obj, statusCode, err := readBody(cli.call("GET", fmt.Sprintf("/services?name=%s", svNameID), nil, nil))
|
|
| 27 | 41 |
if err != nil {
|
| 28 | 42 |
return "", err |
| 29 | 43 |
} |
| 30 | 44 |
|
| 31 | 45 |
if statusCode != http.StatusOK {
|
| 32 |
- return "", fmt.Errorf("name query failed for %s due to : statuscode(%d) %v", nameID, statusCode, string(obj))
|
|
| 46 |
+ return "", fmt.Errorf("name query failed for %s due to: (%d) %s", svNameID, statusCode, string(obj))
|
|
| 33 | 47 |
} |
| 34 | 48 |
|
| 35 |
- var list []*networkResource |
|
| 36 |
- err = json.Unmarshal(obj, &list) |
|
| 37 |
- if err != nil {
|
|
| 49 |
+ var list []*serviceResource |
|
| 50 |
+ if err = json.Unmarshal(obj, &list); err != nil {
|
|
| 38 | 51 |
return "", err |
| 39 | 52 |
} |
| 40 |
- if len(list) > 0 {
|
|
| 41 |
- // name query filter will always return a single-element collection |
|
| 42 |
- return list[0].ID, nil |
|
| 53 |
+ for _, sr := range list {
|
|
| 54 |
+ if sr.Network == nwName {
|
|
| 55 |
+ return sr.ID, nil |
|
| 56 |
+ } |
|
| 43 | 57 |
} |
| 44 | 58 |
|
| 45 |
- // Check for Partial-id |
|
| 46 |
- obj, statusCode, err = readBody(cli.call("GET", fmt.Sprintf("/networks/%s/endpoints?partial-id=%s", networkID, nameID), nil, nil))
|
|
| 59 |
+ // Query service by Partial-id (this covers full id as well) |
|
| 60 |
+ obj, statusCode, err = readBody(cli.call("GET", fmt.Sprintf("/services?partial-id=%s", svNameID), nil, nil))
|
|
| 47 | 61 |
if err != nil {
|
| 48 | 62 |
return "", err |
| 49 | 63 |
} |
| 50 | 64 |
|
| 51 | 65 |
if statusCode != http.StatusOK {
|
| 52 |
- return "", fmt.Errorf("partial-id match query failed for %s due to : statuscode(%d) %v", nameID, statusCode, string(obj))
|
|
| 66 |
+ return "", fmt.Errorf("partial-id match query failed for %s due to: (%d) %s", svNameID, statusCode, string(obj))
|
|
| 53 | 67 |
} |
| 54 | 68 |
|
| 55 |
- err = json.Unmarshal(obj, &list) |
|
| 56 |
- if err != nil {
|
|
| 69 |
+ if err = json.Unmarshal(obj, &list); err != nil {
|
|
| 57 | 70 |
return "", err |
| 58 | 71 |
} |
| 59 |
- if len(list) == 0 {
|
|
| 60 |
- return "", fmt.Errorf("resource not found %s", nameID)
|
|
| 61 |
- } |
|
| 62 |
- if len(list) > 1 {
|
|
| 63 |
- return "", fmt.Errorf("multiple services matching the partial identifier (%s). Please use full identifier", nameID)
|
|
| 72 |
+ for _, sr := range list {
|
|
| 73 |
+ if sr.Network == nwName {
|
|
| 74 |
+ return sr.ID, nil |
|
| 75 |
+ } |
|
| 64 | 76 |
} |
| 65 |
- return list[0].ID, nil |
|
| 77 |
+ |
|
| 78 |
+ return "", fmt.Errorf("Service %s not found on network %s", svNameID, nwName)
|
|
| 66 | 79 |
} |
| 67 | 80 |
|
| 68 |
-func lookupContainerID(cli *NetworkCli, nameID string) (string, error) {
|
|
| 81 |
+func lookupContainerID(cli *NetworkCli, cnNameID string) (string, error) {
|
|
| 69 | 82 |
// TODO : containerID to sandbox-key ? |
| 70 |
- return nameID, nil |
|
| 83 |
+ return cnNameID, nil |
|
| 71 | 84 |
} |
| 72 | 85 |
|
| 73 |
-// CmdService handles the network service UI |
|
| 86 |
+// CmdService handles the service UI |
|
| 74 | 87 |
func (cli *NetworkCli) CmdService(chain string, args ...string) error {
|
| 75 | 88 |
cmd := cli.Subcmd(chain, "service", "COMMAND [OPTIONS] [arg...]", serviceUsage(chain), false) |
| 76 | 89 |
cmd.Require(flag.Min, 1) |
| ... | ... |
@@ -82,23 +95,25 @@ func (cli *NetworkCli) CmdService(chain string, args ...string) error {
|
| 82 | 82 |
return err |
| 83 | 83 |
} |
| 84 | 84 |
|
| 85 |
-// CmdServiceCreate handles service create UI |
|
| 86 |
-func (cli *NetworkCli) CmdServiceCreate(chain string, args ...string) error {
|
|
| 87 |
- cmd := cli.Subcmd(chain, "create", "SERVICE NETWORK", "Creates a new service on a network", false) |
|
| 88 |
- cmd.Require(flag.Min, 2) |
|
| 85 |
+// CmdServicePublish handles service create UI |
|
| 86 |
+func (cli *NetworkCli) CmdServicePublish(chain string, args ...string) error {
|
|
| 87 |
+ cmd := cli.Subcmd(chain, "publish", "SERVICE", "Publish a new service on a network", false) |
|
| 88 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Network where to publish the service")
|
|
| 89 |
+ cmd.Require(flag.Min, 1) |
|
| 90 |
+ |
|
| 89 | 91 |
err := cmd.ParseFlags(args, true) |
| 90 | 92 |
if err != nil {
|
| 91 | 93 |
return err |
| 92 | 94 |
} |
| 93 | 95 |
|
| 94 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(1)) |
|
| 95 |
- if err != nil {
|
|
| 96 |
- return err |
|
| 96 |
+ // Default network changes will come later |
|
| 97 |
+ nw := "docker0" |
|
| 98 |
+ if *flNetwork != "" {
|
|
| 99 |
+ nw = *flNetwork |
|
| 97 | 100 |
} |
| 98 | 101 |
|
| 99 |
- ec := endpointCreate{Name: cmd.Arg(0), NetworkID: networkID}
|
|
| 100 |
- |
|
| 101 |
- obj, _, err := readBody(cli.call("POST", "/networks/"+networkID+"/endpoints", ec, nil))
|
|
| 102 |
+ sc := serviceCreate{Name: cmd.Arg(0), Network: nw}
|
|
| 103 |
+ obj, _, err := readBody(cli.call("POST", "/services", sc, nil))
|
|
| 102 | 104 |
if err != nil {
|
| 103 | 105 |
return err |
| 104 | 106 |
} |
| ... | ... |
@@ -113,39 +128,40 @@ func (cli *NetworkCli) CmdServiceCreate(chain string, args ...string) error {
|
| 113 | 113 |
return nil |
| 114 | 114 |
} |
| 115 | 115 |
|
| 116 |
-// CmdServiceRm handles service delete UI |
|
| 117 |
-func (cli *NetworkCli) CmdServiceRm(chain string, args ...string) error {
|
|
| 118 |
- cmd := cli.Subcmd(chain, "rm", "SERVICE NETWORK", "Deletes a service", false) |
|
| 119 |
- cmd.Require(flag.Min, 2) |
|
| 116 |
+// CmdServiceUnpublish handles service delete UI |
|
| 117 |
+func (cli *NetworkCli) CmdServiceUnpublish(chain string, args ...string) error {
|
|
| 118 |
+ cmd := cli.Subcmd(chain, "unpublish", "SERVICE", "Removes a service", false) |
|
| 119 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Network where to publish the service")
|
|
| 120 |
+ cmd.Require(flag.Min, 1) |
|
| 121 |
+ |
|
| 120 | 122 |
err := cmd.ParseFlags(args, true) |
| 121 | 123 |
if err != nil {
|
| 122 | 124 |
return err |
| 123 | 125 |
} |
| 124 | 126 |
|
| 125 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(1)) |
|
| 126 |
- if err != nil {
|
|
| 127 |
- return err |
|
| 127 |
+ // Default network changes will come later |
|
| 128 |
+ nw := "docker0" |
|
| 129 |
+ if *flNetwork != "" {
|
|
| 130 |
+ nw = *flNetwork |
|
| 128 | 131 |
} |
| 129 | 132 |
|
| 130 |
- serviceID, err := lookupServiceID(cli, networkID, cmd.Arg(0)) |
|
| 133 |
+ serviceID, err := lookupServiceID(cli, nw, cmd.Arg(0)) |
|
| 131 | 134 |
if err != nil {
|
| 132 | 135 |
return err |
| 133 | 136 |
} |
| 134 | 137 |
|
| 135 |
- _, _, err = readBody(cli.call("DELETE", "/networks/"+networkID+"/endpoints/"+serviceID, nil, nil))
|
|
| 136 |
- if err != nil {
|
|
| 137 |
- return err |
|
| 138 |
- } |
|
| 139 |
- return nil |
|
| 138 |
+ _, _, err = readBody(cli.call("DELETE", "/services/"+serviceID, nil, nil))
|
|
| 139 |
+ |
|
| 140 |
+ return err |
|
| 140 | 141 |
} |
| 141 | 142 |
|
| 142 | 143 |
// CmdServiceLs handles service list UI |
| 143 | 144 |
func (cli *NetworkCli) CmdServiceLs(chain string, args ...string) error {
|
| 144 |
- cmd := cli.Subcmd(chain, "ls", "NETWORK", "Lists all the services on a network", false) |
|
| 145 |
+ cmd := cli.Subcmd(chain, "ls", "SERVICE", "Lists all the services on a network", false) |
|
| 146 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Only show the services that are published on the specified network")
|
|
| 145 | 147 |
quiet := cmd.Bool([]string{"q", "-quiet"}, false, "Only display numeric IDs")
|
| 146 | 148 |
noTrunc := cmd.Bool([]string{"#notrunc", "-no-trunc"}, false, "Do not truncate the output")
|
| 147 |
- nLatest := cmd.Bool([]string{"l", "-latest"}, false, "Show the latest network created")
|
|
| 148 |
- last := cmd.Int([]string{"n"}, -1, "Show n last created networks")
|
|
| 149 |
+ |
|
| 149 | 150 |
err := cmd.ParseFlags(args, true) |
| 150 | 151 |
if err != nil {
|
| 151 | 152 |
return err |
| ... | ... |
@@ -153,151 +169,174 @@ func (cli *NetworkCli) CmdServiceLs(chain string, args ...string) error {
|
| 153 | 153 |
|
| 154 | 154 |
cmd.Require(flag.Min, 1) |
| 155 | 155 |
|
| 156 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(0)) |
|
| 157 |
- if err != nil {
|
|
| 158 |
- return err |
|
| 156 |
+ var obj []byte |
|
| 157 |
+ if *flNetwork == "" {
|
|
| 158 |
+ obj, _, err = readBody(cli.call("GET", "/services", nil, nil))
|
|
| 159 |
+ } else {
|
|
| 160 |
+ obj, _, err = readBody(cli.call("GET", "/services?network="+*flNetwork, nil, nil))
|
|
| 159 | 161 |
} |
| 160 |
- |
|
| 161 |
- obj, _, err := readBody(cli.call("GET", "/networks/"+networkID+"/endpoints", nil, nil))
|
|
| 162 | 162 |
if err != nil {
|
| 163 |
- fmt.Fprintf(cli.err, "%s", err.Error()) |
|
| 164 | 163 |
return err |
| 165 | 164 |
} |
| 166 |
- if *last == -1 && *nLatest {
|
|
| 167 |
- *last = 1 |
|
| 168 |
- } |
|
| 169 | 165 |
|
| 170 |
- var endpointResources []endpointResource |
|
| 171 |
- err = json.Unmarshal(obj, &endpointResources) |
|
| 166 |
+ var serviceResources []serviceResource |
|
| 167 |
+ err = json.Unmarshal(obj, &serviceResources) |
|
| 172 | 168 |
if err != nil {
|
| 169 |
+ fmt.Println(err) |
|
| 173 | 170 |
return err |
| 174 | 171 |
} |
| 175 | 172 |
|
| 176 | 173 |
wr := tabwriter.NewWriter(cli.out, 20, 1, 3, ' ', 0) |
| 177 | 174 |
// unless quiet (-q) is specified, print field titles |
| 178 | 175 |
if !*quiet {
|
| 179 |
- fmt.Fprintln(wr, "NETWORK SERVICE ID\tNAME\tNETWORK") |
|
| 176 |
+ fmt.Fprintln(wr, "SERVICE ID\tNAME\tNETWORK\tPROVIDER") |
|
| 180 | 177 |
} |
| 181 | 178 |
|
| 182 |
- for _, networkResource := range endpointResources {
|
|
| 183 |
- ID := networkResource.ID |
|
| 184 |
- netName := networkResource.Name |
|
| 179 |
+ for _, sr := range serviceResources {
|
|
| 180 |
+ ID := sr.ID |
|
| 181 |
+ bkID, err := getBackendID(cli, ID) |
|
| 182 |
+ if err != nil {
|
|
| 183 |
+ return err |
|
| 184 |
+ } |
|
| 185 | 185 |
if !*noTrunc {
|
| 186 | 186 |
ID = stringid.TruncateID(ID) |
| 187 |
+ bkID = stringid.TruncateID(bkID) |
|
| 187 | 188 |
} |
| 188 |
- if *quiet {
|
|
| 189 |
+ if !*quiet {
|
|
| 190 |
+ fmt.Fprintf(wr, "%s\t%s\t%s\t%s\n", ID, sr.Name, sr.Network, bkID) |
|
| 191 |
+ } else {
|
|
| 189 | 192 |
fmt.Fprintln(wr, ID) |
| 190 |
- continue |
|
| 191 | 193 |
} |
| 192 |
- network := networkResource.Network |
|
| 193 |
- fmt.Fprintf(wr, "%s\t%s\t%s", |
|
| 194 |
- ID, |
|
| 195 |
- netName, |
|
| 196 |
- network) |
|
| 197 |
- fmt.Fprint(wr, "\n") |
|
| 198 | 194 |
} |
| 199 | 195 |
wr.Flush() |
| 200 | 196 |
|
| 201 | 197 |
return nil |
| 202 | 198 |
} |
| 203 | 199 |
|
| 200 |
+func getBackendID(cli *NetworkCli, servID string) (string, error) {
|
|
| 201 |
+ var ( |
|
| 202 |
+ obj []byte |
|
| 203 |
+ err error |
|
| 204 |
+ bk string |
|
| 205 |
+ ) |
|
| 206 |
+ |
|
| 207 |
+ if obj, _, err = readBody(cli.call("GET", "/services/"+servID+"/backend", nil, nil)); err == nil {
|
|
| 208 |
+ var bkl []backendResource |
|
| 209 |
+ if err := json.NewDecoder(bytes.NewReader(obj)).Decode(&bkl); err == nil {
|
|
| 210 |
+ if len(bkl) > 0 {
|
|
| 211 |
+ bk = bkl[0].ID |
|
| 212 |
+ } |
|
| 213 |
+ } else {
|
|
| 214 |
+ // Only print a message, don't make the caller cli fail for this |
|
| 215 |
+ fmt.Fprintf(cli.out, "Failed to retrieve provider list for service %s (%v)", servID, err) |
|
| 216 |
+ } |
|
| 217 |
+ } |
|
| 218 |
+ |
|
| 219 |
+ return bk, err |
|
| 220 |
+} |
|
| 221 |
+ |
|
| 204 | 222 |
// CmdServiceInfo handles service info UI |
| 205 | 223 |
func (cli *NetworkCli) CmdServiceInfo(chain string, args ...string) error {
|
| 206 |
- cmd := cli.Subcmd(chain, "info", "SERVICE NETWORK", "Displays detailed information on a service", false) |
|
| 207 |
- cmd.Require(flag.Min, 2) |
|
| 224 |
+ cmd := cli.Subcmd(chain, "info", "SERVICE", "Displays detailed information about a service", false) |
|
| 225 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Network where to publish the service")
|
|
| 226 |
+ cmd.Require(flag.Min, 1) |
|
| 227 |
+ |
|
| 208 | 228 |
err := cmd.ParseFlags(args, true) |
| 209 | 229 |
if err != nil {
|
| 210 | 230 |
return err |
| 211 | 231 |
} |
| 212 | 232 |
|
| 213 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(1)) |
|
| 214 |
- if err != nil {
|
|
| 215 |
- return err |
|
| 233 |
+ // Default network changes will come later |
|
| 234 |
+ nw := "docker0" |
|
| 235 |
+ if *flNetwork != "" {
|
|
| 236 |
+ nw = *flNetwork |
|
| 216 | 237 |
} |
| 217 | 238 |
|
| 218 |
- serviceID, err := lookupServiceID(cli, networkID, cmd.Arg(0)) |
|
| 239 |
+ serviceID, err := lookupServiceID(cli, nw, cmd.Arg(0)) |
|
| 219 | 240 |
if err != nil {
|
| 220 | 241 |
return err |
| 221 | 242 |
} |
| 222 | 243 |
|
| 223 |
- obj, _, err := readBody(cli.call("GET", "/networks/"+networkID+"/endpoints/"+serviceID, nil, nil))
|
|
| 244 |
+ obj, _, err := readBody(cli.call("GET", "/services/"+serviceID, nil, nil))
|
|
| 224 | 245 |
if err != nil {
|
| 225 |
- fmt.Fprintf(cli.err, "%s", err.Error()) |
|
| 226 | 246 |
return err |
| 227 | 247 |
} |
| 228 | 248 |
|
| 229 |
- endpointResource := &endpointResource{}
|
|
| 230 |
- if err := json.NewDecoder(bytes.NewReader(obj)).Decode(endpointResource); err != nil {
|
|
| 249 |
+ sr := &serviceResource{}
|
|
| 250 |
+ if err := json.NewDecoder(bytes.NewReader(obj)).Decode(sr); err != nil {
|
|
| 231 | 251 |
return err |
| 232 | 252 |
} |
| 233 |
- fmt.Fprintf(cli.out, "Service Id: %s\n", endpointResource.ID) |
|
| 234 |
- fmt.Fprintf(cli.out, "\tName: %s\n", endpointResource.Name) |
|
| 235 |
- fmt.Fprintf(cli.out, "\tNetwork: %s\n", endpointResource.Network) |
|
| 253 |
+ |
|
| 254 |
+ fmt.Fprintf(cli.out, "Service Id: %s\n", sr.ID) |
|
| 255 |
+ fmt.Fprintf(cli.out, "\tName: %s\n", sr.Name) |
|
| 256 |
+ fmt.Fprintf(cli.out, "\tNetwork: %s\n", sr.Network) |
|
| 236 | 257 |
|
| 237 | 258 |
return nil |
| 238 | 259 |
} |
| 239 | 260 |
|
| 240 |
-// CmdServiceJoin handles service join UI |
|
| 241 |
-func (cli *NetworkCli) CmdServiceJoin(chain string, args ...string) error {
|
|
| 242 |
- cmd := cli.Subcmd(chain, "join", "CONTAINER SERVICE NETWORK", "Sets a container as a service backend", false) |
|
| 243 |
- cmd.Require(flag.Min, 3) |
|
| 261 |
+// CmdServiceAttach handles service attach UI |
|
| 262 |
+func (cli *NetworkCli) CmdServiceAttach(chain string, args ...string) error {
|
|
| 263 |
+ cmd := cli.Subcmd(chain, "attach", "CONTAINER SERVICE", "Sets a container as a service backend", false) |
|
| 264 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Network where to publish the service")
|
|
| 265 |
+ cmd.Require(flag.Min, 2) |
|
| 266 |
+ |
|
| 244 | 267 |
err := cmd.ParseFlags(args, true) |
| 245 | 268 |
if err != nil {
|
| 246 | 269 |
return err |
| 247 | 270 |
} |
| 248 | 271 |
|
| 249 |
- containerID, err := lookupContainerID(cli, cmd.Arg(0)) |
|
| 250 |
- if err != nil {
|
|
| 251 |
- return err |
|
| 272 |
+ // Default network changes will come later |
|
| 273 |
+ nw := "docker0" |
|
| 274 |
+ if *flNetwork != "" {
|
|
| 275 |
+ nw = *flNetwork |
|
| 252 | 276 |
} |
| 253 | 277 |
|
| 254 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(2)) |
|
| 278 |
+ containerID, err := lookupContainerID(cli, cmd.Arg(0)) |
|
| 255 | 279 |
if err != nil {
|
| 256 | 280 |
return err |
| 257 | 281 |
} |
| 258 | 282 |
|
| 259 |
- serviceID, err := lookupServiceID(cli, networkID, cmd.Arg(1)) |
|
| 283 |
+ serviceID, err := lookupServiceID(cli, nw, cmd.Arg(1)) |
|
| 260 | 284 |
if err != nil {
|
| 261 | 285 |
return err |
| 262 | 286 |
} |
| 263 | 287 |
|
| 264 |
- nc := endpointJoin{ContainerID: containerID}
|
|
| 288 |
+ nc := serviceAttach{ContainerID: containerID}
|
|
| 265 | 289 |
|
| 266 |
- _, _, err = readBody(cli.call("POST", "/networks/"+networkID+"/endpoints/"+serviceID+"/containers", nc, nil))
|
|
| 267 |
- if err != nil {
|
|
| 268 |
- fmt.Fprintf(cli.err, "%s", err.Error()) |
|
| 269 |
- return err |
|
| 270 |
- } |
|
| 271 |
- return nil |
|
| 290 |
+ _, _, err = readBody(cli.call("POST", "/services/"+serviceID+"/backend", nc, nil))
|
|
| 291 |
+ |
|
| 292 |
+ return err |
|
| 272 | 293 |
} |
| 273 | 294 |
|
| 274 |
-// CmdServiceLeave handles service leave UI |
|
| 275 |
-func (cli *NetworkCli) CmdServiceLeave(chain string, args ...string) error {
|
|
| 276 |
- cmd := cli.Subcmd(chain, "leave", "CONTAINER SERVICE NETWORK", "Removes a container from service backend", false) |
|
| 277 |
- cmd.Require(flag.Min, 3) |
|
| 295 |
+// CmdServiceDetach handles service detach UI |
|
| 296 |
+func (cli *NetworkCli) CmdServiceDetach(chain string, args ...string) error {
|
|
| 297 |
+ cmd := cli.Subcmd(chain, "detach", "CONTAINER SERVICE", "Removes a container from service backend", false) |
|
| 298 |
+ flNetwork := cmd.String([]string{"net", "-network"}, "", "Network where to publish the service")
|
|
| 299 |
+ cmd.Require(flag.Min, 2) |
|
| 300 |
+ |
|
| 278 | 301 |
err := cmd.ParseFlags(args, true) |
| 279 | 302 |
if err != nil {
|
| 280 | 303 |
return err |
| 281 | 304 |
} |
| 282 | 305 |
|
| 283 |
- containerID, err := lookupContainerID(cli, cmd.Arg(0)) |
|
| 284 |
- if err != nil {
|
|
| 285 |
- return err |
|
| 306 |
+ // Default network changes will come later |
|
| 307 |
+ nw := "docker0" |
|
| 308 |
+ if *flNetwork != "" {
|
|
| 309 |
+ nw = *flNetwork |
|
| 286 | 310 |
} |
| 287 | 311 |
|
| 288 |
- networkID, err := lookupNetworkID(cli, cmd.Arg(2)) |
|
| 312 |
+ containerID, err := lookupContainerID(cli, cmd.Arg(0)) |
|
| 289 | 313 |
if err != nil {
|
| 290 | 314 |
return err |
| 291 | 315 |
} |
| 292 | 316 |
|
| 293 |
- serviceID, err := lookupServiceID(cli, networkID, cmd.Arg(1)) |
|
| 317 |
+ serviceID, err := lookupServiceID(cli, nw, cmd.Arg(1)) |
|
| 294 | 318 |
if err != nil {
|
| 295 | 319 |
return err |
| 296 | 320 |
} |
| 297 | 321 |
|
| 298 |
- _, _, err = readBody(cli.call("DELETE", "/networks/"+networkID+"/endpoints/"+serviceID+"/containers/"+containerID, nil, nil))
|
|
| 322 |
+ _, _, err = readBody(cli.call("DELETE", "/services/"+serviceID+"/backend/"+containerID, nil, nil))
|
|
| 299 | 323 |
if err != nil {
|
| 300 |
- fmt.Fprintf(cli.err, "%s", err.Error()) |
|
| 301 | 324 |
return err |
| 302 | 325 |
} |
| 303 | 326 |
return nil |
| ... | ... |
@@ -8,19 +8,24 @@ import "github.com/docker/libnetwork/types" |
| 8 | 8 |
|
| 9 | 9 |
// networkResource is the body of the "get network" http response message |
| 10 | 10 |
type networkResource struct {
|
| 11 |
- Name string `json:"name"` |
|
| 12 |
- ID string `json:"id"` |
|
| 13 |
- Type string `json:"type"` |
|
| 14 |
- Endpoints []*endpointResource `json:"endpoints"` |
|
| 11 |
+ Name string `json:"name"` |
|
| 12 |
+ ID string `json:"id"` |
|
| 13 |
+ Type string `json:"type"` |
|
| 14 |
+ Services []*serviceResource `json:"services"` |
|
| 15 | 15 |
} |
| 16 | 16 |
|
| 17 |
-// endpointResource is the body of the "get endpoint" http response message |
|
| 18 |
-type endpointResource struct {
|
|
| 17 |
+// serviceResource is the body of the "get service" http response message |
|
| 18 |
+type serviceResource struct {
|
|
| 19 | 19 |
Name string `json:"name"` |
| 20 | 20 |
ID string `json:"id"` |
| 21 | 21 |
Network string `json:"network"` |
| 22 | 22 |
} |
| 23 | 23 |
|
| 24 |
+// backendResource is the body of "get service backend" response message |
|
| 25 |
+type backendResource struct {
|
|
| 26 |
+ ID string `json:"id"` |
|
| 27 |
+} |
|
| 28 |
+ |
|
| 24 | 29 |
/*********** |
| 25 | 30 |
Body types |
| 26 | 31 |
************/ |
| ... | ... |
@@ -32,37 +37,37 @@ type networkCreate struct {
|
| 32 | 32 |
Options map[string]interface{} `json:"options"`
|
| 33 | 33 |
} |
| 34 | 34 |
|
| 35 |
-// endpointCreate represents the body of the "create endpoint" http request message |
|
| 36 |
-type endpointCreate struct {
|
|
| 35 |
+// serviceCreate represents the body of the "publish service" http request message |
|
| 36 |
+type serviceCreate struct {
|
|
| 37 | 37 |
Name string `json:"name"` |
| 38 |
- NetworkID string `json:"network_id"` |
|
| 38 |
+ Network string `json:"network_name"` |
|
| 39 | 39 |
ExposedPorts []types.TransportPort `json:"exposed_ports"` |
| 40 | 40 |
PortMapping []types.PortBinding `json:"port_mapping"` |
| 41 | 41 |
} |
| 42 | 42 |
|
| 43 |
-// endpointJoin represents the expected body of the "join endpoint" or "leave endpoint" http request messages |
|
| 44 |
-type endpointJoin struct {
|
|
| 45 |
- ContainerID string `json:"container_id"` |
|
| 46 |
- HostName string `json:"host_name"` |
|
| 47 |
- DomainName string `json:"domain_name"` |
|
| 48 |
- HostsPath string `json:"hosts_path"` |
|
| 49 |
- ResolvConfPath string `json:"resolv_conf_path"` |
|
| 50 |
- DNS []string `json:"dns"` |
|
| 51 |
- ExtraHosts []endpointExtraHost `json:"extra_hosts"` |
|
| 52 |
- ParentUpdates []endpointParentUpdate `json:"parent_updates"` |
|
| 53 |
- UseDefaultSandbox bool `json:"use_default_sandbox"` |
|
| 43 |
+// serviceAttach represents the expected body of the "attach/detach backend to/from service" http request messages |
|
| 44 |
+type serviceAttach struct {
|
|
| 45 |
+ ContainerID string `json:"container_id"` |
|
| 46 |
+ HostName string `json:"host_name"` |
|
| 47 |
+ DomainName string `json:"domain_name"` |
|
| 48 |
+ HostsPath string `json:"hosts_path"` |
|
| 49 |
+ ResolvConfPath string `json:"resolv_conf_path"` |
|
| 50 |
+ DNS []string `json:"dns"` |
|
| 51 |
+ ExtraHosts []serviceExtraHost `json:"extra_hosts"` |
|
| 52 |
+ ParentUpdates []serviceParentUpdate `json:"parent_updates"` |
|
| 53 |
+ UseDefaultSandbox bool `json:"use_default_sandbox"` |
|
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 |
-// EndpointExtraHost represents the extra host object |
|
| 57 |
-type endpointExtraHost struct {
|
|
| 56 |
+// serviceExtraHost represents the extra host object |
|
| 57 |
+type serviceExtraHost struct {
|
|
| 58 | 58 |
Name string `json:"name"` |
| 59 | 59 |
Address string `json:"address"` |
| 60 | 60 |
} |
| 61 | 61 |
|
| 62 | 62 |
// EndpointParentUpdate is the object carrying the information about the |
| 63 | 63 |
// endpoint parent that needs to be updated |
| 64 |
-type endpointParentUpdate struct {
|
|
| 65 |
- EndpointID string `json:"endpoint_id"` |
|
| 64 |
+type serviceParentUpdate struct {
|
|
| 65 |
+ EndpointID string `json:"service_id"` |
|
| 66 | 66 |
Name string `json:"name"` |
| 67 | 67 |
Address string `json:"address"` |
| 68 | 68 |
} |
| ... | ... |
@@ -122,6 +122,10 @@ func (d *dnetConnection) dnetDaemon() error {
|
| 122 | 122 |
post.Methods("GET", "PUT", "POST", "DELETE").HandlerFunc(httpHandler)
|
| 123 | 123 |
post = r.PathPrefix("/networks").Subrouter()
|
| 124 | 124 |
post.Methods("GET", "PUT", "POST", "DELETE").HandlerFunc(httpHandler)
|
| 125 |
+ post = r.PathPrefix("/{.*}/services").Subrouter()
|
|
| 126 |
+ post.Methods("GET", "PUT", "POST", "DELETE").HandlerFunc(httpHandler)
|
|
| 127 |
+ post = r.PathPrefix("/services").Subrouter()
|
|
| 128 |
+ post.Methods("GET", "PUT", "POST", "DELETE").HandlerFunc(httpHandler)
|
|
| 125 | 129 |
return http.ListenAndServe(d.addr, r) |
| 126 | 130 |
} |
| 127 | 131 |
|