diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 3a42b67c75f8e..9d8efa8d42f76 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -136,7 +136,7 @@ jobs:
# Check for any typos
- name: Check for typos
- uses: crate-ci/typos@v1.16.19
+ uses: crate-ci/typos@v1.16.21
with:
config: .github/workflows/typos.toml
diff --git a/.github/workflows/security.yaml b/.github/workflows/security.yaml
index 6685ea1d2a071..0f26a126da995 100644
--- a/.github/workflows/security.yaml
+++ b/.github/workflows/security.yaml
@@ -122,7 +122,7 @@ jobs:
image_name: ${{ steps.build.outputs.image }}
- name: Run Trivy vulnerability scanner
- uses: aquasecurity/trivy-action@fbd16365eb88e12433951383f5e99bd901fc618f
+ uses: aquasecurity/trivy-action@b77b85c0254bba6789e787844f0585cde1e56320
with:
image-ref: ${{ steps.build.outputs.image }}
format: sarif
diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml
index fe348b00b484b..ed6d1d0127bc0 100644
--- a/.github/workflows/stale.yaml
+++ b/.github/workflows/stale.yaml
@@ -52,8 +52,8 @@ jobs:
with:
token: ${{ github.token }}
repository: ${{ github.repository }}
- retain_days: 1
- keep_minimum_runs: 1
+ retain_days: 30
+ keep_minimum_runs: 30
delete_workflow_pattern: pr-cleanup.yaml
- name: Delete PR Deploy workflow skipped runs
@@ -61,7 +61,6 @@ jobs:
with:
token: ${{ github.token }}
repository: ${{ github.repository }}
- retain_days: 0
- keep_minimum_runs: 0
- delete_run_by_conclusion_pattern: skipped
+ retain_days: 30
+ keep_minimum_runs: 30
delete_workflow_pattern: pr-deploy.yaml
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 0664d7e81cc75..6f726162d260a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -20,7 +20,7 @@
"codersdk",
"cronstrue",
"databasefake",
- "dbfake",
+ "dbmem",
"dbgen",
"dbtype",
"DERP",
diff --git a/Makefile b/Makefile
index 65e1132be0ee1..72e44308c6f03 100644
--- a/Makefile
+++ b/Makefile
@@ -448,13 +448,15 @@ lint/helm:
DB_GEN_FILES := \
coderd/database/querier.go \
coderd/database/unique_constraint.go \
- coderd/database/dbfake/dbfake.go \
+ coderd/database/dbmem/dbmem.go \
coderd/database/dbmetrics/dbmetrics.go \
coderd/database/dbauthz/dbauthz.go \
coderd/database/dbmock/dbmock.go
# all gen targets should be added here and to gen/mark-fresh
gen: \
+ tailnet/proto/tailnet.pb.go \
+ agent/proto/agent.pb.go \
provisionersdk/proto/provisioner.pb.go \
provisionerd/proto/provisionerd.pb.go \
coderd/database/dump.sql \
@@ -479,6 +481,8 @@ gen: \
# used during releases so we don't run generation scripts.
gen/mark-fresh:
files="\
+ tailnet/proto/tailnet.pb.go \
+ agent/proto/agent.pb.go \
provisionersdk/proto/provisioner.pb.go \
provisionerd/proto/provisionerd.pb.go \
coderd/database/dump.sql \
@@ -524,6 +528,22 @@ coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $
coderd/database/dbmock/dbmock.go: coderd/database/db.go coderd/database/querier.go
go generate ./coderd/database/dbmock/
+tailnet/proto/tailnet.pb.go: tailnet/proto/tailnet.proto
+ protoc \
+ --go_out=. \
+ --go_opt=paths=source_relative \
+ --go-drpc_out=. \
+ --go-drpc_opt=paths=source_relative \
+ ./tailnet/proto/tailnet.proto
+
+agent/proto/agent.pb.go: agent/proto/agent.proto
+ protoc \
+ --go_out=. \
+ --go_opt=paths=source_relative \
+ --go-drpc_out=. \
+ --go-drpc_opt=paths=source_relative \
+ ./agent/proto/agent.proto
+
provisionersdk/proto/provisioner.pb.go: provisionersdk/proto/provisioner.proto
protoc \
--go_out=. \
diff --git a/README.md b/README.md
index 3f7d835125ff9..27634813adf34 100644
--- a/README.md
+++ b/README.md
@@ -70,7 +70,7 @@ curl -L https://coder.com/install.sh | sh
You can run the install script with `--dry-run` to see the commands that will be used to install without executing them. You can modify the installation process by including flags. Run the install script with `--help` for reference.
-> See [install](docs/install) for additional methods.
+> See [install](https://coder.com/docs/v2/latest/install) for additional methods.
Once installed, you can start a production deployment1 with a single command:
diff --git a/agent/agent.go b/agent/agent.go
index 93daba559c49e..0d2326d2ab9d3 100644
--- a/agent/agent.go
+++ b/agent/agent.go
@@ -536,6 +536,14 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
continue
case <-report:
if len(updatedMetadata) > 0 {
+ select {
+ case <-reportSemaphore:
+ default:
+ // If there's already a report in flight, don't send
+ // another one, wait for next tick instead.
+ continue
+ }
+
metadata := make([]agentsdk.Metadata, 0, len(updatedMetadata))
for key, result := range updatedMetadata {
metadata = append(metadata, agentsdk.Metadata{
@@ -545,14 +553,6 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
delete(updatedMetadata, key)
}
- select {
- case <-reportSemaphore:
- default:
- // If there's already a report in flight, don't send
- // another one, wait for next tick instead.
- continue
- }
-
go func() {
ctx, cancel := context.WithTimeout(ctx, reportTimeout)
defer func() {
@@ -743,7 +743,7 @@ func (a *agent) run(ctx context.Context) error {
return script.RunOnStart
})
if err != nil {
- a.logger.Warn(ctx, "startup script failed", slog.Error(err))
+ a.logger.Warn(ctx, "startup script(s) failed", slog.Error(err))
if errors.Is(err, agentscripts.ErrTimeout) {
a.setLifecycle(ctx, codersdk.WorkspaceAgentLifecycleStartTimeout)
} else {
@@ -1465,6 +1465,7 @@ func (a *agent) Close() error {
return script.RunOnStop
})
if err != nil {
+ a.logger.Warn(ctx, "shutdown script(s) failed", slog.Error(err))
if errors.Is(err, agentscripts.ErrTimeout) {
lifecycleState = codersdk.WorkspaceAgentLifecycleShutdownTimeout
} else {
diff --git a/agent/agent_test.go b/agent/agent_test.go
index bf71c4f1638f9..b54f877fcdab9 100644
--- a/agent/agent_test.go
+++ b/agent/agent_test.go
@@ -350,8 +350,13 @@ func TestAgent_Session_TTY_MOTD(t *testing.T) {
unexpected: []string{},
},
{
- name: "Trim",
- manifest: agentsdk.Manifest{},
+ name: "Trim",
+ // Enable motd since it will be printed after the banner,
+ // this ensures that we can test for an exact mount of
+ // newlines.
+ manifest: agentsdk.Manifest{
+ MOTDFile: name,
+ },
banner: codersdk.ServiceBannerConfig{
Enabled: true,
Message: "\n\n\n\n\n\nbanner\n\n\n\n\n\n",
@@ -375,6 +380,7 @@ func TestAgent_Session_TTY_MOTD(t *testing.T) {
}
}
+//nolint:tparallel // Sub tests need to run sequentially.
func TestAgent_Session_TTY_MOTD_Update(t *testing.T) {
t.Parallel()
if runtime.GOOS == "windows" {
@@ -434,33 +440,38 @@ func TestAgent_Session_TTY_MOTD_Update(t *testing.T) {
}
//nolint:dogsled // Allow the blank identifiers.
conn, client, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, setSBInterval)
- for _, test := range tests {
+
+ sshClient, err := conn.SSHClient(ctx)
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ _ = sshClient.Close()
+ })
+
+ //nolint:paralleltest // These tests need to swap the banner func.
+ for i, test := range tests {
test := test
- // Set new banner func and wait for the agent to call it to update the
- // banner.
- ready := make(chan struct{}, 2)
- client.SetServiceBannerFunc(func() (codersdk.ServiceBannerConfig, error) {
- select {
- case ready <- struct{}{}:
- default:
- }
- return test.banner, nil
- })
- <-ready
- <-ready // Wait for two updates to ensure the value has propagated.
+ t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
+ // Set new banner func and wait for the agent to call it to update the
+ // banner.
+ ready := make(chan struct{}, 2)
+ client.SetServiceBannerFunc(func() (codersdk.ServiceBannerConfig, error) {
+ select {
+ case ready <- struct{}{}:
+ default:
+ }
+ return test.banner, nil
+ })
+ <-ready
+ <-ready // Wait for two updates to ensure the value has propagated.
- sshClient, err := conn.SSHClient(ctx)
- require.NoError(t, err)
- t.Cleanup(func() {
- _ = sshClient.Close()
- })
- session, err := sshClient.NewSession()
- require.NoError(t, err)
- t.Cleanup(func() {
- _ = session.Close()
- })
+ session, err := sshClient.NewSession()
+ require.NoError(t, err)
+ t.Cleanup(func() {
+ _ = session.Close()
+ })
- testSessionOutput(t, session, test.expected, test.unexpected, nil)
+ testSessionOutput(t, session, test.expected, test.unexpected, nil)
+ })
}
}
diff --git a/agent/agentscripts/agentscripts.go b/agent/agentscripts/agentscripts.go
index 98a6901ebbbc4..3acc48b0a140c 100644
--- a/agent/agentscripts/agentscripts.go
+++ b/agent/agentscripts/agentscripts.go
@@ -27,6 +27,14 @@ import (
var (
// ErrTimeout is returned when a script times out.
ErrTimeout = xerrors.New("script timed out")
+ // ErrOutputPipesOpen is returned when a script exits leaving the output
+ // pipe(s) (stdout, stderr) open. This happens because we set WaitDelay on
+ // the command, which gives us two things:
+ //
+ // 1. The ability to ensure that a script exits (this is important for e.g.
+ // blocking login, and avoiding doing so indefinitely)
+ // 2. Improved command cancellation on timeout
+ ErrOutputPipesOpen = xerrors.New("script exited without closing output pipes")
parser = cron.NewParser(cron.Second | cron.Minute | cron.Hour | cron.Dom | cron.Month | cron.DowOptional)
)
@@ -97,7 +105,15 @@ func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript) error {
// StartCron starts the cron scheduler.
// This is done async to allow for the caller to execute scripts prior.
func (r *Runner) StartCron() {
- r.cron.Start()
+ // cron.Start() and cron.Stop() does not guarantee that the cron goroutine
+ // has exited by the time the `cron.Stop()` context returns, so we need to
+ // track it manually.
+ err := r.trackCommandGoroutine(func() {
+ r.cron.Run()
+ })
+ if err != nil {
+ r.Logger.Warn(context.Background(), "start cron failed", slog.Error(err))
+ }
}
// Execute runs a set of scripts according to a filter.
@@ -240,7 +256,22 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
err = cmdCtx.Err()
case err = <-cmdDone:
}
- if errors.Is(err, context.DeadlineExceeded) {
+ switch {
+ case errors.Is(err, exec.ErrWaitDelay):
+ err = ErrOutputPipesOpen
+ message := fmt.Sprintf("script exited successfully, but output pipes were not closed after %s", cmd.WaitDelay)
+ details := fmt.Sprint(
+ "This usually means a child process was started with references to stdout or stderr. As a result, this " +
+ "process may now have been terminated. Consider redirecting the output or using a separate " +
+ "\"coder_script\" for the process, see " +
+ "https://coder.com/docs/v2/latest/templates/troubleshooting#startup-script-issues for more information.",
+ )
+ // Inform the user by propagating the message via log writers.
+ _, _ = fmt.Fprintf(cmd.Stderr, "WARNING: %s. %s\n", message, details)
+ // Also log to agent logs for ease of debugging.
+ r.Logger.Warn(ctx, message, slog.F("details", details), slog.Error(err))
+
+ case errors.Is(err, context.DeadlineExceeded):
err = ErrTimeout
}
return err
@@ -254,7 +285,7 @@ func (r *Runner) Close() error {
}
close(r.closed)
r.cronCtxCancel()
- r.cron.Stop()
+ <-r.cron.Stop().Done()
r.cmdCloseWait.Wait()
return nil
}
diff --git a/agent/proto/agent.pb.go b/agent/proto/agent.pb.go
new file mode 100644
index 0000000000000..fb75710f1cd56
--- /dev/null
+++ b/agent/proto/agent.pb.go
@@ -0,0 +1,2453 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.30.0
+// protoc v4.23.3
+// source: agent/proto/agent.proto
+
+package proto
+
+import (
+ proto "github.com/coder/coder/v2/tailnet/proto"
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ durationpb "google.golang.org/protobuf/types/known/durationpb"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type AppHealth int32
+
+const (
+ AppHealth_APP_HEALTH_UNSPECIFIED AppHealth = 0
+ AppHealth_DISABLED AppHealth = 1
+ AppHealth_INITIALIZING AppHealth = 2
+ AppHealth_HEALTHY AppHealth = 3
+ AppHealth_UNHEALTHY AppHealth = 4
+)
+
+// Enum value maps for AppHealth.
+var (
+ AppHealth_name = map[int32]string{
+ 0: "APP_HEALTH_UNSPECIFIED",
+ 1: "DISABLED",
+ 2: "INITIALIZING",
+ 3: "HEALTHY",
+ 4: "UNHEALTHY",
+ }
+ AppHealth_value = map[string]int32{
+ "APP_HEALTH_UNSPECIFIED": 0,
+ "DISABLED": 1,
+ "INITIALIZING": 2,
+ "HEALTHY": 3,
+ "UNHEALTHY": 4,
+ }
+)
+
+func (x AppHealth) Enum() *AppHealth {
+ p := new(AppHealth)
+ *p = x
+ return p
+}
+
+func (x AppHealth) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (AppHealth) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[0].Descriptor()
+}
+
+func (AppHealth) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[0]
+}
+
+func (x AppHealth) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use AppHealth.Descriptor instead.
+func (AppHealth) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{0}
+}
+
+type WorkspaceApp_SharingLevel int32
+
+const (
+ WorkspaceApp_SHARING_LEVEL_UNSPECIFIED WorkspaceApp_SharingLevel = 0
+ WorkspaceApp_OWNER WorkspaceApp_SharingLevel = 1
+ WorkspaceApp_AUTHENTICATED WorkspaceApp_SharingLevel = 2
+ WorkspaceApp_PUBLIC WorkspaceApp_SharingLevel = 3
+)
+
+// Enum value maps for WorkspaceApp_SharingLevel.
+var (
+ WorkspaceApp_SharingLevel_name = map[int32]string{
+ 0: "SHARING_LEVEL_UNSPECIFIED",
+ 1: "OWNER",
+ 2: "AUTHENTICATED",
+ 3: "PUBLIC",
+ }
+ WorkspaceApp_SharingLevel_value = map[string]int32{
+ "SHARING_LEVEL_UNSPECIFIED": 0,
+ "OWNER": 1,
+ "AUTHENTICATED": 2,
+ "PUBLIC": 3,
+ }
+)
+
+func (x WorkspaceApp_SharingLevel) Enum() *WorkspaceApp_SharingLevel {
+ p := new(WorkspaceApp_SharingLevel)
+ *p = x
+ return p
+}
+
+func (x WorkspaceApp_SharingLevel) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (WorkspaceApp_SharingLevel) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[1].Descriptor()
+}
+
+func (WorkspaceApp_SharingLevel) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[1]
+}
+
+func (x WorkspaceApp_SharingLevel) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use WorkspaceApp_SharingLevel.Descriptor instead.
+func (WorkspaceApp_SharingLevel) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{0, 0}
+}
+
+type WorkspaceApp_Health int32
+
+const (
+ WorkspaceApp_HEALTH_UNSPECIFIED WorkspaceApp_Health = 0
+ WorkspaceApp_DISABLED WorkspaceApp_Health = 1
+ WorkspaceApp_INITIALIZING WorkspaceApp_Health = 2
+ WorkspaceApp_HEALTHY WorkspaceApp_Health = 3
+ WorkspaceApp_UNHEALTHY WorkspaceApp_Health = 4
+)
+
+// Enum value maps for WorkspaceApp_Health.
+var (
+ WorkspaceApp_Health_name = map[int32]string{
+ 0: "HEALTH_UNSPECIFIED",
+ 1: "DISABLED",
+ 2: "INITIALIZING",
+ 3: "HEALTHY",
+ 4: "UNHEALTHY",
+ }
+ WorkspaceApp_Health_value = map[string]int32{
+ "HEALTH_UNSPECIFIED": 0,
+ "DISABLED": 1,
+ "INITIALIZING": 2,
+ "HEALTHY": 3,
+ "UNHEALTHY": 4,
+ }
+)
+
+func (x WorkspaceApp_Health) Enum() *WorkspaceApp_Health {
+ p := new(WorkspaceApp_Health)
+ *p = x
+ return p
+}
+
+func (x WorkspaceApp_Health) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (WorkspaceApp_Health) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[2].Descriptor()
+}
+
+func (WorkspaceApp_Health) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[2]
+}
+
+func (x WorkspaceApp_Health) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use WorkspaceApp_Health.Descriptor instead.
+func (WorkspaceApp_Health) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{0, 1}
+}
+
+type Stats_Metric_Type int32
+
+const (
+ Stats_Metric_TYPE_UNSPECIFIED Stats_Metric_Type = 0
+ Stats_Metric_COUNTER Stats_Metric_Type = 1
+ Stats_Metric_GAUGE Stats_Metric_Type = 2
+)
+
+// Enum value maps for Stats_Metric_Type.
+var (
+ Stats_Metric_Type_name = map[int32]string{
+ 0: "TYPE_UNSPECIFIED",
+ 1: "COUNTER",
+ 2: "GAUGE",
+ }
+ Stats_Metric_Type_value = map[string]int32{
+ "TYPE_UNSPECIFIED": 0,
+ "COUNTER": 1,
+ "GAUGE": 2,
+ }
+)
+
+func (x Stats_Metric_Type) Enum() *Stats_Metric_Type {
+ p := new(Stats_Metric_Type)
+ *p = x
+ return p
+}
+
+func (x Stats_Metric_Type) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Stats_Metric_Type) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[3].Descriptor()
+}
+
+func (Stats_Metric_Type) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[3]
+}
+
+func (x Stats_Metric_Type) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Stats_Metric_Type.Descriptor instead.
+func (Stats_Metric_Type) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{5, 1, 0}
+}
+
+type Lifecycle_State int32
+
+const (
+ Lifecycle_STATE_UNSPECIFIED Lifecycle_State = 0
+ Lifecycle_CREATED Lifecycle_State = 1
+ Lifecycle_STARTED Lifecycle_State = 2
+ Lifecycle_START_TIMEOUT Lifecycle_State = 3
+ Lifecycle_START_ERROR Lifecycle_State = 4
+ Lifecycle_READY Lifecycle_State = 5
+ Lifecycle_SHUTTING_DOWN Lifecycle_State = 6
+ Lifecycle_SHUTDOWN_TIMEOUT Lifecycle_State = 7
+ Lifecycle_SHUTDOWN_ERROR Lifecycle_State = 8
+ Lifecycle_OFF Lifecycle_State = 9
+)
+
+// Enum value maps for Lifecycle_State.
+var (
+ Lifecycle_State_name = map[int32]string{
+ 0: "STATE_UNSPECIFIED",
+ 1: "CREATED",
+ 2: "STARTED",
+ 3: "START_TIMEOUT",
+ 4: "START_ERROR",
+ 5: "READY",
+ 6: "SHUTTING_DOWN",
+ 7: "SHUTDOWN_TIMEOUT",
+ 8: "SHUTDOWN_ERROR",
+ 9: "OFF",
+ }
+ Lifecycle_State_value = map[string]int32{
+ "STATE_UNSPECIFIED": 0,
+ "CREATED": 1,
+ "STARTED": 2,
+ "START_TIMEOUT": 3,
+ "START_ERROR": 4,
+ "READY": 5,
+ "SHUTTING_DOWN": 6,
+ "SHUTDOWN_TIMEOUT": 7,
+ "SHUTDOWN_ERROR": 8,
+ "OFF": 9,
+ }
+)
+
+func (x Lifecycle_State) Enum() *Lifecycle_State {
+ p := new(Lifecycle_State)
+ *p = x
+ return p
+}
+
+func (x Lifecycle_State) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Lifecycle_State) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[4].Descriptor()
+}
+
+func (Lifecycle_State) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[4]
+}
+
+func (x Lifecycle_State) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Lifecycle_State.Descriptor instead.
+func (Lifecycle_State) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{8, 0}
+}
+
+type Log_Level int32
+
+const (
+ Log_LEVEL_UNSPECIFIED Log_Level = 0
+ Log_TRACE Log_Level = 1
+ Log_DEBUG Log_Level = 2
+ Log_INFO Log_Level = 3
+ Log_WARN Log_Level = 4
+ Log_ERROR Log_Level = 5
+)
+
+// Enum value maps for Log_Level.
+var (
+ Log_Level_name = map[int32]string{
+ 0: "LEVEL_UNSPECIFIED",
+ 1: "TRACE",
+ 2: "DEBUG",
+ 3: "INFO",
+ 4: "WARN",
+ 5: "ERROR",
+ }
+ Log_Level_value = map[string]int32{
+ "LEVEL_UNSPECIFIED": 0,
+ "TRACE": 1,
+ "DEBUG": 2,
+ "INFO": 3,
+ "WARN": 4,
+ "ERROR": 5,
+ }
+)
+
+func (x Log_Level) Enum() *Log_Level {
+ p := new(Log_Level)
+ *p = x
+ return p
+}
+
+func (x Log_Level) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (Log_Level) Descriptor() protoreflect.EnumDescriptor {
+ return file_agent_proto_agent_proto_enumTypes[5].Descriptor()
+}
+
+func (Log_Level) Type() protoreflect.EnumType {
+ return &file_agent_proto_agent_proto_enumTypes[5]
+}
+
+func (x Log_Level) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use Log_Level.Descriptor instead.
+func (Log_Level) EnumDescriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{17, 0}
+}
+
+type WorkspaceApp struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"`
+ Url string `protobuf:"bytes,2,opt,name=url,proto3" json:"url,omitempty"`
+ External bool `protobuf:"varint,3,opt,name=external,proto3" json:"external,omitempty"`
+ Slug string `protobuf:"bytes,4,opt,name=slug,proto3" json:"slug,omitempty"`
+ DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"`
+ Command string `protobuf:"bytes,6,opt,name=command,proto3" json:"command,omitempty"`
+ Icon string `protobuf:"bytes,7,opt,name=icon,proto3" json:"icon,omitempty"`
+ Subdomain bool `protobuf:"varint,8,opt,name=subdomain,proto3" json:"subdomain,omitempty"`
+ SubdomainName string `protobuf:"bytes,9,opt,name=subdomain_name,json=subdomainName,proto3" json:"subdomain_name,omitempty"`
+ SharingLevel WorkspaceApp_SharingLevel `protobuf:"varint,10,opt,name=sharing_level,json=sharingLevel,proto3,enum=coder.agent.v2.WorkspaceApp_SharingLevel" json:"sharing_level,omitempty"`
+ Healthcheck *WorkspaceApp_HealthCheck `protobuf:"bytes,11,opt,name=healthcheck,proto3" json:"healthcheck,omitempty"`
+ Health WorkspaceApp_Health `protobuf:"varint,12,opt,name=health,proto3,enum=coder.agent.v2.WorkspaceApp_Health" json:"health,omitempty"`
+}
+
+func (x *WorkspaceApp) Reset() {
+ *x = WorkspaceApp{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *WorkspaceApp) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*WorkspaceApp) ProtoMessage() {}
+
+func (x *WorkspaceApp) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use WorkspaceApp.ProtoReflect.Descriptor instead.
+func (*WorkspaceApp) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *WorkspaceApp) GetUuid() []byte {
+ if x != nil {
+ return x.Uuid
+ }
+ return nil
+}
+
+func (x *WorkspaceApp) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetExternal() bool {
+ if x != nil {
+ return x.External
+ }
+ return false
+}
+
+func (x *WorkspaceApp) GetSlug() string {
+ if x != nil {
+ return x.Slug
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetDisplayName() string {
+ if x != nil {
+ return x.DisplayName
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetCommand() string {
+ if x != nil {
+ return x.Command
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetIcon() string {
+ if x != nil {
+ return x.Icon
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetSubdomain() bool {
+ if x != nil {
+ return x.Subdomain
+ }
+ return false
+}
+
+func (x *WorkspaceApp) GetSubdomainName() string {
+ if x != nil {
+ return x.SubdomainName
+ }
+ return ""
+}
+
+func (x *WorkspaceApp) GetSharingLevel() WorkspaceApp_SharingLevel {
+ if x != nil {
+ return x.SharingLevel
+ }
+ return WorkspaceApp_SHARING_LEVEL_UNSPECIFIED
+}
+
+func (x *WorkspaceApp) GetHealthcheck() *WorkspaceApp_HealthCheck {
+ if x != nil {
+ return x.Healthcheck
+ }
+ return nil
+}
+
+func (x *WorkspaceApp) GetHealth() WorkspaceApp_Health {
+ if x != nil {
+ return x.Health
+ }
+ return WorkspaceApp_HEALTH_UNSPECIFIED
+}
+
+type Manifest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ GitAuthConfigs uint32 `protobuf:"varint,1,opt,name=git_auth_configs,json=gitAuthConfigs,proto3" json:"git_auth_configs,omitempty"`
+ VsCodePortProxyUri string `protobuf:"bytes,2,opt,name=vs_code_port_proxy_uri,json=vsCodePortProxyUri,proto3" json:"vs_code_port_proxy_uri,omitempty"`
+ Apps []*WorkspaceApp `protobuf:"bytes,3,rep,name=apps,proto3" json:"apps,omitempty"`
+ DerpMap *proto.DERPMap `protobuf:"bytes,4,opt,name=derp_map,json=derpMap,proto3" json:"derp_map,omitempty"`
+}
+
+func (x *Manifest) Reset() {
+ *x = Manifest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Manifest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Manifest) ProtoMessage() {}
+
+func (x *Manifest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Manifest.ProtoReflect.Descriptor instead.
+func (*Manifest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *Manifest) GetGitAuthConfigs() uint32 {
+ if x != nil {
+ return x.GitAuthConfigs
+ }
+ return 0
+}
+
+func (x *Manifest) GetVsCodePortProxyUri() string {
+ if x != nil {
+ return x.VsCodePortProxyUri
+ }
+ return ""
+}
+
+func (x *Manifest) GetApps() []*WorkspaceApp {
+ if x != nil {
+ return x.Apps
+ }
+ return nil
+}
+
+func (x *Manifest) GetDerpMap() *proto.DERPMap {
+ if x != nil {
+ return x.DerpMap
+ }
+ return nil
+}
+
+type GetManifestRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetManifestRequest) Reset() {
+ *x = GetManifestRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetManifestRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetManifestRequest) ProtoMessage() {}
+
+func (x *GetManifestRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetManifestRequest.ProtoReflect.Descriptor instead.
+func (*GetManifestRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{2}
+}
+
+type ServiceBanner struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Enabled bool `protobuf:"varint,1,opt,name=enabled,proto3" json:"enabled,omitempty"`
+ Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"`
+ BackgroundColor string `protobuf:"bytes,3,opt,name=background_color,json=backgroundColor,proto3" json:"background_color,omitempty"`
+}
+
+func (x *ServiceBanner) Reset() {
+ *x = ServiceBanner{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ServiceBanner) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ServiceBanner) ProtoMessage() {}
+
+func (x *ServiceBanner) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ServiceBanner.ProtoReflect.Descriptor instead.
+func (*ServiceBanner) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *ServiceBanner) GetEnabled() bool {
+ if x != nil {
+ return x.Enabled
+ }
+ return false
+}
+
+func (x *ServiceBanner) GetMessage() string {
+ if x != nil {
+ return x.Message
+ }
+ return ""
+}
+
+func (x *ServiceBanner) GetBackgroundColor() string {
+ if x != nil {
+ return x.BackgroundColor
+ }
+ return ""
+}
+
+type GetServiceBannerRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *GetServiceBannerRequest) Reset() {
+ *x = GetServiceBannerRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *GetServiceBannerRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*GetServiceBannerRequest) ProtoMessage() {}
+
+func (x *GetServiceBannerRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use GetServiceBannerRequest.ProtoReflect.Descriptor instead.
+func (*GetServiceBannerRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{4}
+}
+
+type Stats struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // ConnectionsByProto is a count of connections by protocol.
+ ConnectionsByProto map[string]int64 `protobuf:"bytes,1,rep,name=connections_by_proto,json=connectionsByProto,proto3" json:"connections_by_proto,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"varint,2,opt,name=value,proto3"`
+ // ConnectionCount is the number of connections received by an agent.
+ ConnectionCount int64 `protobuf:"varint,2,opt,name=connection_count,json=connectionCount,proto3" json:"connection_count,omitempty"`
+ // ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.
+ ConnectionMedianLatencyMs float64 `protobuf:"fixed64,3,opt,name=connection_median_latency_ms,json=connectionMedianLatencyMs,proto3" json:"connection_median_latency_ms,omitempty"`
+ // RxPackets is the number of received packets.
+ RxPackets int64 `protobuf:"varint,4,opt,name=rx_packets,json=rxPackets,proto3" json:"rx_packets,omitempty"`
+ // RxBytes is the number of received bytes.
+ RxBytes int64 `protobuf:"varint,5,opt,name=rx_bytes,json=rxBytes,proto3" json:"rx_bytes,omitempty"`
+ // TxPackets is the number of transmitted bytes.
+ TxPackets int64 `protobuf:"varint,6,opt,name=tx_packets,json=txPackets,proto3" json:"tx_packets,omitempty"`
+ // TxBytes is the number of transmitted bytes.
+ TxBytes int64 `protobuf:"varint,7,opt,name=tx_bytes,json=txBytes,proto3" json:"tx_bytes,omitempty"`
+ // SessionCountVSCode is the number of connections received by an agent
+ // that are from our VS Code extension.
+ SessionCountVscode int64 `protobuf:"varint,8,opt,name=session_count_vscode,json=sessionCountVscode,proto3" json:"session_count_vscode,omitempty"`
+ // SessionCountJetBrains is the number of connections received by an agent
+ // that are from our JetBrains extension.
+ SessionCountJetbrains int64 `protobuf:"varint,9,opt,name=session_count_jetbrains,json=sessionCountJetbrains,proto3" json:"session_count_jetbrains,omitempty"`
+ // SessionCountReconnectingPTY is the number of connections received by an agent
+ // that are from the reconnecting web terminal.
+ SessionCountReconnectingPty int64 `protobuf:"varint,10,opt,name=session_count_reconnecting_pty,json=sessionCountReconnectingPty,proto3" json:"session_count_reconnecting_pty,omitempty"`
+ // SessionCountSSH is the number of connections received by an agent
+ // that are normal, non-tagged SSH sessions.
+ SessionCountSsh int64 `protobuf:"varint,11,opt,name=session_count_ssh,json=sessionCountSsh,proto3" json:"session_count_ssh,omitempty"`
+}
+
+func (x *Stats) Reset() {
+ *x = Stats{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Stats) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Stats) ProtoMessage() {}
+
+func (x *Stats) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Stats.ProtoReflect.Descriptor instead.
+func (*Stats) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{5}
+}
+
+func (x *Stats) GetConnectionsByProto() map[string]int64 {
+ if x != nil {
+ return x.ConnectionsByProto
+ }
+ return nil
+}
+
+func (x *Stats) GetConnectionCount() int64 {
+ if x != nil {
+ return x.ConnectionCount
+ }
+ return 0
+}
+
+func (x *Stats) GetConnectionMedianLatencyMs() float64 {
+ if x != nil {
+ return x.ConnectionMedianLatencyMs
+ }
+ return 0
+}
+
+func (x *Stats) GetRxPackets() int64 {
+ if x != nil {
+ return x.RxPackets
+ }
+ return 0
+}
+
+func (x *Stats) GetRxBytes() int64 {
+ if x != nil {
+ return x.RxBytes
+ }
+ return 0
+}
+
+func (x *Stats) GetTxPackets() int64 {
+ if x != nil {
+ return x.TxPackets
+ }
+ return 0
+}
+
+func (x *Stats) GetTxBytes() int64 {
+ if x != nil {
+ return x.TxBytes
+ }
+ return 0
+}
+
+func (x *Stats) GetSessionCountVscode() int64 {
+ if x != nil {
+ return x.SessionCountVscode
+ }
+ return 0
+}
+
+func (x *Stats) GetSessionCountJetbrains() int64 {
+ if x != nil {
+ return x.SessionCountJetbrains
+ }
+ return 0
+}
+
+func (x *Stats) GetSessionCountReconnectingPty() int64 {
+ if x != nil {
+ return x.SessionCountReconnectingPty
+ }
+ return 0
+}
+
+func (x *Stats) GetSessionCountSsh() int64 {
+ if x != nil {
+ return x.SessionCountSsh
+ }
+ return 0
+}
+
+type UpdateStatsRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Stats *Stats `protobuf:"bytes,1,opt,name=stats,proto3" json:"stats,omitempty"`
+}
+
+func (x *UpdateStatsRequest) Reset() {
+ *x = UpdateStatsRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateStatsRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateStatsRequest) ProtoMessage() {}
+
+func (x *UpdateStatsRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateStatsRequest.ProtoReflect.Descriptor instead.
+func (*UpdateStatsRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{6}
+}
+
+func (x *UpdateStatsRequest) GetStats() *Stats {
+ if x != nil {
+ return x.Stats
+ }
+ return nil
+}
+
+type UpdateStatsResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ ReportIntervalNanoseconds *durationpb.Duration `protobuf:"bytes,1,opt,name=report_interval_nanoseconds,json=reportIntervalNanoseconds,proto3" json:"report_interval_nanoseconds,omitempty"`
+}
+
+func (x *UpdateStatsResponse) Reset() {
+ *x = UpdateStatsResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[7]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateStatsResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateStatsResponse) ProtoMessage() {}
+
+func (x *UpdateStatsResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[7]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateStatsResponse.ProtoReflect.Descriptor instead.
+func (*UpdateStatsResponse) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{7}
+}
+
+func (x *UpdateStatsResponse) GetReportIntervalNanoseconds() *durationpb.Duration {
+ if x != nil {
+ return x.ReportIntervalNanoseconds
+ }
+ return nil
+}
+
+type Lifecycle struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ State Lifecycle_State `protobuf:"varint,1,opt,name=state,proto3,enum=coder.agent.v2.Lifecycle_State" json:"state,omitempty"`
+}
+
+func (x *Lifecycle) Reset() {
+ *x = Lifecycle{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[8]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Lifecycle) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Lifecycle) ProtoMessage() {}
+
+func (x *Lifecycle) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[8]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Lifecycle.ProtoReflect.Descriptor instead.
+func (*Lifecycle) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{8}
+}
+
+func (x *Lifecycle) GetState() Lifecycle_State {
+ if x != nil {
+ return x.State
+ }
+ return Lifecycle_STATE_UNSPECIFIED
+}
+
+type UpdateLifecycleRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Lifecycle *Lifecycle `protobuf:"bytes,1,opt,name=lifecycle,proto3" json:"lifecycle,omitempty"`
+}
+
+func (x *UpdateLifecycleRequest) Reset() {
+ *x = UpdateLifecycleRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateLifecycleRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateLifecycleRequest) ProtoMessage() {}
+
+func (x *UpdateLifecycleRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateLifecycleRequest.ProtoReflect.Descriptor instead.
+func (*UpdateLifecycleRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *UpdateLifecycleRequest) GetLifecycle() *Lifecycle {
+ if x != nil {
+ return x.Lifecycle
+ }
+ return nil
+}
+
+type BatchUpdateAppHealthRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Updates []*BatchUpdateAppHealthRequest_HealthUpdate `protobuf:"bytes,1,rep,name=updates,proto3" json:"updates,omitempty"`
+}
+
+func (x *BatchUpdateAppHealthRequest) Reset() {
+ *x = BatchUpdateAppHealthRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[10]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchUpdateAppHealthRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchUpdateAppHealthRequest) ProtoMessage() {}
+
+func (x *BatchUpdateAppHealthRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[10]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchUpdateAppHealthRequest.ProtoReflect.Descriptor instead.
+func (*BatchUpdateAppHealthRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{10}
+}
+
+func (x *BatchUpdateAppHealthRequest) GetUpdates() []*BatchUpdateAppHealthRequest_HealthUpdate {
+ if x != nil {
+ return x.Updates
+ }
+ return nil
+}
+
+type BatchUpdateAppHealthResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *BatchUpdateAppHealthResponse) Reset() {
+ *x = BatchUpdateAppHealthResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[11]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchUpdateAppHealthResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchUpdateAppHealthResponse) ProtoMessage() {}
+
+func (x *BatchUpdateAppHealthResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[11]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchUpdateAppHealthResponse.ProtoReflect.Descriptor instead.
+func (*BatchUpdateAppHealthResponse) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{11}
+}
+
+type Startup struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"`
+ ExpandedDirectory string `protobuf:"bytes,2,opt,name=expanded_directory,json=expandedDirectory,proto3" json:"expanded_directory,omitempty"`
+ Subsystems []string `protobuf:"bytes,3,rep,name=subsystems,proto3" json:"subsystems,omitempty"`
+}
+
+func (x *Startup) Reset() {
+ *x = Startup{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Startup) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Startup) ProtoMessage() {}
+
+func (x *Startup) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Startup.ProtoReflect.Descriptor instead.
+func (*Startup) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{12}
+}
+
+func (x *Startup) GetVersion() string {
+ if x != nil {
+ return x.Version
+ }
+ return ""
+}
+
+func (x *Startup) GetExpandedDirectory() string {
+ if x != nil {
+ return x.ExpandedDirectory
+ }
+ return ""
+}
+
+func (x *Startup) GetSubsystems() []string {
+ if x != nil {
+ return x.Subsystems
+ }
+ return nil
+}
+
+type UpdateStartupRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Startup *Startup `protobuf:"bytes,1,opt,name=startup,proto3" json:"startup,omitempty"`
+}
+
+func (x *UpdateStartupRequest) Reset() {
+ *x = UpdateStartupRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *UpdateStartupRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*UpdateStartupRequest) ProtoMessage() {}
+
+func (x *UpdateStartupRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use UpdateStartupRequest.ProtoReflect.Descriptor instead.
+func (*UpdateStartupRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{13}
+}
+
+func (x *UpdateStartupRequest) GetStartup() *Startup {
+ if x != nil {
+ return x.Startup
+ }
+ return nil
+}
+
+type Metadata struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"`
+ CollectedAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=collected_at,json=collectedAt,proto3" json:"collected_at,omitempty"`
+ Age int64 `protobuf:"varint,3,opt,name=age,proto3" json:"age,omitempty"`
+ Value string `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"`
+ Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"`
+}
+
+func (x *Metadata) Reset() {
+ *x = Metadata{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Metadata) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Metadata) ProtoMessage() {}
+
+func (x *Metadata) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Metadata.ProtoReflect.Descriptor instead.
+func (*Metadata) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{14}
+}
+
+func (x *Metadata) GetKey() string {
+ if x != nil {
+ return x.Key
+ }
+ return ""
+}
+
+func (x *Metadata) GetCollectedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.CollectedAt
+ }
+ return nil
+}
+
+func (x *Metadata) GetAge() int64 {
+ if x != nil {
+ return x.Age
+ }
+ return 0
+}
+
+func (x *Metadata) GetValue() string {
+ if x != nil {
+ return x.Value
+ }
+ return ""
+}
+
+func (x *Metadata) GetError() string {
+ if x != nil {
+ return x.Error
+ }
+ return ""
+}
+
+type BatchUpdateMetadataRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Metadata []*Metadata `protobuf:"bytes,2,rep,name=metadata,proto3" json:"metadata,omitempty"`
+}
+
+func (x *BatchUpdateMetadataRequest) Reset() {
+ *x = BatchUpdateMetadataRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[15]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchUpdateMetadataRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchUpdateMetadataRequest) ProtoMessage() {}
+
+func (x *BatchUpdateMetadataRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[15]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchUpdateMetadataRequest.ProtoReflect.Descriptor instead.
+func (*BatchUpdateMetadataRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{15}
+}
+
+func (x *BatchUpdateMetadataRequest) GetMetadata() []*Metadata {
+ if x != nil {
+ return x.Metadata
+ }
+ return nil
+}
+
+type BatchUpdateMetadataResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *BatchUpdateMetadataResponse) Reset() {
+ *x = BatchUpdateMetadataResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[16]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchUpdateMetadataResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchUpdateMetadataResponse) ProtoMessage() {}
+
+func (x *BatchUpdateMetadataResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[16]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchUpdateMetadataResponse.ProtoReflect.Descriptor instead.
+func (*BatchUpdateMetadataResponse) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{16}
+}
+
+type Log struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ CreatedAt *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
+ Output string `protobuf:"bytes,2,opt,name=output,proto3" json:"output,omitempty"`
+ Level Log_Level `protobuf:"varint,3,opt,name=level,proto3,enum=coder.agent.v2.Log_Level" json:"level,omitempty"`
+}
+
+func (x *Log) Reset() {
+ *x = Log{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[17]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Log) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Log) ProtoMessage() {}
+
+func (x *Log) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[17]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Log.ProtoReflect.Descriptor instead.
+func (*Log) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{17}
+}
+
+func (x *Log) GetCreatedAt() *timestamppb.Timestamp {
+ if x != nil {
+ return x.CreatedAt
+ }
+ return nil
+}
+
+func (x *Log) GetOutput() string {
+ if x != nil {
+ return x.Output
+ }
+ return ""
+}
+
+func (x *Log) GetLevel() Log_Level {
+ if x != nil {
+ return x.Level
+ }
+ return Log_LEVEL_UNSPECIFIED
+}
+
+type BatchCreateLogsRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ SourceId []byte `protobuf:"bytes,1,opt,name=source_id,json=sourceId,proto3" json:"source_id,omitempty"`
+ Logs []*Log `protobuf:"bytes,2,rep,name=logs,proto3" json:"logs,omitempty"`
+}
+
+func (x *BatchCreateLogsRequest) Reset() {
+ *x = BatchCreateLogsRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[18]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchCreateLogsRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchCreateLogsRequest) ProtoMessage() {}
+
+func (x *BatchCreateLogsRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[18]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchCreateLogsRequest.ProtoReflect.Descriptor instead.
+func (*BatchCreateLogsRequest) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{18}
+}
+
+func (x *BatchCreateLogsRequest) GetSourceId() []byte {
+ if x != nil {
+ return x.SourceId
+ }
+ return nil
+}
+
+func (x *BatchCreateLogsRequest) GetLogs() []*Log {
+ if x != nil {
+ return x.Logs
+ }
+ return nil
+}
+
+type BatchCreateLogsResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *BatchCreateLogsResponse) Reset() {
+ *x = BatchCreateLogsResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[19]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchCreateLogsResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchCreateLogsResponse) ProtoMessage() {}
+
+func (x *BatchCreateLogsResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[19]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchCreateLogsResponse.ProtoReflect.Descriptor instead.
+func (*BatchCreateLogsResponse) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{19}
+}
+
+type WorkspaceApp_HealthCheck struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Url string `protobuf:"bytes,1,opt,name=url,proto3" json:"url,omitempty"`
+ Interval int32 `protobuf:"varint,2,opt,name=interval,proto3" json:"interval,omitempty"`
+ Threshold int32 `protobuf:"varint,3,opt,name=threshold,proto3" json:"threshold,omitempty"`
+}
+
+func (x *WorkspaceApp_HealthCheck) Reset() {
+ *x = WorkspaceApp_HealthCheck{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[20]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *WorkspaceApp_HealthCheck) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*WorkspaceApp_HealthCheck) ProtoMessage() {}
+
+func (x *WorkspaceApp_HealthCheck) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[20]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use WorkspaceApp_HealthCheck.ProtoReflect.Descriptor instead.
+func (*WorkspaceApp_HealthCheck) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{0, 0}
+}
+
+func (x *WorkspaceApp_HealthCheck) GetUrl() string {
+ if x != nil {
+ return x.Url
+ }
+ return ""
+}
+
+func (x *WorkspaceApp_HealthCheck) GetInterval() int32 {
+ if x != nil {
+ return x.Interval
+ }
+ return 0
+}
+
+func (x *WorkspaceApp_HealthCheck) GetThreshold() int32 {
+ if x != nil {
+ return x.Threshold
+ }
+ return 0
+}
+
+type Stats_Metric struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ Type Stats_Metric_Type `protobuf:"varint,2,opt,name=type,proto3,enum=coder.agent.v2.Stats_Metric_Type" json:"type,omitempty"`
+ Value float64 `protobuf:"fixed64,3,opt,name=value,proto3" json:"value,omitempty"`
+ Labels map[string]string `protobuf:"bytes,4,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *Stats_Metric) Reset() {
+ *x = Stats_Metric{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[22]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Stats_Metric) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Stats_Metric) ProtoMessage() {}
+
+func (x *Stats_Metric) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[22]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Stats_Metric.ProtoReflect.Descriptor instead.
+func (*Stats_Metric) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{5, 1}
+}
+
+func (x *Stats_Metric) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *Stats_Metric) GetType() Stats_Metric_Type {
+ if x != nil {
+ return x.Type
+ }
+ return Stats_Metric_TYPE_UNSPECIFIED
+}
+
+func (x *Stats_Metric) GetValue() float64 {
+ if x != nil {
+ return x.Value
+ }
+ return 0
+}
+
+func (x *Stats_Metric) GetLabels() map[string]string {
+ if x != nil {
+ return x.Labels
+ }
+ return nil
+}
+
+type BatchUpdateAppHealthRequest_HealthUpdate struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"`
+ Health AppHealth `protobuf:"varint,2,opt,name=health,proto3,enum=coder.agent.v2.AppHealth" json:"health,omitempty"`
+}
+
+func (x *BatchUpdateAppHealthRequest_HealthUpdate) Reset() {
+ *x = BatchUpdateAppHealthRequest_HealthUpdate{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_agent_proto_agent_proto_msgTypes[24]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *BatchUpdateAppHealthRequest_HealthUpdate) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*BatchUpdateAppHealthRequest_HealthUpdate) ProtoMessage() {}
+
+func (x *BatchUpdateAppHealthRequest_HealthUpdate) ProtoReflect() protoreflect.Message {
+ mi := &file_agent_proto_agent_proto_msgTypes[24]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use BatchUpdateAppHealthRequest_HealthUpdate.ProtoReflect.Descriptor instead.
+func (*BatchUpdateAppHealthRequest_HealthUpdate) Descriptor() ([]byte, []int) {
+ return file_agent_proto_agent_proto_rawDescGZIP(), []int{10, 0}
+}
+
+func (x *BatchUpdateAppHealthRequest_HealthUpdate) GetUuid() []byte {
+ if x != nil {
+ return x.Uuid
+ }
+ return nil
+}
+
+func (x *BatchUpdateAppHealthRequest_HealthUpdate) GetHealth() AppHealth {
+ if x != nil {
+ return x.Health
+ }
+ return AppHealth_APP_HEALTH_UNSPECIFIED
+}
+
+var File_agent_proto_agent_proto protoreflect.FileDescriptor
+
+var file_agent_proto_agent_proto_rawDesc = []byte{
+ 0x0a, 0x17, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61, 0x67,
+ 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0e, 0x63, 0x6f, 0x64, 0x65, 0x72,
+ 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x1a, 0x1b, 0x74, 0x61, 0x69, 0x6c, 0x6e,
+ 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
+ 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d,
+ 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xe5, 0x05, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6b,
+ 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03,
+ 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a,
+ 0x0a, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x73, 0x6c,
+ 0x75, 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x73, 0x6c, 0x75, 0x67, 0x12, 0x21,
+ 0x0a, 0x0c, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x4e, 0x61, 0x6d,
+ 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x69,
+ 0x63, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12,
+ 0x1c, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x08, 0x20, 0x01,
+ 0x28, 0x08, 0x52, 0x09, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x25, 0x0a,
+ 0x0e, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+ 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e,
+ 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x5f,
+ 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x29, 0x2e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72,
+ 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x2e, 0x53, 0x68, 0x61, 0x72, 0x69, 0x6e,
+ 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x0c, 0x73, 0x68, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x4c,
+ 0x65, 0x76, 0x65, 0x6c, 0x12, 0x4a, 0x0a, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68,
+ 0x65, 0x63, 0x6b, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73,
+ 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68,
+ 0x65, 0x63, 0x6b, 0x52, 0x0b, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x63, 0x68, 0x65, 0x63, 0x6b,
+ 0x12, 0x3b, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e,
+ 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76,
+ 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x2e, 0x48,
+ 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x1a, 0x59, 0x0a,
+ 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x10, 0x0a, 0x03,
+ 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x1a,
+ 0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05,
+ 0x52, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x68,
+ 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x74,
+ 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c, 0x64, 0x22, 0x57, 0x0a, 0x0c, 0x53, 0x68, 0x61, 0x72,
+ 0x69, 0x6e, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x48, 0x41, 0x52,
+ 0x49, 0x4e, 0x47, 0x5f, 0x4c, 0x45, 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+ 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4f, 0x57, 0x4e, 0x45, 0x52,
+ 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41,
+ 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x10,
+ 0x03, 0x22, 0x5c, 0x0a, 0x06, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x16, 0x0a, 0x12, 0x48,
+ 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45,
+ 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49, 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10,
+ 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54, 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e,
+ 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03,
+ 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x22,
+ 0xd0, 0x01, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x10,
+ 0x67, 0x69, 0x74, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x67, 0x69, 0x74, 0x41, 0x75, 0x74, 0x68, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x32, 0x0a, 0x16, 0x76, 0x73, 0x5f, 0x63, 0x6f, 0x64,
+ 0x65, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x5f, 0x75, 0x72, 0x69,
+ 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x76, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x50, 0x6f,
+ 0x72, 0x74, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x55, 0x72, 0x69, 0x12, 0x30, 0x0a, 0x04, 0x61, 0x70,
+ 0x70, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72,
+ 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70,
+ 0x61, 0x63, 0x65, 0x41, 0x70, 0x70, 0x52, 0x04, 0x61, 0x70, 0x70, 0x73, 0x12, 0x34, 0x0a, 0x08,
+ 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6d, 0x61, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76,
+ 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x52, 0x07, 0x64, 0x65, 0x72, 0x70, 0x4d,
+ 0x61, 0x70, 0x22, 0x14, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73,
+ 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x6e, 0x0a, 0x0d, 0x53, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61,
+ 0x62, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62,
+ 0x6c, 0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x29, 0x0a,
+ 0x10, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x5f, 0x63, 0x6f, 0x6c, 0x6f,
+ 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f,
+ 0x75, 0x6e, 0x64, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x47, 0x65, 0x74, 0x53,
+ 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x22, 0x89, 0x07, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x5f, 0x0a,
+ 0x14, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x5f, 0x62, 0x79, 0x5f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x73, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79,
+ 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x63, 0x6f, 0x6e, 0x6e,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x29,
+ 0x0a, 0x10, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75,
+ 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x1c, 0x63, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x6e, 0x5f, 0x6c,
+ 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x01, 0x52,
+ 0x19, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4d, 0x65, 0x64, 0x69, 0x61,
+ 0x6e, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x78,
+ 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
+ 0x72, 0x78, 0x50, 0x61, 0x63, 0x6b, 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x72, 0x78, 0x5f,
+ 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x72, 0x78, 0x42,
+ 0x79, 0x74, 0x65, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x70, 0x61, 0x63, 0x6b, 0x65,
+ 0x74, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x74, 0x78, 0x50, 0x61, 0x63, 0x6b,
+ 0x65, 0x74, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18,
+ 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x07, 0x74, 0x78, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x30,
+ 0x0a, 0x14, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f,
+ 0x76, 0x73, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x12, 0x73, 0x65,
+ 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x73, 0x63, 0x6f, 0x64, 0x65,
+ 0x12, 0x36, 0x0a, 0x17, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e,
+ 0x74, 0x5f, 0x6a, 0x65, 0x74, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x15, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x4a,
+ 0x65, 0x74, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x43, 0x0a, 0x1e, 0x73, 0x65, 0x73, 0x73,
+ 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e,
+ 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x70, 0x74, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x1b, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65,
+ 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6e, 0x67, 0x50, 0x74, 0x79, 0x12, 0x2a, 0x0a,
+ 0x11, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x73,
+ 0x73, 0x68, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0f, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f,
+ 0x6e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x53, 0x73, 0x68, 0x1a, 0x45, 0x0a, 0x17, 0x43, 0x6f, 0x6e,
+ 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x42, 0x79, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01,
+ 0x1a, 0x9c, 0x02, 0x0a, 0x06, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x35, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x21, 0x2e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53,
+ 0x74, 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x54, 0x79, 0x70, 0x65,
+ 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x06,
+ 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74,
+ 0x61, 0x74, 0x73, 0x2e, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c,
+ 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x1a, 0x39,
+ 0x0a, 0x0b, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a,
+ 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12,
+ 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
+ 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x34, 0x0a, 0x04, 0x54, 0x79, 0x70,
+ 0x65, 0x12, 0x14, 0x0a, 0x10, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
+ 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x4f, 0x55, 0x4e, 0x54,
+ 0x45, 0x52, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x47, 0x41, 0x55, 0x47, 0x45, 0x10, 0x02, 0x22,
+ 0x41, 0x0a, 0x12, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65,
+ 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x05, 0x73, 0x74, 0x61,
+ 0x74, 0x73, 0x22, 0x70, 0x0a, 0x13, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74,
+ 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x59, 0x0a, 0x1b, 0x72, 0x65, 0x70,
+ 0x6f, 0x72, 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6e, 0x61, 0x6e,
+ 0x6f, 0x73, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19,
+ 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x19, 0x72, 0x65, 0x70, 0x6f, 0x72,
+ 0x74, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x4e, 0x61, 0x6e, 0x6f, 0x73, 0x65, 0x63,
+ 0x6f, 0x6e, 0x64, 0x73, 0x22, 0xf2, 0x01, 0x0a, 0x09, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63,
+ 0x6c, 0x65, 0x12, 0x35, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0e, 0x32, 0x1f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e,
+ 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x2e, 0x53, 0x74, 0x61,
+ 0x74, 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x22, 0xad, 0x01, 0x0a, 0x05, 0x53, 0x74,
+ 0x61, 0x74, 0x65, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x55, 0x4e, 0x53,
+ 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x43, 0x52,
+ 0x45, 0x41, 0x54, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x53, 0x54, 0x41, 0x52, 0x54,
+ 0x45, 0x44, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x54, 0x41, 0x52, 0x54, 0x5f, 0x54, 0x49,
+ 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x03, 0x12, 0x0f, 0x0a, 0x0b, 0x53, 0x54, 0x41, 0x52, 0x54,
+ 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x52, 0x45, 0x41, 0x44,
+ 0x59, 0x10, 0x05, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x48, 0x55, 0x54, 0x54, 0x49, 0x4e, 0x47, 0x5f,
+ 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x06, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f,
+ 0x57, 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x4f, 0x55, 0x54, 0x10, 0x07, 0x12, 0x12, 0x0a, 0x0e,
+ 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x08,
+ 0x12, 0x07, 0x0a, 0x03, 0x4f, 0x46, 0x46, 0x10, 0x09, 0x22, 0x51, 0x0a, 0x16, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x37, 0x0a, 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61,
+ 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c,
+ 0x65, 0x52, 0x09, 0x6c, 0x69, 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x22, 0xc8, 0x01, 0x0a,
+ 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48,
+ 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x52, 0x0a, 0x07,
+ 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61,
+ 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74,
+ 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x07, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73,
+ 0x1a, 0x55, 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x12, 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04,
+ 0x75, 0x75, 0x69, 0x64, 0x12, 0x31, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x18, 0x02,
+ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52,
+ 0x06, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x22, 0x1e, 0x0a, 0x1c, 0x42, 0x61, 0x74, 0x63, 0x68,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x72, 0x0a, 0x07, 0x53, 0x74, 0x61, 0x72, 0x74,
+ 0x75, 0x70, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x2d, 0x0a, 0x12,
+ 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64, 0x65, 0x64, 0x5f, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f,
+ 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x78, 0x70, 0x61, 0x6e, 0x64,
+ 0x65, 0x64, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1e, 0x0a, 0x0a, 0x73,
+ 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52,
+ 0x0a, 0x73, 0x75, 0x62, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x22, 0x49, 0x0a, 0x14, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x12, 0x31, 0x0a, 0x07, 0x73, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x18, 0x01,
+ 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x07, 0x73,
+ 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x22, 0x99, 0x01, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+ 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x3d, 0x0a, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+ 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
+ 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
+ 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+ 0x65, 0x64, 0x41, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
+ 0x03, 0x52, 0x03, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x14, 0x0a, 0x05,
+ 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72,
+ 0x6f, 0x72, 0x22, 0x52, 0x0a, 0x1a, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x34, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x03,
+ 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65,
+ 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x1d, 0x0a, 0x1b, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x73,
+ 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xde, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x39, 0x0a,
+ 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63,
+ 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70,
+ 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
+ 0x12, 0x2f, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,
+ 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32,
+ 0x2e, 0x4c, 0x6f, 0x67, 0x2e, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65,
+ 0x6c, 0x22, 0x53, 0x0a, 0x05, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x15, 0x0a, 0x11, 0x4c, 0x45,
+ 0x56, 0x45, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10,
+ 0x00, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05,
+ 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10,
+ 0x03, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x04, 0x12, 0x09, 0x0a, 0x05, 0x45,
+ 0x52, 0x52, 0x4f, 0x52, 0x10, 0x05, 0x22, 0x5e, 0x0a, 0x16, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43,
+ 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x64, 0x12, 0x27, 0x0a,
+ 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x6f, 0x67,
+ 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0x19, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43,
+ 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x2a, 0x63, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x12, 0x1a,
+ 0x0a, 0x16, 0x41, 0x50, 0x50, 0x5f, 0x48, 0x45, 0x41, 0x4c, 0x54, 0x48, 0x5f, 0x55, 0x4e, 0x53,
+ 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0c, 0x0a, 0x08, 0x44, 0x49,
+ 0x53, 0x41, 0x42, 0x4c, 0x45, 0x44, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x49, 0x4e, 0x49, 0x54,
+ 0x49, 0x41, 0x4c, 0x49, 0x5a, 0x49, 0x4e, 0x47, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x48, 0x45,
+ 0x41, 0x4c, 0x54, 0x48, 0x59, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x55, 0x4e, 0x48, 0x45, 0x41,
+ 0x4c, 0x54, 0x48, 0x59, 0x10, 0x04, 0x32, 0xb2, 0x07, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74,
+ 0x12, 0x4b, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12,
+ 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32,
+ 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e,
+ 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x12, 0x5a, 0x0a,
+ 0x10, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65,
+ 0x72, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e,
+ 0x76, 0x32, 0x2e, 0x47, 0x65, 0x74, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e,
+ 0x6e, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x65, 0x72, 0x76,
+ 0x69, 0x63, 0x65, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x12, 0x56, 0x0a, 0x0b, 0x55, 0x70, 0x64,
+ 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x12, 0x22, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72,
+ 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65,
+ 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x23, 0x2e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x12, 0x54, 0x0a, 0x0f, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65, 0x63,
+ 0x79, 0x63, 0x6c, 0x65, 0x12, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65,
+ 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x66, 0x65,
+ 0x63, 0x79, 0x63, 0x6c, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4c, 0x69,
+ 0x66, 0x65, 0x63, 0x79, 0x63, 0x6c, 0x65, 0x12, 0x72, 0x0a, 0x15, 0x42, 0x61, 0x74, 0x63, 0x68,
+ 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x73,
+ 0x12, 0x2b, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76,
+ 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70,
+ 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x41, 0x70, 0x70, 0x48, 0x65, 0x61,
+ 0x6c, 0x74, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x0d, 0x55,
+ 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x24, 0x2e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x55, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x75, 0x70, 0x12, 0x6e, 0x0a, 0x13, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
+ 0x74, 0x61, 0x12, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d,
+ 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b,
+ 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e,
+ 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64,
+ 0x61, 0x74, 0x61, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x62, 0x0a, 0x0f, 0x42,
+ 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x26,
+ 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e,
+ 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61,
+ 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65,
+ 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
+ 0x56, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70,
+ 0x73, 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
+ 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x45, 0x52, 0x50, 0x4d,
+ 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45,
+ 0x52, 0x50, 0x4d, 0x61, 0x70, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x43, 0x6f, 0x6f, 0x72, 0x64,
+ 0x69, 0x6e, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12, 0x23, 0x2e, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e,
+ 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
+ 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52,
+ 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x27, 0x5a, 0x25, 0x67,
+ 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f,
+ 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2f, 0x70,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_agent_proto_agent_proto_rawDescOnce sync.Once
+ file_agent_proto_agent_proto_rawDescData = file_agent_proto_agent_proto_rawDesc
+)
+
+func file_agent_proto_agent_proto_rawDescGZIP() []byte {
+ file_agent_proto_agent_proto_rawDescOnce.Do(func() {
+ file_agent_proto_agent_proto_rawDescData = protoimpl.X.CompressGZIP(file_agent_proto_agent_proto_rawDescData)
+ })
+ return file_agent_proto_agent_proto_rawDescData
+}
+
+var file_agent_proto_agent_proto_enumTypes = make([]protoimpl.EnumInfo, 6)
+var file_agent_proto_agent_proto_msgTypes = make([]protoimpl.MessageInfo, 25)
+var file_agent_proto_agent_proto_goTypes = []interface{}{
+ (AppHealth)(0), // 0: coder.agent.v2.AppHealth
+ (WorkspaceApp_SharingLevel)(0), // 1: coder.agent.v2.WorkspaceApp.SharingLevel
+ (WorkspaceApp_Health)(0), // 2: coder.agent.v2.WorkspaceApp.Health
+ (Stats_Metric_Type)(0), // 3: coder.agent.v2.Stats.Metric.Type
+ (Lifecycle_State)(0), // 4: coder.agent.v2.Lifecycle.State
+ (Log_Level)(0), // 5: coder.agent.v2.Log.Level
+ (*WorkspaceApp)(nil), // 6: coder.agent.v2.WorkspaceApp
+ (*Manifest)(nil), // 7: coder.agent.v2.Manifest
+ (*GetManifestRequest)(nil), // 8: coder.agent.v2.GetManifestRequest
+ (*ServiceBanner)(nil), // 9: coder.agent.v2.ServiceBanner
+ (*GetServiceBannerRequest)(nil), // 10: coder.agent.v2.GetServiceBannerRequest
+ (*Stats)(nil), // 11: coder.agent.v2.Stats
+ (*UpdateStatsRequest)(nil), // 12: coder.agent.v2.UpdateStatsRequest
+ (*UpdateStatsResponse)(nil), // 13: coder.agent.v2.UpdateStatsResponse
+ (*Lifecycle)(nil), // 14: coder.agent.v2.Lifecycle
+ (*UpdateLifecycleRequest)(nil), // 15: coder.agent.v2.UpdateLifecycleRequest
+ (*BatchUpdateAppHealthRequest)(nil), // 16: coder.agent.v2.BatchUpdateAppHealthRequest
+ (*BatchUpdateAppHealthResponse)(nil), // 17: coder.agent.v2.BatchUpdateAppHealthResponse
+ (*Startup)(nil), // 18: coder.agent.v2.Startup
+ (*UpdateStartupRequest)(nil), // 19: coder.agent.v2.UpdateStartupRequest
+ (*Metadata)(nil), // 20: coder.agent.v2.Metadata
+ (*BatchUpdateMetadataRequest)(nil), // 21: coder.agent.v2.BatchUpdateMetadataRequest
+ (*BatchUpdateMetadataResponse)(nil), // 22: coder.agent.v2.BatchUpdateMetadataResponse
+ (*Log)(nil), // 23: coder.agent.v2.Log
+ (*BatchCreateLogsRequest)(nil), // 24: coder.agent.v2.BatchCreateLogsRequest
+ (*BatchCreateLogsResponse)(nil), // 25: coder.agent.v2.BatchCreateLogsResponse
+ (*WorkspaceApp_HealthCheck)(nil), // 26: coder.agent.v2.WorkspaceApp.HealthCheck
+ nil, // 27: coder.agent.v2.Stats.ConnectionsByProtoEntry
+ (*Stats_Metric)(nil), // 28: coder.agent.v2.Stats.Metric
+ nil, // 29: coder.agent.v2.Stats.Metric.LabelsEntry
+ (*BatchUpdateAppHealthRequest_HealthUpdate)(nil), // 30: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate
+ (*proto.DERPMap)(nil), // 31: coder.tailnet.v2.DERPMap
+ (*durationpb.Duration)(nil), // 32: google.protobuf.Duration
+ (*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp
+ (*proto.StreamDERPMapsRequest)(nil), // 34: coder.tailnet.v2.StreamDERPMapsRequest
+ (*proto.CoordinateRequest)(nil), // 35: coder.tailnet.v2.CoordinateRequest
+ (*proto.CoordinateResponse)(nil), // 36: coder.tailnet.v2.CoordinateResponse
+}
+var file_agent_proto_agent_proto_depIdxs = []int32{
+ 1, // 0: coder.agent.v2.WorkspaceApp.sharing_level:type_name -> coder.agent.v2.WorkspaceApp.SharingLevel
+ 26, // 1: coder.agent.v2.WorkspaceApp.healthcheck:type_name -> coder.agent.v2.WorkspaceApp.HealthCheck
+ 2, // 2: coder.agent.v2.WorkspaceApp.health:type_name -> coder.agent.v2.WorkspaceApp.Health
+ 6, // 3: coder.agent.v2.Manifest.apps:type_name -> coder.agent.v2.WorkspaceApp
+ 31, // 4: coder.agent.v2.Manifest.derp_map:type_name -> coder.tailnet.v2.DERPMap
+ 27, // 5: coder.agent.v2.Stats.connections_by_proto:type_name -> coder.agent.v2.Stats.ConnectionsByProtoEntry
+ 11, // 6: coder.agent.v2.UpdateStatsRequest.stats:type_name -> coder.agent.v2.Stats
+ 32, // 7: coder.agent.v2.UpdateStatsResponse.report_interval_nanoseconds:type_name -> google.protobuf.Duration
+ 4, // 8: coder.agent.v2.Lifecycle.state:type_name -> coder.agent.v2.Lifecycle.State
+ 14, // 9: coder.agent.v2.UpdateLifecycleRequest.lifecycle:type_name -> coder.agent.v2.Lifecycle
+ 30, // 10: coder.agent.v2.BatchUpdateAppHealthRequest.updates:type_name -> coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate
+ 18, // 11: coder.agent.v2.UpdateStartupRequest.startup:type_name -> coder.agent.v2.Startup
+ 33, // 12: coder.agent.v2.Metadata.collected_at:type_name -> google.protobuf.Timestamp
+ 20, // 13: coder.agent.v2.BatchUpdateMetadataRequest.metadata:type_name -> coder.agent.v2.Metadata
+ 33, // 14: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp
+ 5, // 15: coder.agent.v2.Log.level:type_name -> coder.agent.v2.Log.Level
+ 23, // 16: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log
+ 3, // 17: coder.agent.v2.Stats.Metric.type:type_name -> coder.agent.v2.Stats.Metric.Type
+ 29, // 18: coder.agent.v2.Stats.Metric.labels:type_name -> coder.agent.v2.Stats.Metric.LabelsEntry
+ 0, // 19: coder.agent.v2.BatchUpdateAppHealthRequest.HealthUpdate.health:type_name -> coder.agent.v2.AppHealth
+ 8, // 20: coder.agent.v2.Agent.GetManifest:input_type -> coder.agent.v2.GetManifestRequest
+ 10, // 21: coder.agent.v2.Agent.GetServiceBanner:input_type -> coder.agent.v2.GetServiceBannerRequest
+ 12, // 22: coder.agent.v2.Agent.UpdateStats:input_type -> coder.agent.v2.UpdateStatsRequest
+ 15, // 23: coder.agent.v2.Agent.UpdateLifecycle:input_type -> coder.agent.v2.UpdateLifecycleRequest
+ 16, // 24: coder.agent.v2.Agent.BatchUpdateAppHealths:input_type -> coder.agent.v2.BatchUpdateAppHealthRequest
+ 19, // 25: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest
+ 21, // 26: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest
+ 24, // 27: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest
+ 34, // 28: coder.agent.v2.Agent.StreamDERPMaps:input_type -> coder.tailnet.v2.StreamDERPMapsRequest
+ 35, // 29: coder.agent.v2.Agent.CoordinateTailnet:input_type -> coder.tailnet.v2.CoordinateRequest
+ 7, // 30: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest
+ 9, // 31: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner
+ 13, // 32: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse
+ 14, // 33: coder.agent.v2.Agent.UpdateLifecycle:output_type -> coder.agent.v2.Lifecycle
+ 17, // 34: coder.agent.v2.Agent.BatchUpdateAppHealths:output_type -> coder.agent.v2.BatchUpdateAppHealthResponse
+ 18, // 35: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup
+ 22, // 36: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse
+ 25, // 37: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse
+ 31, // 38: coder.agent.v2.Agent.StreamDERPMaps:output_type -> coder.tailnet.v2.DERPMap
+ 36, // 39: coder.agent.v2.Agent.CoordinateTailnet:output_type -> coder.tailnet.v2.CoordinateResponse
+ 30, // [30:40] is the sub-list for method output_type
+ 20, // [20:30] is the sub-list for method input_type
+ 20, // [20:20] is the sub-list for extension type_name
+ 20, // [20:20] is the sub-list for extension extendee
+ 0, // [0:20] is the sub-list for field type_name
+}
+
+func init() { file_agent_proto_agent_proto_init() }
+func file_agent_proto_agent_proto_init() {
+ if File_agent_proto_agent_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_agent_proto_agent_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*WorkspaceApp); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Manifest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetManifestRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ServiceBanner); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*GetServiceBannerRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Stats); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateStatsRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateStatsResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Lifecycle); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateLifecycleRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchUpdateAppHealthRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchUpdateAppHealthResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Startup); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*UpdateStartupRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Metadata); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchUpdateMetadataRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchUpdateMetadataResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Log); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchCreateLogsRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchCreateLogsResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*WorkspaceApp_HealthCheck); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Stats_Metric); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_agent_proto_agent_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*BatchUpdateAppHealthRequest_HealthUpdate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_agent_proto_agent_proto_rawDesc,
+ NumEnums: 6,
+ NumMessages: 25,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_agent_proto_agent_proto_goTypes,
+ DependencyIndexes: file_agent_proto_agent_proto_depIdxs,
+ EnumInfos: file_agent_proto_agent_proto_enumTypes,
+ MessageInfos: file_agent_proto_agent_proto_msgTypes,
+ }.Build()
+ File_agent_proto_agent_proto = out.File
+ file_agent_proto_agent_proto_rawDesc = nil
+ file_agent_proto_agent_proto_goTypes = nil
+ file_agent_proto_agent_proto_depIdxs = nil
+}
diff --git a/agent/proto/agent.proto b/agent/proto/agent.proto
new file mode 100644
index 0000000000000..5d6c09c167db0
--- /dev/null
+++ b/agent/proto/agent.proto
@@ -0,0 +1,211 @@
+syntax = "proto3";
+option go_package = "github.com/coder/coder/v2/agent/proto";
+
+package coder.agent.v2;
+
+import "tailnet/proto/tailnet.proto";
+import "google/protobuf/timestamp.proto";
+import "google/protobuf/duration.proto";
+
+message WorkspaceApp {
+ bytes uuid = 1;
+ string url = 2;
+ bool external = 3;
+ string slug = 4;
+ string display_name = 5;
+ string command = 6;
+ string icon = 7;
+ bool subdomain = 8;
+ string subdomain_name = 9;
+
+ enum SharingLevel {
+ SHARING_LEVEL_UNSPECIFIED = 0;
+ OWNER = 1;
+ AUTHENTICATED = 2;
+ PUBLIC = 3;
+ }
+ SharingLevel sharing_level = 10;
+
+ message HealthCheck {
+ string url = 1;
+ int32 interval = 2;
+ int32 threshold = 3;
+ }
+ HealthCheck healthcheck = 11;
+
+ enum Health {
+ HEALTH_UNSPECIFIED = 0;
+ DISABLED = 1;
+ INITIALIZING = 2;
+ HEALTHY = 3;
+ UNHEALTHY = 4;
+ }
+ Health health = 12;
+}
+
+message Manifest {
+ uint32 git_auth_configs = 1;
+ string vs_code_port_proxy_uri = 2;
+ repeated WorkspaceApp apps = 3;
+ coder.tailnet.v2.DERPMap derp_map = 4;
+}
+
+message GetManifestRequest {}
+
+message ServiceBanner {
+ bool enabled = 1;
+ string message = 2;
+ string background_color = 3;
+}
+
+message GetServiceBannerRequest {}
+
+message Stats {
+ // ConnectionsByProto is a count of connections by protocol.
+ map connections_by_proto = 1;
+ // ConnectionCount is the number of connections received by an agent.
+ int64 connection_count = 2;
+ // ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.
+ double connection_median_latency_ms = 3;
+ // RxPackets is the number of received packets.
+ int64 rx_packets = 4;
+ // RxBytes is the number of received bytes.
+ int64 rx_bytes = 5;
+ // TxPackets is the number of transmitted bytes.
+ int64 tx_packets = 6;
+ // TxBytes is the number of transmitted bytes.
+ int64 tx_bytes = 7;
+
+ // SessionCountVSCode is the number of connections received by an agent
+ // that are from our VS Code extension.
+ int64 session_count_vscode = 8;
+ // SessionCountJetBrains is the number of connections received by an agent
+ // that are from our JetBrains extension.
+ int64 session_count_jetbrains = 9;
+ // SessionCountReconnectingPTY is the number of connections received by an agent
+ // that are from the reconnecting web terminal.
+ int64 session_count_reconnecting_pty = 10;
+ // SessionCountSSH is the number of connections received by an agent
+ // that are normal, non-tagged SSH sessions.
+ int64 session_count_ssh = 11;
+
+ message Metric {
+ string name = 1;
+
+ enum Type {
+ TYPE_UNSPECIFIED = 0;
+ COUNTER = 1;
+ GAUGE = 2;
+ }
+ Type type = 2;
+
+ double value = 3;
+ map labels = 4;
+ }
+}
+
+message UpdateStatsRequest{
+ Stats stats = 1;
+}
+
+message UpdateStatsResponse {
+ google.protobuf.Duration report_interval_nanoseconds = 1;
+}
+
+message Lifecycle {
+ enum State {
+ STATE_UNSPECIFIED = 0;
+ CREATED = 1;
+ STARTED = 2;
+ START_TIMEOUT = 3;
+ START_ERROR = 4;
+ READY = 5;
+ SHUTTING_DOWN = 6;
+ SHUTDOWN_TIMEOUT = 7;
+ SHUTDOWN_ERROR = 8;
+ OFF = 9;
+ }
+ State state = 1;
+}
+
+message UpdateLifecycleRequest {
+ Lifecycle lifecycle = 1;
+}
+
+enum AppHealth {
+ APP_HEALTH_UNSPECIFIED = 0;
+ DISABLED = 1;
+ INITIALIZING = 2;
+ HEALTHY = 3;
+ UNHEALTHY = 4;
+}
+
+message BatchUpdateAppHealthRequest {
+ message HealthUpdate {
+ bytes uuid = 1;
+ AppHealth health = 2;
+ }
+ repeated HealthUpdate updates = 1;
+}
+
+message BatchUpdateAppHealthResponse {}
+
+message Startup {
+ string version = 1;
+ string expanded_directory = 2;
+ repeated string subsystems = 3;
+}
+
+message UpdateStartupRequest{
+ Startup startup = 1;
+}
+
+message Metadata {
+ string key = 1;
+ google.protobuf.Timestamp collected_at = 2;
+ int64 age = 3;
+ string value = 4;
+ string error = 5;
+}
+
+message BatchUpdateMetadataRequest {
+ repeated Metadata metadata = 2;
+}
+
+message BatchUpdateMetadataResponse {}
+
+message Log {
+ google.protobuf.Timestamp created_at = 1;
+ string output = 2;
+
+ enum Level {
+ LEVEL_UNSPECIFIED = 0;
+ TRACE = 1;
+ DEBUG = 2;
+ INFO = 3;
+ WARN = 4;
+ ERROR = 5;
+ }
+ Level level = 3;
+}
+
+message BatchCreateLogsRequest {
+ bytes source_id = 1;
+ repeated Log logs = 2;
+}
+
+message BatchCreateLogsResponse {}
+
+service Agent {
+ rpc GetManifest(GetManifestRequest) returns (Manifest);
+ rpc GetServiceBanner(GetServiceBannerRequest) returns (ServiceBanner);
+ rpc UpdateStats(UpdateStatsRequest) returns (UpdateStatsResponse);
+ rpc UpdateLifecycle(UpdateLifecycleRequest) returns (Lifecycle);
+ rpc BatchUpdateAppHealths(BatchUpdateAppHealthRequest) returns (BatchUpdateAppHealthResponse);
+ rpc UpdateStartup(UpdateStartupRequest) returns (Startup);
+ rpc BatchUpdateMetadata(BatchUpdateMetadataRequest) returns (BatchUpdateMetadataResponse);
+ rpc BatchCreateLogs(BatchCreateLogsRequest) returns (BatchCreateLogsResponse);
+
+ rpc StreamDERPMaps(tailnet.v2.StreamDERPMapsRequest) returns (stream tailnet.v2.DERPMap);
+ rpc CoordinateTailnet(stream tailnet.v2.CoordinateRequest) returns (stream tailnet.v2.CoordinateResponse);
+}
diff --git a/agent/proto/agent_drpc.pb.go b/agent/proto/agent_drpc.pb.go
new file mode 100644
index 0000000000000..b64ca2b4f2bc7
--- /dev/null
+++ b/agent/proto/agent_drpc.pb.go
@@ -0,0 +1,539 @@
+// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
+// protoc-gen-go-drpc version: v0.0.33
+// source: agent/proto/agent.proto
+
+package proto
+
+import (
+ context "context"
+ errors "errors"
+ proto1 "github.com/coder/coder/v2/tailnet/proto"
+ protojson "google.golang.org/protobuf/encoding/protojson"
+ proto "google.golang.org/protobuf/proto"
+ drpc "storj.io/drpc"
+ drpcerr "storj.io/drpc/drpcerr"
+)
+
+type drpcEncoding_File_agent_proto_agent_proto struct{}
+
+func (drpcEncoding_File_agent_proto_agent_proto) Marshal(msg drpc.Message) ([]byte, error) {
+ return proto.Marshal(msg.(proto.Message))
+}
+
+func (drpcEncoding_File_agent_proto_agent_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) {
+ return proto.MarshalOptions{}.MarshalAppend(buf, msg.(proto.Message))
+}
+
+func (drpcEncoding_File_agent_proto_agent_proto) Unmarshal(buf []byte, msg drpc.Message) error {
+ return proto.Unmarshal(buf, msg.(proto.Message))
+}
+
+func (drpcEncoding_File_agent_proto_agent_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
+ return protojson.Marshal(msg.(proto.Message))
+}
+
+func (drpcEncoding_File_agent_proto_agent_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
+ return protojson.Unmarshal(buf, msg.(proto.Message))
+}
+
+type DRPCAgentClient interface {
+ DRPCConn() drpc.Conn
+
+ GetManifest(ctx context.Context, in *GetManifestRequest) (*Manifest, error)
+ GetServiceBanner(ctx context.Context, in *GetServiceBannerRequest) (*ServiceBanner, error)
+ UpdateStats(ctx context.Context, in *UpdateStatsRequest) (*UpdateStatsResponse, error)
+ UpdateLifecycle(ctx context.Context, in *UpdateLifecycleRequest) (*Lifecycle, error)
+ BatchUpdateAppHealths(ctx context.Context, in *BatchUpdateAppHealthRequest) (*BatchUpdateAppHealthResponse, error)
+ UpdateStartup(ctx context.Context, in *UpdateStartupRequest) (*Startup, error)
+ BatchUpdateMetadata(ctx context.Context, in *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error)
+ BatchCreateLogs(ctx context.Context, in *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error)
+ StreamDERPMaps(ctx context.Context, in *proto1.StreamDERPMapsRequest) (DRPCAgent_StreamDERPMapsClient, error)
+ CoordinateTailnet(ctx context.Context) (DRPCAgent_CoordinateTailnetClient, error)
+}
+
+type drpcAgentClient struct {
+ cc drpc.Conn
+}
+
+func NewDRPCAgentClient(cc drpc.Conn) DRPCAgentClient {
+ return &drpcAgentClient{cc}
+}
+
+func (c *drpcAgentClient) DRPCConn() drpc.Conn { return c.cc }
+
+func (c *drpcAgentClient) GetManifest(ctx context.Context, in *GetManifestRequest) (*Manifest, error) {
+ out := new(Manifest)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/GetManifest", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) GetServiceBanner(ctx context.Context, in *GetServiceBannerRequest) (*ServiceBanner, error) {
+ out := new(ServiceBanner)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/GetServiceBanner", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) UpdateStats(ctx context.Context, in *UpdateStatsRequest) (*UpdateStatsResponse, error) {
+ out := new(UpdateStatsResponse)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/UpdateStats", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) UpdateLifecycle(ctx context.Context, in *UpdateLifecycleRequest) (*Lifecycle, error) {
+ out := new(Lifecycle)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/UpdateLifecycle", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) BatchUpdateAppHealths(ctx context.Context, in *BatchUpdateAppHealthRequest) (*BatchUpdateAppHealthResponse, error) {
+ out := new(BatchUpdateAppHealthResponse)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/BatchUpdateAppHealths", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) UpdateStartup(ctx context.Context, in *UpdateStartupRequest) (*Startup, error) {
+ out := new(Startup)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/UpdateStartup", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) BatchUpdateMetadata(ctx context.Context, in *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error) {
+ out := new(BatchUpdateMetadataResponse)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/BatchUpdateMetadata", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) BatchCreateLogs(ctx context.Context, in *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error) {
+ out := new(BatchCreateLogsResponse)
+ err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/BatchCreateLogs", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
+func (c *drpcAgentClient) StreamDERPMaps(ctx context.Context, in *proto1.StreamDERPMapsRequest) (DRPCAgent_StreamDERPMapsClient, error) {
+ stream, err := c.cc.NewStream(ctx, "/coder.agent.v2.Agent/StreamDERPMaps", drpcEncoding_File_agent_proto_agent_proto{})
+ if err != nil {
+ return nil, err
+ }
+ x := &drpcAgent_StreamDERPMapsClient{stream}
+ if err := x.MsgSend(in, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return nil, err
+ }
+ if err := x.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type DRPCAgent_StreamDERPMapsClient interface {
+ drpc.Stream
+ Recv() (*proto1.DERPMap, error)
+}
+
+type drpcAgent_StreamDERPMapsClient struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_StreamDERPMapsClient) GetStream() drpc.Stream {
+ return x.Stream
+}
+
+func (x *drpcAgent_StreamDERPMapsClient) Recv() (*proto1.DERPMap, error) {
+ m := new(proto1.DERPMap)
+ if err := x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcAgent_StreamDERPMapsClient) RecvMsg(m *proto1.DERPMap) error {
+ return x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
+
+func (c *drpcAgentClient) CoordinateTailnet(ctx context.Context) (DRPCAgent_CoordinateTailnetClient, error) {
+ stream, err := c.cc.NewStream(ctx, "/coder.agent.v2.Agent/CoordinateTailnet", drpcEncoding_File_agent_proto_agent_proto{})
+ if err != nil {
+ return nil, err
+ }
+ x := &drpcAgent_CoordinateTailnetClient{stream}
+ return x, nil
+}
+
+type DRPCAgent_CoordinateTailnetClient interface {
+ drpc.Stream
+ Send(*proto1.CoordinateRequest) error
+ Recv() (*proto1.CoordinateResponse, error)
+}
+
+type drpcAgent_CoordinateTailnetClient struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_CoordinateTailnetClient) GetStream() drpc.Stream {
+ return x.Stream
+}
+
+func (x *drpcAgent_CoordinateTailnetClient) Send(m *proto1.CoordinateRequest) error {
+ return x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
+
+func (x *drpcAgent_CoordinateTailnetClient) Recv() (*proto1.CoordinateResponse, error) {
+ m := new(proto1.CoordinateResponse)
+ if err := x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcAgent_CoordinateTailnetClient) RecvMsg(m *proto1.CoordinateResponse) error {
+ return x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
+
+type DRPCAgentServer interface {
+ GetManifest(context.Context, *GetManifestRequest) (*Manifest, error)
+ GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error)
+ UpdateStats(context.Context, *UpdateStatsRequest) (*UpdateStatsResponse, error)
+ UpdateLifecycle(context.Context, *UpdateLifecycleRequest) (*Lifecycle, error)
+ BatchUpdateAppHealths(context.Context, *BatchUpdateAppHealthRequest) (*BatchUpdateAppHealthResponse, error)
+ UpdateStartup(context.Context, *UpdateStartupRequest) (*Startup, error)
+ BatchUpdateMetadata(context.Context, *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error)
+ BatchCreateLogs(context.Context, *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error)
+ StreamDERPMaps(*proto1.StreamDERPMapsRequest, DRPCAgent_StreamDERPMapsStream) error
+ CoordinateTailnet(DRPCAgent_CoordinateTailnetStream) error
+}
+
+type DRPCAgentUnimplementedServer struct{}
+
+func (s *DRPCAgentUnimplementedServer) GetManifest(context.Context, *GetManifestRequest) (*Manifest, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) UpdateStats(context.Context, *UpdateStatsRequest) (*UpdateStatsResponse, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) UpdateLifecycle(context.Context, *UpdateLifecycleRequest) (*Lifecycle, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) BatchUpdateAppHealths(context.Context, *BatchUpdateAppHealthRequest) (*BatchUpdateAppHealthResponse, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) UpdateStartup(context.Context, *UpdateStartupRequest) (*Startup, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) BatchUpdateMetadata(context.Context, *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) BatchCreateLogs(context.Context, *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error) {
+ return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) StreamDERPMaps(*proto1.StreamDERPMapsRequest, DRPCAgent_StreamDERPMapsStream) error {
+ return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCAgentUnimplementedServer) CoordinateTailnet(DRPCAgent_CoordinateTailnetStream) error {
+ return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+type DRPCAgentDescription struct{}
+
+func (DRPCAgentDescription) NumMethods() int { return 10 }
+
+func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
+ switch n {
+ case 0:
+ return "/coder.agent.v2.Agent/GetManifest", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ GetManifest(
+ ctx,
+ in1.(*GetManifestRequest),
+ )
+ }, DRPCAgentServer.GetManifest, true
+ case 1:
+ return "/coder.agent.v2.Agent/GetServiceBanner", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ GetServiceBanner(
+ ctx,
+ in1.(*GetServiceBannerRequest),
+ )
+ }, DRPCAgentServer.GetServiceBanner, true
+ case 2:
+ return "/coder.agent.v2.Agent/UpdateStats", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ UpdateStats(
+ ctx,
+ in1.(*UpdateStatsRequest),
+ )
+ }, DRPCAgentServer.UpdateStats, true
+ case 3:
+ return "/coder.agent.v2.Agent/UpdateLifecycle", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ UpdateLifecycle(
+ ctx,
+ in1.(*UpdateLifecycleRequest),
+ )
+ }, DRPCAgentServer.UpdateLifecycle, true
+ case 4:
+ return "/coder.agent.v2.Agent/BatchUpdateAppHealths", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ BatchUpdateAppHealths(
+ ctx,
+ in1.(*BatchUpdateAppHealthRequest),
+ )
+ }, DRPCAgentServer.BatchUpdateAppHealths, true
+ case 5:
+ return "/coder.agent.v2.Agent/UpdateStartup", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ UpdateStartup(
+ ctx,
+ in1.(*UpdateStartupRequest),
+ )
+ }, DRPCAgentServer.UpdateStartup, true
+ case 6:
+ return "/coder.agent.v2.Agent/BatchUpdateMetadata", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ BatchUpdateMetadata(
+ ctx,
+ in1.(*BatchUpdateMetadataRequest),
+ )
+ }, DRPCAgentServer.BatchUpdateMetadata, true
+ case 7:
+ return "/coder.agent.v2.Agent/BatchCreateLogs", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return srv.(DRPCAgentServer).
+ BatchCreateLogs(
+ ctx,
+ in1.(*BatchCreateLogsRequest),
+ )
+ }, DRPCAgentServer.BatchCreateLogs, true
+ case 8:
+ return "/coder.agent.v2.Agent/StreamDERPMaps", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return nil, srv.(DRPCAgentServer).
+ StreamDERPMaps(
+ in1.(*proto1.StreamDERPMapsRequest),
+ &drpcAgent_StreamDERPMapsStream{in2.(drpc.Stream)},
+ )
+ }, DRPCAgentServer.StreamDERPMaps, true
+ case 9:
+ return "/coder.agent.v2.Agent/CoordinateTailnet", drpcEncoding_File_agent_proto_agent_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return nil, srv.(DRPCAgentServer).
+ CoordinateTailnet(
+ &drpcAgent_CoordinateTailnetStream{in1.(drpc.Stream)},
+ )
+ }, DRPCAgentServer.CoordinateTailnet, true
+ default:
+ return "", nil, nil, nil, false
+ }
+}
+
+func DRPCRegisterAgent(mux drpc.Mux, impl DRPCAgentServer) error {
+ return mux.Register(impl, DRPCAgentDescription{})
+}
+
+type DRPCAgent_GetManifestStream interface {
+ drpc.Stream
+ SendAndClose(*Manifest) error
+}
+
+type drpcAgent_GetManifestStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_GetManifestStream) SendAndClose(m *Manifest) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_GetServiceBannerStream interface {
+ drpc.Stream
+ SendAndClose(*ServiceBanner) error
+}
+
+type drpcAgent_GetServiceBannerStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_GetServiceBannerStream) SendAndClose(m *ServiceBanner) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_UpdateStatsStream interface {
+ drpc.Stream
+ SendAndClose(*UpdateStatsResponse) error
+}
+
+type drpcAgent_UpdateStatsStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_UpdateStatsStream) SendAndClose(m *UpdateStatsResponse) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_UpdateLifecycleStream interface {
+ drpc.Stream
+ SendAndClose(*Lifecycle) error
+}
+
+type drpcAgent_UpdateLifecycleStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_UpdateLifecycleStream) SendAndClose(m *Lifecycle) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_BatchUpdateAppHealthsStream interface {
+ drpc.Stream
+ SendAndClose(*BatchUpdateAppHealthResponse) error
+}
+
+type drpcAgent_BatchUpdateAppHealthsStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_BatchUpdateAppHealthsStream) SendAndClose(m *BatchUpdateAppHealthResponse) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_UpdateStartupStream interface {
+ drpc.Stream
+ SendAndClose(*Startup) error
+}
+
+type drpcAgent_UpdateStartupStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_UpdateStartupStream) SendAndClose(m *Startup) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_BatchUpdateMetadataStream interface {
+ drpc.Stream
+ SendAndClose(*BatchUpdateMetadataResponse) error
+}
+
+type drpcAgent_BatchUpdateMetadataStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_BatchUpdateMetadataStream) SendAndClose(m *BatchUpdateMetadataResponse) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_BatchCreateLogsStream interface {
+ drpc.Stream
+ SendAndClose(*BatchCreateLogsResponse) error
+}
+
+type drpcAgent_BatchCreateLogsStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_BatchCreateLogsStream) SendAndClose(m *BatchCreateLogsResponse) error {
+ if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return err
+ }
+ return x.CloseSend()
+}
+
+type DRPCAgent_StreamDERPMapsStream interface {
+ drpc.Stream
+ Send(*proto1.DERPMap) error
+}
+
+type drpcAgent_StreamDERPMapsStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_StreamDERPMapsStream) Send(m *proto1.DERPMap) error {
+ return x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
+
+type DRPCAgent_CoordinateTailnetStream interface {
+ drpc.Stream
+ Send(*proto1.CoordinateResponse) error
+ Recv() (*proto1.CoordinateRequest, error)
+}
+
+type drpcAgent_CoordinateTailnetStream struct {
+ drpc.Stream
+}
+
+func (x *drpcAgent_CoordinateTailnetStream) Send(m *proto1.CoordinateResponse) error {
+ return x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
+
+func (x *drpcAgent_CoordinateTailnetStream) Recv() (*proto1.CoordinateRequest, error) {
+ m := new(proto1.CoordinateRequest)
+ if err := x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcAgent_CoordinateTailnetStream) RecvMsg(m *proto1.CoordinateRequest) error {
+ return x.MsgRecv(m, drpcEncoding_File_agent_proto_agent_proto{})
+}
diff --git a/agent/reconnectingpty/reconnectingpty.go b/agent/reconnectingpty/reconnectingpty.go
index 30b1f44801b9f..280cf62aaa841 100644
--- a/agent/reconnectingpty/reconnectingpty.go
+++ b/agent/reconnectingpty/reconnectingpty.go
@@ -196,8 +196,8 @@ func (s *ptyState) waitForStateOrContext(ctx context.Context, state State) (Stat
// until EOF or an error writing to ptty or reading from conn.
func readConnLoop(ctx context.Context, conn net.Conn, ptty pty.PTYCmd, metrics *prometheus.CounterVec, logger slog.Logger) {
decoder := json.NewDecoder(conn)
- var req codersdk.ReconnectingPTYRequest
for {
+ var req codersdk.ReconnectingPTYRequest
err := decoder.Decode(&req)
if xerrors.Is(err, io.EOF) {
return
diff --git a/cli/cliui/agent_test.go b/cli/cliui/agent_test.go
index ffb116f3a8f01..4cb10d8ec073e 100644
--- a/cli/cliui/agent_test.go
+++ b/cli/cliui/agent_test.go
@@ -5,12 +5,14 @@ import (
"bytes"
"context"
"io"
+ "os"
"strings"
"sync/atomic"
"testing"
"time"
"github.com/google/uuid"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/xerrors"
@@ -25,9 +27,31 @@ import (
func TestAgent(t *testing.T) {
t.Parallel()
+ waitLines := func(t *testing.T, output <-chan string, lines ...string) error {
+ t.Helper()
+
+ var got []string
+ outerLoop:
+ for _, want := range lines {
+ for {
+ select {
+ case line := <-output:
+ got = append(got, line)
+ if strings.Contains(line, want) {
+ continue outerLoop
+ }
+ case <-time.After(testutil.WaitShort):
+ assert.Failf(t, "timed out waiting for line", "want: %q; got: %q", want, got)
+ return xerrors.Errorf("timed out waiting for line: %q; got: %q", want, got)
+ }
+ }
+ }
+ return nil
+ }
+
for _, tc := range []struct {
name string
- iter []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error
+ iter []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error
logs chan []codersdk.WorkspaceAgentLog
opts cliui.AgentOptions
want []string
@@ -38,12 +62,15 @@ func TestAgent(t *testing.T) {
opts: cliui.AgentOptions{
FetchInterval: time.Millisecond,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnecting
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "â§— Waiting for the workspace agent to connect")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.FirstConnectedAt = ptr.Ref(time.Now())
return nil
@@ -62,12 +89,15 @@ func TestAgent(t *testing.T) {
opts: cliui.AgentOptions{
FetchInterval: time.Millisecond,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnecting
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "â§— Waiting for the workspace agent to connect")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStartTimeout
agent.FirstConnectedAt = ptr.Ref(time.Now())
@@ -87,18 +117,24 @@ func TestAgent(t *testing.T) {
opts: cliui.AgentOptions{
FetchInterval: 1 * time.Millisecond,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnecting
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStarting
agent.StartedAt = ptr.Ref(time.Now())
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "â§— Waiting for the workspace agent to connect")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentTimeout
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "The workspace agent is having trouble connecting, wait for it to connect or restart your workspace.")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.FirstConnectedAt = ptr.Ref(time.Now())
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleReady
@@ -120,8 +156,8 @@ func TestAgent(t *testing.T) {
opts: cliui.AgentOptions{
FetchInterval: 1 * time.Millisecond,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentDisconnected
agent.FirstConnectedAt = ptr.Ref(time.Now().Add(-1 * time.Minute))
agent.LastConnectedAt = ptr.Ref(time.Now().Add(-1 * time.Minute))
@@ -131,7 +167,10 @@ func TestAgent(t *testing.T) {
agent.ReadyAt = ptr.Ref(time.Now())
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "â§— The workspace agent lost connection")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.DisconnectedAt = nil
agent.LastConnectedAt = ptr.Ref(time.Now())
@@ -151,8 +190,8 @@ func TestAgent(t *testing.T) {
FetchInterval: time.Millisecond,
Wait: true,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, logs chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.FirstConnectedAt = ptr.Ref(time.Now())
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStarting
@@ -170,7 +209,7 @@ func TestAgent(t *testing.T) {
}
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, logs chan []codersdk.WorkspaceAgentLog) error {
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleReady
agent.ReadyAt = ptr.Ref(time.Now())
logs <- []codersdk.WorkspaceAgentLog{
@@ -195,8 +234,8 @@ func TestAgent(t *testing.T) {
FetchInterval: time.Millisecond,
Wait: true,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, logs chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.FirstConnectedAt = ptr.Ref(time.Now())
agent.StartedAt = ptr.Ref(time.Now())
@@ -224,8 +263,8 @@ func TestAgent(t *testing.T) {
opts: cliui.AgentOptions{
FetchInterval: time.Millisecond,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, logs chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentDisconnected
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleOff
return nil
@@ -239,8 +278,8 @@ func TestAgent(t *testing.T) {
FetchInterval: time.Millisecond,
Wait: true,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, logs chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnected
agent.FirstConnectedAt = ptr.Ref(time.Now())
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleStarting
@@ -253,7 +292,10 @@ func TestAgent(t *testing.T) {
}
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, logs chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "Hello world")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.ReadyAt = ptr.Ref(time.Now())
agent.LifecycleState = codersdk.WorkspaceAgentLifecycleShuttingDown
return nil
@@ -272,12 +314,15 @@ func TestAgent(t *testing.T) {
FetchInterval: time.Millisecond,
Wait: true,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentConnecting
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "â§— Waiting for the workspace agent to connect")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
return xerrors.New("bad")
},
},
@@ -292,13 +337,16 @@ func TestAgent(t *testing.T) {
FetchInterval: time.Millisecond,
Wait: true,
},
- iter: []func(context.Context, *codersdk.WorkspaceAgent, chan []codersdk.WorkspaceAgentLog) error{
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ iter: []func(context.Context, *testing.T, *codersdk.WorkspaceAgent, <-chan string, chan []codersdk.WorkspaceAgentLog) error{
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, _ <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
agent.Status = codersdk.WorkspaceAgentTimeout
agent.TroubleshootingURL = "https://troubleshoot"
return nil
},
- func(_ context.Context, agent *codersdk.WorkspaceAgent, _ chan []codersdk.WorkspaceAgentLog) error {
+ func(_ context.Context, t *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
+ return waitLines(t, output, "The workspace agent is having trouble connecting, wait for it to connect or restart your workspace.")
+ },
+ func(_ context.Context, _ *testing.T, agent *codersdk.WorkspaceAgent, output <-chan string, _ chan []codersdk.WorkspaceAgentLog) error {
return xerrors.New("bad")
},
},
@@ -317,21 +365,27 @@ func TestAgent(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
- var buf bytes.Buffer
+ r, w, err := os.Pipe()
+ require.NoError(t, err, "create pipe failed")
+ defer r.Close()
+ defer w.Close()
+
agent := codersdk.WorkspaceAgent{
ID: uuid.New(),
Status: codersdk.WorkspaceAgentConnecting,
CreatedAt: time.Now(),
LifecycleState: codersdk.WorkspaceAgentLifecycleCreated,
}
+ output := make(chan string, 100) // Buffered to avoid blocking, overflow is discarded.
logs := make(chan []codersdk.WorkspaceAgentLog, 1)
cmd := &clibase.Cmd{
Handler: func(inv *clibase.Invocation) error {
tc.opts.Fetch = func(_ context.Context, _ uuid.UUID) (codersdk.WorkspaceAgent, error) {
+ t.Log("iter", len(tc.iter))
var err error
if len(tc.iter) > 0 {
- err = tc.iter[0](ctx, &agent, logs)
+ err = tc.iter[0](ctx, t, &agent, output, logs)
tc.iter = tc.iter[1:]
}
return agent, err
@@ -352,27 +406,25 @@ func TestAgent(t *testing.T) {
close(fetchLogs)
return fetchLogs, closeFunc(func() error { return nil }), nil
}
- err := cliui.Agent(inv.Context(), &buf, uuid.Nil, tc.opts)
+ err := cliui.Agent(inv.Context(), w, uuid.Nil, tc.opts)
+ _ = w.Close()
return err
},
}
inv := cmd.Invoke()
- w := clitest.StartWithWaiter(t, inv)
- if tc.wantErr {
- w.RequireError()
- } else {
- w.RequireSuccess()
- }
+ waiter := clitest.StartWithWaiter(t, inv)
- s := bufio.NewScanner(&buf)
+ s := bufio.NewScanner(r)
for s.Scan() {
line := s.Text()
t.Log(line)
+ select {
+ case output <- line:
+ default:
+ t.Logf("output overflow: %s", line)
+ }
if len(tc.want) == 0 {
- for i := 0; i < 5; i++ {
- t.Log(line)
- }
require.Fail(t, "unexpected line", line)
}
require.Contains(t, line, tc.want[0])
@@ -382,6 +434,12 @@ func TestAgent(t *testing.T) {
if len(tc.want) > 0 {
require.Fail(t, "missing lines: "+strings.Join(tc.want, ", "))
}
+
+ if tc.wantErr {
+ waiter.RequireError()
+ } else {
+ waiter.RequireSuccess()
+ }
})
}
diff --git a/cli/dotfiles.go b/cli/dotfiles.go
index cf3b1391d5e9a..f3d15515585e3 100644
--- a/cli/dotfiles.go
+++ b/cli/dotfiles.go
@@ -22,6 +22,7 @@ import (
func (r *RootCmd) dotfiles() *clibase.Cmd {
var symlinkDir string
var gitbranch string
+ var dotfilesRepoDir string
cmd := &clibase.Cmd{
Use: "dotfiles ",
@@ -35,11 +36,10 @@ func (r *RootCmd) dotfiles() *clibase.Cmd {
),
Handler: func(inv *clibase.Invocation) error {
var (
- dotfilesRepoDir = "dotfiles"
- gitRepo = inv.Args[0]
- cfg = r.createConfig()
- cfgDir = string(cfg)
- dotfilesDir = filepath.Join(cfgDir, dotfilesRepoDir)
+ gitRepo = inv.Args[0]
+ cfg = r.createConfig()
+ cfgDir = string(cfg)
+ dotfilesDir = filepath.Join(cfgDir, dotfilesRepoDir)
// This follows the same pattern outlined by others in the market:
// https://github.com/coder/coder/pull/1696#issue-1245742312
installScriptSet = []string{
@@ -290,6 +290,13 @@ func (r *RootCmd) dotfiles() *clibase.Cmd {
"If empty, will default to cloning the default branch or using the existing branch in the cloned repo on disk.",
Value: clibase.StringOf(&gitbranch),
},
+ {
+ Flag: "repo-dir",
+ Default: "dotfiles",
+ Env: "CODER_DOTFILES_REPO_DIR",
+ Description: "Specifies the directory for the dotfiles repository, relative to global config directory.",
+ Value: clibase.StringOf(&dotfilesRepoDir),
+ },
cliui.SkipPromptOption(),
}
return cmd
diff --git a/cli/dotfiles_test.go b/cli/dotfiles_test.go
index d5511c986aecc..6726f35b785ad 100644
--- a/cli/dotfiles_test.go
+++ b/cli/dotfiles_test.go
@@ -50,6 +50,68 @@ func TestDotfiles(t *testing.T) {
require.NoError(t, err)
require.Equal(t, string(b), "wow")
})
+ t.Run("SwitchRepoDir", func(t *testing.T) {
+ t.Parallel()
+ _, root := clitest.New(t)
+ testRepo := testGitRepo(t, root)
+
+ // nolint:gosec
+ err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
+ require.NoError(t, err)
+
+ c := exec.Command("git", "add", ".bashrc")
+ c.Dir = testRepo
+ err = c.Run()
+ require.NoError(t, err)
+
+ c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
+ c.Dir = testRepo
+ out, err := c.CombinedOutput()
+ require.NoError(t, err, string(out))
+
+ inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "--repo-dir", "testrepo", "-y", testRepo)
+ err = inv.Run()
+ require.NoError(t, err)
+
+ b, err := os.ReadFile(filepath.Join(string(root), ".bashrc"))
+ require.NoError(t, err)
+ require.Equal(t, string(b), "wow")
+
+ stat, staterr := os.Stat(filepath.Join(string(root), "testrepo"))
+ require.NoError(t, staterr)
+ require.True(t, stat.IsDir())
+ })
+ t.Run("SwitchRepoDirRelative", func(t *testing.T) {
+ t.Parallel()
+ _, root := clitest.New(t)
+ testRepo := testGitRepo(t, root)
+
+ // nolint:gosec
+ err := os.WriteFile(filepath.Join(testRepo, ".bashrc"), []byte("wow"), 0o750)
+ require.NoError(t, err)
+
+ c := exec.Command("git", "add", ".bashrc")
+ c.Dir = testRepo
+ err = c.Run()
+ require.NoError(t, err)
+
+ c = exec.Command("git", "commit", "-m", `"add .bashrc"`)
+ c.Dir = testRepo
+ out, err := c.CombinedOutput()
+ require.NoError(t, err, string(out))
+
+ inv, _ := clitest.New(t, "dotfiles", "--global-config", string(root), "--symlink-dir", string(root), "--repo-dir", "./relrepo", "-y", testRepo)
+ err = inv.Run()
+ require.NoError(t, err)
+
+ b, err := os.ReadFile(filepath.Join(string(root), ".bashrc"))
+ require.NoError(t, err)
+ require.Equal(t, string(b), "wow")
+
+ stat, staterr := os.Stat(filepath.Join(string(root), "relrepo"))
+ require.NoError(t, staterr)
+ require.True(t, stat.IsDir())
+ })
t.Run("InstallScript", func(t *testing.T) {
t.Parallel()
if runtime.GOOS == "windows" {
diff --git a/cli/server.go b/cli/server.go
index be855419a6052..61755840382e1 100644
--- a/cli/server.go
+++ b/cli/server.go
@@ -68,7 +68,7 @@ import (
"github.com/coder/coder/v2/coderd/autobuild"
"github.com/coder/coder/v2/coderd/batchstats"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbmetrics"
"github.com/coder/coder/v2/coderd/database/dbpurge"
"github.com/coder/coder/v2/coderd/database/migrations"
@@ -542,7 +542,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
AppHostname: appHostname,
AppHostnameRegex: appHostnameRegex,
Logger: logger.Named("coderd"),
- Database: dbfake.New(),
+ Database: dbmem.New(),
BaseDERPMap: derpMap,
Pubsub: pubsub.NewInMemory(),
CacheDir: cacheDir,
@@ -633,7 +633,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
if vals.InMemoryDatabase {
// This is only used for testing.
- options.Database = dbfake.New()
+ options.Database = dbmem.New()
options.Pubsub = pubsub.NewInMemory()
} else {
sqlDB, err := ConnectToPostgres(ctx, logger, sqlDriver, vals.PostgresURL.String())
@@ -1206,6 +1206,14 @@ func WriteConfigMW(cfg *codersdk.DeploymentValues) clibase.MiddlewareFunc {
// isLocalURL returns true if the hostname of the provided URL appears to
// resolve to a loopback address.
func IsLocalURL(ctx context.Context, u *url.URL) (bool, error) {
+ // In tests, we commonly use "example.com" or "google.com", which
+ // are not loopback, so avoid the DNS lookup to avoid flakes.
+ if flag.Lookup("test.v") != nil {
+ if u.Hostname() == "example.com" || u.Hostname() == "google.com" {
+ return false, nil
+ }
+ }
+
resolver := &net.Resolver{}
ips, err := resolver.LookupIPAddr(ctx, u.Hostname())
if err != nil {
diff --git a/cli/testdata/coder_dotfiles_--help.golden b/cli/testdata/coder_dotfiles_--help.golden
index a54e576b2526a..14991512127da 100644
--- a/cli/testdata/coder_dotfiles_--help.golden
+++ b/cli/testdata/coder_dotfiles_--help.golden
@@ -15,6 +15,10 @@ OPTIONS:
default branch or using the existing branch in the cloned repo on
disk.
+ --repo-dir string, $CODER_DOTFILES_REPO_DIR (default: dotfiles)
+ Specifies the directory for the dotfiles repository, relative to
+ global config directory.
+
--symlink-dir string, $CODER_SYMLINK_DIR
Specifies the directory for the dotfiles symlink destinations. If
empty, will use $HOME.
diff --git a/coderd/awsidentity/awsidentity.go b/coderd/awsidentity/awsidentity.go
index 98d0e694786c9..ff96fd2b0af1f 100644
--- a/coderd/awsidentity/awsidentity.go
+++ b/coderd/awsidentity/awsidentity.go
@@ -16,16 +16,23 @@ import (
type Region string
const (
- Other Region = "other"
- HongKong Region = "hongkong"
- Bahrain Region = "bahrain"
- CapeTown Region = "capetown"
- Milan Region = "milan"
- China Region = "china"
- GovCloud Region = "govcloud"
+ Other Region = "other"
+ CapeTown Region = "capetown"
+ HongKong Region = "hongkong"
+ Hyderabad Region = "hyderabad"
+ Jakarta Region = "jakarta"
+ Melbourne Region = "melbourne"
+ China Region = "china"
+ Milan Region = "milan"
+ Spain Region = "spain"
+ Zurich Region = "zurich"
+ TelAviv Region = "telaviv"
+ Bahrain Region = "bahrain"
+ UAE Region = "uae"
+ GovCloud Region = "govcloud"
)
-var All = []Region{Other, HongKong, Bahrain, CapeTown, Milan, China, GovCloud}
+var All = []Region{Other, CapeTown, HongKong, Hyderabad, Jakarta, Melbourne, China, Milan, Spain, Zurich, TelAviv, Bahrain, UAE, GovCloud}
// Certificates hold public keys for various AWS regions. See:
type Certificates map[Region]string
@@ -193,6 +200,104 @@ WtgIe3M3iwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAHzQC5XZVeuD9GTJTsbO5AyH
ZQvki/jfARNrD9dgBRYZzLC/NOkWG6M9wlrmks9RtdNxc53nLxKq4I2Dd73gI0yQ
wYu9YYwmM/LMgmPlI33Rg2Ohwq4DVgT3hO170PL6Fsgiq3dMvctSImJvjWktBQaT
bcAgaZLHGIpXPrWSA2d+
+-----END CERTIFICATE-----`,
+ TelAviv: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAX0QQGVLMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTExMTExODI2
+MzVaGA8yMjAwMTExMTE4MjYzNVowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDr
+c24u3AgFxnoPgzxR6yFXOamcPuxYXhYKWmapb+S8vOy5hpLoRe4RkOrY0cM3bN07
+GdEMlin5mU0y1t8y3ct4YewvmkgT42kTyMM+t1K4S0xsqjXxxS716uGYh7eWtkxr
+Cihj8AbXN/6pa095h+7TZyl2n83keiNUzM2KoqQVMwIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBADwA6VVEIIZD2YL00F12po40xDLzIc9XvqFPS9iFaWi2ho8wLio7wA49
+VYEFZSI9CR3SGB9tL8DUib97mlxmd1AcGShMmMlhSB29vhuhrUNB/FmU7H8s62/j
+D6cOR1A1cClIyZUe1yT1ZbPySCs43J+Thr8i8FSRxzDBSZZi5foW
+-----END CERTIFICATE-----`,
+ UAE: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXjRrnDjMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTA0MTQxODM5
+MzNaGA8yMjAwMDQxNDE4MzkzM1owXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc
+aTgW/KyA6zyruJQrYy00a6wqLA7eeUzk3bMiTkLsTeDQfrkaZMfBAjGaaOymRo1C
+3qzE4rIenmahvUplu9ZmLwL1idWXMRX2RlSvIt+d2SeoKOKQWoc2UOFZMHYxDue7
+zkyk1CIRaBukTeY13/RIrlc6X61zJ5BBtZXlHwayjQIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBABTqTy3R6RXKPW45FA+cgo7YZEj/Cnz5YaoUivRRdX2A83BHuBTvJE2+
+WX00FTEj4hRVjameE1nENoO8Z7fUVloAFDlDo69fhkJeSvn51D1WRrPnoWGgEfr1
++OfK1bAcKTtfkkkP9r4RdwSjKzO5Zu/B+Wqm3kVEz/QNcz6npmA6
+-----END CERTIFICATE-----`,
+ Zurich: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXjSGFGiMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTA0MTQyMDM1
+MTJaGA8yMjAwMDQxNDIwMzUxMlowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2
+mdGdps5Rz2jzYcGNsgETTGUthJRrVqSnUWJXTlVaIbkGPLKO6Or7AfWKFp2sgRJ8
+vLsjoBVR5cESVK7cuK1wItjvJyi/opKZAUusJx2hpgU3pUHhlp9ATh/VeVD582jT
+d9IY+8t5MDa6Z3fGliByEiXz0LEHdi8MBacLREu1TwIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBAILlpoE3k9o7KdALAxsFJNitVS+g3RMzdbiFM+7MA63Nv5fsf+0xgcjS
+NBElvPCDKFvTJl4QQhToy056llO5GvdS9RK+H8xrP2mrqngApoKTApv93vHBixgF
+Sn5KrczRO0YSm3OjkqbydU7DFlmkXXR7GYE+5jbHvQHYiT1J5sMu
+-----END CERTIFICATE-----`,
+ Spain: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXjwLkiaMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTA0MjAxNjQ3
+NDhaGA8yMjAwMDQyMDE2NDc0OFowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDB
+/VvR1+45Aey5zn3vPk6xBm5o9grSDL6D2iAuprQnfVXn8CIbSDbWFhA3fi5ippjK
+kh3sl8VyCvCOUXKdOaNrYBrPRkrdHdBuL2Tc84RO+3m/rxIUZ2IK1fDlC6sWAjdd
+f6sBrV2w2a78H0H8EwuwiSgttURBjwJ7KPPJCqaqrQIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBAKR+FzqQDzun/iMMzcFucmLMl5BxEblrFXOz7IIuOeiGkndmrqUeDCyk
+ztLku45s7hxdNy4ltTuVAaE5aNBdw5J8U1mRvsKvHLy2ThH6hAWKwTqtPAJp7M21
+GDwgDDOkPSz6XVOehg+hBgiphYp84DUbWVYeP8YqLEJSqscKscWC
+-----END CERTIFICATE-----`,
+ Melbourne: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXjSh40SMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTA0MTQyMjM2
+NDJaGA8yMjAwMDQxNDIyMzY0MlowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH
+ezwQr2VQpQSTW5TXNefiQrP+qWTGAbGsPeMX4hBMjAJUKys2NIRcRZaLM/BCew2F
+IPVjNtlaj6Gwn9ipU4Mlz3zIwAMWi1AvGMSreppt+wV6MRtfOjh0Dvj/veJe88aE
+ZJMozNgkJFRS+WFWsckQeL56tf6kY6QTlNo8V/0CsQIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBAF7vpPghH0FRo5gu49EArRNPrIvW1egMdZHrzJNqbztLCtV/wcgkqIww
+uXYj+1rhlL+/iMpQWjdVGEqIZSeXn5fLmdx50eegFCwND837r9e8XYTiQS143Sxt
+9+Yi6BZ7U7YD8kK9NBWoJxFqUeHdpRCs0O7COjT3gwm7ZxvAmssh
+-----END CERTIFICATE-----`,
+ Jakarta: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXbVDG2yMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTAxMDYwMDE1
+MzBaGA8yMjAwMDEwNjAwMTUzMFowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn
+CS/Vbt0gQ1ebWcur2hSO7PnJifE4OPxQ7RgSAlc4/spJp1sDP+ZrS0LO1ZJfKhXf
+1R9S3AUwLnsc7b+IuVXdY5LK9RKqu64nyXP5dx170zoL8loEyCSuRR2fs+04i2Qs
+WBVP+KFNAn7P5L1EHRjkgTO8kjNKviwRV+OkP9ab5wIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBAI4WUy6+DKh0JDSzQEZNyBgNlSoSuC2owtMxCwGB6nBfzzfcekWvs6eo
+fLTSGovrReX7MtVgrcJBZjmPIentw5dWUs+87w/g9lNwUnUt0ZHYyh2tuBG6hVJu
+UEwDJ/z3wDd6wQviLOTF3MITawt9P8siR1hXqLJNxpjRQFZrgHqi
+-----END CERTIFICATE-----`,
+ Hyderabad: `-----BEGIN CERTIFICATE-----
+MIICMzCCAZygAwIBAgIGAXjwLj9CMA0GCSqGSIb3DQEBBQUAMFwxCzAJBgNVBAYT
+AlVTMRkwFwYDVQQIDBBXYXNoaW5ndG9uIFN0YXRlMRAwDgYDVQQHDAdTZWF0dGxl
+MSAwHgYDVQQKDBdBbWF6b24gV2ViIFNlcnZpY2VzIExMQzAgFw0yMTA0MjAxNjQ3
+NDVaGA8yMjAwMDQyMDE2NDc0NVowXDELMAkGA1UEBhMCVVMxGTAXBgNVBAgMEFdh
+c2hpbmd0b24gU3RhdGUxEDAOBgNVBAcMB1NlYXR0bGUxIDAeBgNVBAoMF0FtYXpv
+biBXZWIgU2VydmljZXMgTExDMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDT
+wHu0ND+sFcobrjvcAYm0PNRD8f4R1jAzvoLt2+qGeOTAyO1Httj6cmsYN3AP1hN5
+iYuppFiYsl2eNPa/CD0Vg0BAfDFlV5rzjpA0j7TJabVh4kj7JvtD+xYMi6wEQA4x
+6SPONY4OeZ2+8o/HS8nucpWDVdPRO6ciWUlMhjmDmwIDAQABMA0GCSqGSIb3DQEB
+BQUAA4GBAAy6sgTdRkTqELHBeWj69q60xHyUmsWqHAQNXKVc9ApWGG4onzuqlMbG
+ETwUZ9mTq2vxlV0KvuetCDNS5u4cJsxe/TGGbYP0yP2qfMl0cCImzRI5W0gn8gog
+dervfeT7nH5ih0TWEy/QDWfkQ601L4erm4yh4YQq8vcqAPSkf04N
-----END CERTIFICATE-----`,
GovCloud: `-----BEGIN CERTIFICATE-----
MIIDCzCCAnSgAwIBAgIJAIe9Hnq82O7UMA0GCSqGSIb3DQEBCwUAMFwxCzAJBgNV
diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go
index a5847839b2478..48239450ebe1a 100644
--- a/coderd/database/dbauthz/dbauthz_test.go
+++ b/coderd/database/dbauthz/dbauthz_test.go
@@ -16,8 +16,8 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/util/slice"
@@ -62,7 +62,7 @@ func TestAsNoActor(t *testing.T) {
func TestPing(t *testing.T) {
t.Parallel()
- q := dbauthz.New(dbfake.New(), &coderdtest.RecordingAuthorizer{}, slog.Make(), accessControlStorePointer())
+ q := dbauthz.New(dbmem.New(), &coderdtest.RecordingAuthorizer{}, slog.Make(), accessControlStorePointer())
_, err := q.Ping(context.Background())
require.NoError(t, err, "must not error")
}
@@ -71,7 +71,7 @@ func TestPing(t *testing.T) {
func TestInTX(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
q := dbauthz.New(db, &coderdtest.RecordingAuthorizer{
Wrapped: &coderdtest.FakeAuthorizer{AlwaysReturn: xerrors.New("custom error")},
}, slog.Make(), accessControlStorePointer())
@@ -99,7 +99,7 @@ func TestNew(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
exp = dbgen.Workspace(t, db, database.Workspace{})
rec = &coderdtest.RecordingAuthorizer{
Wrapped: &coderdtest.FakeAuthorizer{AlwaysReturn: nil},
@@ -126,7 +126,7 @@ func TestNew(t *testing.T) {
// as only the first db call will be made. But it is better than nothing.
func TestDBAuthzRecursive(t *testing.T) {
t.Parallel()
- q := dbauthz.New(dbfake.New(), &coderdtest.RecordingAuthorizer{
+ q := dbauthz.New(dbmem.New(), &coderdtest.RecordingAuthorizer{
Wrapped: &coderdtest.FakeAuthorizer{AlwaysReturn: nil},
}, slog.Make(), accessControlStorePointer())
actor := rbac.Subject{
diff --git a/coderd/database/dbauthz/setup_test.go b/coderd/database/dbauthz/setup_test.go
index 968b882f2d263..304b8673a9f8d 100644
--- a/coderd/database/dbauthz/setup_test.go
+++ b/coderd/database/dbauthz/setup_test.go
@@ -20,7 +20,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbmock"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/coderd/rbac/regosql"
@@ -104,7 +104,7 @@ func (s *MethodTestSuite) Subtest(testCaseF func(db database.Store, check *expec
methodName := names[len(names)-1]
s.methodAccounting[methodName]++
- db := dbfake.New()
+ db := dbmem.New()
fakeAuthorizer := &coderdtest.FakeAuthorizer{
AlwaysReturn: nil,
}
diff --git a/coderd/database/dbgen/dbgen_test.go b/coderd/database/dbgen/dbgen_test.go
index d7d961b1ae2fe..531c8bb25cd53 100644
--- a/coderd/database/dbgen/dbgen_test.go
+++ b/coderd/database/dbgen/dbgen_test.go
@@ -8,8 +8,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
)
func TestGenerator(t *testing.T) {
@@ -17,7 +17,7 @@ func TestGenerator(t *testing.T) {
t.Run("AuditLog", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
_ = dbgen.AuditLog(t, db, database.AuditLog{})
logs := must(db.GetAuditLogsOffset(context.Background(), database.GetAuditLogsOffsetParams{Limit: 1}))
require.Len(t, logs, 1)
@@ -25,28 +25,28 @@ func TestGenerator(t *testing.T) {
t.Run("APIKey", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp, _ := dbgen.APIKey(t, db, database.APIKey{})
require.Equal(t, exp, must(db.GetAPIKeyByID(context.Background(), exp.ID)))
})
t.Run("File", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.File(t, db, database.File{})
require.Equal(t, exp, must(db.GetFileByID(context.Background(), exp.ID)))
})
t.Run("UserLink", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.UserLink(t, db, database.UserLink{})
require.Equal(t, exp, must(db.GetUserLinkByLinkedID(context.Background(), exp.LinkedID)))
})
t.Run("GitAuthLink", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.ExternalAuthLink(t, db, database.ExternalAuthLink{})
require.Equal(t, exp, must(db.GetExternalAuthLink(context.Background(), database.GetExternalAuthLinkParams{
ProviderID: exp.ProviderID,
@@ -56,28 +56,28 @@ func TestGenerator(t *testing.T) {
t.Run("WorkspaceResource", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.WorkspaceResource(t, db, database.WorkspaceResource{})
require.Equal(t, exp, must(db.GetWorkspaceResourceByID(context.Background(), exp.ID)))
})
t.Run("WorkspaceApp", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.WorkspaceApp(t, db, database.WorkspaceApp{})
require.Equal(t, exp, must(db.GetWorkspaceAppsByAgentID(context.Background(), exp.AgentID))[0])
})
t.Run("WorkspaceResourceMetadata", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.WorkspaceResourceMetadatums(t, db, database.WorkspaceResourceMetadatum{})
require.Equal(t, exp, must(db.GetWorkspaceResourceMetadataByResourceIDs(context.Background(), []uuid.UUID{exp[0].WorkspaceResourceID})))
})
t.Run("WorkspaceProxy", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp, secret := dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})
require.Len(t, secret, 64)
require.Equal(t, exp, must(db.GetWorkspaceProxyByID(context.Background(), exp.ID)))
@@ -85,21 +85,21 @@ func TestGenerator(t *testing.T) {
t.Run("Job", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.ProvisionerJob(t, db, nil, database.ProvisionerJob{})
require.Equal(t, exp, must(db.GetProvisionerJobByID(context.Background(), exp.ID)))
})
t.Run("Group", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.Group(t, db, database.Group{})
require.Equal(t, exp, must(db.GetGroupByID(context.Background(), exp.ID)))
})
t.Run("GroupMember", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
g := dbgen.Group(t, db, database.Group{})
u := dbgen.User(t, db, database.User{})
exp := []database.User{u}
@@ -110,14 +110,14 @@ func TestGenerator(t *testing.T) {
t.Run("Organization", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.Organization(t, db, database.Organization{})
require.Equal(t, exp, must(db.GetOrganizationByID(context.Background(), exp.ID)))
})
t.Run("OrganizationMember", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.OrganizationMember(t, db, database.OrganizationMember{})
require.Equal(t, exp, must(db.GetOrganizationMemberByUserID(context.Background(), database.GetOrganizationMemberByUserIDParams{
OrganizationID: exp.OrganizationID,
@@ -127,49 +127,49 @@ func TestGenerator(t *testing.T) {
t.Run("Workspace", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.Workspace(t, db, database.Workspace{})
require.Equal(t, exp, must(db.GetWorkspaceByID(context.Background(), exp.ID)))
})
t.Run("WorkspaceAgent", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.WorkspaceAgent(t, db, database.WorkspaceAgent{})
require.Equal(t, exp, must(db.GetWorkspaceAgentByID(context.Background(), exp.ID)))
})
t.Run("Template", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.Template(t, db, database.Template{})
require.Equal(t, exp, must(db.GetTemplateByID(context.Background(), exp.ID)))
})
t.Run("TemplateVersion", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.TemplateVersion(t, db, database.TemplateVersion{})
require.Equal(t, exp, must(db.GetTemplateVersionByID(context.Background(), exp.ID)))
})
t.Run("WorkspaceBuild", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.WorkspaceBuild(t, db, database.WorkspaceBuild{})
require.Equal(t, exp, must(db.GetWorkspaceBuildByID(context.Background(), exp.ID)))
})
t.Run("User", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.User(t, db, database.User{})
require.Equal(t, exp, must(db.GetUserByID(context.Background(), exp.ID)))
})
t.Run("SSHKey", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
exp := dbgen.GitSSHKey(t, db, database.GitSSHKey{})
require.Equal(t, exp, must(db.GetGitSSHKey(context.Background(), exp.UserID)))
})
diff --git a/coderd/database/dbfake/dbfake.go b/coderd/database/dbmem/dbmem.go
similarity index 99%
rename from coderd/database/dbfake/dbfake.go
rename to coderd/database/dbmem/dbmem.go
index e2ddde14e2d00..a0e48473602ad 100644
--- a/coderd/database/dbfake/dbfake.go
+++ b/coderd/database/dbmem/dbmem.go
@@ -1,4 +1,4 @@
-package dbfake
+package dbmem
import (
"context"
@@ -705,7 +705,7 @@ func provisonerJobStatus(j database.ProvisionerJob) database.ProvisionerJobStatu
return database.ProvisionerJobStatusRunning
}
-// isNull is only used in dbfake, so reflect is ok. Use this to make the logic
+// isNull is only used in dbmem, so reflect is ok. Use this to make the logic
// look more similar to the postgres.
func isNull(v interface{}) bool {
return !isNotNull(v)
@@ -4868,7 +4868,7 @@ func (q *FakeQuerier) InsertUser(_ context.Context, arg database.InsertUserParam
return database.User{}, err
}
- // There is a common bug when using dbfake that 2 inserted users have the
+ // There is a common bug when using dbmem that 2 inserted users have the
// same created_at time. This causes user order to not be deterministic,
// which breaks some unit tests.
// To fix this, we make sure that the created_at time is always greater
diff --git a/coderd/database/dbfake/dbfake_test.go b/coderd/database/dbmem/dbmem_test.go
similarity index 97%
rename from coderd/database/dbfake/dbfake_test.go
rename to coderd/database/dbmem/dbmem_test.go
index 3cbc54042f782..e7d7bd76bd132 100644
--- a/coderd/database/dbfake/dbfake_test.go
+++ b/coderd/database/dbmem/dbmem_test.go
@@ -1,4 +1,4 @@
-package dbfake_test
+package dbmem_test
import (
"context"
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
)
@@ -20,7 +20,7 @@ import (
func TestInTx(t *testing.T) {
t.Parallel()
- uut := dbfake.New()
+ uut := dbmem.New()
inTx := make(chan any)
queriesDone := make(chan any)
@@ -67,7 +67,7 @@ func TestInTx(t *testing.T) {
func TestUserOrder(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
now := dbtime.Now()
usernames := []string{"b-user", "d-user", "a-user", "c-user", "e-user"}
@@ -88,7 +88,7 @@ func TestUserOrder(t *testing.T) {
func TestProxyByHostname(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
// Insert a bunch of different proxies.
proxies := []struct {
diff --git a/coderd/database/dbpurge/dbpurge_test.go b/coderd/database/dbpurge/dbpurge_test.go
index f83d1b81a1d2a..64fc74b4775ca 100644
--- a/coderd/database/dbpurge/dbpurge_test.go
+++ b/coderd/database/dbpurge/dbpurge_test.go
@@ -9,7 +9,7 @@ import (
"github.com/stretchr/testify/require"
"cdr.dev/slog/sloggers/slogtest"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbpurge"
)
@@ -20,7 +20,7 @@ func TestMain(m *testing.M) {
// Ensures no goroutines leak.
func TestPurge(t *testing.T) {
t.Parallel()
- purger := dbpurge.New(context.Background(), slogtest.Make(t, nil), dbfake.New())
+ purger := dbpurge.New(context.Background(), slogtest.Make(t, nil), dbmem.New())
err := purger.Close()
require.NoError(t, err)
}
diff --git a/coderd/database/dbtestutil/db.go b/coderd/database/dbtestutil/db.go
index 65e1afecc7948..c179917c0594a 100644
--- a/coderd/database/dbtestutil/db.go
+++ b/coderd/database/dbtestutil/db.go
@@ -18,7 +18,7 @@ import (
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/postgres"
"github.com/coder/coder/v2/coderd/database/pubsub"
)
@@ -79,7 +79,7 @@ func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) {
opt(&o)
}
- db := dbfake.New()
+ db := dbmem.New()
ps := pubsub.NewInMemory()
if WillUsePostgres() {
connectionURL := os.Getenv("CODER_PG_CONNECTION_URL")
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index 0e79c875f93bc..dcf63c6f66f9e 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -925,6 +925,7 @@ CREATE TABLE workspace_agents (
ready_at timestamp with time zone,
subsystems workspace_agent_subsystem[] DEFAULT '{}'::workspace_agent_subsystem[],
display_apps display_app[] DEFAULT '{vscode,vscode_insiders,web_terminal,ssh_helper,port_forwarding_helper}'::display_app[],
+ api_version text DEFAULT ''::text NOT NULL,
CONSTRAINT max_logs_length CHECK ((logs_length <= 1048576)),
CONSTRAINT subsystems_not_none CHECK ((NOT ('none'::workspace_agent_subsystem = ANY (subsystems))))
);
diff --git a/coderd/database/migrations/000167_workspace_agent_api_version.down.sql b/coderd/database/migrations/000167_workspace_agent_api_version.down.sql
new file mode 100644
index 0000000000000..53c2b3417a983
--- /dev/null
+++ b/coderd/database/migrations/000167_workspace_agent_api_version.down.sql
@@ -0,0 +1,3 @@
+BEGIN;
+ALTER TABLE workspace_agents DROP COLUMN api_version;
+COMMIT;
diff --git a/coderd/database/migrations/000167_workspace_agent_api_version.up.sql b/coderd/database/migrations/000167_workspace_agent_api_version.up.sql
new file mode 100644
index 0000000000000..b4187e51efa93
--- /dev/null
+++ b/coderd/database/migrations/000167_workspace_agent_api_version.up.sql
@@ -0,0 +1,3 @@
+BEGIN;
+ALTER TABLE workspace_agents ADD COLUMN api_version TEXT DEFAULT '' NOT NULL;
+COMMIT;
diff --git a/coderd/database/models.go b/coderd/database/models.go
index c67afa74faa9a..4d5a0193ccc7c 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -2117,6 +2117,7 @@ type WorkspaceAgent struct {
ReadyAt sql.NullTime `db:"ready_at" json:"ready_at"`
Subsystems []WorkspaceAgentSubsystem `db:"subsystems" json:"subsystems"`
DisplayApps []DisplayApp `db:"display_apps" json:"display_apps"`
+ APIVersion string `db:"api_version" json:"api_version"`
}
type WorkspaceAgentLog struct {
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index 50da65e9c74a4..b1eb3af14719e 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -7109,7 +7109,7 @@ func (q *sqlQuerier) DeleteOldWorkspaceAgentLogs(ctx context.Context) error {
const getWorkspaceAgentAndOwnerByAuthToken = `-- name: GetWorkspaceAgentAndOwnerByAuthToken :one
SELECT
- workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps,
+ workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version,
workspaces.id AS workspace_id,
users.id AS owner_id,
users.username AS owner_name,
@@ -7204,6 +7204,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndOwnerByAuthToken(ctx context.Context, a
&i.WorkspaceAgent.ReadyAt,
pq.Array(&i.WorkspaceAgent.Subsystems),
pq.Array(&i.WorkspaceAgent.DisplayApps),
+ &i.WorkspaceAgent.APIVersion,
&i.WorkspaceID,
&i.OwnerID,
&i.OwnerName,
@@ -7216,7 +7217,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndOwnerByAuthToken(ctx context.Context, a
const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one
SELECT
- id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps
+ id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version
FROM
workspace_agents
WHERE
@@ -7256,13 +7257,14 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
)
return i, err
}
const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one
SELECT
- id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps
+ id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version
FROM
workspace_agents
WHERE
@@ -7304,6 +7306,7 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
)
return i, err
}
@@ -7462,7 +7465,7 @@ func (q *sqlQuerier) GetWorkspaceAgentMetadata(ctx context.Context, arg GetWorks
const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many
SELECT
- id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps
+ id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version
FROM
workspace_agents
WHERE
@@ -7508,6 +7511,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
); err != nil {
return nil, err
}
@@ -7523,7 +7527,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
}
const getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many
-SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps FROM workspace_agents WHERE created_at > $1
+SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version FROM workspace_agents WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
@@ -7565,6 +7569,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
); err != nil {
return nil, err
}
@@ -7581,7 +7586,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
const getWorkspaceAgentsInLatestBuildByWorkspaceID = `-- name: GetWorkspaceAgentsInLatestBuildByWorkspaceID :many
SELECT
- workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps
+ workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.expanded_directory, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps, workspace_agents.api_version
FROM
workspace_agents
JOIN
@@ -7639,6 +7644,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Co
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
); err != nil {
return nil, err
}
@@ -7675,7 +7681,7 @@ INSERT INTO
display_apps
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, expanded_directory, logs_length, logs_overflowed, started_at, ready_at, subsystems, display_apps, api_version
`
type InsertWorkspaceAgentParams struct {
@@ -7749,6 +7755,7 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
+ &i.APIVersion,
)
return i, err
}
diff --git a/coderd/database/sqlc.yaml b/coderd/database/sqlc.yaml
index 592b2c7b5e32e..956485311e4a1 100644
--- a/coderd/database/sqlc.yaml
+++ b/coderd/database/sqlc.yaml
@@ -38,6 +38,7 @@ overrides:
api_key_scope: APIKeyScope
api_key_scope_all: APIKeyScopeAll
api_key_scope_application_connect: APIKeyScopeApplicationConnect
+ api_version: APIVersion
avatar_url: AvatarURL
created_by_avatar_url: CreatedByAvatarURL
dbcrypt_key: DBCryptKey
diff --git a/coderd/externalauth.go b/coderd/externalauth.go
index 774a5f860397d..b1b7acc8bc449 100644
--- a/coderd/externalauth.go
+++ b/coderd/externalauth.go
@@ -268,8 +268,9 @@ func (api *API) externalAuthCallback(externalAuthConfig *externalauth.Config) ht
redirect := state.Redirect
if redirect == "" {
- // This is a nicely rendered screen on the frontend
- redirect = fmt.Sprintf("/external-auth/%s", externalAuthConfig.ID)
+ // This is a nicely rendered screen on the frontend. Passing the query param lets the
+ // FE know not to enter the authentication loop again, and instead display an error.
+ redirect = fmt.Sprintf("/external-auth/%s?redirected=true", externalAuthConfig.ID)
}
http.Redirect(rw, r, redirect, http.StatusTemporaryRedirect)
}
diff --git a/coderd/externalauth/externalauth_test.go b/coderd/externalauth/externalauth_test.go
index d790c32989ea7..2108063b91f46 100644
--- a/coderd/externalauth/externalauth_test.go
+++ b/coderd/externalauth/externalauth_test.go
@@ -19,7 +19,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest/oidctest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/externalauth"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/testutil"
@@ -223,7 +223,7 @@ func TestRefreshToken(t *testing.T) {
t.Run("Updates", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
validateCalls := 0
refreshCalls := 0
fake, config, link := setupOauth2Test(t, testConfig{
@@ -265,7 +265,7 @@ func TestRefreshToken(t *testing.T) {
t.Run("WithExtra", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
fake, config, link := setupOauth2Test(t, testConfig{
FakeIDPOpts: []oidctest.FakeIDPOpt{
oidctest.WithMutateToken(func(token map[string]interface{}) {
diff --git a/coderd/httpmw/actor_test.go b/coderd/httpmw/actor_test.go
index fc9580166298e..ef05a8cb3a3d2 100644
--- a/coderd/httpmw/actor_test.go
+++ b/coderd/httpmw/actor_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
@@ -38,7 +38,7 @@ func TestRequireAPIKeyOrWorkspaceProxyAuth(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -75,7 +75,7 @@ func TestRequireAPIKeyOrWorkspaceProxyAuth(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, userToken = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -114,7 +114,7 @@ func TestRequireAPIKeyOrWorkspaceProxyAuth(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
proxy, token = dbgen.WorkspaceProxy(t, db, database.WorkspaceProxy{})
r = httptest.NewRequest("GET", "/", nil)
diff --git a/coderd/httpmw/apikey_test.go b/coderd/httpmw/apikey_test.go
index f3ceba017d773..33ba90a4d728c 100644
--- a/coderd/httpmw/apikey_test.go
+++ b/coderd/httpmw/apikey_test.go
@@ -19,8 +19,8 @@ import (
"golang.org/x/oauth2"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw"
@@ -48,7 +48,7 @@ func TestAPIKey(t *testing.T) {
t.Run("NoCookie", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -64,7 +64,7 @@ func TestAPIKey(t *testing.T) {
t.Run("NoCookieRedirects", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -83,7 +83,7 @@ func TestAPIKey(t *testing.T) {
t.Run("InvalidFormat", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -101,7 +101,7 @@ func TestAPIKey(t *testing.T) {
t.Run("InvalidIDLength", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -119,7 +119,7 @@ func TestAPIKey(t *testing.T) {
t.Run("InvalidSecretLength", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -137,7 +137,7 @@ func TestAPIKey(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
id, secret = randomAPIKeyParts()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -156,7 +156,7 @@ func TestAPIKey(t *testing.T) {
t.Run("UserLinkNotFound", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
user = dbgen.User(t, db, database.User{
@@ -184,7 +184,7 @@ func TestAPIKey(t *testing.T) {
t.Run("InvalidSecret", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
user = dbgen.User(t, db, database.User{})
@@ -209,7 +209,7 @@ func TestAPIKey(t *testing.T) {
t.Run("Expired", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -238,7 +238,7 @@ func TestAPIKey(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -273,7 +273,7 @@ func TestAPIKey(t *testing.T) {
t.Run("ValidWithScope", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -310,7 +310,7 @@ func TestAPIKey(t *testing.T) {
t.Run("QueryParameter", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -342,7 +342,7 @@ func TestAPIKey(t *testing.T) {
t.Run("ValidUpdateLastUsed", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -373,7 +373,7 @@ func TestAPIKey(t *testing.T) {
t.Run("ValidUpdateExpiry", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -404,7 +404,7 @@ func TestAPIKey(t *testing.T) {
t.Run("NoRefresh", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -436,7 +436,7 @@ func TestAPIKey(t *testing.T) {
t.Run("OAuthNotExpired", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -472,7 +472,7 @@ func TestAPIKey(t *testing.T) {
t.Run("OAuthRefresh", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -520,7 +520,7 @@ func TestAPIKey(t *testing.T) {
t.Run("RemoteIPUpdates", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -551,7 +551,7 @@ func TestAPIKey(t *testing.T) {
t.Run("RedirectToLogin", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -572,7 +572,7 @@ func TestAPIKey(t *testing.T) {
t.Run("Optional", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -603,7 +603,7 @@ func TestAPIKey(t *testing.T) {
t.Run("Tokens", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
sentAPIKey, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
@@ -636,7 +636,7 @@ func TestAPIKey(t *testing.T) {
t.Run("MissongConfig", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
user = dbgen.User(t, db, database.User{})
_, token = dbgen.APIKey(t, db, database.APIKey{
UserID: user.ID,
diff --git a/coderd/httpmw/groupparam_test.go b/coderd/httpmw/groupparam_test.go
index a0c50ee0857b5..a44fbc52df38b 100644
--- a/coderd/httpmw/groupparam_test.go
+++ b/coderd/httpmw/groupparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
)
@@ -23,7 +23,7 @@ func TestGroupParam(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
group = dbgen.Group(t, db, database.Group{})
r = httptest.NewRequest("GET", "/", nil)
w = httptest.NewRecorder()
@@ -52,7 +52,7 @@ func TestGroupParam(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
group = dbgen.Group(t, db, database.Group{})
r = httptest.NewRequest("GET", "/", nil)
w = httptest.NewRecorder()
diff --git a/coderd/httpmw/organizationparam_test.go b/coderd/httpmw/organizationparam_test.go
index 0457168132e9a..d492353e6815d 100644
--- a/coderd/httpmw/organizationparam_test.go
+++ b/coderd/httpmw/organizationparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
@@ -38,7 +38,7 @@ func TestOrganizationParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
rw = httptest.NewRecorder()
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
@@ -60,7 +60,7 @@ func TestOrganizationParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
rw = httptest.NewRecorder()
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
@@ -83,7 +83,7 @@ func TestOrganizationParam(t *testing.T) {
t.Run("InvalidUUID", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
rw = httptest.NewRecorder()
r, _ = setupAuthentication(db)
rtr = chi.NewRouter()
@@ -106,7 +106,7 @@ func TestOrganizationParam(t *testing.T) {
t.Run("NotInOrganization", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
rw = httptest.NewRecorder()
r, u = setupAuthentication(db)
rtr = chi.NewRouter()
@@ -139,7 +139,7 @@ func TestOrganizationParam(t *testing.T) {
t.Run("Success", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
rw = httptest.NewRecorder()
r, user = setupAuthentication(db)
rtr = chi.NewRouter()
diff --git a/coderd/httpmw/ratelimit_test.go b/coderd/httpmw/ratelimit_test.go
index edb368829cf37..a320e05af7ffe 100644
--- a/coderd/httpmw/ratelimit_test.go
+++ b/coderd/httpmw/ratelimit_test.go
@@ -13,8 +13,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/coderd/rbac"
"github.com/coder/coder/v2/codersdk"
@@ -71,7 +71,7 @@ func TestRateLimit(t *testing.T) {
t.Run("RegularUser", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
u := dbgen.User(t, db, database.User{})
_, key := dbgen.APIKey(t, db, database.APIKey{UserID: u.ID})
@@ -114,7 +114,7 @@ func TestRateLimit(t *testing.T) {
t.Run("OwnerBypass", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
u := dbgen.User(t, db, database.User{
RBACRoles: []string{rbac.RoleOwner()},
diff --git a/coderd/httpmw/templateparam_test.go b/coderd/httpmw/templateparam_test.go
index d8608781905d5..18b0b2f584e5f 100644
--- a/coderd/httpmw/templateparam_test.go
+++ b/coderd/httpmw/templateparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
@@ -43,7 +43,7 @@ func TestTemplateParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractTemplateParam(db))
rtr.Get("/", nil)
@@ -58,7 +58,7 @@ func TestTemplateParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractTemplateParam(db))
rtr.Get("/", nil)
@@ -75,7 +75,7 @@ func TestTemplateParam(t *testing.T) {
t.Run("BadUUID", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractTemplateParam(db))
rtr.Get("/", nil)
@@ -92,7 +92,7 @@ func TestTemplateParam(t *testing.T) {
t.Run("Template", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
diff --git a/coderd/httpmw/templateversionparam_test.go b/coderd/httpmw/templateversionparam_test.go
index 1cf4da6e832b0..3f67aafbcf191 100644
--- a/coderd/httpmw/templateversionparam_test.go
+++ b/coderd/httpmw/templateversionparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
@@ -47,7 +47,7 @@ func TestTemplateVersionParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractTemplateVersionParam(db))
rtr.Get("/", nil)
@@ -62,7 +62,7 @@ func TestTemplateVersionParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractTemplateVersionParam(db))
rtr.Get("/", nil)
@@ -79,7 +79,7 @@ func TestTemplateVersionParam(t *testing.T) {
t.Run("TemplateVersion", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
diff --git a/coderd/httpmw/userparam_test.go b/coderd/httpmw/userparam_test.go
index 040948ff60cf3..bda00193e9a24 100644
--- a/coderd/httpmw/userparam_test.go
+++ b/coderd/httpmw/userparam_test.go
@@ -10,8 +10,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
@@ -20,7 +20,7 @@ func TestUserParam(t *testing.T) {
t.Parallel()
setup := func(t *testing.T) (database.Store, *httptest.ResponseRecorder, *http.Request) {
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
diff --git a/coderd/httpmw/workspaceagentparam_test.go b/coderd/httpmw/workspaceagentparam_test.go
index 0ac2bb9eb01b9..16f81124d12d7 100644
--- a/coderd/httpmw/workspaceagentparam_test.go
+++ b/coderd/httpmw/workspaceagentparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
@@ -61,7 +61,7 @@ func TestWorkspaceAgentParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceBuildParam(db))
rtr.Get("/", nil)
@@ -76,7 +76,7 @@ func TestWorkspaceAgentParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceAgentParam(db))
rtr.Get("/", nil)
@@ -93,7 +93,7 @@ func TestWorkspaceAgentParam(t *testing.T) {
t.Run("WorkspaceAgent", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
diff --git a/coderd/httpmw/workspacebuildparam_test.go b/coderd/httpmw/workspacebuildparam_test.go
index bade2b19d8dfc..fb2d2f044f77f 100644
--- a/coderd/httpmw/workspacebuildparam_test.go
+++ b/coderd/httpmw/workspacebuildparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
)
@@ -43,7 +43,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceBuildParam(db))
rtr.Get("/", nil)
@@ -58,7 +58,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceBuildParam(db))
rtr.Get("/", nil)
@@ -75,7 +75,7 @@ func TestWorkspaceBuildParam(t *testing.T) {
t.Run("WorkspaceBuild", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
diff --git a/coderd/httpmw/workspaceparam_test.go b/coderd/httpmw/workspaceparam_test.go
index d65fb53f8f28d..54daf661c39c8 100644
--- a/coderd/httpmw/workspaceparam_test.go
+++ b/coderd/httpmw/workspaceparam_test.go
@@ -16,8 +16,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
@@ -75,7 +75,7 @@ func TestWorkspaceParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceParam(db))
rtr.Get("/", nil)
@@ -90,7 +90,7 @@ func TestWorkspaceParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceParam(db))
rtr.Get("/", nil)
@@ -106,7 +106,7 @@ func TestWorkspaceParam(t *testing.T) {
t.Run("Found", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractAPIKeyMW(httpmw.ExtractAPIKeyConfig{
@@ -348,7 +348,7 @@ type setupConfig struct {
func setupWorkspaceWithAgents(t testing.TB, cfg setupConfig) (database.Store, *http.Request) {
t.Helper()
- db := dbfake.New()
+ db := dbmem.New()
var (
user = dbgen.User(t, db, database.User{})
diff --git a/coderd/httpmw/workspaceproxy_test.go b/coderd/httpmw/workspaceproxy_test.go
index 27b85643ce43d..b0a028f3caee8 100644
--- a/coderd/httpmw/workspaceproxy_test.go
+++ b/coderd/httpmw/workspaceproxy_test.go
@@ -12,8 +12,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
@@ -33,7 +33,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("NoHeader", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -48,7 +48,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("InvalidFormat", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -65,7 +65,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("InvalidID", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -82,7 +82,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("InvalidSecretLength", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -99,7 +99,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -119,7 +119,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("InvalidSecret", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -142,7 +142,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("Valid", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -165,7 +165,7 @@ func TestExtractWorkspaceProxy(t *testing.T) {
t.Run("Deleted", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -201,7 +201,7 @@ func TestExtractWorkspaceProxyParam(t *testing.T) {
t.Run("OKName", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -225,7 +225,7 @@ func TestExtractWorkspaceProxyParam(t *testing.T) {
t.Run("OKID", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
@@ -249,7 +249,7 @@ func TestExtractWorkspaceProxyParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
)
@@ -267,7 +267,7 @@ func TestExtractWorkspaceProxyParam(t *testing.T) {
t.Run("FetchPrimary", func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
r = httptest.NewRequest("GET", "/", nil)
rw = httptest.NewRecorder()
deploymentID = uuid.New()
diff --git a/coderd/httpmw/workspaceresourceparam_test.go b/coderd/httpmw/workspaceresourceparam_test.go
index e61e4016cb261..9549e8e6d3ecf 100644
--- a/coderd/httpmw/workspaceresourceparam_test.go
+++ b/coderd/httpmw/workspaceresourceparam_test.go
@@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpmw"
)
@@ -46,7 +46,7 @@ func TestWorkspaceResourceParam(t *testing.T) {
t.Run("None", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(httpmw.ExtractWorkspaceResourceParam(db))
rtr.Get("/", nil)
@@ -61,7 +61,7 @@ func TestWorkspaceResourceParam(t *testing.T) {
t.Run("NotFound", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractWorkspaceResourceParam(db),
@@ -80,7 +80,7 @@ func TestWorkspaceResourceParam(t *testing.T) {
t.Run("FoundBadJobType", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractWorkspaceResourceParam(db),
@@ -102,7 +102,7 @@ func TestWorkspaceResourceParam(t *testing.T) {
t.Run("Found", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
rtr := chi.NewRouter()
rtr.Use(
httpmw.ExtractWorkspaceResourceParam(db),
diff --git a/coderd/metricscache/metricscache_test.go b/coderd/metricscache/metricscache_test.go
index 1d34668559b32..996b9940d0056 100644
--- a/coderd/metricscache/metricscache_test.go
+++ b/coderd/metricscache/metricscache_test.go
@@ -11,8 +11,8 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/metricscache"
"github.com/coder/coder/v2/codersdk"
@@ -210,7 +210,7 @@ func TestCache_TemplateUsers(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
var (
- db = dbfake.New()
+ db = dbmem.New()
cache = metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
TemplateDAUs: testutil.IntervalFast,
})
@@ -342,7 +342,7 @@ func TestCache_BuildTime(t *testing.T) {
ctx := context.Background()
var (
- db = dbfake.New()
+ db = dbmem.New()
cache = metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
TemplateDAUs: testutil.IntervalFast,
})
@@ -436,7 +436,7 @@ func TestCache_BuildTime(t *testing.T) {
func TestCache_DeploymentStats(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
cache := metricscache.New(db, slogtest.Make(t, nil), metricscache.Intervals{
DeploymentStats: testutil.IntervalFast,
})
diff --git a/coderd/prometheusmetrics/prometheusmetrics_test.go b/coderd/prometheusmetrics/prometheusmetrics_test.go
index fb00ced6d9548..8256c2f7e2e90 100644
--- a/coderd/prometheusmetrics/prometheusmetrics_test.go
+++ b/coderd/prometheusmetrics/prometheusmetrics_test.go
@@ -26,8 +26,8 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/prometheusmetrics"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/codersdk/agentsdk"
@@ -48,13 +48,13 @@ func TestActiveUsers(t *testing.T) {
}{{
Name: "None",
Database: func(t *testing.T) database.Store {
- return dbfake.New()
+ return dbmem.New()
},
Count: 0,
}, {
Name: "One",
Database: func(t *testing.T) database.Store {
- db := dbfake.New()
+ db := dbmem.New()
dbgen.APIKey(t, db, database.APIKey{
LastUsed: dbtime.Now(),
})
@@ -64,7 +64,7 @@ func TestActiveUsers(t *testing.T) {
}, {
Name: "OneWithExpired",
Database: func(t *testing.T) database.Store {
- db := dbfake.New()
+ db := dbmem.New()
dbgen.APIKey(t, db, database.APIKey{
LastUsed: dbtime.Now(),
@@ -81,7 +81,7 @@ func TestActiveUsers(t *testing.T) {
}, {
Name: "Multiple",
Database: func(t *testing.T) database.Store {
- db := dbfake.New()
+ db := dbmem.New()
dbgen.APIKey(t, db, database.APIKey{
LastUsed: dbtime.Now(),
})
@@ -200,13 +200,13 @@ func TestWorkspaces(t *testing.T) {
}{{
Name: "None",
Database: func() database.Store {
- return dbfake.New()
+ return dbmem.New()
},
Total: 0,
}, {
Name: "Multiple",
Database: func() database.Store {
- db := dbfake.New()
+ db := dbmem.New()
insertCanceled(db)
insertFailed(db)
insertFailed(db)
diff --git a/coderd/provisionerdserver/acquirer_test.go b/coderd/provisionerdserver/acquirer_test.go
index 7036df817b264..bed8eccb68aca 100644
--- a/coderd/provisionerdserver/acquirer_test.go
+++ b/coderd/provisionerdserver/acquirer_test.go
@@ -17,7 +17,7 @@ import (
"cdr.dev/slog"
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/provisionerjobs"
"github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/coderd/provisionerdserver"
@@ -31,7 +31,7 @@ func TestMain(m *testing.M) {
// TestAcquirer_Store tests that a database.Store is accepted as a provisionerdserver.AcquirerStore
func TestAcquirer_Store(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
ps := pubsub.NewInMemory()
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
defer cancel()
diff --git a/coderd/provisionerdserver/provisionerdserver.go b/coderd/provisionerdserver/provisionerdserver.go
index 38038df49dd90..6465eab1d9fe9 100644
--- a/coderd/provisionerdserver/provisionerdserver.go
+++ b/coderd/provisionerdserver/provisionerdserver.go
@@ -1206,6 +1206,13 @@ func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob)
case <-wait:
// Wait for the next potential timeout to occur.
if err := s.Pubsub.Publish(codersdk.WorkspaceNotifyChannel(workspaceBuild.WorkspaceID), []byte{}); err != nil {
+ if s.lifecycleCtx.Err() != nil {
+ // If the server is shutting down, we don't want to log this error, nor wait around.
+ s.Logger.Debug(ctx, "stopping notifications due to server shutdown",
+ slog.F("workspace_build_id", workspaceBuild.ID),
+ )
+ return
+ }
s.Logger.Error(ctx, "workspace notification after agent timeout failed",
slog.F("workspace_build_id", workspaceBuild.ID),
slog.Error(err),
diff --git a/coderd/provisionerdserver/provisionerdserver_internal_test.go b/coderd/provisionerdserver/provisionerdserver_internal_test.go
index 427a1c428b4fa..acf9508307070 100644
--- a/coderd/provisionerdserver/provisionerdserver_internal_test.go
+++ b/coderd/provisionerdserver/provisionerdserver_internal_test.go
@@ -10,8 +10,8 @@ import (
"golang.org/x/oauth2"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/testutil"
)
@@ -21,14 +21,14 @@ func TestObtainOIDCAccessToken(t *testing.T) {
ctx := context.Background()
t.Run("NoToken", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
_, err := obtainOIDCAccessToken(ctx, db, nil, uuid.Nil)
require.NoError(t, err)
})
t.Run("InvalidConfig", func(t *testing.T) {
// We still want OIDC to succeed even if exchanging the token fails.
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
user := dbgen.User(t, db, database.User{})
dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID,
@@ -40,7 +40,7 @@ func TestObtainOIDCAccessToken(t *testing.T) {
})
t.Run("Exchange", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
user := dbgen.User(t, db, database.User{})
dbgen.UserLink(t, db, database.UserLink{
UserID: user.ID,
diff --git a/coderd/provisionerdserver/provisionerdserver_test.go b/coderd/provisionerdserver/provisionerdserver_test.go
index db97724c72987..bc16b01c1e8cf 100644
--- a/coderd/provisionerdserver/provisionerdserver_test.go
+++ b/coderd/provisionerdserver/provisionerdserver_test.go
@@ -27,8 +27,8 @@ import (
"github.com/coder/coder/v2/cli/clibase"
"github.com/coder/coder/v2/coderd/audit"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/coder/coder/v2/coderd/externalauth"
@@ -1525,7 +1525,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
}
t.Run("NoAgents", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
@@ -1538,7 +1538,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
})
t.Run("InvalidAgentToken", func(t *testing.T) {
t.Parallel()
- err := insert(dbfake.New(), uuid.New(), &sdkproto.Resource{
+ err := insert(dbmem.New(), uuid.New(), &sdkproto.Resource{
Name: "something",
Type: "aws_instance",
Agents: []*sdkproto.Agent{{
@@ -1551,7 +1551,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
})
t.Run("DuplicateApps", func(t *testing.T) {
t.Parallel()
- err := insert(dbfake.New(), uuid.New(), &sdkproto.Resource{
+ err := insert(dbmem.New(), uuid.New(), &sdkproto.Resource{
Name: "something",
Type: "aws_instance",
Agents: []*sdkproto.Agent{{
@@ -1566,7 +1566,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
})
t.Run("Success", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
@@ -1623,7 +1623,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
t.Run("AllDisplayApps", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
@@ -1651,7 +1651,7 @@ func TestInsertWorkspaceResource(t *testing.T) {
t.Run("DisableDefaultApps", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
@@ -1689,7 +1689,7 @@ func setup(t *testing.T, ignoreLogErrors bool, ov *overrides) (proto.DRPCProvisi
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
logger := slogtest.Make(t, nil).Leveled(slog.LevelDebug)
- db := dbfake.New()
+ db := dbmem.New()
ps := pubsub.NewInMemory()
deploymentValues := &codersdk.DeploymentValues{}
var externalAuthConfigs []*externalauth.Config
diff --git a/coderd/telemetry/telemetry_test.go b/coderd/telemetry/telemetry_test.go
index cec216564b99b..5df6be77f763e 100644
--- a/coderd/telemetry/telemetry_test.go
+++ b/coderd/telemetry/telemetry_test.go
@@ -18,8 +18,8 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/buildinfo"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/telemetry"
"github.com/coder/coder/v2/testutil"
@@ -36,7 +36,7 @@ func TestTelemetry(t *testing.T) {
var err error
- db := dbfake.New()
+ db := dbmem.New()
ctx := testutil.Context(t, testutil.WaitMedium)
_, _ = dbgen.APIKey(t, db, database.APIKey{})
@@ -106,7 +106,7 @@ func TestTelemetry(t *testing.T) {
})
t.Run("HashedEmail", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
_ = dbgen.User(t, db, database.User{
Email: "kyle@coder.com",
})
@@ -119,7 +119,7 @@ func TestTelemetry(t *testing.T) {
// nolint:paralleltest
func TestTelemetryInstallSource(t *testing.T) {
t.Setenv("CODER_TELEMETRY_INSTALL_SOURCE", "aws_marketplace")
- db := dbfake.New()
+ db := dbmem.New()
deployment, _ := collectSnapshot(t, db)
require.Equal(t, "aws_marketplace", deployment.InstallSource)
}
diff --git a/coderd/updatecheck/updatecheck_test.go b/coderd/updatecheck/updatecheck_test.go
index 103064eb7e6de..afc0f57cbdd41 100644
--- a/coderd/updatecheck/updatecheck_test.go
+++ b/coderd/updatecheck/updatecheck_test.go
@@ -14,7 +14,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/updatecheck"
"github.com/coder/coder/v2/testutil"
)
@@ -49,7 +49,7 @@ func TestChecker_Notify(t *testing.T) {
}))
defer srv.Close()
- db := dbfake.New()
+ db := dbmem.New()
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Named(t.Name())
notify := make(chan updatecheck.Result, len(wantVersion))
c := updatecheck.New(db, logger, updatecheck.Options{
@@ -131,7 +131,7 @@ func TestChecker_Latest(t *testing.T) {
}))
defer srv.Close()
- db := dbfake.New()
+ db := dbmem.New()
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Named(t.Name())
c := updatecheck.New(db, logger, updatecheck.Options{
URL: srv.URL,
diff --git a/coderd/workspacebuilds_test.go b/coderd/workspacebuilds_test.go
index 1f487e6915d40..0978a1743affd 100644
--- a/coderd/workspacebuilds_test.go
+++ b/coderd/workspacebuilds_test.go
@@ -48,14 +48,12 @@ func TestWorkspaceBuild(t *testing.T) {
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
auditor.ResetLogs()
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
-
- ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
- defer cancel()
-
- _, err := client.WorkspaceBuild(ctx, workspace.LatestBuild.ID)
- require.NoError(t, err)
- require.Len(t, auditor.AuditLogs(), 1)
+ _ = coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
+ // Create workspace will also start a build, so we need to wait for
+ // it to ensure all events are recorded.
+ require.Len(t, auditor.AuditLogs(), 2)
require.Equal(t, auditor.AuditLogs()[0].Ip.IPNet.IP.String(), "127.0.0.1")
+ require.Equal(t, auditor.AuditLogs()[1].Ip.IPNet.IP.String(), "127.0.0.1")
}
func TestWorkspaceBuildByBuildNumber(t *testing.T) {
diff --git a/codersdk/deployment_test.go b/codersdk/deployment_test.go
index 7cecc288512ca..d6846557cd9cc 100644
--- a/codersdk/deployment_test.go
+++ b/codersdk/deployment_test.go
@@ -209,25 +209,26 @@ func TestTimezoneOffsets(t *testing.T) {
ExpectedOffset int
}{
{
- Name: "UTX",
+ Name: "UTC",
Loc: time.UTC,
ExpectedOffset: 0,
},
- {
- Name: "Eastern",
- Loc: must(time.LoadLocation("America/New_York")),
- ExpectedOffset: -4,
- },
- {
- Name: "Central",
- Loc: must(time.LoadLocation("America/Chicago")),
- ExpectedOffset: -5,
- },
- {
- Name: "Ireland",
- Loc: must(time.LoadLocation("Europe/Dublin")),
- ExpectedOffset: 1,
- },
+ // The following test cases are broken re: daylight savings
+ //{
+ // Name: "Eastern",
+ // Loc: must(time.LoadLocation("America/New_York")),
+ // ExpectedOffset: -4,
+ //},
+ //{
+ // Name: "Central",
+ // Loc: must(time.LoadLocation("America/Chicago")),
+ // ExpectedOffset: -5,
+ //},
+ //{
+ // Name: "Ireland",
+ // Loc: must(time.LoadLocation("Europe/Dublin")),
+ // ExpectedOffset: 1,
+ //},
{
Name: "HalfHourTz",
// This timezone is +6:30, but the function rounds to the nearest hour.
diff --git a/docs/changelogs/README.md b/docs/changelogs/README.md
index 1dc1c8c5a18a6..753c7ecbd5abb 100644
--- a/docs/changelogs/README.md
+++ b/docs/changelogs/README.md
@@ -13,8 +13,8 @@ git checkout main; git pull; git fetch --all
export CODER_IGNORE_MISSING_COMMIT_METADATA=1
export BRANCH=main
./scripts/release/generate_release_notes.sh \
- --old-version=v2.3.0 \
- --new-version=v2.3.1 \
+ --old-version=v2.3.3 \
+ --new-version=v2.3.4 \
--ref=$(git rev-parse --short "${ref:-origin/$BRANCH}") \
- > ./docs/changelogs/v2.3.1.md
+ > ./docs/changelogs/v2.3.4.md
```
diff --git a/docs/changelogs/v2.3.2.md b/docs/changelogs/v2.3.2.md
new file mode 100644
index 0000000000000..373914ac0a5de
--- /dev/null
+++ b/docs/changelogs/v2.3.2.md
@@ -0,0 +1,37 @@
+## Changelog
+
+### Important features
+
+- Moved workspace cleanup to an experimental feature (#10363) (@sreya)
+
+### Features
+
+- Add telemetry for external provisioners (#10322) (@coadler)
+- Expose template insights as Prometheus metrics (#10325) (@mtojek)
+- Add user groups column to users table (#10284) (@Parkreiner)
+- Add cli support for `--require-active-version` (#10337) (@sreya)
+- Add frontend support for mandating active template version (#10338) (@sreya)
+
+### Bug fixes
+
+- Add requester IP to workspace build audit logs (#10242) (@coadler)
+- Resolve User is not unauthenticated error seen on logout (#10349) (@Kira-Pilot)
+- Show dormant and suspended users in groups (#10333) (@Kira-Pilot)
+- Fix additional cluster SA, role names (#10366) (@ericpaulsen)
+- Update external-auth docs to use `coder_external_auth` (#10347) (@matifali)
+- b8c7b56fd fix(site): fix tabs in the template layout (#10334) (@BrunoQuaresma)
+
+### Documentation
+
+- Update vscode web docs (#10327) (@matifali)
+- Rework telemetry doc and add CLI warning (#10354) (@ammario)
+
+Compare: [`v2.3.1...v2.3.2`](https://github.com/coder/coder/compare/v2.3.1...v2.3.2)
+
+## Container image
+
+- `docker pull ghcr.io/coder/coder:v2.3.2`
+
+## Install/upgrade
+
+Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
diff --git a/docs/changelogs/v2.3.3.md b/docs/changelogs/v2.3.3.md
new file mode 100644
index 0000000000000..9460703a6df7a
--- /dev/null
+++ b/docs/changelogs/v2.3.3.md
@@ -0,0 +1,43 @@
+## Changelog
+
+### Features
+
+- Make the dotfiles repository directory configurable for `coder dotfiles` (#10377) (@JoshVee)
+- Expose template version to provisioner (#10306) (@JoshVee)
+
+### Bug fixes
+
+- Initialize terminal with correct size (#10369) (@code-asher)
+- Disable tests broken by daylight savings (#10414) (@spikecurtis)
+- Add new aws regions to instance identity (#10434) (@kylecarbs)
+- Prevent infinite redirect oauth auth flow (#10430) (@Emyrk)
+- Prevent metadata from being discarded if report is slow (#10386) (@mafredri)
+- Track cron run and wait for cron stop (#10388) (@mafredri)
+- Display informative error for ErrWaitDelay (#10407) (@mafredri)
+- Avoid error log during shutdown (#10402) (@mafredri)
+- Update installation link (#10275) (@devarshishimpi)
+
+### Tests
+
+- 8f1b4fb06 test(agent): fix service banner trim test flake (#10384) (@mafredri)
+- 1286904de test(agent): improve TestAgent_Session_TTY_MOTD_Update (#10385) (@mafredri)
+- eac155aec test(cli): fix TestServer flake due to DNS lookup (#10390) (@mafredri)
+- 9d3785def test(cli/cliui): make agent tests more robust (#10415) (@mafredri)
+- 6683ad989 test(coderd): fix TestWorkspaceBuild flake (#10387) (@mafredri)
+
+### Continuous integration
+
+- 39fbf74c7 ci: bump the github-actions group with 1 update (#10379) (@app/dependabot)
+- 6b7858c51 ci: bump the github-actions group with 2 updates (#10420) (@app/dependabot)
+
+### Chores
+
+Compare: [`v2.3.2...v2.3.3`](https://github.com/coder/coder/compare/v2.3.2...v2.3.3)
+
+## Container image
+
+- `docker pull ghcr.io/coder/coder:v2.3.3`
+
+## Install/upgrade
+
+Refer to our docs to [install](https://coder.com/docs/v2/latest/install) or [upgrade](https://coder.com/docs/v2/latest/admin/upgrade) Coder, or use a release asset below.
diff --git a/docs/cli/dotfiles.md b/docs/cli/dotfiles.md
index 59446a8b84d77..2ed5ab1525cb0 100644
--- a/docs/cli/dotfiles.md
+++ b/docs/cli/dotfiles.md
@@ -28,6 +28,16 @@ coder dotfiles [flags]
Specifies which branch to clone. If empty, will default to cloning the default branch or using the existing branch in the cloned repo on disk.
+### --repo-dir
+
+| | |
+| ----------- | ------------------------------------- |
+| Type | string |
+| Environment | $CODER_DOTFILES_REPO_DIR |
+| Default | dotfiles |
+
+Specifies the directory for the dotfiles repository, relative to global config directory.
+
### --symlink-dir
| | |
diff --git a/docs/templates/open-in-coder.md b/docs/templates/open-in-coder.md
index a2478d233685b..936c04681a446 100644
--- a/docs/templates/open-in-coder.md
+++ b/docs/templates/open-in-coder.md
@@ -20,8 +20,8 @@ authentication in your Coder deployment.
### 2. Modify your template to auto-clone repos
-The id in the template's `coder_git_auth` data source must match the
-`CODER_GITAUTH_0_ID` in the Coder deployment configuration.
+The id in the template's `coder_external_auth` data source must match the
+`CODER_EXTERNAL_AUTH_X_ID` in the Coder deployment configuration.
If you want the template to clone a specific git repo:
diff --git a/enterprise/audit/audit_test.go b/enterprise/audit/audit_test.go
index b4f5e0f2aab89..6d825306c3346 100644
--- a/enterprise/audit/audit_test.go
+++ b/enterprise/audit/audit_test.go
@@ -8,7 +8,7 @@ import (
"golang.org/x/xerrors"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/enterprise/audit"
"github.com/coder/coder/v2/enterprise/audit/audittest"
)
@@ -91,7 +91,7 @@ func TestAuditor(t *testing.T) {
var (
backend = &testBackend{decision: test.backendDecision, err: test.backendError}
exporter = audit.NewAuditor(
- dbfake.New(),
+ dbmem.New(),
audit.FilterFunc(func(_ context.Context, _ database.AuditLog) (audit.FilterDecision, error) {
return test.filterDecision, test.filterError
}),
diff --git a/enterprise/audit/backends/postgres_test.go b/enterprise/audit/backends/postgres_test.go
index b3fa1f31d0cbd..f566db9cb507b 100644
--- a/enterprise/audit/backends/postgres_test.go
+++ b/enterprise/audit/backends/postgres_test.go
@@ -7,7 +7,7 @@ import (
"github.com/stretchr/testify/require"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/enterprise/audit"
"github.com/coder/coder/v2/enterprise/audit/audittest"
"github.com/coder/coder/v2/enterprise/audit/backends"
@@ -20,7 +20,7 @@ func TestPostgresBackend(t *testing.T) {
var (
ctx, cancel = context.WithCancel(context.Background())
- db = dbfake.New()
+ db = dbmem.New()
pgb = backends.NewPostgres(db, true)
alog = audittest.RandomLog()
)
diff --git a/enterprise/coderd/coderd_test.go b/enterprise/coderd/coderd_test.go
index 873618842b4f8..855ecef059c75 100644
--- a/enterprise/coderd/coderd_test.go
+++ b/enterprise/coderd/coderd_test.go
@@ -17,7 +17,7 @@ import (
"github.com/coder/coder/v2/coderd/coderdtest"
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/dbauthz"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/rbac"
@@ -191,7 +191,7 @@ func TestAuditLogging(t *testing.T) {
_, _, api, _ := coderdenttest.NewWithAPI(t, &coderdenttest.Options{
AuditLogging: true,
Options: &coderdtest.Options{
- Auditor: audit.NewAuditor(dbfake.New(), audit.DefaultFilter),
+ Auditor: audit.NewAuditor(dbmem.New(), audit.DefaultFilter),
},
LicenseOptions: &coderdenttest.LicenseOptions{
Features: license.Features{
@@ -200,7 +200,7 @@ func TestAuditLogging(t *testing.T) {
},
})
auditor := *api.AGPL.Auditor.Load()
- ea := audit.NewAuditor(dbfake.New(), audit.DefaultFilter)
+ ea := audit.NewAuditor(dbmem.New(), audit.DefaultFilter)
t.Logf("%T = %T", auditor, ea)
assert.EqualValues(t, reflect.ValueOf(ea).Type(), reflect.ValueOf(auditor).Type())
})
diff --git a/enterprise/coderd/coderdenttest/coderdenttest.go b/enterprise/coderd/coderdenttest/coderdenttest.go
index 1c3f7c4fc83e0..26e3bfaef22d6 100644
--- a/enterprise/coderd/coderdenttest/coderdenttest.go
+++ b/enterprise/coderd/coderdenttest/coderdenttest.go
@@ -10,7 +10,7 @@ import (
"testing"
"time"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/pubsub"
"github.com/golang-jwt/jwt/v4"
@@ -133,8 +133,8 @@ func NewWithAPI(t *testing.T, options *Options) (
// we check for the in-memory test types so that the real types don't have to exported
_, ok := coderAPI.Pubsub.(*pubsub.MemoryPubsub)
require.False(t, ok, "FeatureHighAvailability is incompatible with MemoryPubsub")
- _, ok = coderAPI.Database.(*dbfake.FakeQuerier)
- require.False(t, ok, "FeatureHighAvailability is incompatible with dbfake")
+ _, ok = coderAPI.Database.(*dbmem.FakeQuerier)
+ require.False(t, ok, "FeatureHighAvailability is incompatible with dbmem")
}
}
_ = AddLicense(t, client, lo)
diff --git a/enterprise/coderd/dormancy/dormantusersjob_test.go b/enterprise/coderd/dormancy/dormantusersjob_test.go
index 4c3853cc987a3..c752e84bc1d90 100644
--- a/enterprise/coderd/dormancy/dormantusersjob_test.go
+++ b/enterprise/coderd/dormancy/dormantusersjob_test.go
@@ -11,7 +11,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/enterprise/coderd/dormancy"
"github.com/coder/coder/v2/testutil"
)
@@ -25,7 +25,7 @@ func TestCheckInactiveUsers(t *testing.T) {
// Add some dormant accounts
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
- db := dbfake.New()
+ db := dbmem.New()
ctx, cancelFunc := context.WithCancel(context.Background())
t.Cleanup(cancelFunc)
diff --git a/enterprise/coderd/license/license_test.go b/enterprise/coderd/license/license_test.go
index 1335a89aca18e..f57dd0292d5c2 100644
--- a/enterprise/coderd/license/license_test.go
+++ b/enterprise/coderd/license/license_test.go
@@ -11,7 +11,7 @@ import (
"cdr.dev/slog"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
@@ -29,7 +29,7 @@ func TestEntitlements(t *testing.T) {
t.Run("Defaults", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, all)
require.NoError(t, err)
require.False(t, entitlements.HasLicense)
@@ -41,7 +41,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("Always return the current user count", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 1, coderdenttest.Keys, all)
require.NoError(t, err)
require.False(t, entitlements.HasLicense)
@@ -50,7 +50,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("SingleLicenseNothing", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{}),
Exp: time.Now().Add(time.Hour),
@@ -66,7 +66,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("SingleLicenseAll", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: func() license.Features {
@@ -89,7 +89,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("SingleLicenseGrace", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -115,7 +115,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("Expiration warning", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -144,7 +144,7 @@ func TestEntitlements(t *testing.T) {
t.Run("Expiration warning for license expiring in 1 day", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -173,7 +173,7 @@ func TestEntitlements(t *testing.T) {
t.Run("Expiration warning for trials", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -203,7 +203,7 @@ func TestEntitlements(t *testing.T) {
t.Run("Expiration warning for non trials", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -232,7 +232,7 @@ func TestEntitlements(t *testing.T) {
t.Run("SingleLicenseNotEntitled", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{}),
Exp: time.Now().Add(time.Hour),
@@ -260,7 +260,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("TooManyUsers", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
activeUser1, err := db.InsertUser(context.Background(), database.InsertUserParams{
ID: uuid.New(),
Username: "test1",
@@ -306,7 +306,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("MaximizeUserLimit", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertUser(context.Background(), database.InsertUserParams{})
db.InsertUser(context.Background(), database.InsertUserParams{})
db.InsertLicense(context.Background(), database.InsertLicenseParams{
@@ -334,7 +334,7 @@ func TestEntitlements(t *testing.T) {
})
t.Run("MultipleLicenseEnabled", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
// One trial
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
@@ -358,7 +358,7 @@ func TestEntitlements(t *testing.T) {
t.Run("AllFeatures", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -380,7 +380,7 @@ func TestEntitlements(t *testing.T) {
t.Run("AllFeaturesAlwaysEnable", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: dbtime.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -403,7 +403,7 @@ func TestEntitlements(t *testing.T) {
t.Run("AllFeaturesGrace", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: dbtime.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -427,7 +427,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleReplicasNoLicense", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 2, 1, coderdenttest.Keys, all)
require.NoError(t, err)
require.False(t, entitlements.HasLicense)
@@ -437,7 +437,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleReplicasNotEntitled", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -457,7 +457,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleReplicasGrace", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
Features: license.Features{
@@ -479,7 +479,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleGitAuthNoLicense", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
entitlements, err := license.Entitlements(context.Background(), db, slog.Logger{}, 1, 2, coderdenttest.Keys, all)
require.NoError(t, err)
require.False(t, entitlements.HasLicense)
@@ -489,7 +489,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleGitAuthNotEntitled", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
Exp: time.Now().Add(time.Hour),
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
@@ -509,7 +509,7 @@ func TestEntitlements(t *testing.T) {
t.Run("MultipleGitAuthGrace", func(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
db.InsertLicense(context.Background(), database.InsertLicenseParams{
JWT: coderdenttest.GenerateLicense(t, coderdenttest.LicenseOptions{
GraceAt: time.Now().Add(-time.Hour),
diff --git a/enterprise/coderd/proxyhealth/proxyhealth_test.go b/enterprise/coderd/proxyhealth/proxyhealth_test.go
index 96502fa1f56e6..6f20c1e48ebef 100644
--- a/enterprise/coderd/proxyhealth/proxyhealth_test.go
+++ b/enterprise/coderd/proxyhealth/proxyhealth_test.go
@@ -12,8 +12,8 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/httpapi"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/enterprise/coderd/proxyhealth"
@@ -46,7 +46,7 @@ func TestProxyHealth_Nil(t *testing.T) {
func TestProxyHealth_Unregistered(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
proxies := []database.WorkspaceProxy{
insertProxy(t, db, ""),
@@ -72,7 +72,7 @@ func TestProxyHealth_Unregistered(t *testing.T) {
func TestProxyHealth_Unhealthy(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
srvBadReport := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
httpapi.Write(context.Background(), w, http.StatusOK, codersdk.ProxyHealthReport{
@@ -112,7 +112,7 @@ func TestProxyHealth_Unhealthy(t *testing.T) {
func TestProxyHealth_Reachable(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
httpapi.Write(context.Background(), w, http.StatusOK, codersdk.ProxyHealthReport{
@@ -147,7 +147,7 @@ func TestProxyHealth_Reachable(t *testing.T) {
func TestProxyHealth_Unreachable(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
cli := &http.Client{
Transport: &http.Transport{
diff --git a/enterprise/replicasync/replicasync_test.go b/enterprise/replicasync/replicasync_test.go
index 343dd940a5bd3..89ee49bec2bb6 100644
--- a/enterprise/replicasync/replicasync_test.go
+++ b/enterprise/replicasync/replicasync_test.go
@@ -16,7 +16,7 @@ import (
"cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/v2/coderd/database"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtestutil"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/database/pubsub"
@@ -218,7 +218,7 @@ func TestReplica(t *testing.T) {
// This doesn't use the database fake because creating
// this many PostgreSQL connections takes some
// configuration tweaking.
- db := dbfake.New()
+ db := dbmem.New()
pubsub := pubsub.NewInMemory()
logger := slogtest.Make(t, nil)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
diff --git a/enterprise/trialer/trialer_test.go b/enterprise/trialer/trialer_test.go
index 6a160e1ab53ed..22a9eeaca31a0 100644
--- a/enterprise/trialer/trialer_test.go
+++ b/enterprise/trialer/trialer_test.go
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/require"
- "github.com/coder/coder/v2/coderd/database/dbfake"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/enterprise/coderd/coderdenttest"
"github.com/coder/coder/v2/enterprise/trialer"
)
@@ -23,7 +23,7 @@ func TestTrialer(t *testing.T) {
_, _ = w.Write([]byte(license))
}))
defer srv.Close()
- db := dbfake.New()
+ db := dbmem.New()
gen := trialer.New(db, srv.URL, coderdenttest.Keys)
err := gen(context.Background(), "kyle@coder.com")
diff --git a/examples/templates/fly-docker-image/README.md b/examples/templates/fly-docker-image/README.md
deleted file mode 100644
index df79210a2f6d4..0000000000000
--- a/examples/templates/fly-docker-image/README.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-name: Develop on a Fly.io container
-description: Run workspaces as Firecracker VMs on Fly.io
-tags: [docker, fly.io]
-icon: /icon/fly.io.svg
----
-
-# Coder Fly.io Template
-
-This template provisions a [code-server](https://github.com/coder/code-server) instance on [fly.io](https://fly.io) using the [codercom/code-server](https://hub.docker.com/r/codercom/code-server) image.
-
-## Prerequisites
-
-- [flyctl](https://fly.io/docs/getting-started/installing-flyctl/) installed.
-- [Coder](https://coder.com/) already setup and running with coder-cli installed locally.
-
-## Getting started
-
-1. Run `coder templates init` and select this template. Follow the instructions that appear.
-2. cd into the directory that was created. (e.g. `cd fly-docker-image`)
-3. Create the new template by running the following command from the `fly-docker-image` directory:
-
-```bash
-coder templates create fly-docker-image \
- --var fly_api_token=$(flyctl auth token) \
- --var fly_org=personal
-```
-
-> If the Coder server is also running as a fly.io app, then instead of setting variable `fly_api_token` you can also set a fly.io secret with the name `FLY_API_TOKEN`
->
-> ```bash
-> flyctl secrets set FLY_API_TOKEN=$(flyctl auth token) --app
-> ```
-
-> Read our blog [post](coder.com/blog/deploying-coder-on-fly-io) to learn more about how to deploy Coder on fly.io.
-
-4. Navigate to the Coder dashboard and create a new workspace using the template.
-
-This is all. You should now have a code-server instance running on fly.io.
diff --git a/examples/templates/fly-docker-image/main.tf b/examples/templates/fly-docker-image/main.tf
deleted file mode 100644
index 1ef7b120c9f87..0000000000000
--- a/examples/templates/fly-docker-image/main.tf
+++ /dev/null
@@ -1,347 +0,0 @@
-terraform {
- required_providers {
- fly = {
- source = "fly-apps/fly"
- }
- coder = {
- source = "coder/coder"
- }
- }
-}
-
-provider "fly" {
- fly_api_token = var.fly_api_token == "" ? null : var.fly_api_token
-}
-
-provider "coder" {
-}
-
-resource "fly_app" "workspace" {
- name = "coder-${lower(data.coder_workspace.me.owner)}-${lower(data.coder_workspace.me.name)}"
- org = var.fly_org
-}
-
-resource "fly_volume" "home-volume" {
- app = fly_app.workspace.name
- name = "coder_${lower(data.coder_workspace.me.owner)}_${lower(replace(data.coder_workspace.me.name, "-", "_"))}_home"
- size = data.coder_parameter.volume-size.value
- region = data.coder_parameter.region.value
-}
-
-resource "fly_machine" "workspace" {
- count = data.coder_workspace.me.start_count
- app = fly_app.workspace.name
- region = data.coder_parameter.region.value
- name = data.coder_workspace.me.name
- image = data.coder_parameter.docker-image.value
- cpus = data.coder_parameter.cpu.value
- cputype = data.coder_parameter.cputype.value
- memorymb = data.coder_parameter.memory.value * 1024
- env = {
- CODER_AGENT_TOKEN = "${coder_agent.main.token}"
- }
- entrypoint = ["sh", "-c", coder_agent.main.init_script]
- services = [
- {
- ports = [
- {
- port = 443
- handlers = ["tls", "http"]
- },
- {
- port = 80
- handlers = ["http"]
- }
-
- ]
- protocol = "tcp",
- "internal_port" = 80
- },
- {
- ports = [
- {
- port = 8080
- handlers = ["tls", "http"]
- }
- ]
- protocol = "tcp",
- "internal_port" = 8080
- }
- ]
- mounts = [
- {
- volume = fly_volume.home-volume.id
- path = "/home/coder"
- }
- ]
-}
-
-variable "fly_api_token" {
- type = string
- description = <<-EOF
-The Fly.io API token to use for deploying the workspace. You can generate one by running:
-
-$ flyctl auth token
-EOF
- sensitive = true
-}
-
-variable "fly_org" {
- type = string
- description = <<-EOF
-The Fly.io organization slug to deploy the workspace in. List organizations by running:
-
-$ flyctl orgs list
-EOF
-}
-
-data "coder_parameter" "docker-image" {
- name = "docker-image"
- display_name = "Docker image"
- description = "The docker image to use for the workspace"
- default = "codercom/code-server:latest"
- icon = "https://raw.githubusercontent.com/matifali/logos/main/docker.svg"
-}
-
-data "coder_parameter" "cpu" {
- name = "cpu"
- display_name = "CPU"
- description = "The number of CPUs to allocate to the workspace (1-8)"
- type = "number"
- default = "1"
- icon = "https://raw.githubusercontent.com/matifali/logos/main/cpu-3.svg"
- mutable = true
- validation {
- min = 1
- max = 8
- }
-}
-
-data "coder_parameter" "cputype" {
- name = "cputype"
- display_name = "CPU type"
- description = "Which CPU type do you want?"
- default = "shared"
- icon = "https://raw.githubusercontent.com/matifali/logos/main/cpu-1.svg"
- mutable = true
- option {
- name = "Shared"
- value = "shared"
- }
- option {
- name = "Performance"
- value = "performance"
- }
-}
-
-data "coder_parameter" "memory" {
- name = "memory"
- display_name = "Memory"
- description = "The amount of memory to allocate to the workspace in GB (up to 16GB)"
- type = "number"
- default = "2"
- icon = "/icon/memory.svg"
- mutable = true
- validation {
- min = data.coder_parameter.cputype.value == "performance" ? 2 : 1 # if the CPU type is performance, the minimum memory is 2GB
- max = 16
- }
-}
-
-data "coder_parameter" "volume-size" {
- name = "volume-size"
- display_name = "Home volume size"
- description = "The size of the volume to create for the workspace in GB (1-20)"
- type = "number"
- default = "1"
- icon = "https://raw.githubusercontent.com/matifali/logos/main/database.svg"
- validation {
- min = 1
- max = 20
- }
-}
-
-# You can see all available regions here: https://fly.io/docs/reference/regions/
-data "coder_parameter" "region" {
- name = "region"
- display_name = "Region"
- description = "The region to deploy the workspace in"
- default = "ams"
- icon = "/emojis/1f30e.png"
- option {
- name = "Amsterdam, Netherlands"
- value = "ams"
- icon = "/emojis/1f1f3-1f1f1.png"
- }
- option {
- name = "Frankfurt, Germany"
- value = "fra"
- icon = "/emojis/1f1e9-1f1ea.png"
- }
- option {
- name = "Paris, France"
- value = "cdg"
- icon = "/emojis/1f1eb-1f1f7.png"
- }
- option {
- name = "Denver, Colorado (US)"
- value = "den"
- icon = "/emojis/1f1fa-1f1f8.png"
- }
- option {
- name = "Dallas, Texas (US)"
- value = "dfw"
- icon = "/emojis/1f1fa-1f1f8.png"
- }
- option {
- name = "Hong Kong"
- value = "hkg"
- icon = "/emojis/1f1ed-1f1f0.png"
- }
- option {
- name = "Los Angeles, California (US)"
- value = "lax"
- icon = "/emojis/1f1fa-1f1f8.png"
- }
- option {
- name = "London, United Kingdom"
- value = "lhr"
- icon = "/emojis/1f1ec-1f1e7.png"
- }
- option {
- name = "Chennai, India"
- value = "maa"
- icon = "/emojis/1f1ee-1f1f3.png"
- }
- option {
- name = "Tokyo, Japan"
- value = "nrt"
- icon = "/emojis/1f1ef-1f1f5.png"
- }
- option {
- name = "Chicago, Illinois (US)"
- value = "ord"
- icon = "/emojis/1f1fa-1f1f8.png"
- }
- option {
- name = "Seattle, Washington (US)"
- value = "sea"
- icon = "/emojis/1f1fa-1f1f8.png"
- }
- option {
- name = "Singapore"
- value = "sin"
- icon = "/emojis/1f1f8-1f1ec.png"
- }
- option {
- name = "Sydney, Australia"
- value = "syd"
- icon = "/emojis/1f1e6-1f1fa.png"
- }
- option {
- name = "Toronto, Canada"
- value = "yyz"
- icon = "/emojis/1f1e8-1f1e6.png"
- }
-}
-
-resource "coder_app" "code-server" {
- count = 1
- agent_id = coder_agent.main.id
- display_name = "code-server"
- slug = "code-server"
- url = "http://localhost:8080?folder=/home/coder/"
- icon = "/icon/code.svg"
- subdomain = false
- share = "owner"
-
- healthcheck {
- url = "http://localhost:8080/healthz"
- interval = 3
- threshold = 10
- }
-}
-
-resource "coder_agent" "main" {
- arch = data.coder_provisioner.me.arch
- os = "linux"
- startup_script_timeout = 180
- startup_script = <<-EOT
- set -e
- # Start code-server
- code-server --auth none >/tmp/code-server.log 2>&1 &
- # Set the hostname to the workspace name
- sudo hostname -b "${data.coder_workspace.me.name}-fly"
- echo "127.0.0.1 ${data.coder_workspace.me.name}-fly" | sudo tee -a /etc/hosts
- # Install the Fly CLI and add it to the PATH
- curl -L https://fly.io/install.sh | sh
- echo "export PATH=$PATH:/home/coder/.fly/bin" >> /home/coder/.bashrc
- source /home/coder/.bashrc
- EOT
-
- metadata {
- key = "cpu"
- display_name = "CPU Usage"
- interval = 5
- timeout = 5
- script = <<-EOT
- #!/bin/bash
- set -e
- top -bn1 | grep "Cpu(s)" | awk '{print $2 + $4 "%"}'
- EOT
- }
- metadata {
- key = "memory"
- display_name = "Memory Usage"
- interval = 5
- timeout = 5
- script = <<-EOT
- #!/bin/bash
- set -e
- free -m | awk 'NR==2{printf "%.2f%%\t", $3*100/$2 }'
- EOT
- }
- metadata {
- key = "disk"
- display_name = "Disk Usage"
- interval = 600 # every 10 minutes
- timeout = 30 # df can take a while on large filesystems
- script = <<-EOT
- #!/bin/bash
- set -e
- df | awk '$NF=="/home/coder" {printf "%s", $5}'
- EOT
- }
-}
-
-resource "coder_metadata" "workspace" {
- count = data.coder_workspace.me.start_count
- resource_id = fly_app.workspace.id
- icon = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].icon
- item {
- key = "Region"
- value = data.coder_parameter.region.option[index(data.coder_parameter.region.option.*.value, data.coder_parameter.region.value)].name
- }
- item {
- key = "CPU Type"
- value = data.coder_parameter.cputype.option[index(data.coder_parameter.cputype.option.*.value, data.coder_parameter.cputype.value)].name
- }
- item {
- key = "CPU Count"
- value = data.coder_parameter.cpu.value
- }
- item {
- key = "Memory (GB)"
- value = data.coder_parameter.memory.value
- }
- item {
- key = "Volume Size (GB)"
- value = data.coder_parameter.volume-size.value
- }
-}
-
-data "coder_provisioner" "me" {
-}
-
-data "coder_workspace" "me" {
-}
diff --git a/examples/web-server/nginx/README.md b/examples/web-server/nginx/README.md
index 5c822856fdb1e..3454fe190f38c 100644
--- a/examples/web-server/nginx/README.md
+++ b/examples/web-server/nginx/README.md
@@ -7,7 +7,7 @@
```env
CODER_HTTP_ADDRESS=127.0.0.1:3000
CODER_ACCESS_URL=https://coder.example.com
- CODER_WILDCARD_ACCESS_URL=*coder.example.com
+ CODER_WILDCARD_ACCESS_URL=*.coder.example.com
```
Throughout the guide, be sure to replace `coder.example.com` with the domain you intend to use with Coder.
diff --git a/go.mod b/go.mod
index 73e8179ff3b66..8ddcf94dc1c9f 100644
--- a/go.mod
+++ b/go.mod
@@ -75,7 +75,7 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/adrg/xdg v0.4.0
github.com/ammario/tlru v0.3.0
- github.com/andybalholm/brotli v1.0.5
+ github.com/andybalholm/brotli v1.0.6
github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2
github.com/awalterschulze/gographviz v2.0.3+incompatible
github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816
@@ -94,12 +94,12 @@ require (
github.com/coder/retry v1.4.0
github.com/coder/terraform-provider-coder v0.12.2
github.com/coder/wgtunnel v0.1.12
- github.com/coreos/go-oidc/v3 v3.6.0
+ github.com/coreos/go-oidc/v3 v3.7.0
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/creack/pty v1.1.18
github.com/dave/dst v0.27.2
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
- github.com/djherbis/times v1.5.0
+ github.com/djherbis/times v1.6.0
github.com/elastic/go-sysinfo v1.11.0
github.com/fatih/color v1.15.0
github.com/fatih/structs v1.1.0
@@ -113,7 +113,7 @@ require (
github.com/go-chi/httprate v0.7.4
github.com/go-chi/render v1.0.1
github.com/go-jose/go-jose/v3 v3.0.0
- github.com/go-logr/logr v1.2.4
+ github.com/go-logr/logr v1.3.0
github.com/go-ping/ping v1.1.0
github.com/go-playground/validator/v10 v10.15.1
github.com/gofrs/flock v0.8.1
@@ -138,9 +138,9 @@ require (
github.com/jmoiron/sqlx v1.3.5
github.com/justinas/nosurf v1.1.1
github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f
- github.com/klauspost/compress v1.17.0
+ github.com/klauspost/compress v1.17.1
github.com/lib/pq v1.10.9
- github.com/mattn/go-isatty v0.0.19
+ github.com/mattn/go-isatty v0.0.20
github.com/mitchellh/go-wordwrap v1.0.1
github.com/mitchellh/mapstructure v1.5.0
github.com/moby/moby v24.0.1+incompatible
@@ -153,7 +153,7 @@ require (
github.com/pkg/sftp v1.13.6-0.20221018182125-7da137aa03f0
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_model v0.5.0
- github.com/prometheus/common v0.44.0
+ github.com/prometheus/common v0.45.0
github.com/quasilyte/go-ruleguard/dsl v0.3.21
github.com/robfig/cron/v3 v3.0.1
github.com/spf13/afero v1.10.0
@@ -174,7 +174,7 @@ require (
go.opentelemetry.io/otel/sdk v1.19.0
go.opentelemetry.io/otel/trace v1.19.0
go.uber.org/atomic v1.11.0
- go.uber.org/goleak v1.2.1
+ go.uber.org/goleak v1.3.0
go4.org/netipx v0.0.0-20230728180743-ad4cb58a6516
golang.org/x/crypto v0.14.0
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
@@ -188,10 +188,10 @@ require (
golang.org/x/tools v0.14.0
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
golang.zx2c4.com/wireguard v0.0.0-20230704135630-469159ecf7d1
- google.golang.org/api v0.147.0
- google.golang.org/grpc v1.58.2
+ google.golang.org/api v0.148.0
+ google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.31.0
- gopkg.in/DataDog/dd-trace-go.v1 v1.55.0
+ gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
gopkg.in/natefinch/lumberjack.v2 v2.2.1
gopkg.in/yaml.v3 v3.0.1
gvisor.dev/gvisor v0.0.0-20230504175454-7b0a1988a28f
@@ -215,7 +215,7 @@ require (
filippo.io/edwards25519 v1.0.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
- github.com/DataDog/datadog-agent/pkg/obfuscate v0.46.0 // indirect
+ github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
github.com/DataDog/go-libddwaf v1.5.0 // indirect
@@ -332,7 +332,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
- github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
+ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect
github.com/mdlayher/genetlink v1.3.2 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
github.com/mdlayher/sdnotify v1.0.0 // indirect
@@ -411,10 +411,10 @@ require (
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard/wgctrl v0.0.0-20230429144221-925a1e7659e6 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect
- google.golang.org/appengine v1.6.7 // indirect
+ google.golang.org/appengine v1.6.8 // indirect
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
howett.net/plist v1.0.0 // indirect
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
diff --git a/go.sum b/go.sum
index 8fe52143c7a00..c4180c4191b45 100644
--- a/go.sum
+++ b/go.sum
@@ -58,11 +58,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DataDog/appsec-internal-go v1.0.0 h1:2u5IkF4DBj3KVeQn5Vg2vjPUtt513zxEYglcqnd500U=
github.com/DataDog/appsec-internal-go v1.0.0/go.mod h1:+Y+4klVWKPOnZx6XESG7QHydOaUGEXyH2j/vSg9JiNM=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.46.0 h1:rUNnUcHC4AlxoImuXmZeOfi6H80BDBHzeagWXWCVhnA=
-github.com/DataDog/datadog-agent/pkg/obfuscate v0.46.0/go.mod h1:e933RWa4kAWuHi5jpzEuOiULlv21HcCFEVIYegmaB5c=
+github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 h1:bUMSNsw1iofWiju9yc1f+kBd33E3hMJtq9GuU602Iy8=
+github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0/go.mod h1:HzySONXnAgSmIQfL6gOv9hWprKJkx8CicuXuUbmgWfo=
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df h1:PbzrhHhs2+RRdKKti7JBSM8ATIeiji2T2cVt/d8GT8k=
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df/go.mod h1:5Q39ZOIOwZMnFyRadp+5gH1bFdjmb+Pgxe+j5XOwaTg=
-github.com/DataDog/datadog-go/v5 v5.1.1/go.mod h1:KhiYb2Badlv9/rofz+OznKoEF5XKTonWyhx5K83AP8E=
github.com/DataDog/datadog-go/v5 v5.3.0 h1:2q2qjFOb3RwAZNU+ez27ZVDwErJv5/VpbBPprz7Z+s8=
github.com/DataDog/datadog-go/v5 v5.3.0/go.mod h1:XRDJk1pTc00gm+ZDiBKsjh7oOOtJfYfglVCmFb8C2+Q=
github.com/DataDog/go-libddwaf v1.5.0 h1:lrHP3VrEriy1M5uQuaOcKphf5GU40mBhihMAp6Ik55c=
@@ -76,7 +75,6 @@ github.com/DataDog/sketches-go v1.4.2/go.mod h1:xJIXldczJyyjnbDop7ZZcLxJdV3+7Kra
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
-github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
@@ -105,8 +103,8 @@ github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3Uu
github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4=
github.com/ammario/tlru v0.3.0 h1:yK8ESoFlEyz/BVVL8yZQKAUzJwFJR/j9EfxjnKxtR/Q=
github.com/ammario/tlru v0.3.0/go.mod h1:aYzRFu0XLo4KavE9W8Lx7tzjkX+pAApz+NgcKYIFUBQ=
-github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
-github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
+github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI=
+github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/apparentlymart/go-dump v0.0.0-20180507223929-23540a00eaa3/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
@@ -249,8 +247,8 @@ github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG
github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ=
github.com/coreos/go-iptables v0.6.0 h1:is9qnZMPYjLd8LYqmm/qlE+wwEgJIkTYdhV3rfZo4jk=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
-github.com/coreos/go-oidc/v3 v3.6.0 h1:AKVxfYw1Gmkn/w96z0DbT/B/xFnzTd3MkZvWLjF4n/o=
-github.com/coreos/go-oidc/v3 v3.6.0/go.mod h1:ZpHUsHBucTUj6WOkrP4E20UPynbLZzhTQ1XKCXkxyPc=
+github.com/coreos/go-oidc/v3 v3.7.0 h1:FTdj0uexT4diYIPlF4yoFVI5MRO1r5+SEcIpEw9vC0o=
+github.com/coreos/go-oidc/v3 v3.7.0/go.mod h1:yQzSCqBnK3e6Fs5l+f5i0F8Kwf0zpH9bPEsbY00KanM=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
@@ -274,8 +272,8 @@ github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 h1:fAjc9m62+UWV/WA
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw=
-github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU=
-github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0=
+github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c=
+github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0=
github.com/dlclark/regexp2 v1.7.0 h1:7lJfhqlPssTb1WQx4yvTHN0uElPEv52sbaECrAQxjAo=
github.com/dlclark/regexp2 v1.7.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/docker/cli v23.0.5+incompatible h1:ufWmAOuD3Vmr7JP2G5K3cyuNC4YZWiAsuDEvFVVDafE=
@@ -359,8 +357,8 @@ github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxF
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
-github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY=
+github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
@@ -624,8 +622,8 @@ github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDS
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
-github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
-github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.1 h1:NE3C767s2ak2bweCZo3+rdP4U/HoyVXLv/X9f2gPS5g=
+github.com/klauspost/compress v1.17.1/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a h1:+RR6SqnTkDLWyICxS1xpjCi/3dhyV+TgZwA6Ww3KncQ=
github.com/kortschak/wol v0.0.0-20200729010619-da482cc4850a/go.mod h1:YTtCCM3ryyfiu4F7t8HQ1mxvp1UBdWM2r6Xa+nGWvDk=
@@ -673,8 +671,8 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
-github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
+github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
+github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -683,8 +681,8 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
-github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
-github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg=
+github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/mdlayher/genetlink v1.3.2 h1:KdrNKe+CTu+IbZnm/GVUMXSqBBLqcGpRDa0xkQy56gw=
github.com/mdlayher/genetlink v1.3.2/go.mod h1:tcC3pkCrPUGIKKsCsp0B3AdaaKuHtaxoJRz3cc+528o=
github.com/mdlayher/netlink v1.7.2 h1:/UtM3ofJap7Vl4QWCPDGXY8d3GIY2UGSDbK+QWmY8/g=
@@ -754,7 +752,6 @@ github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde h1:x0TT0RDC7UhA
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
-github.com/outcaste-io/ristretto v0.2.1/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0=
github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
@@ -788,8 +785,8 @@ github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+L
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw=
github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI=
-github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY=
-github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY=
+github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM=
+github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY=
github.com/prometheus/procfs v0.11.1 h1:xRC8Iq1yyca5ypa9n1EZnWZkt7dwcoRPQwX/5gwaUuI=
github.com/prometheus/procfs v0.11.1/go.mod h1:eesXgaPo1q7lBpVMoMy0ZOFTth9hBn4W/y0/p/ScXhY=
github.com/quasilyte/go-ruleguard/dsl v0.3.21 h1:vNkC6fC6qMLzCOGbnIHOd5ixUGgTbp3Z4fGnUgULlDA=
@@ -982,11 +979,10 @@ go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmY
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
-go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A=
-go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4=
+go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
+go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go4.org/intern v0.0.0-20211027215823-ae77deb06f29/go.mod h1:cS2ma+47FKrLPdXFpr7CuxiTW3eyJbWew4qx0qtQWDA=
go4.org/intern v0.0.0-20230525184215-6c62f75575cb h1:ae7kzL5Cfdmcecbh22ll7lYP3iuUdnfnhiPcSaDgH/8=
go4.org/intern v0.0.0-20230525184215-6c62f75575cb/go.mod h1:Ycrt6raEcnF5FTsLiLKkhBTO6DPX3RCUCUVnks3gFJU=
@@ -1188,6 +1184,7 @@ golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1220,6 +1217,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
@@ -1317,16 +1315,17 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.147.0 h1:Can3FaQo9LlVqxJCodNmeZW/ib3/qKAY3rFeXiHo5gc=
-google.golang.org/api v0.147.0/go.mod h1:pQ/9j83DcmPd/5C9e2nFOdjjNkDZ1G+zkbK2uvdkJMs=
+google.golang.org/api v0.148.0 h1:HBq4TZlN4/1pNcu0geJZ/Q50vIwIXT532UIMYoo0vOs=
+google.golang.org/api v0.148.0/go.mod h1:8/TBgwaKjfqTdacOJrOv2+2Q6fBDU1uHKK06oGSkxzU=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM=
+google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -1366,8 +1365,8 @@ google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97 h1:SeZZZx0cP0fqUyA
google.golang.org/genproto v0.0.0-20231002182017-d307bd883b97/go.mod h1:t1VqOqqvce95G3hIDCT5FeO3YUc6Q4Oe24L/+rNMxRk=
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU=
google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c h1:jHkCUWkseRf+W+edG5hMzr/Uh1xkDREY4caybAq4dpY=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20231009173412-8bfb1ae86b6c/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a h1:a2MQQVoTo96JC9PMGtGBymLp7+/RzpFc2yX/9WfFg1c=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:4cYg8o5yUbm77w8ZX00LhMVNl/YVBFJRYWDc0uYWMs0=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
@@ -1384,8 +1383,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I=
-google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
+google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
+google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
@@ -1402,8 +1401,8 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
-gopkg.in/DataDog/dd-trace-go.v1 v1.55.0 h1:ozWhUpvrDBtZKcRB5flT0waAfnqWz1f5gOf/Y+QIurg=
-gopkg.in/DataDog/dd-trace-go.v1 v1.55.0/go.mod h1:1KvDrWW49v4TPaOAIjZEYdx4ZBrm9sXm5z1s+JIZiWs=
+gopkg.in/DataDog/dd-trace-go.v1 v1.56.1 h1:AUe/ZF7xm6vYnigPe+TY54DmfWYJxhMRaw/TfvrbzvE=
+gopkg.in/DataDog/dd-trace-go.v1 v1.56.1/go.mod h1:KDLJ3CWVOSuVVwu+0ZR5KZo2rP6c7YyBV3v387dIpUU=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go
index 8e22579277f80..e980a26d833fc 100644
--- a/provisioner/terraform/provision.go
+++ b/provisioner/terraform/provision.go
@@ -198,6 +198,7 @@ func provisionEnv(
"CODER_WORKSPACE_OWNER_SESSION_TOKEN="+metadata.GetWorkspaceOwnerSessionToken(),
"CODER_WORKSPACE_TEMPLATE_ID="+metadata.GetTemplateId(),
"CODER_WORKSPACE_TEMPLATE_NAME="+metadata.GetTemplateName(),
+ "CODER_WORKSPACE_TEMPLATE_VERSION="+metadata.GetTemplateVersion(),
)
for key, value := range provisionersdk.AgentScriptEnv() {
env = append(env, key+"="+value)
diff --git a/scripts/dbgen/main.go b/scripts/dbgen/main.go
index ac946ff8a51ad..54b104d04f718 100644
--- a/scripts/dbgen/main.go
+++ b/scripts/dbgen/main.go
@@ -53,11 +53,11 @@ func run() error {
}
databasePath := filepath.Join(localPath, "..", "..", "..", "coderd", "database")
- err = orderAndStubDatabaseFunctions(filepath.Join(databasePath, "dbfake", "dbfake.go"), "q", "FakeQuerier", func(params stubParams) string {
+ err = orderAndStubDatabaseFunctions(filepath.Join(databasePath, "dbmem", "dbmem.go"), "q", "FakeQuerier", func(params stubParams) string {
return `panic("not implemented")`
})
if err != nil {
- return xerrors.Errorf("stub dbfake: %w", err)
+ return xerrors.Errorf("stub dbmem: %w", err)
}
err = orderAndStubDatabaseFunctions(filepath.Join(databasePath, "dbmetrics", "dbmetrics.go"), "m", "metricsStore", func(params stubParams) string {
@@ -257,13 +257,13 @@ func orderAndStubDatabaseFunctions(filePath, receiver, structName string, stub f
contents, err := os.ReadFile(filePath)
if err != nil {
- return xerrors.Errorf("read dbfake: %w", err)
+ return xerrors.Errorf("read dbmem: %w", err)
}
// Required to preserve imports!
f, err := decorator.NewDecoratorWithImports(token.NewFileSet(), packageName, goast.New()).Parse(contents)
if err != nil {
- return xerrors.Errorf("parse dbfake: %w", err)
+ return xerrors.Errorf("parse dbmem: %w", err)
}
pointer := false
@@ -298,8 +298,8 @@ func orderAndStubDatabaseFunctions(filePath, receiver, structName string, stub f
for _, fn := range funcs {
var bodyStmts []dst.Stmt
- // Add input validation, only relevant for dbfake.
- if strings.Contains(filePath, "dbfake") && len(fn.Func.Params.List) == 2 && fn.Func.Params.List[1].Names[0].Name == "arg" {
+ // Add input validation, only relevant for dbmem.
+ if strings.Contains(filePath, "dbmem") && len(fn.Func.Params.List) == 2 && fn.Func.Params.List[1].Names[0].Name == "arg" {
/*
err := validateDatabaseType(arg)
if err != nil {
diff --git a/site/site_test.go b/site/site_test.go
index bf40be9b1cdcf..b240a065fea1b 100644
--- a/site/site_test.go
+++ b/site/site_test.go
@@ -24,8 +24,8 @@ import (
"github.com/coder/coder/v2/coderd/database"
"github.com/coder/coder/v2/coderd/database/db2sdk"
- "github.com/coder/coder/v2/coderd/database/dbfake"
"github.com/coder/coder/v2/coderd/database/dbgen"
+ "github.com/coder/coder/v2/coderd/database/dbmem"
"github.com/coder/coder/v2/coderd/database/dbtime"
"github.com/coder/coder/v2/coderd/httpmw"
"github.com/coder/coder/v2/codersdk"
@@ -42,7 +42,7 @@ func TestInjection(t *testing.T) {
},
}
binFs := http.FS(fstest.MapFS{})
- db := dbfake.New()
+ db := dbmem.New()
handler := site.New(&site.Options{
BinFS: binFs,
Database: db,
@@ -74,7 +74,7 @@ func TestInjection(t *testing.T) {
func TestInjectionFailureProducesCleanHTML(t *testing.T) {
t.Parallel()
- db := dbfake.New()
+ db := dbmem.New()
// Create an expired user with a refresh token, but provide no OAuth2
// configuration so that refresh is impossible, this should result in
diff --git a/site/src/api/queries/appearance.ts b/site/src/api/queries/appearance.ts
index 1e891deb59619..10366b4382d72 100644
--- a/site/src/api/queries/appearance.ts
+++ b/site/src/api/queries/appearance.ts
@@ -6,18 +6,12 @@ import { getMetadataAsJSON } from "utils/metadata";
const initialAppearanceData = getMetadataAsJSON("appearance");
const appearanceConfigKey = ["appearance"] as const;
-export const appearance = (queryClient: QueryClient) => {
+export const appearance = (): UseQueryOptions => {
return {
- queryKey: appearanceConfigKey,
- queryFn: async () => {
- const cachedData = queryClient.getQueryData(appearanceConfigKey);
- if (cachedData === undefined && initialAppearanceData !== undefined) {
- return initialAppearanceData;
- }
-
- return API.getAppearance();
- },
- } satisfies UseQueryOptions;
+ queryKey: ["appearance"],
+ initialData: initialAppearanceData,
+ queryFn: () => API.getAppearance(),
+ };
};
export const updateAppearance = (queryClient: QueryClient) => {
diff --git a/site/src/api/queries/buildInfo.ts b/site/src/api/queries/buildInfo.ts
index c10b458a67fcf..58e61575ef057 100644
--- a/site/src/api/queries/buildInfo.ts
+++ b/site/src/api/queries/buildInfo.ts
@@ -1,4 +1,4 @@
-import { QueryClient, type UseQueryOptions } from "react-query";
+import { type UseQueryOptions } from "react-query";
import { type BuildInfoResponse } from "api/typesGenerated";
import * as API from "api/api";
import { getMetadataAsJSON } from "utils/metadata";
@@ -6,16 +6,10 @@ import { getMetadataAsJSON } from "utils/metadata";
const initialBuildInfoData = getMetadataAsJSON("build-info");
const buildInfoKey = ["buildInfo"] as const;
-export const buildInfo = (queryClient: QueryClient) => {
+export const buildInfo = (): UseQueryOptions => {
return {
queryKey: buildInfoKey,
- queryFn: async () => {
- const cachedData = queryClient.getQueryData(buildInfoKey);
- if (cachedData === undefined && initialBuildInfoData !== undefined) {
- return initialBuildInfoData;
- }
-
- return API.getBuildInfo();
- },
- } satisfies UseQueryOptions;
+ initialData: initialBuildInfoData,
+ queryFn: () => API.getBuildInfo(),
+ };
};
diff --git a/site/src/api/queries/entitlements.ts b/site/src/api/queries/entitlements.ts
index 271d0bbf821ee..6cb0bf9c2572e 100644
--- a/site/src/api/queries/entitlements.ts
+++ b/site/src/api/queries/entitlements.ts
@@ -1,15 +1,16 @@
-import { QueryClient } from "react-query";
+import { QueryClient, UseQueryOptions } from "react-query";
import * as API from "api/api";
import { Entitlements } from "api/typesGenerated";
import { getMetadataAsJSON } from "utils/metadata";
-const ENTITLEMENTS_QUERY_KEY = ["entitlements"];
+const initialEntitlementsData = getMetadataAsJSON("entitlements");
+const ENTITLEMENTS_QUERY_KEY = ["entitlements"] as const;
-export const entitlements = () => {
+export const entitlements = (): UseQueryOptions => {
return {
queryKey: ENTITLEMENTS_QUERY_KEY,
- queryFn: async () =>
- getMetadataAsJSON("entitlements") ?? API.getEntitlements(),
+ queryFn: () => API.getEntitlements(),
+ initialData: initialEntitlementsData,
};
};
diff --git a/site/src/api/queries/experiments.ts b/site/src/api/queries/experiments.ts
index 3d3618819fe77..aa12d5152411b 100644
--- a/site/src/api/queries/experiments.ts
+++ b/site/src/api/queries/experiments.ts
@@ -1,22 +1,16 @@
import * as API from "api/api";
import { getMetadataAsJSON } from "utils/metadata";
import { type Experiments } from "api/typesGenerated";
-import { QueryClient, type UseQueryOptions } from "react-query";
+import { type UseQueryOptions } from "react-query";
const initialExperimentsData = getMetadataAsJSON("experiments");
const experimentsKey = ["experiments"] as const;
-export const experiments = (queryClient: QueryClient) => {
+export const experiments = (): UseQueryOptions => {
return {
queryKey: experimentsKey,
- queryFn: async () => {
- const cachedData = queryClient.getQueryData(experimentsKey);
- if (cachedData === undefined && initialExperimentsData !== undefined) {
- return initialExperimentsData;
- }
-
- return API.getExperiments();
- },
+ initialData: initialExperimentsData,
+ queryFn: () => API.getExperiments(),
} satisfies UseQueryOptions;
};
diff --git a/site/src/api/queries/users.ts b/site/src/api/queries/users.ts
index 8f335c6525f7b..2b6900df13ac8 100644
--- a/site/src/api/queries/users.ts
+++ b/site/src/api/queries/users.ts
@@ -91,7 +91,9 @@ export const authMethods = () => {
const initialUserData = getMetadataAsJSON("user");
-export const me = () => {
+export const me = (): UseQueryOptions & {
+ queryKey: NonNullable["queryKey"]>;
+} => {
return {
queryKey: ["me"],
initialData: initialUserData,
diff --git a/site/src/components/Dashboard/DashboardProvider.tsx b/site/src/components/Dashboard/DashboardProvider.tsx
index 7e06b4a656620..ae05ff0ae7447 100644
--- a/site/src/components/Dashboard/DashboardProvider.tsx
+++ b/site/src/components/Dashboard/DashboardProvider.tsx
@@ -1,4 +1,4 @@
-import { useQuery, useQueryClient } from "react-query";
+import { useQuery } from "react-query";
import { buildInfo } from "api/queries/buildInfo";
import { experiments } from "api/queries/experiments";
import { entitlements } from "api/queries/entitlements";
@@ -39,11 +39,10 @@ export const DashboardProviderContext = createContext<
>(undefined);
export const DashboardProvider: FC = ({ children }) => {
- const queryClient = useQueryClient();
- const buildInfoQuery = useQuery(buildInfo(queryClient));
+ const buildInfoQuery = useQuery(buildInfo());
const entitlementsQuery = useQuery(entitlements());
- const experimentsQuery = useQuery(experiments(queryClient));
- const appearanceQuery = useQuery(appearance(queryClient));
+ const experimentsQuery = useQuery(experiments());
+ const appearanceQuery = useQuery(appearance());
const isLoading =
!buildInfoQuery.data ||
diff --git a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
index d42004b758914..8cc955b596d4c 100644
--- a/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
+++ b/site/src/pages/ExternalAuthPage/ExternalAuthPage.tsx
@@ -6,16 +6,21 @@ import {
} from "api/api";
import { usePermissions } from "hooks";
import { type FC } from "react";
-import { useParams } from "react-router-dom";
+import { useParams, useSearchParams } from "react-router-dom";
import ExternalAuthPageView from "./ExternalAuthPageView";
import { ApiErrorResponse } from "api/errors";
import { isAxiosError } from "axios";
+import Box from "@mui/material/Box";
+import Button from "@mui/material/Button";
+import { SignInLayout } from "components/SignInLayout/SignInLayout";
+import { Welcome } from "components/Welcome/Welcome";
const ExternalAuthPage: FC = () => {
const { provider } = useParams();
if (!provider) {
throw new Error("provider must exist");
}
+ const [searchParams] = useSearchParams();
const permissions = usePermissions();
const queryClient = useQueryClient();
const getExternalAuthProviderQuery = useQuery({
@@ -72,6 +77,35 @@ const ExternalAuthPage: FC = () => {
!getExternalAuthProviderQuery.data.authenticated &&
!getExternalAuthProviderQuery.data.device
) {
+ const redirectedParam = searchParams?.get("redirected");
+ if (redirectedParam && redirectedParam.toLowerCase() === "true") {
+ // The auth flow redirected the user here. If we redirect back to the
+ // callback, that resets the flow and we'll end up in an infinite loop.
+ // So instead, show an error, as the user expects to be authenticated at
+ // this point.
+ // TODO: Unsure what to do about the device auth flow, should we also
+ // show an error there?
+ return (
+
+
+
+ Attempted to validate the user's oauth access token from the
+ authentication flow. This situation may occur as a result of an
+ external authentication provider misconfiguration. Verify the
+ external authentication validation URL is accurately configured.
+
+
+
+
+ );
+ }
window.location.href = `/external-auth/${provider}/callback`;
return null;
}
diff --git a/site/src/pages/TerminalPage/TerminalPage.tsx b/site/src/pages/TerminalPage/TerminalPage.tsx
index c3844fe051cd6..7c82c82a1f5bb 100644
--- a/site/src/pages/TerminalPage/TerminalPage.tsx
+++ b/site/src/pages/TerminalPage/TerminalPage.tsx
@@ -54,7 +54,6 @@ const TerminalPage: FC = () => {
const [terminalState, setTerminalState] = useState<
"connected" | "disconnected" | "initializing"
>("initializing");
- const [fitAddon, setFitAddon] = useState(null);
const [searchParams] = useSearchParams();
// The reconnection token is a unique token that identifies
// a terminal session. It's generated by the client to reduce
@@ -125,7 +124,6 @@ const TerminalPage: FC = () => {
terminal.loadAddon(new CanvasAddon());
}
const fitAddon = new FitAddon();
- setFitAddon(fitAddon);
terminal.loadAddon(fitAddon);
terminal.loadAddon(new Unicode11Addon());
terminal.unicode.activeVersion = "11";
@@ -134,13 +132,21 @@ const TerminalPage: FC = () => {
handleWebLinkRef.current(uri);
}),
);
- setTerminal(terminal);
+
terminal.open(xtermRef.current);
- const listener = () => {
- // This will trigger a resize event on the terminal.
- fitAddon.fit();
- };
+
+ // We have to fit twice here. It's unknown why, but the first fit will
+ // overflow slightly in some scenarios. Applying a second fit resolves this.
+ fitAddon.fit();
+ fitAddon.fit();
+
+ // This will trigger a resize event on the terminal.
+ const listener = () => fitAddon.fit();
window.addEventListener("resize", listener);
+
+ // Terminal is correctly sized and is ready to be used.
+ setTerminal(terminal);
+
return () => {
window.removeEventListener("resize", listener);
terminal.dispose();
@@ -165,16 +171,10 @@ const TerminalPage: FC = () => {
// Hook up the terminal through a web socket.
useEffect(() => {
- if (!terminal || !fitAddon) {
+ if (!terminal) {
return;
}
- // We have to fit twice here. It's unknown why, but
- // the first fit will overflow slightly in some
- // scenarios. Applying a second fit resolves this.
- fitAddon.fit();
- fitAddon.fit();
-
// The terminal should be cleared on each reconnect
// because all data is re-rendered from the backend.
terminal.clear();
@@ -229,6 +229,8 @@ const TerminalPage: FC = () => {
reconnectionToken,
workspaceAgent.id,
command,
+ terminal.rows,
+ terminal.cols,
)
.then((url) => {
if (disposed) {
@@ -289,7 +291,6 @@ const TerminalPage: FC = () => {
};
}, [
command,
- fitAddon,
proxy.preferredPathAppURL,
reconnectionToken,
terminal,
diff --git a/site/src/utils/terminal.ts b/site/src/utils/terminal.ts
index 52d46feaafcf6..d27a6efce379c 100644
--- a/site/src/utils/terminal.ts
+++ b/site/src/utils/terminal.ts
@@ -5,11 +5,15 @@ export const terminalWebsocketUrl = async (
reconnect: string,
agentId: string,
command: string | undefined,
+ height: number,
+ width: number,
): Promise => {
const query = new URLSearchParams({ reconnect });
if (command) {
query.set("command", command);
}
+ query.set("height", height.toString());
+ query.set("width", width.toString());
const url = new URL(baseUrl || `${location.protocol}//${location.host}`);
url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
diff --git a/tailnet/proto/tailnet.pb.go b/tailnet/proto/tailnet.pb.go
new file mode 100644
index 0000000000000..c5318fa7df5d4
--- /dev/null
+++ b/tailnet/proto/tailnet.pb.go
@@ -0,0 +1,1295 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// versions:
+// protoc-gen-go v1.30.0
+// protoc v4.23.3
+// source: tailnet/proto/tailnet.proto
+
+package proto
+
+import (
+ protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+ protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+ timestamppb "google.golang.org/protobuf/types/known/timestamppb"
+ reflect "reflect"
+ sync "sync"
+)
+
+const (
+ // Verify that this generated code is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
+ // Verify that runtime/protoimpl is sufficiently up-to-date.
+ _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
+)
+
+type CoordinateResponse_PeerUpdate_Kind int32
+
+const (
+ CoordinateResponse_PeerUpdate_KIND_UNSPECIFIED CoordinateResponse_PeerUpdate_Kind = 0
+ CoordinateResponse_PeerUpdate_NODE CoordinateResponse_PeerUpdate_Kind = 1
+ CoordinateResponse_PeerUpdate_DISCONNECTED CoordinateResponse_PeerUpdate_Kind = 2
+ CoordinateResponse_PeerUpdate_LOST CoordinateResponse_PeerUpdate_Kind = 3
+)
+
+// Enum value maps for CoordinateResponse_PeerUpdate_Kind.
+var (
+ CoordinateResponse_PeerUpdate_Kind_name = map[int32]string{
+ 0: "KIND_UNSPECIFIED",
+ 1: "NODE",
+ 2: "DISCONNECTED",
+ 3: "LOST",
+ }
+ CoordinateResponse_PeerUpdate_Kind_value = map[string]int32{
+ "KIND_UNSPECIFIED": 0,
+ "NODE": 1,
+ "DISCONNECTED": 2,
+ "LOST": 3,
+ }
+)
+
+func (x CoordinateResponse_PeerUpdate_Kind) Enum() *CoordinateResponse_PeerUpdate_Kind {
+ p := new(CoordinateResponse_PeerUpdate_Kind)
+ *p = x
+ return p
+}
+
+func (x CoordinateResponse_PeerUpdate_Kind) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (CoordinateResponse_PeerUpdate_Kind) Descriptor() protoreflect.EnumDescriptor {
+ return file_tailnet_proto_tailnet_proto_enumTypes[0].Descriptor()
+}
+
+func (CoordinateResponse_PeerUpdate_Kind) Type() protoreflect.EnumType {
+ return &file_tailnet_proto_tailnet_proto_enumTypes[0]
+}
+
+func (x CoordinateResponse_PeerUpdate_Kind) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Use CoordinateResponse_PeerUpdate_Kind.Descriptor instead.
+func (CoordinateResponse_PeerUpdate_Kind) EnumDescriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{4, 0, 0}
+}
+
+type DERPMap struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ HomeParams *DERPMap_HomeParams `protobuf:"bytes,1,opt,name=home_params,json=homeParams,proto3" json:"home_params,omitempty"`
+ Regions map[int32]*DERPMap_Region `protobuf:"bytes,2,rep,name=regions,proto3" json:"regions,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (x *DERPMap) Reset() {
+ *x = DERPMap{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[0]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DERPMap) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DERPMap) ProtoMessage() {}
+
+func (x *DERPMap) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[0]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DERPMap.ProtoReflect.Descriptor instead.
+func (*DERPMap) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *DERPMap) GetHomeParams() *DERPMap_HomeParams {
+ if x != nil {
+ return x.HomeParams
+ }
+ return nil
+}
+
+func (x *DERPMap) GetRegions() map[int32]*DERPMap_Region {
+ if x != nil {
+ return x.Regions
+ }
+ return nil
+}
+
+type StreamDERPMapsRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *StreamDERPMapsRequest) Reset() {
+ *x = StreamDERPMapsRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[1]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StreamDERPMapsRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StreamDERPMapsRequest) ProtoMessage() {}
+
+func (x *StreamDERPMapsRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[1]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StreamDERPMapsRequest.ProtoReflect.Descriptor instead.
+func (*StreamDERPMapsRequest) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{1}
+}
+
+// defined in tailnet/coordinator.go
+type Node struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Id int64 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"`
+ AsOf *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=as_of,json=asOf,proto3" json:"as_of,omitempty"`
+ Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"`
+ Disco string `protobuf:"bytes,4,opt,name=disco,proto3" json:"disco,omitempty"`
+ PreferredDerp int32 `protobuf:"varint,5,opt,name=preferred_derp,json=preferredDerp,proto3" json:"preferred_derp,omitempty"`
+ DerpLatency map[string]float64 `protobuf:"bytes,6,rep,name=derp_latency,json=derpLatency,proto3" json:"derp_latency,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"fixed64,2,opt,name=value,proto3"`
+ DerpForcedWebsocket map[int32]string `protobuf:"bytes,7,rep,name=derp_forced_websocket,json=derpForcedWebsocket,proto3" json:"derp_forced_websocket,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+ Addresses []string `protobuf:"bytes,8,rep,name=addresses,proto3" json:"addresses,omitempty"`
+ AllowedIps []string `protobuf:"bytes,9,rep,name=allowed_ips,json=allowedIps,proto3" json:"allowed_ips,omitempty"`
+ Endpoints []string `protobuf:"bytes,10,rep,name=endpoints,proto3" json:"endpoints,omitempty"`
+}
+
+func (x *Node) Reset() {
+ *x = Node{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[2]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *Node) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Node) ProtoMessage() {}
+
+func (x *Node) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[2]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use Node.ProtoReflect.Descriptor instead.
+func (*Node) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *Node) GetId() int64 {
+ if x != nil {
+ return x.Id
+ }
+ return 0
+}
+
+func (x *Node) GetAsOf() *timestamppb.Timestamp {
+ if x != nil {
+ return x.AsOf
+ }
+ return nil
+}
+
+func (x *Node) GetKey() []byte {
+ if x != nil {
+ return x.Key
+ }
+ return nil
+}
+
+func (x *Node) GetDisco() string {
+ if x != nil {
+ return x.Disco
+ }
+ return ""
+}
+
+func (x *Node) GetPreferredDerp() int32 {
+ if x != nil {
+ return x.PreferredDerp
+ }
+ return 0
+}
+
+func (x *Node) GetDerpLatency() map[string]float64 {
+ if x != nil {
+ return x.DerpLatency
+ }
+ return nil
+}
+
+func (x *Node) GetDerpForcedWebsocket() map[int32]string {
+ if x != nil {
+ return x.DerpForcedWebsocket
+ }
+ return nil
+}
+
+func (x *Node) GetAddresses() []string {
+ if x != nil {
+ return x.Addresses
+ }
+ return nil
+}
+
+func (x *Node) GetAllowedIps() []string {
+ if x != nil {
+ return x.AllowedIps
+ }
+ return nil
+}
+
+func (x *Node) GetEndpoints() []string {
+ if x != nil {
+ return x.Endpoints
+ }
+ return nil
+}
+
+type CoordinateRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ UpdateSelf *CoordinateRequest_UpdateSelf `protobuf:"bytes,1,opt,name=update_self,json=updateSelf,proto3" json:"update_self,omitempty"`
+ Disconnect *CoordinateRequest_Disconnect `protobuf:"bytes,2,opt,name=disconnect,proto3" json:"disconnect,omitempty"`
+ AddTunnel *CoordinateRequest_Tunnel `protobuf:"bytes,3,opt,name=add_tunnel,json=addTunnel,proto3" json:"add_tunnel,omitempty"`
+ RemoveTunnel *CoordinateRequest_Tunnel `protobuf:"bytes,4,opt,name=remove_tunnel,json=removeTunnel,proto3" json:"remove_tunnel,omitempty"`
+}
+
+func (x *CoordinateRequest) Reset() {
+ *x = CoordinateRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[3]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateRequest) ProtoMessage() {}
+
+func (x *CoordinateRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[3]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateRequest.ProtoReflect.Descriptor instead.
+func (*CoordinateRequest) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{3}
+}
+
+func (x *CoordinateRequest) GetUpdateSelf() *CoordinateRequest_UpdateSelf {
+ if x != nil {
+ return x.UpdateSelf
+ }
+ return nil
+}
+
+func (x *CoordinateRequest) GetDisconnect() *CoordinateRequest_Disconnect {
+ if x != nil {
+ return x.Disconnect
+ }
+ return nil
+}
+
+func (x *CoordinateRequest) GetAddTunnel() *CoordinateRequest_Tunnel {
+ if x != nil {
+ return x.AddTunnel
+ }
+ return nil
+}
+
+func (x *CoordinateRequest) GetRemoveTunnel() *CoordinateRequest_Tunnel {
+ if x != nil {
+ return x.RemoveTunnel
+ }
+ return nil
+}
+
+type CoordinateResponse struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ PeerUpdates []*CoordinateResponse_PeerUpdate `protobuf:"bytes,1,rep,name=peer_updates,json=peerUpdates,proto3" json:"peer_updates,omitempty"`
+}
+
+func (x *CoordinateResponse) Reset() {
+ *x = CoordinateResponse{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[4]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateResponse) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateResponse) ProtoMessage() {}
+
+func (x *CoordinateResponse) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[4]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateResponse.ProtoReflect.Descriptor instead.
+func (*CoordinateResponse) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{4}
+}
+
+func (x *CoordinateResponse) GetPeerUpdates() []*CoordinateResponse_PeerUpdate {
+ if x != nil {
+ return x.PeerUpdates
+ }
+ return nil
+}
+
+type DERPMap_HomeParams struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RegionScore map[int32]float64 `protobuf:"bytes,1,rep,name=region_score,json=regionScore,proto3" json:"region_score,omitempty" protobuf_key:"varint,1,opt,name=key,proto3" protobuf_val:"fixed64,2,opt,name=value,proto3"`
+}
+
+func (x *DERPMap_HomeParams) Reset() {
+ *x = DERPMap_HomeParams{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[5]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DERPMap_HomeParams) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DERPMap_HomeParams) ProtoMessage() {}
+
+func (x *DERPMap_HomeParams) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[5]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DERPMap_HomeParams.ProtoReflect.Descriptor instead.
+func (*DERPMap_HomeParams) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{0, 0}
+}
+
+func (x *DERPMap_HomeParams) GetRegionScore() map[int32]float64 {
+ if x != nil {
+ return x.RegionScore
+ }
+ return nil
+}
+
+type DERPMap_Region struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ RegionId int32 `protobuf:"varint,1,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"`
+ EmbeddedRelay bool `protobuf:"varint,2,opt,name=embedded_relay,json=embeddedRelay,proto3" json:"embedded_relay,omitempty"`
+ RegionCode string `protobuf:"bytes,3,opt,name=region_code,json=regionCode,proto3" json:"region_code,omitempty"`
+ RegionName string `protobuf:"bytes,4,opt,name=region_name,json=regionName,proto3" json:"region_name,omitempty"`
+ Avoid bool `protobuf:"varint,5,opt,name=avoid,proto3" json:"avoid,omitempty"`
+ Nodes []*DERPMap_Region_Node `protobuf:"bytes,6,rep,name=nodes,proto3" json:"nodes,omitempty"`
+}
+
+func (x *DERPMap_Region) Reset() {
+ *x = DERPMap_Region{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[6]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DERPMap_Region) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DERPMap_Region) ProtoMessage() {}
+
+func (x *DERPMap_Region) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[6]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DERPMap_Region.ProtoReflect.Descriptor instead.
+func (*DERPMap_Region) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{0, 1}
+}
+
+func (x *DERPMap_Region) GetRegionId() int32 {
+ if x != nil {
+ return x.RegionId
+ }
+ return 0
+}
+
+func (x *DERPMap_Region) GetEmbeddedRelay() bool {
+ if x != nil {
+ return x.EmbeddedRelay
+ }
+ return false
+}
+
+func (x *DERPMap_Region) GetRegionCode() string {
+ if x != nil {
+ return x.RegionCode
+ }
+ return ""
+}
+
+func (x *DERPMap_Region) GetRegionName() string {
+ if x != nil {
+ return x.RegionName
+ }
+ return ""
+}
+
+func (x *DERPMap_Region) GetAvoid() bool {
+ if x != nil {
+ return x.Avoid
+ }
+ return false
+}
+
+func (x *DERPMap_Region) GetNodes() []*DERPMap_Region_Node {
+ if x != nil {
+ return x.Nodes
+ }
+ return nil
+}
+
+type DERPMap_Region_Node struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ RegionId int32 `protobuf:"varint,2,opt,name=region_id,json=regionId,proto3" json:"region_id,omitempty"`
+ HostName string `protobuf:"bytes,3,opt,name=host_name,json=hostName,proto3" json:"host_name,omitempty"`
+ CertName string `protobuf:"bytes,4,opt,name=cert_name,json=certName,proto3" json:"cert_name,omitempty"`
+ Ipv4 string `protobuf:"bytes,5,opt,name=ipv4,proto3" json:"ipv4,omitempty"`
+ Ipv6 string `protobuf:"bytes,6,opt,name=ipv6,proto3" json:"ipv6,omitempty"`
+ StunPort int32 `protobuf:"varint,7,opt,name=stun_port,json=stunPort,proto3" json:"stun_port,omitempty"`
+ StunOnly bool `protobuf:"varint,8,opt,name=stun_only,json=stunOnly,proto3" json:"stun_only,omitempty"`
+ DerpPort int32 `protobuf:"varint,9,opt,name=derp_port,json=derpPort,proto3" json:"derp_port,omitempty"`
+ InsecureForTests bool `protobuf:"varint,10,opt,name=insecure_for_tests,json=insecureForTests,proto3" json:"insecure_for_tests,omitempty"`
+ ForceHttp bool `protobuf:"varint,11,opt,name=force_http,json=forceHttp,proto3" json:"force_http,omitempty"`
+ StunTestIp string `protobuf:"bytes,12,opt,name=stun_test_ip,json=stunTestIp,proto3" json:"stun_test_ip,omitempty"`
+ CanPort_80 bool `protobuf:"varint,13,opt,name=can_port_80,json=canPort80,proto3" json:"can_port_80,omitempty"`
+}
+
+func (x *DERPMap_Region_Node) Reset() {
+ *x = DERPMap_Region_Node{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *DERPMap_Region_Node) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*DERPMap_Region_Node) ProtoMessage() {}
+
+func (x *DERPMap_Region_Node) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[9]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use DERPMap_Region_Node.ProtoReflect.Descriptor instead.
+func (*DERPMap_Region_Node) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{0, 1, 0}
+}
+
+func (x *DERPMap_Region_Node) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetRegionId() int32 {
+ if x != nil {
+ return x.RegionId
+ }
+ return 0
+}
+
+func (x *DERPMap_Region_Node) GetHostName() string {
+ if x != nil {
+ return x.HostName
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetCertName() string {
+ if x != nil {
+ return x.CertName
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetIpv4() string {
+ if x != nil {
+ return x.Ipv4
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetIpv6() string {
+ if x != nil {
+ return x.Ipv6
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetStunPort() int32 {
+ if x != nil {
+ return x.StunPort
+ }
+ return 0
+}
+
+func (x *DERPMap_Region_Node) GetStunOnly() bool {
+ if x != nil {
+ return x.StunOnly
+ }
+ return false
+}
+
+func (x *DERPMap_Region_Node) GetDerpPort() int32 {
+ if x != nil {
+ return x.DerpPort
+ }
+ return 0
+}
+
+func (x *DERPMap_Region_Node) GetInsecureForTests() bool {
+ if x != nil {
+ return x.InsecureForTests
+ }
+ return false
+}
+
+func (x *DERPMap_Region_Node) GetForceHttp() bool {
+ if x != nil {
+ return x.ForceHttp
+ }
+ return false
+}
+
+func (x *DERPMap_Region_Node) GetStunTestIp() string {
+ if x != nil {
+ return x.StunTestIp
+ }
+ return ""
+}
+
+func (x *DERPMap_Region_Node) GetCanPort_80() bool {
+ if x != nil {
+ return x.CanPort_80
+ }
+ return false
+}
+
+type CoordinateRequest_UpdateSelf struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Node *Node `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"`
+}
+
+func (x *CoordinateRequest_UpdateSelf) Reset() {
+ *x = CoordinateRequest_UpdateSelf{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[12]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateRequest_UpdateSelf) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateRequest_UpdateSelf) ProtoMessage() {}
+
+func (x *CoordinateRequest_UpdateSelf) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[12]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateRequest_UpdateSelf.ProtoReflect.Descriptor instead.
+func (*CoordinateRequest_UpdateSelf) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{3, 0}
+}
+
+func (x *CoordinateRequest_UpdateSelf) GetNode() *Node {
+ if x != nil {
+ return x.Node
+ }
+ return nil
+}
+
+type CoordinateRequest_Disconnect struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *CoordinateRequest_Disconnect) Reset() {
+ *x = CoordinateRequest_Disconnect{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[13]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateRequest_Disconnect) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateRequest_Disconnect) ProtoMessage() {}
+
+func (x *CoordinateRequest_Disconnect) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[13]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateRequest_Disconnect.ProtoReflect.Descriptor instead.
+func (*CoordinateRequest_Disconnect) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{3, 1}
+}
+
+type CoordinateRequest_Tunnel struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"`
+}
+
+func (x *CoordinateRequest_Tunnel) Reset() {
+ *x = CoordinateRequest_Tunnel{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[14]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateRequest_Tunnel) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateRequest_Tunnel) ProtoMessage() {}
+
+func (x *CoordinateRequest_Tunnel) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[14]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateRequest_Tunnel.ProtoReflect.Descriptor instead.
+func (*CoordinateRequest_Tunnel) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{3, 2}
+}
+
+func (x *CoordinateRequest_Tunnel) GetUuid() []byte {
+ if x != nil {
+ return x.Uuid
+ }
+ return nil
+}
+
+type CoordinateResponse_PeerUpdate struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Uuid []byte `protobuf:"bytes,1,opt,name=uuid,proto3" json:"uuid,omitempty"`
+ Node *Node `protobuf:"bytes,2,opt,name=node,proto3" json:"node,omitempty"`
+ Kind CoordinateResponse_PeerUpdate_Kind `protobuf:"varint,3,opt,name=kind,proto3,enum=coder.tailnet.v2.CoordinateResponse_PeerUpdate_Kind" json:"kind,omitempty"`
+ Reason string `protobuf:"bytes,4,opt,name=reason,proto3" json:"reason,omitempty"`
+}
+
+func (x *CoordinateResponse_PeerUpdate) Reset() {
+ *x = CoordinateResponse_PeerUpdate{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[15]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *CoordinateResponse_PeerUpdate) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CoordinateResponse_PeerUpdate) ProtoMessage() {}
+
+func (x *CoordinateResponse_PeerUpdate) ProtoReflect() protoreflect.Message {
+ mi := &file_tailnet_proto_tailnet_proto_msgTypes[15]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use CoordinateResponse_PeerUpdate.ProtoReflect.Descriptor instead.
+func (*CoordinateResponse_PeerUpdate) Descriptor() ([]byte, []int) {
+ return file_tailnet_proto_tailnet_proto_rawDescGZIP(), []int{4, 0}
+}
+
+func (x *CoordinateResponse_PeerUpdate) GetUuid() []byte {
+ if x != nil {
+ return x.Uuid
+ }
+ return nil
+}
+
+func (x *CoordinateResponse_PeerUpdate) GetNode() *Node {
+ if x != nil {
+ return x.Node
+ }
+ return nil
+}
+
+func (x *CoordinateResponse_PeerUpdate) GetKind() CoordinateResponse_PeerUpdate_Kind {
+ if x != nil {
+ return x.Kind
+ }
+ return CoordinateResponse_PeerUpdate_KIND_UNSPECIFIED
+}
+
+func (x *CoordinateResponse_PeerUpdate) GetReason() string {
+ if x != nil {
+ return x.Reason
+ }
+ return ""
+}
+
+var File_tailnet_proto_tailnet_proto protoreflect.FileDescriptor
+
+var file_tailnet_proto_tailnet_proto_rawDesc = []byte{
+ 0x0a, 0x1b, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f,
+ 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x10, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x1a,
+ 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
+ 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
+ 0x22, 0xff, 0x07, 0x0a, 0x07, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x12, 0x45, 0x0a, 0x0b,
+ 0x68, 0x6f, 0x6d, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x0b, 0x32, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65,
+ 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x2e, 0x48, 0x6f, 0x6d,
+ 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x52, 0x0a, 0x68, 0x6f, 0x6d, 0x65, 0x50, 0x61, 0x72,
+ 0x61, 0x6d, 0x73, 0x12, 0x40, 0x0a, 0x07, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x02,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69,
+ 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x2e,
+ 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x72, 0x65,
+ 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x1a, 0xa6, 0x01, 0x0a, 0x0a, 0x48, 0x6f, 0x6d, 0x65, 0x50, 0x61,
+ 0x72, 0x61, 0x6d, 0x73, 0x12, 0x58, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x73,
+ 0x63, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45,
+ 0x52, 0x50, 0x4d, 0x61, 0x70, 0x2e, 0x48, 0x6f, 0x6d, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73,
+ 0x2e, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x45, 0x6e, 0x74, 0x72,
+ 0x79, 0x52, 0x0b, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x1a, 0x3e,
+ 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x45, 0x6e, 0x74,
+ 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
+ 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0xe3,
+ 0x04, 0x0a, 0x06, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67,
+ 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x72, 0x65,
+ 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64,
+ 0x65, 0x64, 0x5f, 0x72, 0x65, 0x6c, 0x61, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d,
+ 0x65, 0x6d, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x52, 0x65, 0x6c, 0x61, 0x79, 0x12, 0x1f, 0x0a,
+ 0x0b, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x1f,
+ 0x0a, 0x0b, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12,
+ 0x14, 0x0a, 0x05, 0x61, 0x76, 0x6f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05,
+ 0x61, 0x76, 0x6f, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x05, 0x6e, 0x6f, 0x64, 0x65, 0x73, 0x18, 0x06,
+ 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69,
+ 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x2e,
+ 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x05, 0x6e, 0x6f, 0x64,
+ 0x65, 0x73, 0x1a, 0xff, 0x02, 0x0a, 0x04, 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
+ 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01,
+ 0x28, 0x05, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09,
+ 0x68, 0x6f, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x08, 0x68, 0x6f, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x65, 0x72,
+ 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x65,
+ 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70, 0x76, 0x34, 0x18, 0x05,
+ 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76, 0x34, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x70,
+ 0x76, 0x36, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x70, 0x76, 0x36, 0x12, 0x1b,
+ 0x0a, 0x09, 0x73, 0x74, 0x75, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x08, 0x73, 0x74, 0x75, 0x6e, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x73,
+ 0x74, 0x75, 0x6e, 0x5f, 0x6f, 0x6e, 0x6c, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
+ 0x73, 0x74, 0x75, 0x6e, 0x4f, 0x6e, 0x6c, 0x79, 0x12, 0x1b, 0x0a, 0x09, 0x64, 0x65, 0x72, 0x70,
+ 0x5f, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x64, 0x65, 0x72,
+ 0x70, 0x50, 0x6f, 0x72, 0x74, 0x12, 0x2c, 0x0a, 0x12, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72,
+ 0x65, 0x5f, 0x66, 0x6f, 0x72, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28,
+ 0x08, 0x52, 0x10, 0x69, 0x6e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x46, 0x6f, 0x72, 0x54, 0x65,
+ 0x73, 0x74, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x5f, 0x68, 0x74, 0x74,
+ 0x70, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x48, 0x74,
+ 0x74, 0x70, 0x12, 0x20, 0x0a, 0x0c, 0x73, 0x74, 0x75, 0x6e, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x5f,
+ 0x69, 0x70, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x74, 0x75, 0x6e, 0x54, 0x65,
+ 0x73, 0x74, 0x49, 0x70, 0x12, 0x1e, 0x0a, 0x0b, 0x63, 0x61, 0x6e, 0x5f, 0x70, 0x6f, 0x72, 0x74,
+ 0x5f, 0x38, 0x30, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x63, 0x61, 0x6e, 0x50, 0x6f,
+ 0x72, 0x74, 0x38, 0x30, 0x1a, 0x5c, 0x0a, 0x0c, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x73, 0x45,
+ 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x36, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61,
+ 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70,
+ 0x2e, 0x52, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
+ 0x38, 0x01, 0x22, 0x17, 0x0a, 0x15, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x45, 0x52, 0x50,
+ 0x4d, 0x61, 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xac, 0x04, 0x0a, 0x04,
+ 0x4e, 0x6f, 0x64, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03,
+ 0x52, 0x02, 0x69, 0x64, 0x12, 0x2f, 0x0a, 0x05, 0x61, 0x73, 0x5f, 0x6f, 0x66, 0x18, 0x02, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f,
+ 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52,
+ 0x04, 0x61, 0x73, 0x4f, 0x66, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x0c, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x69, 0x73, 0x63, 0x6f,
+ 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x12, 0x25, 0x0a,
+ 0x0e, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64, 0x5f, 0x64, 0x65, 0x72, 0x70, 0x18,
+ 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x72, 0x65, 0x64,
+ 0x44, 0x65, 0x72, 0x70, 0x12, 0x4a, 0x0a, 0x0c, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x6c, 0x61, 0x74,
+ 0x65, 0x6e, 0x63, 0x79, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x27, 0x2e, 0x63, 0x6f, 0x64,
+ 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f,
+ 0x64, 0x65, 0x2e, 0x44, 0x65, 0x72, 0x70, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x45, 0x6e,
+ 0x74, 0x72, 0x79, 0x52, 0x0b, 0x64, 0x65, 0x72, 0x70, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79,
+ 0x12, 0x63, 0x0a, 0x15, 0x64, 0x65, 0x72, 0x70, 0x5f, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x5f,
+ 0x77, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32,
+ 0x2f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e,
+ 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x2e, 0x44, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, 0x63,
+ 0x65, 0x64, 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79,
+ 0x52, 0x13, 0x64, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x64, 0x57, 0x65, 0x62, 0x73,
+ 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73,
+ 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73,
+ 0x73, 0x65, 0x73, 0x12, 0x1f, 0x0a, 0x0b, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65, 0x64, 0x5f, 0x69,
+ 0x70, 0x73, 0x18, 0x09, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0a, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x65,
+ 0x64, 0x49, 0x70, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74,
+ 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e,
+ 0x74, 0x73, 0x1a, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x72, 0x70, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63,
+ 0x79, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
+ 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
+ 0x38, 0x01, 0x1a, 0x46, 0x0a, 0x18, 0x44, 0x65, 0x72, 0x70, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x64,
+ 0x57, 0x65, 0x62, 0x73, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10,
+ 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79,
+ 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xb6, 0x03, 0x0a, 0x11, 0x43,
+ 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x12, 0x4f, 0x0a, 0x0b, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x65, 0x6c, 0x66, 0x18,
+ 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61,
+ 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e,
+ 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x53, 0x65, 0x6c, 0x66, 0x52, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c,
+ 0x66, 0x12, 0x4e, 0x0a, 0x0a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61,
+ 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e,
+ 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x0a, 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
+ 0x74, 0x12, 0x49, 0x0a, 0x0a, 0x61, 0x64, 0x64, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18,
+ 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61,
+ 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e,
+ 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65,
+ 0x6c, 0x52, 0x09, 0x61, 0x64, 0x64, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x4f, 0x0a, 0x0d,
+ 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x5f, 0x74, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x04, 0x20,
+ 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c,
+ 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74,
+ 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x52,
+ 0x0c, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x38, 0x0a,
+ 0x0a, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x53, 0x65, 0x6c, 0x66, 0x12, 0x2a, 0x0a, 0x04, 0x6e,
+ 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64,
+ 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x1a, 0x0c, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f,
+ 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x1a, 0x1c, 0x0a, 0x06, 0x54, 0x75, 0x6e, 0x6e, 0x65, 0x6c, 0x12,
+ 0x12, 0x0a, 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75,
+ 0x75, 0x69, 0x64, 0x22, 0xdd, 0x02, 0x0a, 0x12, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61,
+ 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x52, 0x0a, 0x0c, 0x70, 0x65,
+ 0x65, 0x72, 0x5f, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b,
+ 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74,
+ 0x65, 0x52, 0x0b, 0x70, 0x65, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x73, 0x1a, 0xf2,
+ 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x12, 0x0a,
+ 0x04, 0x75, 0x75, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x75, 0x75, 0x69,
+ 0x64, 0x12, 0x2a, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32,
+ 0x16, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e,
+ 0x76, 0x32, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x48, 0x0a,
+ 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x34, 0x2e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43,
+ 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
+ 0x65, 0x2e, 0x50, 0x65, 0x65, 0x72, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x4b, 0x69, 0x6e,
+ 0x64, 0x52, 0x04, 0x6b, 0x69, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f,
+ 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x22,
+ 0x42, 0x0a, 0x04, 0x4b, 0x69, 0x6e, 0x64, 0x12, 0x14, 0x0a, 0x10, 0x4b, 0x49, 0x4e, 0x44, 0x5f,
+ 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x08, 0x0a,
+ 0x04, 0x4e, 0x4f, 0x44, 0x45, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x44, 0x49, 0x53, 0x43, 0x4f,
+ 0x4e, 0x4e, 0x45, 0x43, 0x54, 0x45, 0x44, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x4c, 0x4f, 0x53,
+ 0x54, 0x10, 0x03, 0x32, 0xc4, 0x01, 0x0a, 0x06, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x56,
+ 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61, 0x70, 0x73,
+ 0x12, 0x27, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x44, 0x45, 0x52, 0x50, 0x4d, 0x61,
+ 0x70, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x63, 0x6f, 0x64, 0x65,
+ 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x44, 0x45, 0x52,
+ 0x50, 0x4d, 0x61, 0x70, 0x30, 0x01, 0x12, 0x62, 0x0a, 0x11, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69,
+ 0x6e, 0x61, 0x74, 0x65, 0x54, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x12, 0x23, 0x2e, 0x63, 0x6f,
+ 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x43,
+ 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x24, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74,
+ 0x2e, 0x76, 0x32, 0x2e, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x69, 0x6e, 0x61, 0x74, 0x65, 0x52, 0x65,
+ 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x29, 0x5a, 0x27, 0x67, 0x69,
+ 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63,
+ 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x74, 0x61, 0x69, 0x6c, 0x6e, 0x65, 0x74, 0x2f,
+ 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+}
+
+var (
+ file_tailnet_proto_tailnet_proto_rawDescOnce sync.Once
+ file_tailnet_proto_tailnet_proto_rawDescData = file_tailnet_proto_tailnet_proto_rawDesc
+)
+
+func file_tailnet_proto_tailnet_proto_rawDescGZIP() []byte {
+ file_tailnet_proto_tailnet_proto_rawDescOnce.Do(func() {
+ file_tailnet_proto_tailnet_proto_rawDescData = protoimpl.X.CompressGZIP(file_tailnet_proto_tailnet_proto_rawDescData)
+ })
+ return file_tailnet_proto_tailnet_proto_rawDescData
+}
+
+var file_tailnet_proto_tailnet_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_tailnet_proto_tailnet_proto_msgTypes = make([]protoimpl.MessageInfo, 16)
+var file_tailnet_proto_tailnet_proto_goTypes = []interface{}{
+ (CoordinateResponse_PeerUpdate_Kind)(0), // 0: coder.tailnet.v2.CoordinateResponse.PeerUpdate.Kind
+ (*DERPMap)(nil), // 1: coder.tailnet.v2.DERPMap
+ (*StreamDERPMapsRequest)(nil), // 2: coder.tailnet.v2.StreamDERPMapsRequest
+ (*Node)(nil), // 3: coder.tailnet.v2.Node
+ (*CoordinateRequest)(nil), // 4: coder.tailnet.v2.CoordinateRequest
+ (*CoordinateResponse)(nil), // 5: coder.tailnet.v2.CoordinateResponse
+ (*DERPMap_HomeParams)(nil), // 6: coder.tailnet.v2.DERPMap.HomeParams
+ (*DERPMap_Region)(nil), // 7: coder.tailnet.v2.DERPMap.Region
+ nil, // 8: coder.tailnet.v2.DERPMap.RegionsEntry
+ nil, // 9: coder.tailnet.v2.DERPMap.HomeParams.RegionScoreEntry
+ (*DERPMap_Region_Node)(nil), // 10: coder.tailnet.v2.DERPMap.Region.Node
+ nil, // 11: coder.tailnet.v2.Node.DerpLatencyEntry
+ nil, // 12: coder.tailnet.v2.Node.DerpForcedWebsocketEntry
+ (*CoordinateRequest_UpdateSelf)(nil), // 13: coder.tailnet.v2.CoordinateRequest.UpdateSelf
+ (*CoordinateRequest_Disconnect)(nil), // 14: coder.tailnet.v2.CoordinateRequest.Disconnect
+ (*CoordinateRequest_Tunnel)(nil), // 15: coder.tailnet.v2.CoordinateRequest.Tunnel
+ (*CoordinateResponse_PeerUpdate)(nil), // 16: coder.tailnet.v2.CoordinateResponse.PeerUpdate
+ (*timestamppb.Timestamp)(nil), // 17: google.protobuf.Timestamp
+}
+var file_tailnet_proto_tailnet_proto_depIdxs = []int32{
+ 6, // 0: coder.tailnet.v2.DERPMap.home_params:type_name -> coder.tailnet.v2.DERPMap.HomeParams
+ 8, // 1: coder.tailnet.v2.DERPMap.regions:type_name -> coder.tailnet.v2.DERPMap.RegionsEntry
+ 17, // 2: coder.tailnet.v2.Node.as_of:type_name -> google.protobuf.Timestamp
+ 11, // 3: coder.tailnet.v2.Node.derp_latency:type_name -> coder.tailnet.v2.Node.DerpLatencyEntry
+ 12, // 4: coder.tailnet.v2.Node.derp_forced_websocket:type_name -> coder.tailnet.v2.Node.DerpForcedWebsocketEntry
+ 13, // 5: coder.tailnet.v2.CoordinateRequest.update_self:type_name -> coder.tailnet.v2.CoordinateRequest.UpdateSelf
+ 14, // 6: coder.tailnet.v2.CoordinateRequest.disconnect:type_name -> coder.tailnet.v2.CoordinateRequest.Disconnect
+ 15, // 7: coder.tailnet.v2.CoordinateRequest.add_tunnel:type_name -> coder.tailnet.v2.CoordinateRequest.Tunnel
+ 15, // 8: coder.tailnet.v2.CoordinateRequest.remove_tunnel:type_name -> coder.tailnet.v2.CoordinateRequest.Tunnel
+ 16, // 9: coder.tailnet.v2.CoordinateResponse.peer_updates:type_name -> coder.tailnet.v2.CoordinateResponse.PeerUpdate
+ 9, // 10: coder.tailnet.v2.DERPMap.HomeParams.region_score:type_name -> coder.tailnet.v2.DERPMap.HomeParams.RegionScoreEntry
+ 10, // 11: coder.tailnet.v2.DERPMap.Region.nodes:type_name -> coder.tailnet.v2.DERPMap.Region.Node
+ 7, // 12: coder.tailnet.v2.DERPMap.RegionsEntry.value:type_name -> coder.tailnet.v2.DERPMap.Region
+ 3, // 13: coder.tailnet.v2.CoordinateRequest.UpdateSelf.node:type_name -> coder.tailnet.v2.Node
+ 3, // 14: coder.tailnet.v2.CoordinateResponse.PeerUpdate.node:type_name -> coder.tailnet.v2.Node
+ 0, // 15: coder.tailnet.v2.CoordinateResponse.PeerUpdate.kind:type_name -> coder.tailnet.v2.CoordinateResponse.PeerUpdate.Kind
+ 2, // 16: coder.tailnet.v2.Client.StreamDERPMaps:input_type -> coder.tailnet.v2.StreamDERPMapsRequest
+ 4, // 17: coder.tailnet.v2.Client.CoordinateTailnet:input_type -> coder.tailnet.v2.CoordinateRequest
+ 1, // 18: coder.tailnet.v2.Client.StreamDERPMaps:output_type -> coder.tailnet.v2.DERPMap
+ 5, // 19: coder.tailnet.v2.Client.CoordinateTailnet:output_type -> coder.tailnet.v2.CoordinateResponse
+ 18, // [18:20] is the sub-list for method output_type
+ 16, // [16:18] is the sub-list for method input_type
+ 16, // [16:16] is the sub-list for extension type_name
+ 16, // [16:16] is the sub-list for extension extendee
+ 0, // [0:16] is the sub-list for field type_name
+}
+
+func init() { file_tailnet_proto_tailnet_proto_init() }
+func file_tailnet_proto_tailnet_proto_init() {
+ if File_tailnet_proto_tailnet_proto != nil {
+ return
+ }
+ if !protoimpl.UnsafeEnabled {
+ file_tailnet_proto_tailnet_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DERPMap); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*StreamDERPMapsRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*Node); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateResponse); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DERPMap_HomeParams); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DERPMap_Region); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*DERPMap_Region_Node); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateRequest_UpdateSelf); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateRequest_Disconnect); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateRequest_Tunnel); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tailnet_proto_tailnet_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*CoordinateResponse_PeerUpdate); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ }
+ type x struct{}
+ out := protoimpl.TypeBuilder{
+ File: protoimpl.DescBuilder{
+ GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+ RawDescriptor: file_tailnet_proto_tailnet_proto_rawDesc,
+ NumEnums: 1,
+ NumMessages: 16,
+ NumExtensions: 0,
+ NumServices: 1,
+ },
+ GoTypes: file_tailnet_proto_tailnet_proto_goTypes,
+ DependencyIndexes: file_tailnet_proto_tailnet_proto_depIdxs,
+ EnumInfos: file_tailnet_proto_tailnet_proto_enumTypes,
+ MessageInfos: file_tailnet_proto_tailnet_proto_msgTypes,
+ }.Build()
+ File_tailnet_proto_tailnet_proto = out.File
+ file_tailnet_proto_tailnet_proto_rawDesc = nil
+ file_tailnet_proto_tailnet_proto_goTypes = nil
+ file_tailnet_proto_tailnet_proto_depIdxs = nil
+}
diff --git a/tailnet/proto/tailnet.proto b/tailnet/proto/tailnet.proto
new file mode 100644
index 0000000000000..8c3a1e1163916
--- /dev/null
+++ b/tailnet/proto/tailnet.proto
@@ -0,0 +1,94 @@
+syntax = "proto3";
+option go_package = "github.com/coder/coder/v2/tailnet/proto";
+
+package coder.tailnet.v2;
+
+import "google/protobuf/timestamp.proto";
+
+message DERPMap {
+ message HomeParams {
+ map region_score = 1;
+ }
+ HomeParams home_params = 1;
+
+ message Region {
+ int32 region_id = 1;
+ bool embedded_relay = 2;
+ string region_code = 3;
+ string region_name = 4;
+ bool avoid = 5;
+
+ message Node {
+ string name = 1;
+ int32 region_id = 2;
+ string host_name = 3;
+ string cert_name = 4;
+ string ipv4 = 5;
+ string ipv6 = 6;
+ int32 stun_port = 7;
+ bool stun_only = 8;
+ int32 derp_port = 9;
+ bool insecure_for_tests = 10;
+ bool force_http = 11;
+ string stun_test_ip = 12;
+ bool can_port_80 = 13;
+ }
+ repeated Node nodes = 6;
+ }
+ map regions = 2;
+}
+
+message StreamDERPMapsRequest {}
+
+// defined in tailnet/coordinator.go
+message Node {
+ int64 id = 1;
+ google.protobuf.Timestamp as_of = 2;
+ bytes key = 3;
+ string disco = 4;
+ int32 preferred_derp = 5;
+ map derp_latency = 6;
+ map derp_forced_websocket = 7;
+ repeated string addresses = 8;
+ repeated string allowed_ips = 9;
+ repeated string endpoints = 10;
+}
+
+message CoordinateRequest {
+ message UpdateSelf {
+ Node node = 1;
+ }
+ UpdateSelf update_self = 1;
+
+ message Disconnect {}
+ Disconnect disconnect = 2;
+
+ message Tunnel {
+ bytes uuid = 1;
+ }
+ Tunnel add_tunnel = 3;
+ Tunnel remove_tunnel = 4;
+}
+
+message CoordinateResponse {
+ message PeerUpdate {
+ bytes uuid = 1;
+ Node node = 2;
+
+ enum Kind {
+ KIND_UNSPECIFIED = 0;
+ NODE = 1;
+ DISCONNECTED = 2;
+ LOST = 3;
+ }
+ Kind kind = 3;
+
+ string reason = 4;
+ }
+ repeated PeerUpdate peer_updates = 1;
+}
+
+service Client {
+ rpc StreamDERPMaps(StreamDERPMapsRequest) returns (stream DERPMap);
+ rpc CoordinateTailnet(stream CoordinateRequest) returns (stream CoordinateResponse);
+}
diff --git a/tailnet/proto/tailnet_drpc.pb.go b/tailnet/proto/tailnet_drpc.pb.go
new file mode 100644
index 0000000000000..0e0476870426e
--- /dev/null
+++ b/tailnet/proto/tailnet_drpc.pb.go
@@ -0,0 +1,218 @@
+// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
+// protoc-gen-go-drpc version: v0.0.33
+// source: tailnet/proto/tailnet.proto
+
+package proto
+
+import (
+ context "context"
+ errors "errors"
+ protojson "google.golang.org/protobuf/encoding/protojson"
+ proto "google.golang.org/protobuf/proto"
+ drpc "storj.io/drpc"
+ drpcerr "storj.io/drpc/drpcerr"
+)
+
+type drpcEncoding_File_tailnet_proto_tailnet_proto struct{}
+
+func (drpcEncoding_File_tailnet_proto_tailnet_proto) Marshal(msg drpc.Message) ([]byte, error) {
+ return proto.Marshal(msg.(proto.Message))
+}
+
+func (drpcEncoding_File_tailnet_proto_tailnet_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) {
+ return proto.MarshalOptions{}.MarshalAppend(buf, msg.(proto.Message))
+}
+
+func (drpcEncoding_File_tailnet_proto_tailnet_proto) Unmarshal(buf []byte, msg drpc.Message) error {
+ return proto.Unmarshal(buf, msg.(proto.Message))
+}
+
+func (drpcEncoding_File_tailnet_proto_tailnet_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
+ return protojson.Marshal(msg.(proto.Message))
+}
+
+func (drpcEncoding_File_tailnet_proto_tailnet_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
+ return protojson.Unmarshal(buf, msg.(proto.Message))
+}
+
+type DRPCClientClient interface {
+ DRPCConn() drpc.Conn
+
+ StreamDERPMaps(ctx context.Context, in *StreamDERPMapsRequest) (DRPCClient_StreamDERPMapsClient, error)
+ CoordinateTailnet(ctx context.Context) (DRPCClient_CoordinateTailnetClient, error)
+}
+
+type drpcClientClient struct {
+ cc drpc.Conn
+}
+
+func NewDRPCClientClient(cc drpc.Conn) DRPCClientClient {
+ return &drpcClientClient{cc}
+}
+
+func (c *drpcClientClient) DRPCConn() drpc.Conn { return c.cc }
+
+func (c *drpcClientClient) StreamDERPMaps(ctx context.Context, in *StreamDERPMapsRequest) (DRPCClient_StreamDERPMapsClient, error) {
+ stream, err := c.cc.NewStream(ctx, "/coder.tailnet.v2.Client/StreamDERPMaps", drpcEncoding_File_tailnet_proto_tailnet_proto{})
+ if err != nil {
+ return nil, err
+ }
+ x := &drpcClient_StreamDERPMapsClient{stream}
+ if err := x.MsgSend(in, drpcEncoding_File_tailnet_proto_tailnet_proto{}); err != nil {
+ return nil, err
+ }
+ if err := x.CloseSend(); err != nil {
+ return nil, err
+ }
+ return x, nil
+}
+
+type DRPCClient_StreamDERPMapsClient interface {
+ drpc.Stream
+ Recv() (*DERPMap, error)
+}
+
+type drpcClient_StreamDERPMapsClient struct {
+ drpc.Stream
+}
+
+func (x *drpcClient_StreamDERPMapsClient) GetStream() drpc.Stream {
+ return x.Stream
+}
+
+func (x *drpcClient_StreamDERPMapsClient) Recv() (*DERPMap, error) {
+ m := new(DERPMap)
+ if err := x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcClient_StreamDERPMapsClient) RecvMsg(m *DERPMap) error {
+ return x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}
+
+func (c *drpcClientClient) CoordinateTailnet(ctx context.Context) (DRPCClient_CoordinateTailnetClient, error) {
+ stream, err := c.cc.NewStream(ctx, "/coder.tailnet.v2.Client/CoordinateTailnet", drpcEncoding_File_tailnet_proto_tailnet_proto{})
+ if err != nil {
+ return nil, err
+ }
+ x := &drpcClient_CoordinateTailnetClient{stream}
+ return x, nil
+}
+
+type DRPCClient_CoordinateTailnetClient interface {
+ drpc.Stream
+ Send(*CoordinateRequest) error
+ Recv() (*CoordinateResponse, error)
+}
+
+type drpcClient_CoordinateTailnetClient struct {
+ drpc.Stream
+}
+
+func (x *drpcClient_CoordinateTailnetClient) GetStream() drpc.Stream {
+ return x.Stream
+}
+
+func (x *drpcClient_CoordinateTailnetClient) Send(m *CoordinateRequest) error {
+ return x.MsgSend(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}
+
+func (x *drpcClient_CoordinateTailnetClient) Recv() (*CoordinateResponse, error) {
+ m := new(CoordinateResponse)
+ if err := x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcClient_CoordinateTailnetClient) RecvMsg(m *CoordinateResponse) error {
+ return x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}
+
+type DRPCClientServer interface {
+ StreamDERPMaps(*StreamDERPMapsRequest, DRPCClient_StreamDERPMapsStream) error
+ CoordinateTailnet(DRPCClient_CoordinateTailnetStream) error
+}
+
+type DRPCClientUnimplementedServer struct{}
+
+func (s *DRPCClientUnimplementedServer) StreamDERPMaps(*StreamDERPMapsRequest, DRPCClient_StreamDERPMapsStream) error {
+ return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+func (s *DRPCClientUnimplementedServer) CoordinateTailnet(DRPCClient_CoordinateTailnetStream) error {
+ return drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
+}
+
+type DRPCClientDescription struct{}
+
+func (DRPCClientDescription) NumMethods() int { return 2 }
+
+func (DRPCClientDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
+ switch n {
+ case 0:
+ return "/coder.tailnet.v2.Client/StreamDERPMaps", drpcEncoding_File_tailnet_proto_tailnet_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return nil, srv.(DRPCClientServer).
+ StreamDERPMaps(
+ in1.(*StreamDERPMapsRequest),
+ &drpcClient_StreamDERPMapsStream{in2.(drpc.Stream)},
+ )
+ }, DRPCClientServer.StreamDERPMaps, true
+ case 1:
+ return "/coder.tailnet.v2.Client/CoordinateTailnet", drpcEncoding_File_tailnet_proto_tailnet_proto{},
+ func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
+ return nil, srv.(DRPCClientServer).
+ CoordinateTailnet(
+ &drpcClient_CoordinateTailnetStream{in1.(drpc.Stream)},
+ )
+ }, DRPCClientServer.CoordinateTailnet, true
+ default:
+ return "", nil, nil, nil, false
+ }
+}
+
+func DRPCRegisterClient(mux drpc.Mux, impl DRPCClientServer) error {
+ return mux.Register(impl, DRPCClientDescription{})
+}
+
+type DRPCClient_StreamDERPMapsStream interface {
+ drpc.Stream
+ Send(*DERPMap) error
+}
+
+type drpcClient_StreamDERPMapsStream struct {
+ drpc.Stream
+}
+
+func (x *drpcClient_StreamDERPMapsStream) Send(m *DERPMap) error {
+ return x.MsgSend(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}
+
+type DRPCClient_CoordinateTailnetStream interface {
+ drpc.Stream
+ Send(*CoordinateResponse) error
+ Recv() (*CoordinateRequest, error)
+}
+
+type drpcClient_CoordinateTailnetStream struct {
+ drpc.Stream
+}
+
+func (x *drpcClient_CoordinateTailnetStream) Send(m *CoordinateResponse) error {
+ return x.MsgSend(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}
+
+func (x *drpcClient_CoordinateTailnetStream) Recv() (*CoordinateRequest, error) {
+ m := new(CoordinateRequest)
+ if err := x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{}); err != nil {
+ return nil, err
+ }
+ return m, nil
+}
+
+func (x *drpcClient_CoordinateTailnetStream) RecvMsg(m *CoordinateRequest) error {
+ return x.MsgRecv(m, drpcEncoding_File_tailnet_proto_tailnet_proto{})
+}