mirror of https://github.com/coder/coder.git
feat(coderd): add provisioner build version and api_version on serve (#11369)
* assert provisioner daemon version and api_version in unit tests * add build info in HTTP header, extract codersdk.BuildVersionHeader * add api_version to codersdk.ProvisionerDaemon * testutil.MustString -> testutil.MustRandString
This commit is contained in:
parent
9031b498ea
commit
1ef96022b0
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/coder/v2/cli/cliui"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
)
|
||||
|
||||
|
@ -58,7 +59,7 @@ func TestLogin(t *testing.T) {
|
|||
t.Parallel()
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("X-Coder-Build-Version", "something")
|
||||
w.Header().Set(codersdk.BuildVersionHeader, "something")
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
w.Write([]byte("Not Found"))
|
||||
}))
|
||||
|
|
|
@ -10052,6 +10052,9 @@ const docTemplate = `{
|
|||
"codersdk.ProvisionerDaemon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
|
|
|
@ -9036,6 +9036,9 @@
|
|||
"codersdk.ProvisionerDaemon": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"api_version": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
|
|
|
@ -564,7 +564,7 @@ func New(options *Options) *API {
|
|||
// Build-Version is helpful for debugging.
|
||||
func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("X-Coder-Build-Version", buildinfo.Version())
|
||||
w.Header().Add(codersdk.BuildVersionHeader, buildinfo.Version())
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
},
|
||||
|
@ -1194,7 +1194,7 @@ func (api *API) CreateInMemoryProvisionerDaemon(ctx context.Context, name string
|
|||
Tags: provisionersdk.MutateTags(uuid.Nil, nil),
|
||||
LastSeenAt: sql.NullTime{Time: dbtime.Now(), Valid: true},
|
||||
Version: buildinfo.Version(),
|
||||
APIVersion: "1.0",
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to create in-memory provisioner daemon: %w", err)
|
||||
|
|
|
@ -7279,6 +7279,7 @@ func (q *FakeQuerier) UpsertProvisionerDaemon(_ context.Context, arg database.Up
|
|||
ReplicaID: uuid.NullUUID{},
|
||||
LastSeenAt: arg.LastSeenAt,
|
||||
Version: arg.Version,
|
||||
APIVersion: arg.APIVersion,
|
||||
}
|
||||
q.provisionerDaemons = append(q.provisionerDaemons, d)
|
||||
return d, nil
|
||||
|
|
|
@ -218,7 +218,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
|
|||
CreatedAt: now.Add(-14 * 24 * time.Hour),
|
||||
LastSeenAt: sql.NullTime{Valid: true, Time: now.Add(-7 * 24 * time.Hour).Add(time.Minute)},
|
||||
Version: "1.0.0",
|
||||
APIVersion: "1.0",
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
|
||||
|
@ -229,7 +229,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
|
|||
CreatedAt: now.Add(-8 * 24 * time.Hour),
|
||||
LastSeenAt: sql.NullTime{Valid: true, Time: now.Add(-8 * 24 * time.Hour).Add(time.Hour)},
|
||||
Version: "1.0.0",
|
||||
APIVersion: "1.0",
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
|
||||
|
@ -242,7 +242,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
|
|||
},
|
||||
CreatedAt: now.Add(-9 * 24 * time.Hour),
|
||||
Version: "1.0.0",
|
||||
APIVersion: "1.0",
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = db.UpsertProvisionerDaemon(ctx, database.UpsertProvisionerDaemonParams{
|
||||
|
@ -256,7 +256,7 @@ func TestDeleteOldProvisionerDaemons(t *testing.T) {
|
|||
CreatedAt: now.Add(-6 * 24 * time.Hour),
|
||||
LastSeenAt: sql.NullTime{Valid: true, Time: now.Add(-6 * 24 * time.Hour)},
|
||||
Version: "1.0.0",
|
||||
APIVersion: "1.0",
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import (
|
|||
"golang.org/x/oauth2"
|
||||
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/cli/clibase"
|
||||
"github.com/coder/coder/v2/coderd/audit"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
|
@ -1784,8 +1785,8 @@ func setup(t *testing.T, ignoreLogErrors bool, ov *overrides) (proto.DRPCProvisi
|
|||
Provisioners: []database.ProvisionerType{database.ProvisionerTypeEcho},
|
||||
Tags: database.StringMap{},
|
||||
LastSeenAt: sql.NullTime{},
|
||||
Version: "",
|
||||
APIVersion: "1.0",
|
||||
Version: buildinfo.Version(),
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -78,6 +78,9 @@ const (
|
|||
|
||||
// ProvisionerDaemonPSK contains the authentication pre-shared key for an external provisioner daemon
|
||||
ProvisionerDaemonPSK = "Coder-Provisioner-Daemon-PSK"
|
||||
|
||||
// BuildVersionHeader contains build information of Coder.
|
||||
BuildVersionHeader = "X-Coder-Build-Version"
|
||||
)
|
||||
|
||||
// loggableMimeTypes is a list of MIME types that are safe to log
|
||||
|
|
|
@ -15,6 +15,7 @@ import (
|
|||
"golang.org/x/xerrors"
|
||||
"nhooyr.io/websocket"
|
||||
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/codersdk/drpc"
|
||||
"github.com/coder/coder/v2/provisionerd/proto"
|
||||
"github.com/coder/coder/v2/provisionerd/runner"
|
||||
|
@ -41,6 +42,7 @@ type ProvisionerDaemon struct {
|
|||
LastSeenAt NullTime `json:"last_seen_at,omitempty" format:"date-time"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
APIVersion string `json:"api_version"`
|
||||
Provisioners []ProvisionerType `json:"provisioners"`
|
||||
Tags map[string]string `json:"tags"`
|
||||
}
|
||||
|
@ -212,6 +214,7 @@ func (c *Client) ServeProvisionerDaemon(ctx context.Context, req ServeProvisione
|
|||
}
|
||||
headers := http.Header{}
|
||||
|
||||
headers.Set(BuildVersionHeader, buildinfo.Version())
|
||||
if req.PreSharedKey == "" {
|
||||
// use session token if we don't have a PSK.
|
||||
jar, err := cookiejar.New(nil)
|
||||
|
|
|
@ -203,7 +203,7 @@ func (c *Client) HasFirstUser(ctx context.Context) (bool, error) {
|
|||
if res.StatusCode == http.StatusNotFound {
|
||||
// ensure we are talking to coder and not
|
||||
// some other service that returns 404
|
||||
v := res.Header.Get("X-Coder-Build-Version")
|
||||
v := res.Header.Get(BuildVersionHeader)
|
||||
if v == "" {
|
||||
return false, xerrors.Errorf("missing build version header, not a coder instance")
|
||||
}
|
||||
|
|
|
@ -1051,6 +1051,7 @@ curl -X GET http://coder-server:8080/api/v2/organizations/{organization}/provisi
|
|||
```json
|
||||
[
|
||||
{
|
||||
"api_version": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -1078,6 +1079,7 @@ Status Code **200**
|
|||
| Name | Type | Required | Restrictions | Description |
|
||||
| ------------------- | ----------------- | -------- | ------------ | ----------- |
|
||||
| `[array item]` | array | false | | |
|
||||
| `» api_version` | string | false | | |
|
||||
| `» created_at` | string(date-time) | false | | |
|
||||
| `» id` | string(uuid) | false | | |
|
||||
| `» last_seen_at` | string(date-time) | false | | |
|
||||
|
|
|
@ -3902,6 +3902,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
|
||||
```json
|
||||
{
|
||||
"api_version": "string",
|
||||
"created_at": "2019-08-24T14:15:22Z",
|
||||
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
|
||||
"last_seen_at": "2019-08-24T14:15:22Z",
|
||||
|
@ -3919,6 +3920,7 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
|
|||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| ------------------ | --------------- | -------- | ------------ | ----------- |
|
||||
| `api_version` | string | false | | |
|
||||
| `created_at` | string | false | | |
|
||||
| `id` | string | false | | |
|
||||
| `last_seen_at` | string | false | | |
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/cli/clitest"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
|
@ -49,6 +50,8 @@ func TestProvisionerDaemon_PSK(t *testing.T) {
|
|||
}, testutil.WaitShort, testutil.IntervalSlow)
|
||||
require.Equal(t, "matt-daemon", daemons[0].Name)
|
||||
require.Equal(t, provisionersdk.ScopeOrganization, daemons[0].Tags[provisionersdk.TagScope])
|
||||
require.Equal(t, buildinfo.Version(), daemons[0].Version)
|
||||
require.Equal(t, provisionersdk.APIVersionCurrent, daemons[0].APIVersion)
|
||||
}
|
||||
|
||||
func TestProvisionerDaemon_SessionToken(t *testing.T) {
|
||||
|
@ -84,6 +87,8 @@ func TestProvisionerDaemon_SessionToken(t *testing.T) {
|
|||
assert.Equal(t, "my-daemon", daemons[0].Name)
|
||||
assert.Equal(t, provisionersdk.ScopeUser, daemons[0].Tags[provisionersdk.TagScope])
|
||||
assert.Equal(t, anotherUser.ID.String(), daemons[0].Tags[provisionersdk.TagOwner])
|
||||
assert.Equal(t, buildinfo.Version(), daemons[0].Version)
|
||||
assert.Equal(t, provisionersdk.APIVersionCurrent, daemons[0].APIVersion)
|
||||
})
|
||||
|
||||
t.Run("ScopeAnotherUser", func(t *testing.T) {
|
||||
|
@ -118,6 +123,8 @@ func TestProvisionerDaemon_SessionToken(t *testing.T) {
|
|||
assert.Equal(t, provisionersdk.ScopeUser, daemons[0].Tags[provisionersdk.TagScope])
|
||||
// This should get clobbered to the user who started the daemon.
|
||||
assert.Equal(t, anotherUser.ID.String(), daemons[0].Tags[provisionersdk.TagOwner])
|
||||
assert.Equal(t, buildinfo.Version(), daemons[0].Version)
|
||||
assert.Equal(t, provisionersdk.APIVersionCurrent, daemons[0].APIVersion)
|
||||
})
|
||||
|
||||
t.Run("ScopeOrg", func(t *testing.T) {
|
||||
|
@ -150,5 +157,7 @@ func TestProvisionerDaemon_SessionToken(t *testing.T) {
|
|||
}, testutil.WaitShort, testutil.IntervalSlow)
|
||||
assert.Equal(t, "org-daemon", daemons[0].Name)
|
||||
assert.Equal(t, provisionersdk.ScopeOrganization, daemons[0].Tags[provisionersdk.TagScope])
|
||||
assert.Equal(t, buildinfo.Version(), daemons[0].Version)
|
||||
assert.Equal(t, provisionersdk.APIVersionCurrent, daemons[0].APIVersion)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@ import (
|
|||
"github.com/coder/coder/v2/coderd/database/dbgen"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtestutil"
|
||||
"github.com/coder/coder/v2/coderd/database/postgres"
|
||||
"github.com/coder/coder/v2/cryptorand"
|
||||
"github.com/coder/coder/v2/enterprise/dbcrypt"
|
||||
"github.com/coder/coder/v2/pty/ptytest"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
// TestServerDBCrypt tests end-to-end encryption, decryption, and deletion
|
||||
|
@ -50,7 +50,7 @@ func TestServerDBCrypt(t *testing.T) {
|
|||
users := genData(t, db)
|
||||
|
||||
// Setup an initial cipher A
|
||||
keyA := mustString(t, 32)
|
||||
keyA := testutil.MustRandString(t, 32)
|
||||
cipherA, err := dbcrypt.NewCiphers([]byte(keyA))
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -87,7 +87,7 @@ func TestServerDBCrypt(t *testing.T) {
|
|||
}
|
||||
|
||||
// Re-encrypt all existing data with a new cipher.
|
||||
keyB := mustString(t, 32)
|
||||
keyB := testutil.MustRandString(t, 32)
|
||||
cipherBA, err := dbcrypt.NewCiphers([]byte(keyB), []byte(keyA))
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -160,7 +160,7 @@ func TestServerDBCrypt(t *testing.T) {
|
|||
}
|
||||
|
||||
// Re-encrypt all existing data with a new cipher.
|
||||
keyC := mustString(t, 32)
|
||||
keyC := testutil.MustRandString(t, 32)
|
||||
cipherC, err := dbcrypt.NewCiphers([]byte(keyC))
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -222,7 +222,7 @@ func genData(t *testing.T, db database.Store) []database.User {
|
|||
for _, status := range database.AllUserStatusValues() {
|
||||
for _, loginType := range database.AllLoginTypeValues() {
|
||||
for _, deleted := range []bool{false, true} {
|
||||
randName := mustString(t, 32)
|
||||
randName := testutil.MustRandString(t, 32)
|
||||
usr := dbgen.User(t, db, database.User{
|
||||
Username: randName,
|
||||
Email: randName + "@notcoder.com",
|
||||
|
@ -252,13 +252,6 @@ func genData(t *testing.T, db database.Store) []database.User {
|
|||
return users
|
||||
}
|
||||
|
||||
func mustString(t *testing.T, n int) string {
|
||||
t.Helper()
|
||||
s, err := cryptorand.String(n)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
||||
|
||||
func requireEncryptedEquals(t *testing.T, c dbcrypt.Cipher, expected, actual string) {
|
||||
t.Helper()
|
||||
var decodedVal []byte
|
||||
|
|
|
@ -233,6 +233,8 @@ func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request)
|
|||
authCtx = dbauthz.AsSystemRestricted(ctx)
|
||||
}
|
||||
|
||||
versionHdrVal := r.Header.Get(codersdk.BuildVersionHeader)
|
||||
|
||||
// Create the daemon in the database.
|
||||
now := dbtime.Now()
|
||||
daemon, err := api.Database.UpsertProvisionerDaemon(authCtx, database.UpsertProvisionerDaemonParams{
|
||||
|
@ -241,8 +243,8 @@ func (api *API) provisionerDaemonServe(rw http.ResponseWriter, r *http.Request)
|
|||
Tags: tags,
|
||||
CreatedAt: now,
|
||||
LastSeenAt: sql.NullTime{Time: now, Valid: true},
|
||||
Version: "", // TODO: provisionerd needs to send version
|
||||
APIVersion: "1.0",
|
||||
Version: versionHdrVal,
|
||||
APIVersion: provisionersdk.APIVersionCurrent,
|
||||
})
|
||||
if err != nil {
|
||||
if !xerrors.Is(err, context.Canceled) {
|
||||
|
@ -361,6 +363,7 @@ func convertProvisionerDaemon(daemon database.ProvisionerDaemon) codersdk.Provis
|
|||
Name: daemon.Name,
|
||||
Tags: daemon.Tags,
|
||||
Version: daemon.Version,
|
||||
APIVersion: daemon.APIVersion,
|
||||
}
|
||||
for _, provisionerType := range daemon.Provisioners {
|
||||
result.Provisioners = append(result.Provisioners, codersdk.ProvisionerType(provisionerType))
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
|
||||
"cdr.dev/slog"
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
"github.com/coder/coder/v2/buildinfo"
|
||||
"github.com/coder/coder/v2/coderd/coderdtest"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
|
@ -40,9 +41,10 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
daemonName := testutil.MustRandString(t, 63)
|
||||
srv, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: daemonName,
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -54,7 +56,11 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
|
||||
daemons, err := client.ProvisionerDaemons(ctx) //nolint:gocritic // Test assertion.
|
||||
require.NoError(t, err)
|
||||
require.Len(t, daemons, 1)
|
||||
if assert.Len(t, daemons, 1) {
|
||||
assert.Equal(t, daemonName, daemons[0].Name)
|
||||
assert.Equal(t, buildinfo.Version(), daemons[0].Version)
|
||||
assert.Equal(t, provisionersdk.APIVersionCurrent, daemons[0].APIVersion)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("NoLicense", func(t *testing.T) {
|
||||
|
@ -63,9 +69,10 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
templateAdminClient, _ := coderdtest.CreateAnotherUser(t, client, user.OrganizationID, rbac.RoleTemplateAdmin())
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
daemonName := testutil.MustRandString(t, 63)
|
||||
_, err := templateAdminClient.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: daemonName,
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -90,7 +97,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
defer cancel()
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 63),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -117,7 +124,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
defer cancel()
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 63),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -212,7 +219,9 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
another := codersdk.New(client.URL)
|
||||
daemonName := testutil.MustRandString(t, 63)
|
||||
srv, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
Name: daemonName,
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -229,6 +238,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
daemons, err := client.ProvisionerDaemons(ctx) //nolint:gocritic // Test assertion.
|
||||
require.NoError(t, err)
|
||||
if assert.Len(t, daemons, 1) {
|
||||
assert.Equal(t, daemonName, daemons[0].Name)
|
||||
assert.Equal(t, provisionersdk.ScopeOrganization, daemons[0].Tags[provisionersdk.TagScope])
|
||||
}
|
||||
})
|
||||
|
@ -274,7 +284,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
pd := provisionerd.New(func(ctx context.Context) (provisionerdproto.DRPCProvisionerDaemonClient, error) {
|
||||
return another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 63),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -352,7 +362,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
defer cancel()
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 32),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -387,7 +397,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
another := codersdk.New(client.URL)
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 63),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
@ -420,7 +430,7 @@ func TestProvisionerDaemonServe(t *testing.T) {
|
|||
another := codersdk.New(client.URL)
|
||||
_, err := another.ServeProvisionerDaemon(ctx, codersdk.ServeProvisionerDaemonRequest{
|
||||
ID: uuid.New(),
|
||||
Name: t.Name(),
|
||||
Name: testutil.MustRandString(t, 63),
|
||||
Organization: user.OrganizationID,
|
||||
Provisioners: []codersdk.ProvisionerType{
|
||||
codersdk.ProvisionerTypeEcho,
|
||||
|
|
|
@ -323,7 +323,7 @@ func New(ctx context.Context, opts *Options) (*Server, error) {
|
|||
// Build-Version is helpful for debugging.
|
||||
func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Add("X-Coder-Build-Version", buildinfo.Version())
|
||||
w.Header().Add(codersdk.BuildVersionHeader, buildinfo.Version())
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
},
|
||||
|
|
|
@ -20,6 +20,13 @@ import (
|
|||
"github.com/coder/coder/v2/provisionersdk/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
// APIVersionCurrent is the current provisionerd API version.
|
||||
// Breaking changes to the provisionerd API **MUST** increment
|
||||
// the major version below.
|
||||
APIVersionCurrent = "1.0"
|
||||
)
|
||||
|
||||
// ServeOptions are configurations to serve a provisioner.
|
||||
type ServeOptions struct {
|
||||
// Listener serves multiple connections. Cannot be combined with Conn.
|
||||
|
|
|
@ -79,6 +79,7 @@ export const provisioners: TypesGen.ProvisionerDaemon[] = [
|
|||
provisioners: [],
|
||||
tags: {},
|
||||
version: "v2.34.5",
|
||||
api_version: "1.0",
|
||||
},
|
||||
{
|
||||
id: "cdr-basic",
|
||||
|
@ -87,6 +88,7 @@ export const provisioners: TypesGen.ProvisionerDaemon[] = [
|
|||
provisioners: [],
|
||||
tags: {},
|
||||
version: "v2.34.5",
|
||||
api_version: "1.0",
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -809,6 +809,7 @@ export interface ProvisionerDaemon {
|
|||
readonly last_seen_at?: string;
|
||||
readonly name: string;
|
||||
readonly version: string;
|
||||
readonly api_version: string;
|
||||
readonly provisioners: ProvisionerType[];
|
||||
readonly tags: Record<string, string>;
|
||||
}
|
||||
|
|
|
@ -336,6 +336,7 @@ export const MockProvisioner: TypesGen.ProvisionerDaemon = {
|
|||
provisioners: ["echo"],
|
||||
tags: { scope: "organization" },
|
||||
version: "v2.34.5",
|
||||
api_version: "1.0",
|
||||
};
|
||||
|
||||
export const MockUserProvisioner: TypesGen.ProvisionerDaemon = {
|
||||
|
@ -345,6 +346,7 @@ export const MockUserProvisioner: TypesGen.ProvisionerDaemon = {
|
|||
provisioners: ["echo"],
|
||||
tags: { scope: "user", owner: "12345678-abcd-1234-abcd-1234567890abcd" },
|
||||
version: "v2.34.5",
|
||||
api_version: "1.0",
|
||||
};
|
||||
|
||||
export const MockProvisionerJob: TypesGen.ProvisionerJob = {
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package testutil
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/v2/cryptorand"
|
||||
)
|
||||
|
||||
// MustRandString returns a random string of length n.
|
||||
func MustRandString(t *testing.T, n int) string {
|
||||
t.Helper()
|
||||
s, err := cryptorand.String(n)
|
||||
require.NoError(t, err)
|
||||
return s
|
||||
}
|
Loading…
Reference in New Issue