Skip to content

Commit a230dec

Browse files
authored
Merge branch 'jaaydenh/dynamic-params-websocket' into jaaydenh/dynamic-params-diagnostics
2 parents 0658c35 + 71d8fa9 commit a230dec

File tree

21 files changed

+796
-100
lines changed

21 files changed

+796
-100
lines changed

agent/reconnectingpty/screen.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,9 @@ func (rpty *screenReconnectingPTY) doAttach(ctx context.Context, conn net.Conn,
307307
if closeErr != nil {
308308
logger.Debug(ctx, "closed ptty with error", slog.Error(closeErr))
309309
}
310-
closeErr = process.Kill()
311-
if closeErr != nil {
312-
logger.Debug(ctx, "killed process with error", slog.Error(closeErr))
310+
killErr := process.Kill()
311+
if killErr != nil {
312+
logger.Debug(ctx, "killed process with error", slog.Error(killErr))
313313
}
314314
rpty.metrics.WithLabelValues("screen_wait").Add(1)
315315
return nil, nil, err

cli/configssh_test.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
435435
"# :hostname-suffix=coder-suffix",
436436
"# :header=X-Test-Header=foo",
437437
"# :header=X-Test-Header2=bar",
438-
"# :header-command=printf h1=v1 h2=\"v2\" h3='v3'",
438+
"# :header-command=echo h1=v1 h2=\"v2\" h3='v3'",
439439
"#",
440440
}, "\n"),
441441
strings.Join([]string{
@@ -451,7 +451,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
451451
"--hostname-suffix", "coder-suffix",
452452
"--header", "X-Test-Header=foo",
453453
"--header", "X-Test-Header2=bar",
454-
"--header-command", "printf h1=v1 h2=\"v2\" h3='v3'",
454+
"--header-command", "echo h1=v1 h2=\"v2\" h3='v3'",
455455
},
456456
},
457457
{
@@ -566,36 +566,36 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
566566
name: "Header command",
567567
args: []string{
568568
"--yes",
569-
"--header-command", "printf h1=v1",
569+
"--header-command", "echo h1=v1",
570570
},
571571
wantErr: false,
572572
hasAgent: true,
573573
wantConfig: wantConfig{
574-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1" ssh .* --ssh-host-prefix coder. %h`,
574+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1" ssh .* --ssh-host-prefix coder. %h`,
575575
},
576576
},
577577
{
578578
name: "Header command with double quotes",
579579
args: []string{
580580
"--yes",
581-
"--header-command", "printf h1=v1 h2=\"v2\"",
581+
"--header-command", "echo h1=v1 h2=\"v2\"",
582582
},
583583
wantErr: false,
584584
hasAgent: true,
585585
wantConfig: wantConfig{
586-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1 h2=\\\"v2\\\"" ssh .* --ssh-host-prefix coder. %h`,
586+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1 h2=\\\"v2\\\"" ssh .* --ssh-host-prefix coder. %h`,
587587
},
588588
},
589589
{
590590
name: "Header command with single quotes",
591591
args: []string{
592592
"--yes",
593-
"--header-command", "printf h1=v1 h2='v2'",
593+
"--header-command", "echo h1=v1 h2='v2'",
594594
},
595595
wantErr: false,
596596
hasAgent: true,
597597
wantConfig: wantConfig{
598-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1 h2='v2'" ssh .* --ssh-host-prefix coder. %h`,
598+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1 h2='v2'" ssh .* --ssh-host-prefix coder. %h`,
599599
},
600600
},
601601
{

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ func (s *MethodTestSuite) TestOrganization() {
886886
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: a.ID})
887887
b := dbgen.Organization(s.T(), db, database.Organization{})
888888
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: b.ID})
889-
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: false}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
889+
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: sql.NullBool{Valid: true, Bool: false}}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
890890
}))
891891
s.Run("InsertOrganization", s.Subtest(func(db database.Store, check *expects) {
892892
check.Args(database.InsertOrganizationParams{
@@ -994,8 +994,7 @@ func (s *MethodTestSuite) TestOrganization() {
994994
member, policy.ActionRead,
995995
member, policy.ActionDelete).
996996
WithNotAuthorized("no rows").
997-
WithCancelled(cancelledErr).
998-
ErrorsWithInMemDB(sql.ErrNoRows)
997+
WithCancelled(cancelledErr)
999998
}))
1000999
s.Run("UpdateOrganization", s.Subtest(func(db database.Store, check *expects) {
10011000
o := dbgen.Organization(s.T(), db, database.Organization{

coderd/database/dbfake/builder.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type OrganizationBuilder struct {
1717
t *testing.T
1818
db database.Store
1919
seed database.Organization
20+
delete bool
2021
allUsersAllowance int32
2122
members []uuid.UUID
2223
groups map[database.Group][]uuid.UUID
@@ -45,6 +46,12 @@ func (b OrganizationBuilder) EveryoneAllowance(allowance int) OrganizationBuilde
4546
return b
4647
}
4748

49+
func (b OrganizationBuilder) Deleted(deleted bool) OrganizationBuilder {
50+
//nolint: revive // returns modified struct
51+
b.delete = deleted
52+
return b
53+
}
54+
4855
func (b OrganizationBuilder) Seed(seed database.Organization) OrganizationBuilder {
4956
//nolint: revive // returns modified struct
5057
b.seed = seed
@@ -119,6 +126,17 @@ func (b OrganizationBuilder) Do() OrganizationResponse {
119126
}
120127
}
121128

129+
if b.delete {
130+
now := dbtime.Now()
131+
err = b.db.UpdateOrganizationDeletedByID(ctx, database.UpdateOrganizationDeletedByIDParams{
132+
UpdatedAt: now,
133+
ID: org.ID,
134+
})
135+
require.NoError(b.t, err)
136+
org.Deleted = true
137+
org.UpdatedAt = now
138+
}
139+
122140
return OrganizationResponse{
123141
Org: org,
124142
AllUsersGroup: everyone,

coderd/database/dbmem/dbmem.go

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2357,10 +2357,13 @@ func (q *FakeQuerier) DeleteOrganizationMember(ctx context.Context, arg database
23572357
q.mutex.Lock()
23582358
defer q.mutex.Unlock()
23592359

2360-
deleted := slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
2361-
return member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
2360+
deleted := false
2361+
q.data.organizationMembers = slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
2362+
match := member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
2363+
deleted = deleted || match
2364+
return match
23622365
})
2363-
if len(deleted) == 0 {
2366+
if !deleted {
23642367
return sql.ErrNoRows
23652368
}
23662369

@@ -4156,6 +4159,9 @@ func (q *FakeQuerier) GetOrganizations(_ context.Context, args database.GetOrgan
41564159
if args.Name != "" && !strings.EqualFold(org.Name, args.Name) {
41574160
continue
41584161
}
4162+
if args.Deleted != org.Deleted {
4163+
continue
4164+
}
41594165
tmp = append(tmp, org)
41604166
}
41614167

@@ -4172,7 +4178,11 @@ func (q *FakeQuerier) GetOrganizationsByUserID(_ context.Context, arg database.G
41724178
continue
41734179
}
41744180
for _, organization := range q.organizations {
4175-
if organization.ID != organizationMember.OrganizationID || organization.Deleted != arg.Deleted {
4181+
if organization.ID != organizationMember.OrganizationID {
4182+
continue
4183+
}
4184+
4185+
if arg.Deleted.Valid && organization.Deleted != arg.Deleted.Bool {
41764186
continue
41774187
}
41784188
organizations = append(organizations, organization)

coderd/database/queries.sql.go

Lines changed: 9 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/organizations.sql

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ SELECT
5555
FROM
5656
organizations
5757
WHERE
58-
-- Optionally include deleted organizations
59-
deleted = @deleted AND
58+
-- Optionally provide a filter for deleted organizations.
59+
CASE WHEN
60+
sqlc.narg('deleted') :: boolean IS NULL THEN
61+
true
62+
ELSE
63+
deleted = sqlc.narg('deleted')
64+
END AND
6065
id = ANY(
6166
SELECT
6267
organization_id

coderd/httpmw/prometheus.go

Lines changed: 42 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package httpmw
33
import (
44
"net/http"
55
"strconv"
6+
"strings"
67
"time"
78

89
"github.com/go-chi/chi/v5"
@@ -22,18 +23,18 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
2223
Name: "requests_processed_total",
2324
Help: "The total number of processed API requests",
2425
}, []string{"code", "method", "path"})
25-
requestsConcurrent := factory.NewGauge(prometheus.GaugeOpts{
26+
requestsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{
2627
Namespace: "coderd",
2728
Subsystem: "api",
2829
Name: "concurrent_requests",
2930
Help: "The number of concurrent API requests.",
30-
})
31-
websocketsConcurrent := factory.NewGauge(prometheus.GaugeOpts{
31+
}, []string{"method", "path"})
32+
websocketsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{
3233
Namespace: "coderd",
3334
Subsystem: "api",
3435
Name: "concurrent_websockets",
3536
Help: "The total number of concurrent API websockets.",
36-
})
37+
}, []string{"path"})
3738
websocketsDist := factory.NewHistogramVec(prometheus.HistogramOpts{
3839
Namespace: "coderd",
3940
Subsystem: "api",
@@ -61,7 +62,6 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
6162
var (
6263
start = time.Now()
6364
method = r.Method
64-
rctx = chi.RouteContext(r.Context())
6565
)
6666

6767
sw, ok := w.(*tracing.StatusWriter)
@@ -72,24 +72,25 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
7272
var (
7373
dist *prometheus.HistogramVec
7474
distOpts []string
75+
path = getRoutePattern(r)
7576
)
77+
7678
// We want to count WebSockets separately.
7779
if httpapi.IsWebsocketUpgrade(r) {
78-
websocketsConcurrent.Inc()
79-
defer websocketsConcurrent.Dec()
80+
websocketsConcurrent.WithLabelValues(path).Inc()
81+
defer websocketsConcurrent.WithLabelValues(path).Dec()
8082

8183
dist = websocketsDist
8284
} else {
83-
requestsConcurrent.Inc()
84-
defer requestsConcurrent.Dec()
85+
requestsConcurrent.WithLabelValues(method, path).Inc()
86+
defer requestsConcurrent.WithLabelValues(method, path).Dec()
8587

8688
dist = requestsDist
8789
distOpts = []string{method}
8890
}
8991

9092
next.ServeHTTP(w, r)
9193

92-
path := rctx.RoutePattern()
9394
distOpts = append(distOpts, path)
9495
statusStr := strconv.Itoa(sw.Status)
9596

@@ -98,3 +99,34 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
9899
})
99100
}
100101
}
102+
103+
func getRoutePattern(r *http.Request) string {
104+
rctx := chi.RouteContext(r.Context())
105+
if rctx == nil {
106+
return ""
107+
}
108+
109+
if pattern := rctx.RoutePattern(); pattern != "" {
110+
// Pattern is already available
111+
return pattern
112+
}
113+
114+
routePath := r.URL.Path
115+
if r.URL.RawPath != "" {
116+
routePath = r.URL.RawPath
117+
}
118+
119+
tctx := chi.NewRouteContext()
120+
routes := rctx.Routes
121+
if routes != nil && !routes.Match(tctx, r.Method, routePath) {
122+
// No matching pattern. /api/* requests will be matched as "UNKNOWN"
123+
// All other ones will be matched as "STATIC".
124+
if strings.HasPrefix(routePath, "/api/") {
125+
return "UNKNOWN"
126+
}
127+
return "STATIC"
128+
}
129+
130+
// tctx has the updated pattern, since Match mutates it
131+
return tctx.RoutePattern()
132+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy