Skip to content

Commit 0d29eaf

Browse files
committed
Move provisioner daemons query to enterprise
1 parent 3f0738e commit 0d29eaf

File tree

5 files changed

+94
-209
lines changed

5 files changed

+94
-209
lines changed

coderd/coderd.go

Lines changed: 63 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package coderd
22

33
import (
4+
"context"
45
"crypto/tls"
56
"crypto/x509"
67
"fmt"
@@ -18,10 +19,13 @@ import (
1819
"github.com/go-chi/chi/v5/middleware"
1920
"github.com/google/uuid"
2021
"github.com/klauspost/compress/zstd"
22+
"github.com/moby/moby/pkg/namesgenerator"
2123
"github.com/prometheus/client_golang/prometheus"
2224
"go.opentelemetry.io/otel/trace"
2325
"golang.org/x/xerrors"
2426
"google.golang.org/api/idtoken"
27+
"storj.io/drpc/drpcmux"
28+
"storj.io/drpc/drpcserver"
2529
"tailscale.com/derp"
2630
"tailscale.com/derp/derphttp"
2731
"tailscale.com/tailcfg"
@@ -37,12 +41,15 @@ import (
3741
"github.com/coder/coder/coderd/httpapi"
3842
"github.com/coder/coder/coderd/httpmw"
3943
"github.com/coder/coder/coderd/metricscache"
44+
"github.com/coder/coder/coderd/provisionerdserver"
4045
"github.com/coder/coder/coderd/rbac"
4146
"github.com/coder/coder/coderd/telemetry"
4247
"github.com/coder/coder/coderd/tracing"
4348
"github.com/coder/coder/coderd/workspacequota"
4449
"github.com/coder/coder/coderd/wsconncache"
4550
"github.com/coder/coder/codersdk"
51+
"github.com/coder/coder/provisionerd/proto"
52+
"github.com/coder/coder/provisionersdk"
4653
"github.com/coder/coder/site"
4754
"github.com/coder/coder/tailnet"
4855
)
@@ -329,13 +336,6 @@ func New(options *Options) *API {
329336
r.Get("/{fileID}", api.fileByID)
330337
r.Post("/", api.postFile)
331338
})
332-
333-
r.Route("/provisionerdaemons", func(r chi.Router) {
334-
r.Use(
335-
apiKeyMiddleware,
336-
)
337-
r.Get("/", api.provisionerDaemons)
338-
})
339339
r.Route("/organizations", func(r chi.Router) {
340340
r.Use(
341341
apiKeyMiddleware,
@@ -641,3 +641,59 @@ func compressHandler(h http.Handler) http.Handler {
641641

642642
return cmp.Handler(h)
643643
}
644+
645+
// CreateInMemoryProvisionerDaemon is an in-memory connection to a provisionerd. Useful when starting coderd and provisionerd
646+
// in the same process.
647+
func (api *API) CreateInMemoryProvisionerDaemon(ctx context.Context) (client proto.DRPCProvisionerDaemonClient, err error) {
648+
clientSession, serverSession := provisionersdk.TransportPipe()
649+
defer func() {
650+
if err != nil {
651+
_ = clientSession.Close()
652+
_ = serverSession.Close()
653+
}
654+
}()
655+
656+
name := namesgenerator.GetRandomName(1)
657+
daemon, err := api.Database.InsertProvisionerDaemon(ctx, database.InsertProvisionerDaemonParams{
658+
ID: uuid.New(),
659+
CreatedAt: database.Now(),
660+
Name: name,
661+
Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho, database.ProvisionerTypeTerraform},
662+
})
663+
if err != nil {
664+
return nil, xerrors.Errorf("insert provisioner daemon %q: %w", name, err)
665+
}
666+
667+
mux := drpcmux.New()
668+
err = proto.DRPCRegisterProvisionerDaemon(mux, &provisionerdserver.Server{
669+
AccessURL: api.AccessURL,
670+
ID: daemon.ID,
671+
Database: api.Database,
672+
Pubsub: api.Pubsub,
673+
Provisioners: daemon.Provisioners,
674+
Telemetry: api.Telemetry,
675+
Logger: api.Logger.Named(fmt.Sprintf("provisionerd-%s", daemon.Name)),
676+
})
677+
if err != nil {
678+
return nil, err
679+
}
680+
server := drpcserver.NewWithOptions(mux, drpcserver.Options{
681+
Log: func(err error) {
682+
if xerrors.Is(err, io.EOF) {
683+
return
684+
}
685+
api.Logger.Debug(ctx, "drpc server error", slog.Error(err))
686+
},
687+
})
688+
go func() {
689+
err := server.Serve(ctx, serverSession)
690+
if err != nil && !xerrors.Is(err, io.EOF) {
691+
api.Logger.Debug(ctx, "provisioner daemon disconnected", slog.Error(err))
692+
}
693+
// close the sessions so we don't leak goroutines serving them.
694+
_ = clientSession.Close()
695+
_ = serverSession.Close()
696+
}()
697+
698+
return proto.NewDRPCProvisionerDaemonClient(provisionersdk.Conn(clientSession)), nil
699+
}

coderd/coderdtest/authorize.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/coder/coder/codersdk"
2020
"github.com/coder/coder/provisioner/echo"
2121
"github.com/coder/coder/provisionersdk/proto"
22-
"github.com/coder/coder/testutil"
2322
)
2423

2524
func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
@@ -204,11 +203,6 @@ func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) {
204203
AssertAction: rbac.ActionRead,
205204
AssertObject: rbac.ResourceTemplate.InOrg(a.Version.OrganizationID),
206205
},
207-
"GET:/api/v2/provisionerdaemons": {
208-
StatusCode: http.StatusOK,
209-
AssertObject: rbac.ResourceProvisionerDaemon,
210-
},
211-
212206
"POST:/api/v2/parameters/{scope}/{id}": {
213207
AssertAction: rbac.ActionUpdate,
214208
AssertObject: rbac.ResourceTemplate,
@@ -303,16 +297,6 @@ func NewAuthTester(ctx context.Context, t *testing.T, client *codersdk.Client, a
303297
if !ok {
304298
t.Fail()
305299
}
306-
// The provisioner will call to coderd and register itself. This is async,
307-
// so we wait for it to occur.
308-
require.Eventually(t, func() bool {
309-
provisionerds, err := client.ProvisionerDaemons(ctx)
310-
return assert.NoError(t, err) && len(provisionerds) > 0
311-
}, testutil.WaitLong, testutil.IntervalSlow)
312-
313-
provisionerds, err := client.ProvisionerDaemons(ctx)
314-
require.NoError(t, err, "fetch provisioners")
315-
require.Len(t, provisionerds, 1)
316300

317301
organization, err := client.Organization(ctx, admin.OrganizationID)
318302
require.NoError(t, err, "fetch org")

coderd/provisionerdaemons.go

Lines changed: 0 additions & 110 deletions
This file was deleted.

coderd/provisionerdaemons_test.go

Lines changed: 0 additions & 76 deletions
This file was deleted.

enterprise/coderd/provisionerdaemons.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package coderd
22

33
import (
4+
"database/sql"
5+
"errors"
46
"fmt"
57
"io"
68
"net/http"
@@ -14,6 +16,7 @@ import (
1416

1517
"cdr.dev/slog"
1618

19+
"github.com/coder/coder/coderd"
1720
"github.com/coder/coder/coderd/database"
1821
"github.com/coder/coder/coderd/httpapi"
1922
"github.com/coder/coder/coderd/httpmw"
@@ -23,6 +26,34 @@ import (
2326
"github.com/coder/coder/provisionerd/proto"
2427
)
2528

29+
func (api *API) provisionerDaemons(rw http.ResponseWriter, r *http.Request) {
30+
ctx := r.Context()
31+
daemons, err := api.Database.GetProvisionerDaemons(ctx)
32+
if errors.Is(err, sql.ErrNoRows) {
33+
err = nil
34+
}
35+
if err != nil {
36+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
37+
Message: "Internal error fetching provisioner daemons.",
38+
Detail: err.Error(),
39+
})
40+
return
41+
}
42+
if daemons == nil {
43+
daemons = []database.ProvisionerDaemon{}
44+
}
45+
daemons, err = coderd.AuthorizeFilter(api.AGPL.HTTPAuth, r, rbac.ActionRead, daemons)
46+
if err != nil {
47+
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
48+
Message: "Internal error fetching provisioner daemons.",
49+
Detail: err.Error(),
50+
})
51+
return
52+
}
53+
54+
httpapi.Write(ctx, rw, http.StatusOK, daemons)
55+
}
56+
2657
func (api *API) postProvisionerDaemon(rw http.ResponseWriter, r *http.Request) {
2758
if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceProvisionerDaemon) {
2859
httpapi.Forbidden(rw)

0 commit comments

Comments
 (0)