Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitcf8be4e

Browse files
authored
feat: add resume support to coordinator connections (#14234)
1 parent0b2ba96 commitcf8be4e

32 files changed

+1706
-465
lines changed

‎cli/server.go

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import (
5656
"cdr.dev/slog"
5757
"cdr.dev/slog/sloggers/sloghuman"
5858
"github.com/coder/pretty"
59+
"github.com/coder/quartz"
5960
"github.com/coder/retry"
6061
"github.com/coder/serpent"
6162
"github.com/coder/wgtunnel/tunnelsdk"
@@ -791,18 +792,26 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
791792
}
792793
}
793794

794-
keyBytes,err:=hex.DecodeString(oauthSigningKeyStr)
795+
oauthKeyBytes,err:=hex.DecodeString(oauthSigningKeyStr)
795796
iferr!=nil {
796797
returnxerrors.Errorf("decode oauth signing key from database: %w",err)
797798
}
798-
iflen(keyBytes)!=len(options.OAuthSigningKey) {
799-
returnxerrors.Errorf("oauth signing key in database is not the correct length, expect %d got %d",len(options.OAuthSigningKey),len(keyBytes))
799+
iflen(oauthKeyBytes)!=len(options.OAuthSigningKey) {
800+
returnxerrors.Errorf("oauth signing key in database is not the correct length, expect %d got %d",len(options.OAuthSigningKey),len(oauthKeyBytes))
800801
}
801-
copy(options.OAuthSigningKey[:],keyBytes)
802+
copy(options.OAuthSigningKey[:],oauthKeyBytes)
802803
ifoptions.OAuthSigningKey== [32]byte{} {
803804
returnxerrors.Errorf("oauth signing key in database is empty")
804805
}
805806

807+
// Read the coordinator resume token signing key from the
808+
// database.
809+
resumeTokenKey,err:=tailnet.ResumeTokenSigningKeyFromDatabase(ctx,tx)
810+
iferr!=nil {
811+
returnxerrors.Errorf("get coordinator resume token key from database: %w",err)
812+
}
813+
options.CoordinatorResumeTokenProvider=tailnet.NewResumeTokenKeyProvider(resumeTokenKey,quartz.NewReal(),tailnet.DefaultResumeTokenExpiry)
814+
806815
returnnil
807816
},nil)
808817
iferr!=nil {

‎coderd/coderd.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ type Options struct {
182182
// AppSecurityKey is the crypto key used to sign and encrypt tokens related to
183183
// workspace applications. It consists of both a signing and encryption key.
184184
AppSecurityKey workspaceapps.SecurityKey
185+
// CoordinatorResumeTokenProvider is used to provide and validate resume
186+
// tokens issued by and passed to the coordinator DRPC API.
187+
CoordinatorResumeTokenProvider tailnet.ResumeTokenProvider
185188

186189
HealthcheckFuncfunc(ctx context.Context,apiKeystring)*healthsdk.HealthcheckReport
187190
HealthcheckTimeout time.Duration
@@ -584,12 +587,16 @@ func New(options *Options) *API {
584587
api.Options.NetworkTelemetryBatchMaxSize,
585588
api.handleNetworkTelemetry,
586589
)
590+
ifoptions.CoordinatorResumeTokenProvider==nil {
591+
panic("CoordinatorResumeTokenProvider is nil")
592+
}
587593
api.TailnetClientService,err=tailnet.NewClientService(tailnet.ClientServiceOptions{
588594
Logger:api.Logger.Named("tailnetclient"),
589595
CoordPtr:&api.TailnetCoordinator,
590596
DERPMapUpdateFrequency:api.Options.DERPMapUpdateFrequency,
591597
DERPMapFn:api.DERPMap,
592598
NetworkTelemetryHandler:api.NetworkTelemetryBatcher.Handler,
599+
ResumeTokenProvider:api.Options.CoordinatorResumeTokenProvider,
593600
})
594601
iferr!=nil {
595602
api.Logger.Fatal(api.ctx,"failed to initialize tailnet client service",slog.Error(err))
@@ -614,6 +621,9 @@ func New(options *Options) *API {
614621
options.WorkspaceAppsStatsCollectorOptions.Reporter=api.statsReporter
615622
}
616623

624+
ifoptions.AppSecurityKey.IsZero() {
625+
api.Logger.Fatal(api.ctx,"app security key cannot be zero")
626+
}
617627
api.workspaceAppServer=&workspaceapps.Server{
618628
Logger:workspaceAppsLogger,
619629

‎coderd/coderdtest/coderdtest.go

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -96,25 +96,26 @@ type Options struct {
9696
// AccessURL denotes a custom access URL. By default we use the httptest
9797
// server's URL. Setting this may result in unexpected behavior (especially
9898
// with running agents).
99-
AccessURL*url.URL
100-
AppHostnamestring
101-
AWSCertificates awsidentity.Certificates
102-
Authorizer rbac.Authorizer
103-
AzureCertificates x509.VerifyOptions
104-
GithubOAuth2Config*coderd.GithubOAuth2Config
105-
RealIPConfig*httpmw.RealIPConfig
106-
OIDCConfig*coderd.OIDCConfig
107-
GoogleTokenValidator*idtoken.Validator
108-
SSHKeygenAlgorithm gitsshkey.Algorithm
109-
AutobuildTicker<-chan time.Time
110-
AutobuildStatschan<- autobuild.Stats
111-
Auditor audit.Auditor
112-
TLSCertificates []tls.Certificate
113-
ExternalAuthConfigs []*externalauth.Config
114-
TrialGeneratorfunc(ctx context.Context,body codersdk.LicensorTrialRequest)error
115-
RefreshEntitlementsfunc(ctx context.Context)error
116-
TemplateScheduleStore schedule.TemplateScheduleStore
117-
Coordinator tailnet.Coordinator
99+
AccessURL*url.URL
100+
AppHostnamestring
101+
AWSCertificates awsidentity.Certificates
102+
Authorizer rbac.Authorizer
103+
AzureCertificates x509.VerifyOptions
104+
GithubOAuth2Config*coderd.GithubOAuth2Config
105+
RealIPConfig*httpmw.RealIPConfig
106+
OIDCConfig*coderd.OIDCConfig
107+
GoogleTokenValidator*idtoken.Validator
108+
SSHKeygenAlgorithm gitsshkey.Algorithm
109+
AutobuildTicker<-chan time.Time
110+
AutobuildStatschan<- autobuild.Stats
111+
Auditor audit.Auditor
112+
TLSCertificates []tls.Certificate
113+
ExternalAuthConfigs []*externalauth.Config
114+
TrialGeneratorfunc(ctx context.Context,body codersdk.LicensorTrialRequest)error
115+
RefreshEntitlementsfunc(ctx context.Context)error
116+
TemplateScheduleStore schedule.TemplateScheduleStore
117+
Coordinator tailnet.Coordinator
118+
CoordinatorResumeTokenProvider tailnet.ResumeTokenProvider
118119

119120
HealthcheckFuncfunc(ctx context.Context,apiKeystring)*healthsdk.HealthcheckReport
120121
HealthcheckTimeout time.Duration
@@ -240,6 +241,9 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
240241
ifoptions.Database==nil {
241242
options.Database,options.Pubsub=dbtestutil.NewDB(t)
242243
}
244+
ifoptions.CoordinatorResumeTokenProvider==nil {
245+
options.CoordinatorResumeTokenProvider=tailnet.NewInsecureTestResumeTokenProvider()
246+
}
243247

244248
ifoptions.NotificationsEnqueuer==nil {
245249
options.NotificationsEnqueuer=new(testutil.FakeNotificationsEnqueuer)
@@ -492,6 +496,7 @@ func NewOptions(t testing.TB, options *Options) (func(http.Handler), context.Can
492496
TailnetCoordinator:options.Coordinator,
493497
BaseDERPMap:derpMap,
494498
DERPMapUpdateFrequency:150*time.Millisecond,
499+
CoordinatorResumeTokenProvider:options.CoordinatorResumeTokenProvider,
495500
MetricsCacheRefreshInterval:options.MetricsCacheRefreshInterval,
496501
AgentStatsRefreshInterval:options.AgentStatsRefreshInterval,
497502
DeploymentValues:options.DeploymentValues,

‎coderd/database/dbauthz/dbauthz.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,7 +1332,9 @@ func (q *querier) GetAnnouncementBanners(ctx context.Context) (string, error) {
13321332
}
13331333

13341334
func (q*querier)GetAppSecurityKey(ctx context.Context) (string,error) {
1335-
// No authz checks
1335+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
1336+
return"",err
1337+
}
13361338
returnq.db.GetAppSecurityKey(ctx)
13371339
}
13381340

@@ -1364,6 +1366,13 @@ func (q *querier) GetAuthorizationUserRoles(ctx context.Context, userID uuid.UUI
13641366
returnq.db.GetAuthorizationUserRoles(ctx,userID)
13651367
}
13661368

1369+
func (q*querier)GetCoordinatorResumeTokenSigningKey(ctx context.Context) (string,error) {
1370+
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
1371+
return"",err
1372+
}
1373+
returnq.db.GetCoordinatorResumeTokenSigningKey(ctx)
1374+
}
1375+
13671376
func (q*querier)GetDBCryptKeys(ctx context.Context) ([]database.DBCryptKey,error) {
13681377
iferr:=q.authorizeContext(ctx,policy.ActionRead,rbac.ResourceSystem);err!=nil {
13691378
returnnil,err
@@ -3792,7 +3801,9 @@ func (q *querier) UpsertAnnouncementBanners(ctx context.Context, value string) e
37923801
}
37933802

37943803
func (q*querier)UpsertAppSecurityKey(ctx context.Context,datastring)error {
3795-
// No authz checks as this is done during startup
3804+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
3805+
returnerr
3806+
}
37963807
returnq.db.UpsertAppSecurityKey(ctx,data)
37973808
}
37983809

@@ -3803,6 +3814,13 @@ func (q *querier) UpsertApplicationName(ctx context.Context, value string) error
38033814
returnq.db.UpsertApplicationName(ctx,value)
38043815
}
38053816

3817+
func (q*querier)UpsertCoordinatorResumeTokenSigningKey(ctx context.Context,valuestring)error {
3818+
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
3819+
returnerr
3820+
}
3821+
returnq.db.UpsertCoordinatorResumeTokenSigningKey(ctx,value)
3822+
}
3823+
38063824
func (q*querier)UpsertDefaultProxy(ctx context.Context,arg database.UpsertDefaultProxyParams)error {
38073825
iferr:=q.authorizeContext(ctx,policy.ActionUpdate,rbac.ResourceSystem);err!=nil {
38083826
returnerr

‎coderd/database/dbauthz/dbauthz_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2531,10 +2531,10 @@ func (s *MethodTestSuite) TestSystemFunctions() {
25312531
check.Args(int32(0)).Asserts(rbac.ResourceSystem,policy.ActionRead)
25322532
}))
25332533
s.Run("GetAppSecurityKey",s.Subtest(func(db database.Store,check*expects) {
2534-
check.Args().Asserts()
2534+
check.Args().Asserts(rbac.ResourceSystem,policy.ActionRead)
25352535
}))
25362536
s.Run("UpsertAppSecurityKey",s.Subtest(func(db database.Store,check*expects) {
2537-
check.Args("").Asserts()
2537+
check.Args("foo").Asserts(rbac.ResourceSystem,policy.ActionUpdate)
25382538
}))
25392539
s.Run("GetApplicationName",s.Subtest(func(db database.Store,check*expects) {
25402540
db.UpsertApplicationName(context.Background(),"foo")
@@ -2574,6 +2574,13 @@ func (s *MethodTestSuite) TestSystemFunctions() {
25742574
db.UpsertOAuthSigningKey(context.Background(),"foo")
25752575
check.Args().Asserts(rbac.ResourceSystem,policy.ActionUpdate)
25762576
}))
2577+
s.Run("UpsertCoordinatorResumeTokenSigningKey",s.Subtest(func(db database.Store,check*expects) {
2578+
check.Args("foo").Asserts(rbac.ResourceSystem,policy.ActionUpdate)
2579+
}))
2580+
s.Run("GetCoordinatorResumeTokenSigningKey",s.Subtest(func(db database.Store,check*expects) {
2581+
db.UpsertCoordinatorResumeTokenSigningKey(context.Background(),"foo")
2582+
check.Args().Asserts(rbac.ResourceSystem,policy.ActionRead)
2583+
}))
25772584
s.Run("InsertMissingGroups",s.Subtest(func(db database.Store,check*expects) {
25782585
check.Args(database.InsertMissingGroupsParams{}).Asserts(rbac.ResourceSystem,policy.ActionCreate).Errors(errMatchAny)
25792586
}))

‎coderd/database/dbmem/dbmem.go

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -196,20 +196,21 @@ type data struct {
196196
customRoles []database.CustomRole
197197
// Locks is a map of lock names. Any keys within the map are currently
198198
// locked.
199-
locksmap[int64]struct{}
200-
deploymentIDstring
201-
derpMeshKeystring
202-
lastUpdateCheck []byte
203-
announcementBanners []byte
204-
healthSettings []byte
205-
notificationsSettings []byte
206-
applicationNamestring
207-
logoURLstring
208-
appSecurityKeystring
209-
oauthSigningKeystring
210-
lastLicenseIDint32
211-
defaultProxyDisplayNamestring
212-
defaultProxyIconURLstring
199+
locksmap[int64]struct{}
200+
deploymentIDstring
201+
derpMeshKeystring
202+
lastUpdateCheck []byte
203+
announcementBanners []byte
204+
healthSettings []byte
205+
notificationsSettings []byte
206+
applicationNamestring
207+
logoURLstring
208+
appSecurityKeystring
209+
oauthSigningKeystring
210+
coordinatorResumeTokenSigningKeystring
211+
lastLicenseIDint32
212+
defaultProxyDisplayNamestring
213+
defaultProxyIconURLstring
213214
}
214215

215216
funcvalidateDatabaseTypeWithValid(v reflect.Value) (handledbool,errerror) {
@@ -2222,6 +2223,15 @@ func (q *FakeQuerier) GetAuthorizationUserRoles(_ context.Context, userID uuid.U
22222223
},nil
22232224
}
22242225

2226+
func (q*FakeQuerier)GetCoordinatorResumeTokenSigningKey(_ context.Context) (string,error) {
2227+
q.mutex.RLock()
2228+
deferq.mutex.RUnlock()
2229+
ifq.coordinatorResumeTokenSigningKey=="" {
2230+
return"",sql.ErrNoRows
2231+
}
2232+
returnq.coordinatorResumeTokenSigningKey,nil
2233+
}
2234+
22252235
func (q*FakeQuerier)GetDBCryptKeys(_ context.Context) ([]database.DBCryptKey,error) {
22262236
q.mutex.RLock()
22272237
deferq.mutex.RUnlock()
@@ -8942,6 +8952,14 @@ func (q *FakeQuerier) UpsertApplicationName(_ context.Context, data string) erro
89428952
returnnil
89438953
}
89448954

8955+
func (q*FakeQuerier)UpsertCoordinatorResumeTokenSigningKey(_ context.Context,valuestring)error {
8956+
q.mutex.Lock()
8957+
deferq.mutex.Unlock()
8958+
8959+
q.coordinatorResumeTokenSigningKey=value
8960+
returnnil
8961+
}
8962+
89458963
func (q*FakeQuerier)UpsertDefaultProxy(_ context.Context,arg database.UpsertDefaultProxyParams)error {
89468964
q.defaultProxyDisplayName=arg.DisplayName
89478965
q.defaultProxyIconURL=arg.IconUrl

‎coderd/database/dbmetrics/dbmetrics.go

Lines changed: 14 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/dbmock/dbmock.go

Lines changed: 29 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/querier.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp