-
Notifications
You must be signed in to change notification settings - Fork 4.5k
storage/raft: Advertise the configured cluster address #9008
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
1c42963
695d120
7f66e86
c7fbbba
5a6d469
3a693b6
c4691b6
8334893
1a305b6
6233474
e48fe48
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| package raft | ||
|
|
||
| import ( | ||
| "context" | ||
| "crypto/rand" | ||
| "crypto/tls" | ||
| "net" | ||
| "testing" | ||
| "time" | ||
|
|
||
| "github.com/hashicorp/vault/vault/cluster" | ||
| ) | ||
|
|
||
| type mockClusterHook struct { | ||
| address net.Addr | ||
| } | ||
|
|
||
| func (*mockClusterHook) AddClient(alpn string, client cluster.Client) {} | ||
| func (*mockClusterHook) RemoveClient(alpn string) {} | ||
| func (*mockClusterHook) AddHandler(alpn string, handler cluster.Handler) {} | ||
| func (*mockClusterHook) StopHandler(alpn string) {} | ||
| func (*mockClusterHook) TLSConfig(ctx context.Context) (*tls.Config, error) { return nil, nil } | ||
| func (m *mockClusterHook) Addr() net.Addr { return m.address } | ||
| func (*mockClusterHook) GetDialerFunc(ctx context.Context, alpnProto string) func(string, time.Duration) (net.Conn, error) { | ||
| return func(string, time.Duration) (net.Conn, error) { | ||
| return nil, nil | ||
| } | ||
| } | ||
|
|
||
| func TestStreamLayer_UnspecifiedIP(t *testing.T) { | ||
| m := &mockClusterHook{ | ||
| address: &cluster.NetAddr{ | ||
| Host: "0.0.0.0:8200", | ||
| }, | ||
| } | ||
|
|
||
| raftTLSKey, err := GenerateTLSKey(rand.Reader) | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| raftTLS := &TLSKeyring{ | ||
| Keys: []*TLSKey{raftTLSKey}, | ||
| ActiveKeyID: raftTLSKey.ID, | ||
| } | ||
|
|
||
| layer, err := NewRaftLayer(nil, raftTLS, m) | ||
| if err == nil { | ||
| t.Fatal("expected error") | ||
| } | ||
|
|
||
| if err.Error() != "cannot use unspecified IP with raft storage: 0.0.0.0:8200" { | ||
| t.Fatalf("unexpected error: %s", err.Error()) | ||
| } | ||
|
|
||
| if layer != nil { | ||
| t.Fatal("expected nil layer") | ||
| } | ||
|
|
||
| m.address.(*cluster.NetAddr).Host = "10.0.0.1:8200" | ||
|
|
||
| layer, err = NewRaftLayer(nil, raftTLS, m) | ||
| if err != nil { | ||
| t.Fatal(err) | ||
| } | ||
|
|
||
| if layer == nil { | ||
| t.Fatal("nil layer") | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -321,6 +321,11 @@ func (c *Core) startClusterListener(ctx context.Context) error { | |
| // If we listened on port 0, record the port the OS gave us. | ||
| c.clusterAddr.Store(fmt.Sprintf("https://%s", c.getClusterListener().Addr())) | ||
| } | ||
|
|
||
| if err := c.getClusterListener().SetAdvertiseAddr(c.ClusterAddr()); err != nil { | ||
calvn marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return err | ||
| } | ||
|
|
||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit confused on how this works.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah this is primarily necessary because our tests use random port assignments, so we actually don't know the port until we start the listener. If we didn't do this here then each test node would be advertising
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see. My only concern here is that the logic right above could be overwriting The call to c.getClusterListener().Addr()) could get us back an address from the listener config that's
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At least raft will then reject the IP. The user will need to re-configure it such that one of the two values is a fully formed hostname.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True. I was trying to think of other potential alternatives to this logic, since
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is a little indirect, but i don't see a great way around that at the moment. Potentially we can push the |
||
| return nil | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this result in raft using a bad listener address if the
cluster_addris, say127.0.0.1:0(a valid address with an unspecified port), and the address in the listener is0.0.0.0:8201since we'd be overwritingc.clusterAddrwith one that raft is unhappy about?