зеркало из https://github.com/docker/engine-api.git
Adding force to the RemoveNode API
Signed-off-by: Diogo Monica <diogo.monica@gmail.com>
This commit is contained in:
Родитель
3d1601b9d2
Коммит
61cb872d9d
|
@ -94,7 +94,7 @@ type NetworkAPIClient interface {
|
||||||
type NodeAPIClient interface {
|
type NodeAPIClient interface {
|
||||||
NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error)
|
NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error)
|
||||||
NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
|
NodeList(ctx context.Context, options types.NodeListOptions) ([]swarm.Node, error)
|
||||||
NodeRemove(ctx context.Context, nodeID string) error
|
NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error
|
||||||
NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error
|
NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,21 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import "golang.org/x/net/context"
|
import (
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/docker/engine-api/types"
|
||||||
|
|
||||||
|
"golang.org/x/net/context"
|
||||||
|
)
|
||||||
|
|
||||||
// NodeRemove removes a Node.
|
// NodeRemove removes a Node.
|
||||||
func (cli *Client) NodeRemove(ctx context.Context, nodeID string) error {
|
func (cli *Client) NodeRemove(ctx context.Context, nodeID string, options types.NodeRemoveOptions) error {
|
||||||
resp, err := cli.delete(ctx, "/nodes/"+nodeID, nil, nil)
|
query := url.Values{}
|
||||||
|
if options.Force {
|
||||||
|
query.Set("force", "1")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := cli.delete(ctx, "/nodes/"+nodeID, query, nil)
|
||||||
ensureReaderClosed(resp)
|
ensureReaderClosed(resp)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/docker/engine-api/types"
|
||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,7 +18,7 @@ func TestNodeRemoveError(t *testing.T) {
|
||||||
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
|
transport: newMockClient(nil, errorMock(http.StatusInternalServerError, "Server error")),
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.NodeRemove(context.Background(), "node_id")
|
err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: false})
|
||||||
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
if err == nil || err.Error() != "Error response from daemon: Server error" {
|
||||||
t.Fatalf("expected a Server Error, got %v", err)
|
t.Fatalf("expected a Server Error, got %v", err)
|
||||||
}
|
}
|
||||||
|
@ -25,23 +27,43 @@ func TestNodeRemoveError(t *testing.T) {
|
||||||
func TestNodeRemove(t *testing.T) {
|
func TestNodeRemove(t *testing.T) {
|
||||||
expectedURL := "/nodes/node_id"
|
expectedURL := "/nodes/node_id"
|
||||||
|
|
||||||
client := &Client{
|
removeCases := []struct {
|
||||||
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
|
force bool
|
||||||
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
expectedForce string
|
||||||
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
}{
|
||||||
}
|
{
|
||||||
if req.Method != "DELETE" {
|
expectedForce: "",
|
||||||
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
},
|
||||||
}
|
{
|
||||||
return &http.Response{
|
force: true,
|
||||||
StatusCode: http.StatusOK,
|
expectedForce: "1",
|
||||||
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
},
|
||||||
}, nil
|
|
||||||
}),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
err := client.NodeRemove(context.Background(), "node_id")
|
for _, removeCase := range removeCases {
|
||||||
if err != nil {
|
client := &Client{
|
||||||
t.Fatal(err)
|
transport: newMockClient(nil, func(req *http.Request) (*http.Response, error) {
|
||||||
|
if !strings.HasPrefix(req.URL.Path, expectedURL) {
|
||||||
|
return nil, fmt.Errorf("Expected URL '%s', got '%s'", expectedURL, req.URL)
|
||||||
|
}
|
||||||
|
if req.Method != "DELETE" {
|
||||||
|
return nil, fmt.Errorf("expected DELETE method, got %s", req.Method)
|
||||||
|
}
|
||||||
|
force := req.URL.Query().Get("force")
|
||||||
|
if force != removeCase.expectedForce {
|
||||||
|
return nil, fmt.Errorf("force not set in URL query properly. expected '%s', got %s", removeCase.expectedForce, force)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &http.Response{
|
||||||
|
StatusCode: http.StatusOK,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader([]byte("body"))),
|
||||||
|
}, nil
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := client.NodeRemove(context.Background(), "node_id", types.NodeRemoveOptions{Force: removeCase.force})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,11 +241,16 @@ func (v VersionResponse) ServerOK() bool {
|
||||||
return v.Server != nil
|
return v.Server != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeListOptions holds parameters to list nodes with.
|
// NodeListOptions holds parameters to list nodes with.
|
||||||
type NodeListOptions struct {
|
type NodeListOptions struct {
|
||||||
Filter filters.Args
|
Filter filters.Args
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NodeRemoveOptions holds parameters to remove nodes with.
|
||||||
|
type NodeRemoveOptions struct {
|
||||||
|
Force bool
|
||||||
|
}
|
||||||
|
|
||||||
// ServiceCreateOptions contains the options to use when creating a service.
|
// ServiceCreateOptions contains the options to use when creating a service.
|
||||||
type ServiceCreateOptions struct {
|
type ServiceCreateOptions struct {
|
||||||
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
// EncodedRegistryAuth is the encoded registry authorization credentials to
|
||||||
|
|
Загрузка…
Ссылка в новой задаче