Browse Source

tailcfg, util/deephash: add DataPlaneAuditLogID to Node and DomainDataPlaneAuditLogID to MapResponse

We're adding two log IDs to facilitate data-plane audit logging: a node-specific
log ID, and a domain-specific log ID.

Updated util/deephash/deephash_test.go with revised expectations for tailcfg.Node.

Updates https://github.com/tailscale/corp/issues/6991

Signed-off-by: Aaron Klotz <[email protected]>
Aaron Klotz 3 years ago
parent
commit
acc7baac6d

+ 7 - 0
tailcfg/tailcfg.go

@@ -235,6 +235,9 @@ type Node struct {
 	ComputedName            string `json:",omitempty"` // MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS)
 	ComputedName            string `json:",omitempty"` // MagicDNS base name (for normal non-shared-in nodes), FQDN (without trailing dot, for shared-in nodes), or Hostname (if no MagicDNS)
 	computedHostIfDifferent string // hostname, if different than ComputedName, otherwise empty
 	computedHostIfDifferent string // hostname, if different than ComputedName, otherwise empty
 	ComputedNameWithHost    string `json:",omitempty"` // either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set
 	ComputedNameWithHost    string `json:",omitempty"` // either "ComputedName" or "ComputedName (computedHostIfDifferent)", if computedHostIfDifferent is set
+
+	// DataPlaneAuditLogID is the per-node logtail ID used for data plane audit logging.
+	DataPlaneAuditLogID string `json:",omitempty"`
 }
 }
 
 
 // DisplayName returns the user-facing name for a node which should
 // DisplayName returns the user-facing name for a node which should
@@ -1373,6 +1376,10 @@ type MapResponse struct {
 	// indicates no change from the value sent earlier.
 	// indicates no change from the value sent earlier.
 	TKAInfo *TKAInfo `json:",omitempty"`
 	TKAInfo *TKAInfo `json:",omitempty"`
 
 
+	// DomainDataPlaneAuditLogID, if non-empty, is the per-tailnet log ID to be
+	// used when writing data plane audit logs.
+	DomainDataPlaneAuditLogID string `json:",omitempty"`
+
 	// Debug is normally nil, except for when the control server
 	// Debug is normally nil, except for when the control server
 	// is setting debug settings on a node.
 	// is setting debug settings on a node.
 	Debug *Debug `json:",omitempty"`
 	Debug *Debug `json:",omitempty"`

+ 1 - 0
tailcfg/tailcfg_clone.go

@@ -95,6 +95,7 @@ var _NodeCloneNeedsRegeneration = Node(struct {
 	ComputedName            string
 	ComputedName            string
 	computedHostIfDifferent string
 	computedHostIfDifferent string
 	ComputedNameWithHost    string
 	ComputedNameWithHost    string
+	DataPlaneAuditLogID     string
 }{})
 }{})
 
 
 // Clone makes a deep copy of Hostinfo.
 // Clone makes a deep copy of Hostinfo.

+ 1 - 0
tailcfg/tailcfg_test.go

@@ -332,6 +332,7 @@ func TestNodeEqual(t *testing.T) {
 		"LastSeen", "Online", "KeepAlive", "MachineAuthorized",
 		"LastSeen", "Online", "KeepAlive", "MachineAuthorized",
 		"Capabilities",
 		"Capabilities",
 		"ComputedName", "computedHostIfDifferent", "ComputedNameWithHost",
 		"ComputedName", "computedHostIfDifferent", "ComputedNameWithHost",
+		"DataPlaneAuditLogID",
 	}
 	}
 	if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) {
 	if have := fieldsOf(reflect.TypeOf(Node{})); !reflect.DeepEqual(have, nodeHandles) {
 		t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
 		t.Errorf("Node.Equal check might be out of sync\nfields: %q\nhandled: %q\n",

+ 2 - 0
tailcfg/tailcfg_view.go

@@ -173,6 +173,7 @@ func (v NodeView) MachineAuthorized() bool           { return v.ж.MachineAuthor
 func (v NodeView) Capabilities() views.Slice[string] { return views.SliceOf(v.ж.Capabilities) }
 func (v NodeView) Capabilities() views.Slice[string] { return views.SliceOf(v.ж.Capabilities) }
 func (v NodeView) ComputedName() string              { return v.ж.ComputedName }
 func (v NodeView) ComputedName() string              { return v.ж.ComputedName }
 func (v NodeView) ComputedNameWithHost() string      { return v.ж.ComputedNameWithHost }
 func (v NodeView) ComputedNameWithHost() string      { return v.ж.ComputedNameWithHost }
+func (v NodeView) DataPlaneAuditLogID() string       { return v.ж.DataPlaneAuditLogID }
 func (v NodeView) Equal(v2 NodeView) bool            { return v.ж.Equal(v2.ж) }
 func (v NodeView) Equal(v2 NodeView) bool            { return v.ж.Equal(v2.ж) }
 
 
 // A compilation failure here means this code must be regenerated, with the command at the top of this file.
 // A compilation failure here means this code must be regenerated, with the command at the top of this file.
@@ -203,6 +204,7 @@ var _NodeViewNeedsRegeneration = Node(struct {
 	ComputedName            string
 	ComputedName            string
 	computedHostIfDifferent string
 	computedHostIfDifferent string
 	ComputedNameWithHost    string
 	ComputedNameWithHost    string
+	DataPlaneAuditLogID     string
 }{})
 }{})
 
 
 // View returns a readonly view of Hostinfo.
 // View returns a readonly view of Hostinfo.

+ 1 - 1
util/deephash/deephash_test.go

@@ -575,7 +575,7 @@ func TestGetTypeHasher(t *testing.T) {
 		{
 		{
 			name: "tailcfg.Node",
 			name: "tailcfg.Node",
 			val:  &tailcfg.Node{},
 			val:  &tailcfg.Node{},
-			out:  "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
+			out:  "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\tn\x88\xf1\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00",
 		},
 		},
 	}
 	}
 	for _, tt := range tests {
 	for _, tt := range tests {