Skip to content

Commit 037b491

Browse files
authored
Merge pull request moby#1826 from aaronlehmann/late-port-binding
Allow managers not to expose a remote API port
2 parents e48c97f + 0eca203 commit 037b491

8 files changed

Lines changed: 306 additions & 112 deletions

File tree

integration/cluster.go

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,20 @@ func (c *testCluster) RandomManager() *testNode {
7373
return managers[idx]
7474
}
7575

76-
// AddManager adds node with Manager role(both agent and manager).
77-
func (c *testCluster) AddManager() error {
76+
// AddManager adds a node with the Manager role. The node will function as both
77+
// an agent and a manager. If lateBind is set, the manager is started before a
78+
// remote API port is bound. This setting only applies to the first manager.
79+
func (c *testCluster) AddManager(lateBind bool) error {
7880
// first node
7981
var n *testNode
8082
if len(c.nodes) == 0 {
81-
node, err := newTestNode("", "")
83+
node, err := newTestNode("", "", lateBind)
8284
if err != nil {
8385
return err
8486
}
8587
n = node
8688
} else {
89+
lateBind = false
8790
joinAddr, err := c.RandomManager().node.RemoteAPIAddr()
8891
if err != nil {
8992
return err
@@ -95,7 +98,7 @@ func (c *testCluster) AddManager() error {
9598
if len(clusterInfo.Clusters) == 0 {
9699
return fmt.Errorf("joining manager: there is no cluster created in storage")
97100
}
98-
node, err := newTestNode(joinAddr, clusterInfo.Clusters[0].RootCA.JoinTokens.Manager)
101+
node, err := newTestNode(joinAddr, clusterInfo.Clusters[0].RootCA.JoinTokens.Manager, false)
99102
if err != nil {
100103
return err
101104
}
@@ -119,6 +122,20 @@ func (c *testCluster) AddManager() error {
119122

120123
c.nodes[n.node.NodeID()] = n
121124
c.nodesOrder[n.node.NodeID()] = c.counter
125+
126+
if lateBind {
127+
// Verify that the control API works
128+
clusterInfo, err := c.api.ListClusters(context.Background(), &api.ListClustersRequest{})
129+
if err != nil {
130+
return err
131+
}
132+
if len(clusterInfo.Clusters) == 0 {
133+
return fmt.Errorf("joining manager: there is no cluster created in storage")
134+
}
135+
136+
return n.node.BindRemote(context.Background(), "127.0.0.1:0", "")
137+
}
138+
122139
return nil
123140
}
124141

@@ -140,7 +157,7 @@ func (c *testCluster) AddAgent() error {
140157
if len(clusterInfo.Clusters) == 0 {
141158
return fmt.Errorf("joining agent: there is no cluster created in storage")
142159
}
143-
node, err := newTestNode(joinAddr, clusterInfo.Clusters[0].RootCA.JoinTokens.Worker)
160+
node, err := newTestNode(joinAddr, clusterInfo.Clusters[0].RootCA.JoinTokens.Worker, false)
144161
if err != nil {
145162
return err
146163
}

integration/integration_test.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ func pollServiceReady(t *testing.T, c *testCluster, sid string) {
125125
func newCluster(t *testing.T, numWorker, numManager int) *testCluster {
126126
cl := newTestCluster()
127127
for i := 0; i < numManager; i++ {
128-
require.NoError(t, cl.AddManager(), "manager number %d", i+1)
128+
require.NoError(t, cl.AddManager(false), "manager number %d", i+1)
129129
}
130130
for i := 0; i < numWorker; i++ {
131131
require.NoError(t, cl.AddAgent(), "agent number %d", i+1)
@@ -145,6 +145,28 @@ func TestClusterCreate(t *testing.T) {
145145
}()
146146
}
147147

148+
func TestServiceCreateLateBind(t *testing.T) {
149+
t.Parallel()
150+
151+
numWorker, numManager := 3, 3
152+
153+
cl := newTestCluster()
154+
for i := 0; i < numManager; i++ {
155+
require.NoError(t, cl.AddManager(true), "manager number %d", i+1)
156+
}
157+
for i := 0; i < numWorker; i++ {
158+
require.NoError(t, cl.AddAgent(), "agent number %d", i+1)
159+
}
160+
161+
defer func() {
162+
require.NoError(t, cl.Stop())
163+
}()
164+
165+
sid, err := cl.CreateService("test_service", 60)
166+
require.NoError(t, err)
167+
pollServiceReady(t, cl, sid)
168+
}
169+
148170
func TestServiceCreate(t *testing.T) {
149171
t.Parallel()
150172

integration/node.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,25 @@ type testNode struct {
2424

2525
// newNode creates new node with specific role(manager or agent) and joins to
2626
// existing cluster. if joinAddr is empty string, then new cluster will be initialized.
27-
// It uses TestExecutor as executor.
28-
func newTestNode(joinAddr, joinToken string) (*testNode, error) {
27+
// It uses TestExecutor as executor. If lateBind is set, the remote API port is not
28+
// bound.
29+
func newTestNode(joinAddr, joinToken string, lateBind bool) (*testNode, error) {
2930
tmpDir, err := ioutil.TempDir("", "swarmkit-integration-")
3031
if err != nil {
3132
return nil, err
3233
}
3334

34-
rAddr := "127.0.0.1:0"
3535
cAddr := filepath.Join(tmpDir, "control.sock")
3636
cfg := &node.Config{
37-
ListenRemoteAPI: rAddr,
3837
ListenControlAPI: cAddr,
3938
JoinAddr: joinAddr,
4039
StateDir: tmpDir,
4140
Executor: &TestExecutor{},
4241
JoinToken: joinToken,
4342
}
43+
if !lateBind {
44+
cfg.ListenRemoteAPI = "127.0.0.1:0"
45+
}
4446
node, err := node.New(cfg)
4547
if err != nil {
4648
return nil, err
@@ -122,6 +124,5 @@ func (n *testNode) ControlClient(ctx context.Context) (api.ControlClient, error)
122124
}
123125

124126
func (n *testNode) IsManager() bool {
125-
_, err := n.node.RemoteAPIAddr()
126-
return err == nil
127+
return n.node.Manager() != nil
127128
}

0 commit comments

Comments
 (0)