mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: log tailnet tunnels to the connection log (#27423)
Co-authored-by: Chris DiGiamo <cd@anthropic.com> Co-authored-by: Chris DiGiamo <cdigiamo@anthropic.com>
This commit is contained in:
co-authored by
Chris DiGiamo
Chris DiGiamo
parent
8cc7f2bb0e
commit
1a6a8be96c
Generated
+2
-1
@@ -379,7 +379,8 @@ CREATE TYPE connection_type AS ENUM (
|
||||
'jetbrains',
|
||||
'reconnecting_pty',
|
||||
'workspace_app',
|
||||
'port_forwarding'
|
||||
'port_forwarding',
|
||||
'tunnel'
|
||||
);
|
||||
|
||||
CREATE TYPE cors_behavior AS ENUM (
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
-- The 'tunnel' enum value is intentionally not removed. Postgres cannot
|
||||
-- drop an enum value in place; removing it would require recreating
|
||||
-- connection_type and rewriting the connection_logs type column, which
|
||||
-- takes an exclusive lock on the table and would have to DELETE all
|
||||
-- tunnel rows (audit data) because they cannot exist in the old type.
|
||||
-- Leaving the value in place is harmless: old code never queries for it
|
||||
-- and renders unknown types without error. This matches the precedent
|
||||
-- of other enum-value additions (e.g. 000517, 000531).
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TYPE connection_type ADD VALUE IF NOT EXISTS 'tunnel';
|
||||
Generated
+4
-1
@@ -1855,6 +1855,7 @@ const (
|
||||
ConnectionTypeReconnectingPty ConnectionType = "reconnecting_pty"
|
||||
ConnectionTypeWorkspaceApp ConnectionType = "workspace_app"
|
||||
ConnectionTypePortForwarding ConnectionType = "port_forwarding"
|
||||
ConnectionTypeTunnel ConnectionType = "tunnel"
|
||||
)
|
||||
|
||||
func (e *ConnectionType) Scan(src interface{}) error {
|
||||
@@ -1899,7 +1900,8 @@ func (e ConnectionType) Valid() bool {
|
||||
ConnectionTypeJetbrains,
|
||||
ConnectionTypeReconnectingPty,
|
||||
ConnectionTypeWorkspaceApp,
|
||||
ConnectionTypePortForwarding:
|
||||
ConnectionTypePortForwarding,
|
||||
ConnectionTypeTunnel:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -1913,6 +1915,7 @@ func AllConnectionTypeValues() []ConnectionType {
|
||||
ConnectionTypeReconnectingPty,
|
||||
ConnectionTypeWorkspaceApp,
|
||||
ConnectionTypePortForwarding,
|
||||
ConnectionTypeTunnel,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4049,6 +4049,20 @@ func TestConnectionLogsOffsetFilters(t *testing.T) {
|
||||
UserID: uuid.NullUUID{UUID: user3.ID, Valid: true},
|
||||
})
|
||||
|
||||
// Tunnel events are point-in-time (no disconnect event is ever
|
||||
// reported), so despite having a NULL disconnect_time they must be
|
||||
// excluded from both status filters.
|
||||
log5 := dbgen.ConnectionLog(t, db, database.UpsertConnectionLogParams{
|
||||
Time: now.Add(-30 * time.Minute),
|
||||
OrganizationID: ws1.OrganizationID,
|
||||
WorkspaceOwnerID: ws1.OwnerID,
|
||||
WorkspaceID: ws1.ID,
|
||||
WorkspaceName: ws1.Name,
|
||||
Type: database.ConnectionTypeTunnel,
|
||||
ConnectionStatus: database.ConnectionStatusConnected,
|
||||
UserID: uuid.NullUUID{UUID: user1.ID, Valid: true},
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
params database.GetConnectionLogsOffsetParams
|
||||
@@ -4058,7 +4072,7 @@ func TestConnectionLogsOffsetFilters(t *testing.T) {
|
||||
name: "NoFilter",
|
||||
params: database.GetConnectionLogsOffsetParams{},
|
||||
expectedLogIDs: []uuid.UUID{
|
||||
log1.ID, log2.ID, log3.ID, log4.ID,
|
||||
log1.ID, log2.ID, log3.ID, log4.ID, log5.ID,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -4073,14 +4087,14 @@ func TestConnectionLogsOffsetFilters(t *testing.T) {
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
WorkspaceOwner: user1.Username,
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log2.ID},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log2.ID, log5.ID},
|
||||
},
|
||||
{
|
||||
name: "WorkspaceOwnerID",
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
WorkspaceOwnerID: user1.ID,
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log2.ID},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log2.ID, log5.ID},
|
||||
},
|
||||
{
|
||||
name: "WorkspaceOwnerEmail",
|
||||
@@ -4096,19 +4110,26 @@ func TestConnectionLogsOffsetFilters(t *testing.T) {
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log2.ID, log4.ID},
|
||||
},
|
||||
{
|
||||
name: "TypeTunnel",
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
Type: string(database.ConnectionTypeTunnel),
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log5.ID},
|
||||
},
|
||||
{
|
||||
name: "UserID",
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
UserID: user1.ID,
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log5.ID},
|
||||
},
|
||||
{
|
||||
name: "Username",
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
Username: user1.Username,
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID},
|
||||
expectedLogIDs: []uuid.UUID{log1.ID, log5.ID},
|
||||
},
|
||||
{
|
||||
name: "UserEmail",
|
||||
@@ -4122,7 +4143,7 @@ func TestConnectionLogsOffsetFilters(t *testing.T) {
|
||||
params: database.GetConnectionLogsOffsetParams{
|
||||
ConnectedAfter: now.Add(-90 * time.Minute), // 1.5 hours ago
|
||||
},
|
||||
expectedLogIDs: []uuid.UUID{log4.ID},
|
||||
expectedLogIDs: []uuid.UUID{log4.ID, log5.ID},
|
||||
},
|
||||
{
|
||||
name: "ConnectedBefore",
|
||||
|
||||
Generated
+6
-4
@@ -13742,8 +13742,9 @@ SELECT COUNT(*) AS count FROM (
|
||||
WHEN $13 :: text != '' THEN
|
||||
(($13 = 'ongoing' AND disconnect_time IS NULL) OR
|
||||
($13 = 'completed' AND disconnect_time IS NOT NULL)) AND
|
||||
-- Exclude web events, since we don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding')
|
||||
-- Exclude point-in-time events reported by coderd, since we
|
||||
-- don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding', 'tunnel')
|
||||
ELSE true
|
||||
END
|
||||
-- Authorize Filter clause will be injected below in
|
||||
@@ -13936,8 +13937,9 @@ WHERE
|
||||
WHEN $13 :: text != '' THEN
|
||||
(($13 = 'ongoing' AND disconnect_time IS NULL) OR
|
||||
($13 = 'completed' AND disconnect_time IS NOT NULL)) AND
|
||||
-- Exclude web events, since we don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding')
|
||||
-- Exclude point-in-time events reported by coderd, since we
|
||||
-- don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding', 'tunnel')
|
||||
ELSE true
|
||||
END
|
||||
-- Authorize Filter clause will be injected below in
|
||||
|
||||
@@ -115,8 +115,9 @@ WHERE
|
||||
WHEN @status :: text != '' THEN
|
||||
((@status = 'ongoing' AND disconnect_time IS NULL) OR
|
||||
(@status = 'completed' AND disconnect_time IS NOT NULL)) AND
|
||||
-- Exclude web events, since we don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding')
|
||||
-- Exclude point-in-time events reported by coderd, since we
|
||||
-- don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding', 'tunnel')
|
||||
ELSE true
|
||||
END
|
||||
-- Authorize Filter clause will be injected below in
|
||||
@@ -230,8 +231,9 @@ SELECT COUNT(*) AS count FROM (
|
||||
WHEN @status :: text != '' THEN
|
||||
((@status = 'ongoing' AND disconnect_time IS NULL) OR
|
||||
(@status = 'completed' AND disconnect_time IS NOT NULL)) AND
|
||||
-- Exclude web events, since we don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding')
|
||||
-- Exclude point-in-time events reported by coderd, since we
|
||||
-- don't know their close time.
|
||||
"type" NOT IN ('workspace_app', 'port_forwarding', 'tunnel')
|
||||
ELSE true
|
||||
END
|
||||
-- Authorize Filter clause will be injected below in
|
||||
|
||||
Reference in New Issue
Block a user