mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-21 04:18:38 +00:00
tailcfg: flesh out some docs on MapResponse, clarify slices w/ omitempty
Updates #cleanup Change-Id: If4caf9d00529edc09ae7af9cc70f6ba0ade38378 Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
a5ffd5e7c3
commit
70ea073478
@ -1077,7 +1077,9 @@ type Endpoint struct {
|
|||||||
Type EndpointType
|
Type EndpointType
|
||||||
}
|
}
|
||||||
|
|
||||||
// MapRequest is sent by a client to start a long-poll network map updates.
|
// MapRequest is sent by a client to either update the control plane
|
||||||
|
// about its current state, or to start a long-poll of network map updates.
|
||||||
|
//
|
||||||
// The request includes a copy of the client's current set of WireGuard
|
// The request includes a copy of the client's current set of WireGuard
|
||||||
// endpoints and general host information.
|
// endpoints and general host information.
|
||||||
//
|
//
|
||||||
@ -1538,6 +1540,27 @@ type PingResponse struct {
|
|||||||
IsLocalIP bool `json:",omitempty"`
|
IsLocalIP bool `json:",omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MapResponse is the response to a MapRequest. It describes the state of the
|
||||||
|
// local node, the peer nodes, the DNS configuration, the packet filter, and
|
||||||
|
// more. A MapRequest, depending on its parameters, may result in the control
|
||||||
|
// plane coordination server sending 0, 1 or a stream of multiple MapResponse
|
||||||
|
// values.
|
||||||
|
//
|
||||||
|
// When the client sets MapRequest.Stream, the server sends a stream of
|
||||||
|
// MapResponses. That long-lived HTTP transaction is called a "map poll". In a
|
||||||
|
// map poll, the first MapResponse will be complete and subsequent MapResponses
|
||||||
|
// will be incremental updates with only changed information.
|
||||||
|
//
|
||||||
|
// The zero value for all fields means "unchanged". Unfortunately, several
|
||||||
|
// fields were defined before that convention was established, so they use a
|
||||||
|
// slice with omitempty, meaning this type can't be used to marshal JSON
|
||||||
|
// containing non-nil zero-length slices (meaning explicitly now empty). The
|
||||||
|
// control plane uses a separate type to marshal these fields. This type is
|
||||||
|
// primarily used for unmarshaling responses so the omitempty annotations are
|
||||||
|
// mostly useless, except that this type is also used for the integration test's
|
||||||
|
// fake control server. (It's not necessary to marshal a non-nil zero-length
|
||||||
|
// slice for the things we've needed to test in the integration tests as of
|
||||||
|
// 2023-09-09).
|
||||||
type MapResponse struct {
|
type MapResponse struct {
|
||||||
// MapSessionHandle optionally specifies a unique opaque handle for this
|
// MapSessionHandle optionally specifies a unique opaque handle for this
|
||||||
// stateful MapResponse session. Servers may choose not to send it, and it's
|
// stateful MapResponse session. Servers may choose not to send it, and it's
|
||||||
@ -1638,6 +1661,10 @@ type MapResponse struct {
|
|||||||
// previously streamed non-nil MapResponse.PacketFilter within
|
// previously streamed non-nil MapResponse.PacketFilter within
|
||||||
// the same HTTP response. A non-nil but empty list always means
|
// the same HTTP response. A non-nil but empty list always means
|
||||||
// no PacketFilter (that is, to block everything).
|
// no PacketFilter (that is, to block everything).
|
||||||
|
//
|
||||||
|
// Note that this package's type, due its use of a slice and omitempty, is
|
||||||
|
// unable to marshal a zero-length non-nil slice. The control server needs
|
||||||
|
// to marshal this type using a separate type. See MapResponse docs.
|
||||||
PacketFilter []FilterRule `json:",omitempty"`
|
PacketFilter []FilterRule `json:",omitempty"`
|
||||||
|
|
||||||
// UserProfiles are the user profiles of nodes in the network.
|
// UserProfiles are the user profiles of nodes in the network.
|
||||||
@ -1645,12 +1672,15 @@ type MapResponse struct {
|
|||||||
// user profiles only.
|
// user profiles only.
|
||||||
UserProfiles []UserProfile `json:",omitempty"`
|
UserProfiles []UserProfile `json:",omitempty"`
|
||||||
|
|
||||||
// Health, if non-nil, sets the health state
|
// Health, if non-nil, sets the health state of the node from the control
|
||||||
// of the node from the control plane's perspective.
|
// plane's perspective. A nil value means no change from the previous
|
||||||
// A nil value means no change from the previous MapResponse.
|
// MapResponse. A non-nil 0-length slice restores the health to good (no
|
||||||
// A non-nil 0-length slice restores the health to good (no known problems).
|
// known problems). A non-zero length slice are the list of problems that
|
||||||
// A non-zero length slice are the list of problems that the control place
|
// the control place sees.
|
||||||
// sees.
|
//
|
||||||
|
// Note that this package's type, due its use of a slice and omitempty, is
|
||||||
|
// unable to marshal a zero-length non-nil slice. The control server needs
|
||||||
|
// to marshal this type using a separate type. See MapResponse docs.
|
||||||
Health []string `json:",omitempty"`
|
Health []string `json:",omitempty"`
|
||||||
|
|
||||||
// SSHPolicy, if non-nil, updates the SSH policy for how incoming
|
// SSHPolicy, if non-nil, updates the SSH policy for how incoming
|
||||||
|
@ -705,3 +705,24 @@ func TestCurrentCapabilityVersion(t *testing.T) {
|
|||||||
t.Errorf("CurrentCapabilityVersion = %d; want %d", CurrentCapabilityVersion, max)
|
t.Errorf("CurrentCapabilityVersion = %d; want %d", CurrentCapabilityVersion, max)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalHealth(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
in string // MapResponse JSON
|
||||||
|
want []string // MapResponse.Health wanted value post-unmarshal
|
||||||
|
}{
|
||||||
|
{in: `{}`},
|
||||||
|
{in: `{"Health":null}`},
|
||||||
|
{in: `{"Health":[]}`, want: []string{}},
|
||||||
|
{in: `{"Health":["bad"]}`, want: []string{"bad"}},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
var mr MapResponse
|
||||||
|
if err := json.Unmarshal([]byte(tt.in), &mr); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(mr.Health, tt.want) {
|
||||||
|
t.Errorf("for %#q: got %v; want %v", tt.in, mr.Health, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user