diff --git a/cli/server.go b/cli/server.go
index 40d920bd7432a..b25a0bb7d7de6 100644
--- a/cli/server.go
+++ b/cli/server.go
@@ -33,6 +33,7 @@ import (
"golang.org/x/mod/semver"
"golang.org/x/oauth2"
xgithub "golang.org/x/oauth2/github"
+ "golang.org/x/sync/errgroup"
"golang.org/x/xerrors"
"google.golang.org/api/idtoken"
"google.golang.org/api/option"
@@ -169,8 +170,9 @@ func server() *cobra.Command {
}
var (
- tunnelErrChan <-chan error
ctxTunnel, closeTunnel = context.WithCancel(cmd.Context())
+ devTunnel = (*devtunnel.Tunnel)(nil)
+ devTunnelErrChan = make(<-chan error, 1)
)
defer closeTunnel()
@@ -197,14 +199,37 @@ func server() *cobra.Command {
}
}
if err == nil {
- accessURL, tunnelErrChan, err = devtunnel.New(ctxTunnel, localURL)
+ devTunnel, devTunnelErrChan, err = devtunnel.New(ctxTunnel, logger.Named("devtunnel"))
if err != nil {
return xerrors.Errorf("create tunnel: %w", err)
}
+ accessURL = devTunnel.URL
}
_, _ = fmt.Fprintln(cmd.ErrOrStderr())
}
+ // Warn the user if the access URL appears to be a loopback address.
+ isLocal, err := isLocalURL(cmd.Context(), accessURL)
+ if isLocal || err != nil {
+ var reason string
+ if isLocal {
+ reason = "appears to be a loopback address"
+ } else {
+ reason = "could not be resolved"
+ }
+ _, _ = fmt.Fprintf(cmd.ErrOrStderr(), cliui.Styles.Wrap.Render(
+ cliui.Styles.Warn.Render("Warning:")+" The current access URL:")+"\n\n")
+ _, _ = fmt.Fprintf(cmd.ErrOrStderr(), " "+cliui.Styles.Field.Render(accessURL)+"\n\n")
+ _, _ = fmt.Fprintf(cmd.ErrOrStderr(), cliui.Styles.Wrap.Render(
+ reason+". Provisioned workspaces are unlikely to be able to "+
+ "connect to Coder. Please consider changing your "+
+ "access URL using the --access-url option, or directly "+
+ "specifying access URLs on templates.",
+ )+"\n\n")
+ _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "For more information, see "+
+ "https://github.com/coder/coder/issues/1528\n\n")
+ }
+
validator, err := idtoken.NewValidator(cmd.Context(), option.WithoutAuthentication())
if err != nil {
return err
@@ -329,7 +354,27 @@ func server() *cobra.Command {
return shutdownConnsCtx
},
}
- errCh <- server.Serve(listener)
+
+ wg := errgroup.Group{}
+ wg.Go(func() error {
+ // Make sure to close the tunnel listener if we exit so the
+ // errgroup doesn't wait forever!
+ if dev && tunnel {
+ defer devTunnel.Listener.Close()
+ }
+
+ return server.Serve(listener)
+ })
+
+ if dev && tunnel {
+ wg.Go(func() error {
+ defer listener.Close()
+
+ return server.Serve(devTunnel.Listener)
+ })
+ }
+
+ errCh <- wg.Wait()
}()
config := createConfig(cmd)
@@ -395,7 +440,7 @@ func server() *cobra.Command {
case <-cmd.Context().Done():
coderAPI.Close()
return cmd.Context().Err()
- case err := <-tunnelErrChan:
+ case err := <-devTunnelErrChan:
if err != nil {
return err
}
@@ -458,7 +503,7 @@ func server() *cobra.Command {
if dev && tunnel {
_, _ = fmt.Fprintf(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Waiting for dev tunnel to close...\n")
closeTunnel()
- <-tunnelErrChan
+ <-devTunnelErrChan
}
_, _ = fmt.Fprintf(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Waiting for WebSocket connections to close...\n")
@@ -805,3 +850,24 @@ func serveHandler(ctx context.Context, logger slog.Logger, handler http.Handler,
return func() { _ = srv.Close() }
}
+
+// isLocalURL returns true if the hostname of the provided URL appears to
+// resolve to a loopback address.
+func isLocalURL(ctx context.Context, urlString string) (bool, error) {
+ parsedURL, err := url.Parse(urlString)
+ if err != nil {
+ return false, err
+ }
+ resolver := &net.Resolver{}
+ ips, err := resolver.LookupIPAddr(ctx, parsedURL.Hostname())
+ if err != nil {
+ return false, err
+ }
+
+ for _, ip := range ips {
+ if ip.IP.IsLoopback() {
+ return true, nil
+ }
+ }
+ return false, nil
+}
diff --git a/cli/server_test.go b/cli/server_test.go
index c9afbf2677158..7af01138e8c2c 100644
--- a/cli/server_test.go
+++ b/cli/server_test.go
@@ -118,6 +118,9 @@ func TestServer(t *testing.T) {
} else {
t.Error("expected password line output; got no match")
}
+
+ // Verify that we warned the user about the default access URL possibly not being what they want.
+ assert.Contains(t, buf.String(), "coder/coder/issues/1528")
})
// Duplicated test from "Development" above to test setting email/password via env.
@@ -163,6 +166,32 @@ func TestServer(t *testing.T) {
assert.Contains(t, buf.String(), fmt.Sprintf("password: %s", wantPassword), "expected output %q; got no match", wantPassword)
})
+ t.Run("NoWarningWithRemoteAccessURL", func(t *testing.T) {
+ t.Parallel()
+ ctx, cancelFunc := context.WithCancel(context.Background())
+ defer cancelFunc()
+
+ root, cfg := clitest.New(t, "server", "--dev", "--tunnel=false", "--address", ":0", "--access-url", "http://1.2.3.4:3000/")
+ var buf strings.Builder
+ errC := make(chan error)
+ root.SetOutput(&buf)
+ go func() {
+ errC <- root.ExecuteContext(ctx)
+ }()
+
+ // Just wait for startup
+ require.Eventually(t, func() bool {
+ var err error
+ _, err = cfg.URL().Read()
+ return err == nil
+ }, 15*time.Second, 25*time.Millisecond)
+
+ cancelFunc()
+ require.ErrorIs(t, <-errC, context.Canceled)
+
+ assert.NotContains(t, buf.String(), "coder/coder/issues/1528")
+ })
+
t.Run("TLSBadVersion", func(t *testing.T) {
t.Parallel()
ctx, cancelFunc := context.WithCancel(context.Background())
diff --git a/cli/templateinit.go b/cli/templateinit.go
index 84afa5874fc46..2c4338194e608 100644
--- a/cli/templateinit.go
+++ b/cli/templateinit.go
@@ -24,8 +24,13 @@ func templateInit() *cobra.Command {
exampleNames := []string{}
exampleByName := map[string]examples.Example{}
for _, example := range exampleList {
- exampleNames = append(exampleNames, example.Name)
- exampleByName[example.Name] = example
+ name := fmt.Sprintf(
+ "%s\n%s\n",
+ cliui.Styles.Bold.Render(example.Name),
+ cliui.Styles.Wrap.Copy().PaddingLeft(6).Render(example.Description),
+ )
+ exampleNames = append(exampleNames, name)
+ exampleByName[name] = example
}
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render(
diff --git a/cmd/coder/main.go b/cmd/coder/main.go
index 8fb7ee45f48c7..5cb2ff643e742 100644
--- a/cmd/coder/main.go
+++ b/cmd/coder/main.go
@@ -4,9 +4,6 @@ import (
"errors"
"fmt"
"os"
- "os/exec"
- "path/filepath"
- "strings"
_ "time/tzdata"
"github.com/coder/coder/cli"
@@ -14,7 +11,6 @@ import (
)
func main() {
- dadjoke()
cmd, err := cli.Root().ExecuteC()
if err != nil {
if errors.Is(err, cliui.Canceled) {
@@ -25,23 +21,3 @@ func main() {
os.Exit(1)
}
}
-
-//nolint
-func dadjoke() {
- if os.Getenv("EEOFF") != "" || filepath.Base(os.Args[0]) != "gitpod" {
- return
- }
-
- args := strings.Fields(`run -it --rm git --image=index.docker.io/bitnami/git --command --restart=Never -- git`)
- args = append(args, os.Args[1:]...)
- cmd := exec.Command("kubectl", args...)
- cmd.Stdin = os.Stdin
- cmd.Stdout = os.Stdout
- cmd.Stderr = os.Stderr
- _ = cmd.Start()
- err := cmd.Wait()
- if exitErr, ok := err.(*exec.ExitError); ok {
- os.Exit(exitErr.ExitCode())
- }
- os.Exit(0)
-}
diff --git a/coderd/audit/diff_test.go b/coderd/audit/diff_test.go
index 53f2110f07c26..ba91692a0734f 100644
--- a/coderd/audit/diff_test.go
+++ b/coderd/audit/diff_test.go
@@ -88,6 +88,7 @@ func TestDiff(t *testing.T) {
ActiveVersionID: uuid.UUID{3},
MaxTtl: int64(time.Hour),
MinAutostartInterval: int64(time.Minute),
+ CreatedBy: uuid.NullUUID{UUID: uuid.UUID{4}, Valid: true},
},
exp: audit.Map{
"id": uuid.UUID{1}.String(),
@@ -97,6 +98,7 @@ func TestDiff(t *testing.T) {
"active_version_id": uuid.UUID{3}.String(),
"max_ttl": int64(3600000000000),
"min_autostart_interval": int64(60000000000),
+ "created_by": uuid.UUID{4}.String(),
},
},
})
diff --git a/coderd/audit/table.go b/coderd/audit/table.go
index efdf0de1d6431..7562472f3c583 100644
--- a/coderd/audit/table.go
+++ b/coderd/audit/table.go
@@ -72,6 +72,7 @@ var AuditableResources = auditMap(map[any]map[string]Action{
"description": ActionTrack,
"max_ttl": ActionTrack,
"min_autostart_interval": ActionTrack,
+ "created_by": ActionTrack,
},
&database.TemplateVersion{}: {
"id": ActionTrack,
diff --git a/coderd/coderd.go b/coderd/coderd.go
index 6e88759fa340a..2cd94d1eac646 100644
--- a/coderd/coderd.go
+++ b/coderd/coderd.go
@@ -270,7 +270,10 @@ func New(options *Options) *API {
r.Get("/", api.organizationsByUser)
r.Get("/{organizationname}", api.organizationByUserAndName)
})
- r.Get("/workspace/{workspacename}", api.workspaceByOwnerAndName)
+ r.Route("/workspace/{workspacename}", func(r chi.Router) {
+ r.Get("/", api.workspaceByOwnerAndName)
+ r.Get("/builds/{buildnumber}", api.workspaceBuildByBuildNumber)
+ })
r.Get("/gitsshkey", api.gitSSHKey)
r.Put("/gitsshkey", api.regenerateGitSSHKey)
})
diff --git a/coderd/coderd_test.go b/coderd/coderd_test.go
index 02fba90966992..7053b4ff56cb8 100644
--- a/coderd/coderd_test.go
+++ b/coderd/coderd_test.go
@@ -4,6 +4,7 @@ import (
"context"
"io"
"net/http"
+ "strconv"
"strings"
"testing"
"time"
@@ -163,6 +164,10 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
AssertObject: rbac.ResourceWorkspace,
AssertAction: rbac.ActionRead,
},
+ "GET:/api/v2/users/me/workspace/{workspacename}/builds/{buildnumber}": {
+ AssertObject: rbac.ResourceWorkspace,
+ AssertAction: rbac.ActionRead,
+ },
"GET:/api/v2/workspaces/{workspace}/builds/{workspacebuildname}": {
AssertAction: rbac.ActionRead,
AssertObject: workspaceRBACObj,
@@ -388,6 +393,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
route = strings.ReplaceAll(route, "{workspacename}", workspace.Name)
route = strings.ReplaceAll(route, "{workspacebuildname}", workspace.LatestBuild.Name)
route = strings.ReplaceAll(route, "{workspaceagent}", workspaceResources[0].Agents[0].ID.String())
+ route = strings.ReplaceAll(route, "{buildnumber}", strconv.FormatInt(int64(workspace.LatestBuild.BuildNumber), 10))
route = strings.ReplaceAll(route, "{template}", template.ID.String())
route = strings.ReplaceAll(route, "{hash}", file.Hash)
route = strings.ReplaceAll(route, "{workspaceresource}", workspaceResources[0].ID.String())
diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go
index 8bee0158d1a11..fcc214a5745b7 100644
--- a/coderd/database/databasefake/databasefake.go
+++ b/coderd/database/databasefake/databasefake.go
@@ -625,6 +625,22 @@ func (q *fakeQuerier) GetWorkspaceBuildByWorkspaceIDAndName(_ context.Context, a
return database.WorkspaceBuild{}, sql.ErrNoRows
}
+func (q *fakeQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(_ context.Context, arg database.GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams) (database.WorkspaceBuild, error) {
+ q.mutex.RLock()
+ defer q.mutex.RUnlock()
+
+ for _, workspaceBuild := range q.workspaceBuilds {
+ if workspaceBuild.WorkspaceID.String() != arg.WorkspaceID.String() {
+ continue
+ }
+ if workspaceBuild.BuildNumber != arg.BuildNumber {
+ continue
+ }
+ return workspaceBuild, nil
+ }
+ return database.WorkspaceBuild{}, sql.ErrNoRows
+}
+
func (q *fakeQuerier) GetWorkspacesByOrganizationIDs(_ context.Context, req database.GetWorkspacesByOrganizationIDsParams) ([]database.Workspace, error) {
q.mutex.RLock()
defer q.mutex.RUnlock()
@@ -1325,6 +1341,7 @@ func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTempl
Description: arg.Description,
MaxTtl: arg.MaxTtl,
MinAutostartInterval: arg.MinAutostartInterval,
+ CreatedBy: arg.CreatedBy,
}
q.templates = append(q.templates, template)
return template, nil
diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql
index eff1e9ea6350c..95ef9ff0df3d6 100644
--- a/coderd/database/dump.sql
+++ b/coderd/database/dump.sql
@@ -248,7 +248,8 @@ CREATE TABLE templates (
active_version_id uuid NOT NULL,
description character varying(128) DEFAULT ''::character varying NOT NULL,
max_ttl bigint DEFAULT '604800000000000'::bigint NOT NULL,
- min_autostart_interval bigint DEFAULT '3600000000000'::bigint NOT NULL
+ min_autostart_interval bigint DEFAULT '3600000000000'::bigint NOT NULL,
+ created_by uuid
);
CREATE TABLE users (
@@ -476,6 +477,9 @@ ALTER TABLE ONLY template_versions
ALTER TABLE ONLY template_versions
ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
+ALTER TABLE ONLY templates
+ ADD CONSTRAINT templates_created_by_fkey FOREIGN KEY (created_by) REFERENCES users(id) ON DELETE RESTRICT;
+
ALTER TABLE ONLY templates
ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
diff --git a/coderd/database/migrations/000022_template_created_by.down.sql b/coderd/database/migrations/000022_template_created_by.down.sql
new file mode 100644
index 0000000000000..435291e5ccb10
--- /dev/null
+++ b/coderd/database/migrations/000022_template_created_by.down.sql
@@ -0,0 +1 @@
+ALTER TABLE ONLY templates DROP COLUMN IF EXISTS created_by;
diff --git a/coderd/database/migrations/000022_template_created_by.up.sql b/coderd/database/migrations/000022_template_created_by.up.sql
new file mode 100644
index 0000000000000..7ca6f235591bc
--- /dev/null
+++ b/coderd/database/migrations/000022_template_created_by.up.sql
@@ -0,0 +1 @@
+ALTER TABLE ONLY templates ADD COLUMN IF NOT EXISTS created_by uuid REFERENCES users (id) ON DELETE RESTRICT;
diff --git a/coderd/database/models.go b/coderd/database/models.go
index 22f47053c3955..2454049da0ac0 100644
--- a/coderd/database/models.go
+++ b/coderd/database/models.go
@@ -438,6 +438,7 @@ type Template struct {
Description string `db:"description" json:"description"`
MaxTtl int64 `db:"max_ttl" json:"max_ttl"`
MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"`
+ CreatedBy uuid.NullUUID `db:"created_by" json:"created_by"`
}
type TemplateVersion struct {
diff --git a/coderd/database/querier.go b/coderd/database/querier.go
index 59e8f4577ef8e..c3f57d3a9f795 100644
--- a/coderd/database/querier.go
+++ b/coderd/database/querier.go
@@ -70,6 +70,7 @@ type querier interface {
GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error)
GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UUID) (WorkspaceBuild, error)
GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDParams) ([]WorkspaceBuild, error)
+ GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams) (WorkspaceBuild, error)
GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndNameParams) (WorkspaceBuild, error)
GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error)
GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (Workspace, error)
diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go
index 3eafdd09a9c9c..edb2fc774589c 100644
--- a/coderd/database/queries.sql.go
+++ b/coderd/database/queries.sql.go
@@ -1603,7 +1603,7 @@ func (q *sqlQuerier) UpdateProvisionerJobWithCompleteByID(ctx context.Context, a
const getTemplateByID = `-- name: GetTemplateByID :one
SELECT
- id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
FROM
templates
WHERE
@@ -1627,13 +1627,14 @@ func (q *sqlQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (Templat
&i.Description,
&i.MaxTtl,
&i.MinAutostartInterval,
+ &i.CreatedBy,
)
return i, err
}
const getTemplateByOrganizationAndName = `-- name: GetTemplateByOrganizationAndName :one
SELECT
- id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
FROM
templates
WHERE
@@ -1665,13 +1666,14 @@ func (q *sqlQuerier) GetTemplateByOrganizationAndName(ctx context.Context, arg G
&i.Description,
&i.MaxTtl,
&i.MinAutostartInterval,
+ &i.CreatedBy,
)
return i, err
}
const getTemplatesByIDs = `-- name: GetTemplatesByIDs :many
SELECT
- id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
FROM
templates
WHERE
@@ -1699,6 +1701,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([]
&i.Description,
&i.MaxTtl,
&i.MinAutostartInterval,
+ &i.CreatedBy,
); err != nil {
return nil, err
}
@@ -1715,7 +1718,7 @@ func (q *sqlQuerier) GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([]
const getTemplatesByOrganization = `-- name: GetTemplatesByOrganization :many
SELECT
- id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
FROM
templates
WHERE
@@ -1749,6 +1752,7 @@ func (q *sqlQuerier) GetTemplatesByOrganization(ctx context.Context, arg GetTemp
&i.Description,
&i.MaxTtl,
&i.MinAutostartInterval,
+ &i.CreatedBy,
); err != nil {
return nil, err
}
@@ -1775,10 +1779,11 @@ INSERT INTO
active_version_id,
description,
max_ttl,
- min_autostart_interval
+ min_autostart_interval,
+ created_by
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
`
type InsertTemplateParams struct {
@@ -1792,6 +1797,7 @@ type InsertTemplateParams struct {
Description string `db:"description" json:"description"`
MaxTtl int64 `db:"max_ttl" json:"max_ttl"`
MinAutostartInterval int64 `db:"min_autostart_interval" json:"min_autostart_interval"`
+ CreatedBy uuid.NullUUID `db:"created_by" json:"created_by"`
}
func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error) {
@@ -1806,6 +1812,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam
arg.Description,
arg.MaxTtl,
arg.MinAutostartInterval,
+ arg.CreatedBy,
)
var i Template
err := row.Scan(
@@ -1820,6 +1827,7 @@ func (q *sqlQuerier) InsertTemplate(ctx context.Context, arg InsertTemplateParam
&i.Description,
&i.MaxTtl,
&i.MinAutostartInterval,
+ &i.CreatedBy,
)
return i, err
}
@@ -1873,7 +1881,7 @@ SET
WHERE
id = $1
RETURNING
- id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval
+ id, created_at, updated_at, organization_id, deleted, name, provisioner, active_version_id, description, max_ttl, min_autostart_interval, created_by
`
type UpdateTemplateMetaByIDParams struct {
@@ -3212,6 +3220,41 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg Get
return items, nil
}
+const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
+SELECT
+ id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline
+FROM
+ workspace_builds
+WHERE
+ workspace_id = $1
+ AND build_number = $2
+`
+
+type GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams struct {
+ WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
+ BuildNumber int32 `db:"build_number" json:"build_number"`
+}
+
+func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams) (WorkspaceBuild, error) {
+ row := q.db.QueryRowContext(ctx, getWorkspaceBuildByWorkspaceIDAndBuildNumber, arg.WorkspaceID, arg.BuildNumber)
+ var i WorkspaceBuild
+ err := row.Scan(
+ &i.ID,
+ &i.CreatedAt,
+ &i.UpdatedAt,
+ &i.WorkspaceID,
+ &i.TemplateVersionID,
+ &i.Name,
+ &i.BuildNumber,
+ &i.Transition,
+ &i.InitiatorID,
+ &i.ProvisionerState,
+ &i.JobID,
+ &i.Deadline,
+ )
+ return i, err
+}
+
const getWorkspaceBuildByWorkspaceIDAndName = `-- name: GetWorkspaceBuildByWorkspaceIDAndName :one
SELECT
id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline
diff --git a/coderd/database/queries/templates.sql b/coderd/database/queries/templates.sql
index ffc0b9dabfb38..c3b3753083351 100644
--- a/coderd/database/queries/templates.sql
+++ b/coderd/database/queries/templates.sql
@@ -49,10 +49,11 @@ INSERT INTO
active_version_id,
description,
max_ttl,
- min_autostart_interval
+ min_autostart_interval,
+ created_by
)
VALUES
- ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) RETURNING *;
+ ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *;
-- name: UpdateTemplateActiveVersionByID :exec
UPDATE
diff --git a/coderd/database/queries/workspacebuilds.sql b/coderd/database/queries/workspacebuilds.sql
index 5b53a874060e8..4bace271cb125 100644
--- a/coderd/database/queries/workspacebuilds.sql
+++ b/coderd/database/queries/workspacebuilds.sql
@@ -27,6 +27,15 @@ WHERE
workspace_id = $1
AND "name" = $2;
+-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one
+SELECT
+ *
+FROM
+ workspace_builds
+WHERE
+ workspace_id = $1
+ AND build_number = $2;
+
-- name: GetWorkspaceBuildByWorkspaceID :many
SELECT
*
diff --git a/coderd/devtunnel/tunnel.go b/coderd/devtunnel/tunnel.go
index 265cd317a947c..092cdd52ee5f6 100644
--- a/coderd/devtunnel/tunnel.go
+++ b/coderd/devtunnel/tunnel.go
@@ -1,93 +1,287 @@
package devtunnel
import (
+ "bytes"
"context"
+ "encoding/base64"
+ "encoding/hex"
+ "encoding/json"
"fmt"
- "net/url"
+ "io"
+ "net"
+ "net/http"
+ "net/netip"
"os"
- "strconv"
- "strings"
-
- frpclient "github.com/fatedier/frp/client"
- frpconfig "github.com/fatedier/frp/pkg/config"
- frpconsts "github.com/fatedier/frp/pkg/consts"
- frplog "github.com/fatedier/frp/pkg/util/log"
- frpcrypto "github.com/fatedier/golib/crypto"
+ "path/filepath"
+ "time"
+
"github.com/google/uuid"
- "github.com/moby/moby/pkg/namesgenerator"
"golang.org/x/xerrors"
+ "golang.zx2c4.com/wireguard/conn"
+ "golang.zx2c4.com/wireguard/device"
+ "golang.zx2c4.com/wireguard/tun/netstack"
+ "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
+
+ "cdr.dev/slog"
+)
+
+const (
+ EndpointWireguard = "wg-tunnel-udp.coder.app"
+ EndpointHTTPS = "wg-tunnel.coder.app"
+
+ ServerPublicKey = "+KNSMwed/IlqoesvTMSBNsHFaKVLrmmaCkn0bxIhUg0="
+ ServerUUID = "fcad0000-0000-4000-8000-000000000001"
)
-// New creates a new tunnel pointing at the URL provided. Once created, it
-// returns the external hostname that will resolve to it.
-//
-// The tunnel will exit when the context provided is canceled.
-//
-// Upstream connection occurs synchronously through a selfhosted
-// https://github.com/fatedier/frp instance. The error channel sends an error
-// when the frp client stops.
-func New(ctx context.Context, coderurl *url.URL) (string, <-chan error, error) {
- frpcrypto.DefaultSalt = "frp"
-
- cfg := frpconfig.GetDefaultClientConf()
- cfg.ServerAddr = "frp-tunnel.coder.app"
- cfg.ServerPort = 7000
-
- // Ignore all logs from frp.
- frplog.InitLog("file", os.DevNull, "error", -1, false)
-
- var (
- id = uuid.NewString()
- subdomain = strings.ReplaceAll(namesgenerator.GetRandomName(1), "_", "-")
- portStr = coderurl.Port()
+type Tunnel struct {
+ URL string
+ Listener net.Listener
+}
+
+type Config struct {
+ ID uuid.UUID `json:"id"`
+ PrivateKey device.NoisePrivateKey `json:"private_key"`
+ PublicKey device.NoisePublicKey `json:"public_key"`
+}
+type configExt struct {
+ ID uuid.UUID `json:"id"`
+ PrivateKey device.NoisePrivateKey `json:"-"`
+ PublicKey device.NoisePublicKey `json:"public_key"`
+}
+
+// NewWithConfig calls New with the given config. For documentation, see New.
+func NewWithConfig(ctx context.Context, logger slog.Logger, cfg Config) (*Tunnel, <-chan error, error) {
+ routineEnd, err := startUpdateRoutine(ctx, logger, cfg)
+ if err != nil {
+ return nil, nil, xerrors.Errorf("start update routine: %w", err)
+ }
+
+ tun, tnet, err := netstack.CreateNetTUN(
+ []netip.Addr{netip.AddrFrom16(cfg.ID)},
+ []netip.Addr{netip.AddrFrom4([4]byte{1, 1, 1, 1})},
+ 1420,
)
- if portStr == "" {
- portStr = "80"
+ if err != nil {
+ return nil, nil, xerrors.Errorf("create net TUN: %w", err)
}
- port, err := strconv.ParseInt(portStr, 10, 64)
+ wgip, err := net.ResolveIPAddr("ip", EndpointWireguard)
if err != nil {
- return "", nil, xerrors.Errorf("parse port %q: %w", port, err)
+ return nil, nil, xerrors.Errorf("resolve endpoint: %w", err)
}
- httpcfg := map[string]frpconfig.ProxyConf{
- id: &frpconfig.HTTPProxyConf{
- BaseProxyConf: frpconfig.BaseProxyConf{
- ProxyName: id,
- ProxyType: frpconsts.HTTPProxy,
- UseEncryption: false,
- UseCompression: false,
- LocalSvrConf: frpconfig.LocalSvrConf{
- LocalIP: coderurl.Hostname(),
- LocalPort: int(port),
- },
- },
- DomainConf: frpconfig.DomainConf{
- SubDomain: subdomain,
- },
- Locations: []string{""},
- },
+ dev := device.NewDevice(tun, conn.NewDefaultBind(), device.NewLogger(device.LogLevelSilent, ""))
+ err = dev.IpcSet(fmt.Sprintf(`private_key=%s
+public_key=%s
+endpoint=%s:55555
+persistent_keepalive_interval=21
+allowed_ip=%s/128`,
+ hex.EncodeToString(cfg.PrivateKey[:]),
+ encodeBase64ToHex(ServerPublicKey),
+ wgip.IP.String(),
+ netip.AddrFrom16(uuid.MustParse(ServerUUID)).String(),
+ ))
+ if err != nil {
+ return nil, nil, xerrors.Errorf("configure wireguard ipc: %w", err)
}
- if err := httpcfg[id].CheckForCli(); err != nil {
- return "", nil, xerrors.Errorf("check for cli: %w", err)
+ err = dev.Up()
+ if err != nil {
+ return nil, nil, xerrors.Errorf("wireguard device up: %w", err)
}
- svc, err := frpclient.NewService(cfg, httpcfg, nil, "")
+ wgListen, err := tnet.ListenTCP(&net.TCPAddr{Port: 8090})
if err != nil {
- return "", nil, xerrors.Errorf("create new proxy service: %w", err)
+ return nil, nil, xerrors.Errorf("wireguard device listen: %w", err)
}
- ch := make(chan error, 1)
+ ch := make(chan error)
go func() {
- err := svc.Run()
- ch <- err
- close(ch)
+ select {
+ case <-ctx.Done():
+ _ = wgListen.Close()
+ dev.Close()
+ <-routineEnd
+ close(ch)
+
+ case <-dev.Wait():
+ close(ch)
+ }
}()
+
+ return &Tunnel{
+ URL: fmt.Sprintf("https://%s.%s", cfg.ID, EndpointHTTPS),
+ Listener: wgListen,
+ }, ch, nil
+}
+
+// New creates a tunnel with a public URL and returns a listener for incoming
+// connections on that URL. Connections are made over the wireguard protocol.
+// Tunnel configuration is cached in the user's config directory. Successive
+// calls to New will always use the same URL. If multiple public URLs in
+// parallel are required, use NewWithConfig.
+func New(ctx context.Context, logger slog.Logger) (*Tunnel, <-chan error, error) {
+ cfg, err := readOrGenerateConfig()
+ if err != nil {
+ return nil, nil, xerrors.Errorf("read or generate config: %w", err)
+ }
+
+ return NewWithConfig(ctx, logger, cfg)
+}
+
+func startUpdateRoutine(ctx context.Context, logger slog.Logger, cfg Config) (<-chan struct{}, error) {
+ // Ensure we send the first config before spawning in the background.
+ _, err := sendConfigToServer(ctx, cfg)
+ if err != nil {
+ return nil, xerrors.Errorf("send config to server: %w", err)
+ }
+
+ endCh := make(chan struct{})
go func() {
- <-ctx.Done()
- svc.Close()
+ defer close(endCh)
+ ticker := time.NewTicker(30 * time.Second)
+ defer ticker.Stop()
+
+ for {
+ select {
+ case <-ctx.Done():
+ return
+
+ case <-ticker.C:
+ }
+
+ _, err := sendConfigToServer(ctx, cfg)
+ if err != nil {
+ logger.Debug(ctx, "send tunnel config to server", slog.Error(err))
+ }
+ }
}()
+ return endCh, nil
+}
+
+func sendConfigToServer(ctx context.Context, cfg Config) (created bool, err error) {
+ raw, err := json.Marshal(configExt(cfg))
+ if err != nil {
+ return false, xerrors.Errorf("marshal config: %w", err)
+ }
+
+ req, err := http.NewRequestWithContext(ctx, "POST", "https://"+EndpointHTTPS+"/tun", bytes.NewReader(raw))
+ if err != nil {
+ return false, xerrors.Errorf("new request: %w", err)
+ }
+
+ res, err := http.DefaultClient.Do(req)
+ if err != nil {
+ return false, xerrors.Errorf("do request: %w", err)
+ }
+
+ _, _ = io.Copy(io.Discard, res.Body)
+ _ = res.Body.Close()
+
+ return res.StatusCode == http.StatusCreated, nil
+}
+
+func cfgPath() (string, error) {
+ cfgDir, err := os.UserConfigDir()
+ if err != nil {
+ return "", xerrors.Errorf("get user config dir: %w", err)
+ }
+
+ cfgDir = filepath.Join(cfgDir, "coderv2")
+ err = os.MkdirAll(cfgDir, 0750)
+ if err != nil {
+ return "", xerrors.Errorf("mkdirall config dir %q: %w", cfgDir, err)
+ }
+
+ return filepath.Join(cfgDir, "devtunnel"), nil
+}
+
+func readOrGenerateConfig() (Config, error) {
+ cfgFi, err := cfgPath()
+ if err != nil {
+ return Config{}, xerrors.Errorf("get config path: %w", err)
+ }
+
+ fi, err := os.ReadFile(cfgFi)
+ if err != nil {
+ if os.IsNotExist(err) {
+ cfg, err := GenerateConfig()
+ if err != nil {
+ return Config{}, xerrors.Errorf("generate config: %w", err)
+ }
+
+ err = writeConfig(cfg)
+ if err != nil {
+ return Config{}, xerrors.Errorf("write config: %w", err)
+ }
+
+ return cfg, nil
+ }
+
+ return Config{}, xerrors.Errorf("read config: %w", err)
+ }
+
+ cfg := Config{}
+ err = json.Unmarshal(fi, &cfg)
+ if err != nil {
+ return Config{}, xerrors.Errorf("unmarshal config: %w", err)
+ }
+
+ return cfg, nil
+}
+
+func GenerateConfig() (Config, error) {
+ priv, err := wgtypes.GeneratePrivateKey()
+ if err != nil {
+ return Config{}, xerrors.Errorf("generate private key: %w", err)
+ }
+
+ pub := priv.PublicKey()
+
+ return Config{
+ ID: newUUID(),
+ PrivateKey: device.NoisePrivateKey(priv),
+ PublicKey: device.NoisePublicKey(pub),
+ }, nil
+}
+
+func newUUID() uuid.UUID {
+ u := uuid.New()
+ // 0xfc is the IPV6 prefix for internal networks.
+ u[0] = 0xfc
+ u[1] = 0xca
+
+ return u
+}
+
+func writeConfig(cfg Config) error {
+ cfgFi, err := cfgPath()
+ if err != nil {
+ return xerrors.Errorf("get config path: %w", err)
+ }
+
+ raw, err := json.Marshal(cfg)
+ if err != nil {
+ return xerrors.Errorf("marshal config: %w", err)
+ }
+
+ err = os.WriteFile(cfgFi, raw, 0600)
+ if err != nil {
+ return xerrors.Errorf("write file: %w", err)
+ }
+
+ return nil
+}
+
+func encodeBase64ToHex(key string) string {
+ decoded, err := base64.StdEncoding.DecodeString(key)
+ if err != nil {
+ panic(err)
+ }
+
+ if len(decoded) != 32 {
+ panic((xerrors.New("key should be 32 bytes: " + key)))
+ }
- return fmt.Sprintf("https://%s.try.coder.app", subdomain), ch, nil
+ return hex.EncodeToString(decoded)
}
diff --git a/coderd/devtunnel/tunnel_test.go b/coderd/devtunnel/tunnel_test.go
index b7c8e9e4b77bc..3ea8a63809a0c 100644
--- a/coderd/devtunnel/tunnel_test.go
+++ b/coderd/devtunnel/tunnel_test.go
@@ -2,16 +2,16 @@ package devtunnel_test
import (
"context"
+ "io"
"net"
"net/http"
- "net/http/httptest"
- "net/url"
"testing"
"time"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "golang.org/x/xerrors"
+ "cdr.dev/slog/sloggers/slogtest"
"github.com/coder/coder/coderd/devtunnel"
)
@@ -27,32 +27,51 @@ func TestTunnel(t *testing.T) {
return
}
- srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- w.WriteHeader(http.StatusOK)
- }))
- t.Cleanup(srv.Close)
+ ctx, cancelTun := context.WithCancel(context.Background())
+ defer cancelTun()
- ctx, cancelFunc := context.WithCancel(context.Background())
- defer cancelFunc()
+ server := http.Server{
+ Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ w.WriteHeader(http.StatusOK)
+ }),
+ BaseContext: func(_ net.Listener) context.Context {
+ return ctx
+ },
+ }
- srvURL, err := url.Parse(srv.URL)
+ cfg, err := devtunnel.GenerateConfig()
require.NoError(t, err)
- tunURL, _, err := devtunnel.New(ctx, srvURL)
+ tun, errCh, err := devtunnel.NewWithConfig(ctx, slogtest.Make(t, nil), cfg)
require.NoError(t, err)
- t.Log(tunURL)
+ t.Log(tun.URL)
+
+ go server.Serve(tun.Listener)
+ defer tun.Listener.Close()
+
+ httpClient := &http.Client{
+ Timeout: 10 * time.Second,
+ }
require.Eventually(t, func() bool {
- req, err := http.NewRequestWithContext(ctx, "GET", tunURL, nil)
+ req, err := http.NewRequestWithContext(ctx, "GET", tun.URL, nil)
require.NoError(t, err)
- res, err := http.DefaultClient.Do(req)
- var dnsErr *net.DNSError
- // The name might take a bit to resolve!
- if xerrors.As(err, &dnsErr) {
- return false
- }
+
+ res, err := httpClient.Do(req)
require.NoError(t, err)
defer res.Body.Close()
+ _, _ = io.Copy(io.Discard, res.Body)
+
return res.StatusCode == http.StatusOK
- }, 5*time.Minute, 3*time.Second)
+ }, time.Minute, time.Second)
+
+ httpClient.CloseIdleConnections()
+ assert.NoError(t, server.Close())
+ cancelTun()
+
+ select {
+ case <-errCh:
+ case <-time.After(10 * time.Second):
+ t.Error("tunnel did not close after 10 seconds")
+ }
}
diff --git a/coderd/httpmw/templateparam.go b/coderd/httpmw/templateparam.go
index 05884304b1566..0a7cba43d8a2a 100644
--- a/coderd/httpmw/templateparam.go
+++ b/coderd/httpmw/templateparam.go
@@ -37,6 +37,7 @@ func ExtractTemplateParam(db database.Store) func(http.Handler) http.Handler {
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
Message: fmt.Sprintf("Template %q does not exist.", templateID),
})
+ return
}
if err != nil {
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
diff --git a/coderd/templates.go b/coderd/templates.go
index 386a360111960..d79bd19f70fa2 100644
--- a/coderd/templates.go
+++ b/coderd/templates.go
@@ -1,6 +1,7 @@
package coderd
import (
+ "context"
"database/sql"
"errors"
"fmt"
@@ -49,7 +50,16 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) {
count = uint32(workspaceCounts[0].Count)
}
- httpapi.Write(rw, http.StatusOK, convertTemplate(template, count))
+ createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{template})
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching creator name.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ httpapi.Write(rw, http.StatusOK, convertTemplate(template, count, createdByNameMap[template.ID.String()]))
}
func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) {
@@ -97,6 +107,7 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) {
func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Request) {
var createTemplate codersdk.CreateTemplateRequest
organization := httpmw.OrganizationParam(r)
+ apiKey := httpmw.APIKey(r)
if !api.Authorize(rw, r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) {
return
}
@@ -175,6 +186,10 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
Description: createTemplate.Description,
MaxTtl: int64(maxTTL),
MinAutostartInterval: int64(minAutostartInterval),
+ CreatedBy: uuid.NullUUID{
+ UUID: apiKey.UserID,
+ Valid: true,
+ },
})
if err != nil {
return xerrors.Errorf("insert template: %s", err)
@@ -208,7 +223,12 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
}
}
- template = convertTemplate(dbTemplate, 0)
+ createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), db, []database.Template{dbTemplate})
+ if err != nil {
+ return xerrors.Errorf("get creator name: %w", err)
+ }
+
+ template = convertTemplate(dbTemplate, 0, createdByNameMap[dbTemplate.ID.String()])
return nil
})
if err != nil {
@@ -258,7 +278,16 @@ func (api *API) templatesByOrganization(rw http.ResponseWriter, r *http.Request)
return
}
- httpapi.Write(rw, http.StatusOK, convertTemplates(templates, workspaceCounts))
+ createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, templates)
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching creator names.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ httpapi.Write(rw, http.StatusOK, convertTemplates(templates, workspaceCounts, createdByNameMap))
}
func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Request) {
@@ -304,7 +333,16 @@ func (api *API) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Re
count = uint32(workspaceCounts[0].Count)
}
- httpapi.Write(rw, http.StatusOK, convertTemplate(template, count))
+ createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{template})
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching creator name.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ httpapi.Write(rw, http.StatusOK, convertTemplate(template, count, createdByNameMap[template.ID.String()]))
}
func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
@@ -400,10 +438,35 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) {
return
}
- httpapi.Write(rw, http.StatusOK, convertTemplate(updated, count))
+ createdByNameMap, err := getCreatedByNamesByTemplateIDs(r.Context(), api.Database, []database.Template{updated})
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching creator name.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ httpapi.Write(rw, http.StatusOK, convertTemplate(updated, count, createdByNameMap[updated.ID.String()]))
+}
+
+func getCreatedByNamesByTemplateIDs(ctx context.Context, db database.Store, templates []database.Template) (map[string]string, error) {
+ creators := make(map[string]string, len(templates))
+ for _, template := range templates {
+ if template.CreatedBy.Valid {
+ creator, err := db.GetUserByID(ctx, template.CreatedBy.UUID)
+ if err != nil {
+ return map[string]string{}, err
+ }
+ creators[template.ID.String()] = creator.Username
+ } else {
+ creators[template.ID.String()] = ""
+ }
+ }
+ return creators, nil
}
-func convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template {
+func convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow, createdByNameMap map[string]string) []codersdk.Template {
apiTemplates := make([]codersdk.Template, 0, len(templates))
for _, template := range templates {
found := false
@@ -411,18 +474,18 @@ func convertTemplates(templates []database.Template, workspaceCounts []database.
if workspaceCount.TemplateID.String() != template.ID.String() {
continue
}
- apiTemplates = append(apiTemplates, convertTemplate(template, uint32(workspaceCount.Count)))
+ apiTemplates = append(apiTemplates, convertTemplate(template, uint32(workspaceCount.Count), createdByNameMap[template.ID.String()]))
found = true
break
}
if !found {
- apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0)))
+ apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0), createdByNameMap[template.ID.String()]))
}
}
return apiTemplates
}
-func convertTemplate(template database.Template, workspaceOwnerCount uint32) codersdk.Template {
+func convertTemplate(template database.Template, workspaceOwnerCount uint32, createdByName string) codersdk.Template {
return codersdk.Template{
ID: template.ID,
CreatedAt: template.CreatedAt,
@@ -435,5 +498,7 @@ func convertTemplate(template database.Template, workspaceOwnerCount uint32) cod
Description: template.Description,
MaxTTLMillis: time.Duration(template.MaxTtl).Milliseconds(),
MinAutostartIntervalMillis: time.Duration(template.MinAutostartInterval).Milliseconds(),
+ CreatedByID: template.CreatedBy,
+ CreatedByName: createdByName,
}
}
diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go
index e6505a5395c83..cefe4ded6cdc6 100644
--- a/coderd/workspacebuilds.go
+++ b/coderd/workspacebuilds.go
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"net/http"
+ "strconv"
"github.com/go-chi/chi/v5"
"github.com/google/uuid"
@@ -160,6 +161,82 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(rw, http.StatusOK, apiBuilds)
}
+func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Request) {
+ owner := httpmw.UserParam(r)
+ workspaceName := chi.URLParam(r, "workspacename")
+ buildNumber, err := strconv.ParseInt(chi.URLParam(r, "buildnumber"), 10, 32)
+ if err != nil {
+ httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
+ Message: "Failed to parse build number as integer.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ workspace, err := api.Database.GetWorkspaceByOwnerIDAndName(r.Context(), database.GetWorkspaceByOwnerIDAndNameParams{
+ OwnerID: owner.ID,
+ Name: workspaceName,
+ })
+ if errors.Is(err, sql.ErrNoRows) {
+ httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
+ Message: fmt.Sprintf("Workspace %q does not exist.", workspaceName),
+ })
+ return
+ }
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching workspace by name.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ if !api.Authorize(rw, r, rbac.ActionRead, rbac.ResourceWorkspace.
+ InOrg(workspace.OrganizationID).WithOwner(workspace.OwnerID.String()).WithID(workspace.ID.String())) {
+ return
+ }
+
+ workspaceBuild, err := api.Database.GetWorkspaceBuildByWorkspaceIDAndBuildNumber(r.Context(), database.GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams{
+ WorkspaceID: workspace.ID,
+ BuildNumber: int32(buildNumber),
+ })
+ if errors.Is(err, sql.ErrNoRows) {
+ httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
+ Message: fmt.Sprintf("Workspace %q Build %d does not exist.", workspaceName, buildNumber),
+ })
+ return
+ }
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching workspace build.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ job, err := api.Database.GetProvisionerJobByID(r.Context(), workspaceBuild.JobID)
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching provisioner job.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ users, err := api.Database.GetUsersByIDs(r.Context(), []uuid.UUID{workspace.OwnerID, workspaceBuild.InitiatorID})
+ if err != nil {
+ httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
+ Message: "Internal error fetching user.",
+ Detail: err.Error(),
+ })
+ return
+ }
+
+ httpapi.Write(rw, http.StatusOK,
+ convertWorkspaceBuild(findUser(workspace.OwnerID, users), findUser(workspaceBuild.InitiatorID, users),
+ workspace, workspaceBuild, job))
+}
+
func (api *API) workspaceBuildByName(rw http.ResponseWriter, r *http.Request) {
workspace := httpmw.WorkspaceParam(r)
if !api.Authorize(rw, r, rbac.ActionRead, rbac.ResourceWorkspace.
diff --git a/coderd/workspacebuilds_test.go b/coderd/workspacebuilds_test.go
index 1734f52b836f9..3833cee09171c 100644
--- a/coderd/workspacebuilds_test.go
+++ b/coderd/workspacebuilds_test.go
@@ -2,7 +2,9 @@ package coderd_test
import (
"context"
+ "fmt"
"net/http"
+ "strconv"
"testing"
"time"
@@ -28,6 +30,94 @@ func TestWorkspaceBuild(t *testing.T) {
require.NoError(t, err)
}
+func TestWorkspaceBuildByBuildNumber(t *testing.T) {
+ t.Parallel()
+ t.Run("Successful", func(t *testing.T) {
+ t.Parallel()
+ client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
+ first := coderdtest.CreateFirstUser(t, client)
+ user, err := client.User(context.Background(), codersdk.Me)
+ require.NoError(t, err, "fetch me")
+ version := coderdtest.CreateTemplateVersion(t, client, first.OrganizationID, nil)
+ template := coderdtest.CreateTemplate(t, client, first.OrganizationID, version.ID)
+ coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
+ workspace := coderdtest.CreateWorkspace(t, client, first.OrganizationID, template.ID)
+ _, err = client.WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber(
+ context.Background(),
+ user.Username,
+ workspace.Name,
+ strconv.FormatInt(int64(workspace.LatestBuild.BuildNumber), 10),
+ )
+ require.NoError(t, err)
+ })
+
+ t.Run("BuildNumberNotInt", func(t *testing.T) {
+ t.Parallel()
+ client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
+ first := coderdtest.CreateFirstUser(t, client)
+ user, err := client.User(context.Background(), codersdk.Me)
+ require.NoError(t, err, "fetch me")
+ version := coderdtest.CreateTemplateVersion(t, client, first.OrganizationID, nil)
+ template := coderdtest.CreateTemplate(t, client, first.OrganizationID, version.ID)
+ coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
+ workspace := coderdtest.CreateWorkspace(t, client, first.OrganizationID, template.ID)
+ _, err = client.WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber(
+ context.Background(),
+ user.Username,
+ workspace.Name,
+ "buildNumber",
+ )
+ var apiError *codersdk.Error
+ require.ErrorAs(t, err, &apiError)
+ require.Equal(t, http.StatusBadRequest, apiError.StatusCode())
+ require.ErrorContains(t, apiError, "Failed to parse build number as integer.")
+ })
+
+ t.Run("WorkspaceNotFound", func(t *testing.T) {
+ t.Parallel()
+ client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
+ first := coderdtest.CreateFirstUser(t, client)
+ user, err := client.User(context.Background(), codersdk.Me)
+ require.NoError(t, err, "fetch me")
+ version := coderdtest.CreateTemplateVersion(t, client, first.OrganizationID, nil)
+ template := coderdtest.CreateTemplate(t, client, first.OrganizationID, version.ID)
+ coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
+ workspace := coderdtest.CreateWorkspace(t, client, first.OrganizationID, template.ID)
+ _, err = client.WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber(
+ context.Background(),
+ user.Username,
+ "workspaceName",
+ strconv.FormatInt(int64(workspace.LatestBuild.BuildNumber), 10),
+ )
+ var apiError *codersdk.Error
+ require.ErrorAs(t, err, &apiError)
+ require.Equal(t, http.StatusNotFound, apiError.StatusCode())
+ require.ErrorContains(t, apiError, "Workspace \"workspaceName\" does not exist.")
+ })
+
+ t.Run("WorkspaceBuildNotFound", func(t *testing.T) {
+ t.Parallel()
+ client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
+ first := coderdtest.CreateFirstUser(t, client)
+ user, err := client.User(context.Background(), codersdk.Me)
+ require.NoError(t, err, "fetch me")
+ version := coderdtest.CreateTemplateVersion(t, client, first.OrganizationID, nil)
+ template := coderdtest.CreateTemplate(t, client, first.OrganizationID, version.ID)
+ coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
+ workspace := coderdtest.CreateWorkspace(t, client, first.OrganizationID, template.ID)
+ _, err = client.WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber(
+ context.Background(),
+ user.Username,
+ workspace.Name,
+ "200",
+ )
+ var apiError *codersdk.Error
+ require.ErrorAs(t, err, &apiError)
+ require.Equal(t, http.StatusNotFound, apiError.StatusCode())
+ require.ErrorContains(t, apiError, fmt.Sprintf("Workspace %q Build 200 does not exist.", workspace.Name))
+ })
+}
+
func TestWorkspaceBuilds(t *testing.T) {
t.Parallel()
t.Run("Single", func(t *testing.T) {
diff --git a/codersdk/templates.go b/codersdk/templates.go
index e137c3fca05b3..31f1ea97d9b59 100644
--- a/codersdk/templates.go
+++ b/codersdk/templates.go
@@ -25,6 +25,8 @@ type Template struct {
Description string `json:"description"`
MaxTTLMillis int64 `json:"max_ttl_ms"`
MinAutostartIntervalMillis int64 `json:"min_autostart_interval_ms"`
+ CreatedByID uuid.NullUUID `json:"created_by_id"`
+ CreatedByName string `json:"created_by_name"`
}
type UpdateActiveTemplateVersion struct {
diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go
index ec5dfcbc63ccd..79dae16d8f12c 100644
--- a/codersdk/workspacebuilds.go
+++ b/codersdk/workspacebuilds.go
@@ -103,3 +103,16 @@ func (c *Client) WorkspaceBuildState(ctx context.Context, build uuid.UUID) ([]by
}
return io.ReadAll(res.Body)
}
+
+func (c *Client) WorkspaceBuildByUsernameAndWorkspaceNameAndBuildNumber(ctx context.Context, username string, workspaceName string, buildNumber string) (WorkspaceBuild, error) {
+ res, err := c.Request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/users/%s/workspace/%s/builds/%s", username, workspaceName, buildNumber), nil)
+ if err != nil {
+ return WorkspaceBuild{}, err
+ }
+ defer res.Body.Close()
+ if res.StatusCode != http.StatusOK {
+ return WorkspaceBuild{}, readBodyAsError(res)
+ }
+ var workspaceBuild WorkspaceBuild
+ return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild)
+}
diff --git a/docs/README.md b/docs/README.md
index e01b58e5fa0d8..b69d731b56179 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,5 +1,9 @@
# Coder Documentation
+
+
+
+
## Table of Contents
- [About Coder](./about.md#about-coder)
diff --git a/docs/manifest.json b/docs/manifest.json
index b75b003dc5711..846d49d0b8245 100644
--- a/docs/manifest.json
+++ b/docs/manifest.json
@@ -22,7 +22,7 @@
{
"title": "Quickstart",
"description": "Create your first template and workspace",
- "icon": "",
+ "icon": "",
"path": "./quickstart.md"
},
{
diff --git a/go.mod b/go.mod
index 93f821a3ca5e2..38d06b60a52f2 100644
--- a/go.mod
+++ b/go.mod
@@ -53,8 +53,6 @@ require (
github.com/coder/retry v1.3.0
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf
github.com/creack/pty v1.1.18
- github.com/fatedier/frp v0.42.0
- github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac
github.com/fatih/color v1.13.0
github.com/fatih/structs v1.1.0
github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa
@@ -118,6 +116,9 @@ require (
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.10
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df
+ golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d
+ golang.zx2c4.com/wireguard/tun/netstack v0.0.0-20220407013110-ef5c587f782d
+ golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b
google.golang.org/api v0.82.0
google.golang.org/protobuf v1.28.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
@@ -127,23 +128,16 @@ require (
storj.io/drpc v0.0.30
)
-require (
- github.com/agnivade/levenshtein v1.0.1 // indirect
- github.com/vektah/gqlparser/v2 v2.4.4 // indirect
- github.com/yuin/goldmark v1.4.12 // indirect
-)
-
require (
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
- github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
github.com/Microsoft/go-winio v0.5.2 // indirect
github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect
github.com/OneOfOne/xxhash v1.2.8 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
+ github.com/agnivade/levenshtein v1.0.1 // indirect
github.com/alecthomas/chroma v0.10.0 // indirect
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
- github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bep/godartsass v0.14.0 // indirect
github.com/bep/golibsass v1.1.0 // indirect
@@ -154,15 +148,12 @@ require (
github.com/clbanning/mxj/v2 v2.5.5 // indirect
github.com/containerd/console v1.0.3 // indirect
github.com/containerd/continuity v0.3.0 // indirect
- github.com/coreos/go-oidc v2.2.1+incompatible // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/docker/cli v20.10.14+incompatible // indirect
github.com/docker/docker v20.10.13+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
- github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb // indirect
- github.com/fatedier/kcp-go v2.0.4-0.20190803094908-fe8645b0a904+incompatible // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/gin-gonic/gin v1.7.0 // indirect
github.com/go-chi/chi v1.5.4
@@ -177,11 +168,10 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
- github.com/golang/snappy v0.0.4 // indirect
+ github.com/google/btree v1.0.1 // indirect
github.com/google/go-cmp v0.5.8 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
- github.com/gorilla/mux v1.8.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -191,8 +181,6 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
github.com/klauspost/compress v1.15.0 // indirect
- github.com/klauspost/cpuid/v2 v2.0.6 // indirect
- github.com/klauspost/reedsolomon v1.9.15 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
@@ -224,10 +212,8 @@ require (
github.com/pion/sdp/v3 v3.0.5 // indirect
github.com/pion/srtp/v2 v2.0.9 // indirect
github.com/pion/stun v0.3.5 // indirect
- github.com/pires/go-proxyproto v0.6.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
- github.com/pquerna/cachecontrol v0.1.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
@@ -239,13 +225,12 @@ require (
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/tadvi/systray v0.0.0-20190226123456-11a2b8fa57af // indirect
github.com/tdewolff/parse/v2 v2.5.31 // indirect
- github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 // indirect
- github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b // indirect
- github.com/tjfoc/gmsm v1.4.1 // indirect
+ github.com/vektah/gqlparser/v2 v2.4.4 // indirect
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yashtewari/glob-intersection v0.1.0 // indirect
+ github.com/yuin/goldmark v1.4.12 // indirect
github.com/zclconf/go-cty v1.10.0 // indirect
github.com/zeebo/errs v1.2.2 // indirect
go.opencensus.io v0.23.0 // indirect
@@ -257,10 +242,10 @@ require (
go.opentelemetry.io/otel/trace v1.7.0
go.opentelemetry.io/proto/otlp v0.16.0 // indirect
golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
+ golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220527130721-00d5c0f3be58 // indirect
google.golang.org/grpc v1.47.0 // indirect
- gopkg.in/ini.v1 v1.62.0 // indirect
- gopkg.in/square/go-jose.v2 v2.6.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
+ gvisor.dev/gvisor v0.0.0-20211020211948-f76a604701b6 // indirect
)
diff --git a/go.sum b/go.sum
index 3ba4ccc9472f3..e7077ce680395 100644
--- a/go.sum
+++ b/go.sum
@@ -75,24 +75,28 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOEl
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
+github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
-github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw=
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY=
+github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=
github.com/Azure/go-autorest/autorest/adal v0.9.16/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A=
+github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
+github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
+github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0=
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
+github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
+github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
-github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c h1:/IBSNwUN8+eKzUzbJPqhK839ygXJ82sde8x3ogr6R28=
-github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -106,6 +110,7 @@ github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugX
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84=
+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.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA=
github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
@@ -134,6 +139,7 @@ github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdII
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
+github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
@@ -176,7 +182,6 @@ github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hC
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
-github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
@@ -211,6 +216,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.6.1/go.mod h1:hLZ/AnkIKHLuPGjEiyghNE
github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g=
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
+github.com/bazelbuild/rules_go v0.27.0/go.mod h1:MC23Dc/wkXEyk3Wpq6lCqz0ZAYOZDw2DR5y3N1q2i7M=
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -230,6 +236,7 @@ github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwj
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
github.com/bool64/shared v0.1.4 h1:zwtb1dl2QzDa9TJOq2jzDTdb5IPf9XlxTGKN8cySWT0=
@@ -243,6 +250,7 @@ github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0Bsq
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
github.com/bytecodealliance/wasmtime-go v0.36.0 h1:B6thr7RMM9xQmouBtUqm1RpkJjuLS37m6nxX+iwsQSc=
github.com/bytecodealliance/wasmtime-go v0.36.0/go.mod h1:q320gUxqyI8yB+ZqRuaJOEnGkAnHh6WtJjMaT2CW4wI=
+github.com/cenkalti/backoff v1.1.1-0.20190506075156-2146c9339422/go.mod h1:b6Nc7NRH5C4aCISLry0tLnTjcuTEvoiqcWDdsU0sOGM=
github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
@@ -302,8 +310,6 @@ github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoC
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI=
github.com/coder/glog v1.0.1-0.20220322161911-7365fe7f2cd1 h1:UqBrPWSYvRI2s5RtOul20JukUEpu4ip9u7biBL+ntgk=
github.com/coder/glog v1.0.1-0.20220322161911-7365fe7f2cd1/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4=
-github.com/coder/kcp-go v2.0.4-0.20220409183554-83c0904cec69+incompatible h1:lv2sbJ2U6TOCeQhhtyMlcgBT96hX3AoCa9mIWwJUWuI=
-github.com/coder/kcp-go v2.0.4-0.20220409183554-83c0904cec69+incompatible/go.mod h1:sW9REGQSqLlZLRRby6CuuTsZ3FkqAEkGnrANKve7tzQ=
github.com/coder/retry v1.3.0 h1:5lAAwt/2Cm6lVmnfBY7sOMXcBOwcwJhmV5QGSELIVWY=
github.com/coder/retry v1.3.0/go.mod h1:tXuRgZgWjUnU5LZPT4lJh4ew2elUhexhlnXzrJWdyFY=
github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE=
@@ -318,6 +324,7 @@ github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqh
github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM=
github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo=
+github.com/containerd/cgroups v0.0.0-20201119153540-4cbc285b3327/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE=
github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU=
github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8=
@@ -333,6 +340,7 @@ github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.
github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
+github.com/containerd/containerd v1.3.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
@@ -359,6 +367,7 @@ github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvA
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI=
+github.com/containerd/fifo v0.0.0-20191213151349-ff969a566b00/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0=
github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4=
@@ -374,6 +383,7 @@ github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHr
github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok=
github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0=
+github.com/containerd/imgcrypt v1.0.3/go.mod h1:v4X3p/H0lzcvVE0r7whbRYjYuK9Y2KEJnL08tXT63Is=
github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA=
github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow=
github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms=
@@ -391,6 +401,7 @@ github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8h
github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ=
github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc=
github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk=
+github.com/containerd/typeurl v0.0.0-20200205145503-b45ef1f1f737/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw=
@@ -404,10 +415,12 @@ github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y=
github.com/containernetworking/cni v1.1.0/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw=
github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM=
+github.com/containernetworking/plugins v0.8.7/go.mod h1:R7lXeZaBzpfqapcAbHRW8/CYwm0dHzbz0XEjofx0uB0=
github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8=
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE=
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8=
github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc=
+github.com/containers/ocicrypt v1.0.3/go.mod h1:CUBa+8MRNL/VkpxYIpaMtgn1WgXGyvPQj8jcy0EVG6g=
github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4=
github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY=
@@ -420,8 +433,6 @@ github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmeka
github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU=
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q=
github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
-github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk=
-github.com/coreos/go-oidc v2.2.1+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -453,6 +464,7 @@ github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg=
+github.com/davecgh/go-spew v0.0.0-20151105211317-5215b55f46b2/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -483,11 +495,13 @@ github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4Kfc
github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68=
github.com/docker/distribution v2.8.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v1.4.2-0.20191028175130-9e7d5ac5ea55/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.11+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.13+incompatible h1:5s7uxnKZG+b8hYWlPYUi6x1Sjpq2MSt96d15eLZeHyw=
github.com/docker/docker v20.10.13+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
github.com/docker/docker-credential-helpers v0.6.4/go.mod h1:ofX3UI0Gz1TteYBjtgs07O36Pyasyp66D2uKT7H8W1c=
+github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
@@ -503,6 +517,7 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/edsrzf/mmap-go v0.0.0-20170320065105-0bce6a688712/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M=
+github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
@@ -520,14 +535,9 @@ github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPO
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws=
+github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb h1:wCrNShQidLmvVWn/0PikGmpdP0vtQmnvyRg3ZBEhczw=
-github.com/fatedier/beego v0.0.0-20171024143340-6c6a4f5bd5eb/go.mod h1:wx3gB6dbIfBRcucp94PI9Bt3I0F2c/MyNEWuhzpWiwk=
-github.com/fatedier/frp v0.42.0 h1:IIPCKB5OgGetjIk7vv3MlR3iL8qS0d7uM3kjWs6eymU=
-github.com/fatedier/frp v0.42.0/go.mod h1:NahedvXauelo3mcioq3gahG3BdhTfJ4Gia6rRQnE02A=
-github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac h1:td1FJwN/oz8+9GldeEm3YdBX0Husc0FSPywLesZxi4w=
-github.com/fatedier/golib v0.1.1-0.20220321042308-c306138b83ac/go.mod h1:fLV0TLwHqrnB/L3jbNl67Gn6PCLggDGHniX1wLrA2Qo=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
@@ -616,16 +626,20 @@ github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jT
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
+github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
+github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
+github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
+github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
@@ -639,7 +653,6 @@ github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/j
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
-github.com/go-playground/validator/v10 v10.6.1/go.mod h1:xm76BBt941f7yWdGnI2DVPFFg1UK3YY04qifoXU3lOk=
github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw=
github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU=
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
@@ -696,12 +709,14 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
+github.com/gofrs/flock v0.8.0/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
+github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
@@ -734,6 +749,7 @@ github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
+github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.0.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -762,6 +778,7 @@ github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
github.com/gomodule/redigo v1.8.2/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v2.0.0+incompatible h1:dicJ2oXwypfwUGnB2/TYWYEKiuk9eYQlQO/AnOHl5mI=
@@ -782,12 +799,14 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0=
+github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
github.com/google/go-github/v43 v43.0.1-0.20220414155304-00e42332e405 h1:DdHws/YnnPrSywrjNYu2lEHqYHWp/LnEx56w59esd54=
github.com/google/go-github/v43 v43.0.1-0.20220414155304-00e42332e405/go.mod h1:4RgUDSnsxP19d65zJWqvqJ/poJxBCvmna50eXmIvoR8=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
@@ -808,12 +827,14 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
+github.com/google/pprof v0.0.0-20210423192551-a2663126120b/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
+github.com/google/subcommands v1.0.2-0.20190508160503-636abe8753b8/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -827,11 +848,13 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM=
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM=
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c=
+github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
+github.com/googleapis/gnostic v0.4.0/go.mod h1:on+2t9HRStVgn95RSsFWFz+6Q0Snyqv1awfrALZdbtU=
github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg=
github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU=
github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
@@ -839,7 +862,6 @@ github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv
github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
-github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@@ -872,6 +894,7 @@ github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjh
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
@@ -902,7 +925,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J
github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk=
github.com/hashicorp/terraform-json v0.14.0 h1:sh9iZ1Y8IFJLx+xQiKHGud6/TSUCM0N8e17dKDpqV7s=
github.com/hashicorp/terraform-json v0.14.0/go.mod h1:5A9HIWPkk4e5aeeXIBbkcOvaZbIYnAIkEyqP2pNSckM=
-github.com/hashicorp/yamux v0.0.0-20210707203944-259a57b3608c/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87 h1:xixZ2bWeofWV68J+x6AzmKuVM/JWCQwkWm6GW/MUR6I=
github.com/hashicorp/yamux v0.0.0-20211028200310-0bc27b27de87/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
@@ -914,6 +936,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
@@ -987,6 +1010,7 @@ github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
+github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
@@ -996,7 +1020,6 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
@@ -1029,10 +1052,6 @@ github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U=
github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/cpuid/v2 v2.0.6 h1:dQ5ueTiftKxp0gyjKSx5+8BtPWkyQbd95m8Gys/RarI=
-github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
-github.com/klauspost/reedsolomon v1.9.15 h1:g2erWKD2M6rgnPf89fCji6jNlhMKMdXcuNHMW1SYCIo=
-github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAKAP/qs14y4GCBOk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -1045,6 +1064,7 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/pty v1.1.4-0.20190131011033-7dc38fb350b1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
@@ -1084,6 +1104,7 @@ github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
+github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
@@ -1093,6 +1114,7 @@ github.com/markbates/pkger v0.15.1/go.mod h1:0JoVlrol20BSywW79rN3kdFFsE5xYM+rSCQ
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
+github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a/go.mod h1:M1qoD/MqPgTZIk0EWKB38wE28ACRfVcn+cU08jyArI0=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
@@ -1174,10 +1196,12 @@ github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6U
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
+github.com/mohae/deepcopy v0.0.0-20170308212314-bb9b5e7adda9/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8=
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
@@ -1225,7 +1249,6 @@ github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0=
github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY=
-github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E=
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c=
@@ -1235,9 +1258,9 @@ github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1Cpa
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
+github.com/onsi/gomega v1.10.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0=
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
github.com/open-policy-agent/opa v0.41.0 h1:XDTkP8bcUVuY8WOVbRY4e/KZW31+f+/cxisPc0TPe5E=
@@ -1258,6 +1281,7 @@ github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5X
github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
+github.com/opencontainers/runc v1.0.0-rc90/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0=
github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0=
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc=
@@ -1280,6 +1304,7 @@ github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFSt
github.com/ory/dockertest/v3 v3.9.1 h1:v4dkG+dlu76goxMiTT2j8zV7s4oPPEppKT8K8p2f1kY=
github.com/ory/dockertest/v3 v3.9.1/go.mod h1:42Ir9hmvaAPm0Mgibk6mBPi7SFvTXxEcnztDYOJ//uM=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
@@ -1331,8 +1356,6 @@ github.com/pion/udp v0.1.1 h1:8UAPvyqmsxK8oOjloDk4wUt63TzFe9WEJkg5lChlj7o=
github.com/pion/udp v0.1.1/go.mod h1:6AFo+CMdKQm7UiA0eUPA8/eVCTx8jBIITLZHc9DWX5M=
github.com/pion/webrtc/v3 v3.1.41 h1:QogLjtriu+OwerRp4r6emTg4+zDWUy5R6EqthDBy7c0=
github.com/pion/webrtc/v3 v3.1.41/go.mod h1:sUcW9SFPEWerDqGOBmdYEMfRvbdd7rgwo4bNzfsXww4=
-github.com/pires/go-proxyproto v0.6.2 h1:KAZ7UteSOt6urjme6ZldyFm4wDe/z0ZUP0Yv0Dos0d8=
-github.com/pires/go-proxyproto v0.6.2/go.mod h1:Odh9VFOZJCf9G8cLW5o435Xf1J95Jw9Gw5rnCjcwzAY=
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
@@ -1348,16 +1371,15 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pkg/sftp v1.13.4 h1:Lb0RYJCmgUcBgZosfoi9Y9sbl6+LJgOIgk/2Y4YjMFg=
github.com/pkg/sftp v1.13.4/go.mod h1:LzqnAvaD5TWeNBsZpfKxSYn1MbjWwOsCIAFFJbpIsK8=
+github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
-github.com/pquerna/cachecontrol v0.1.0 h1:yJMy84ti9h/+OEWa752kBTKv4XC30OtVVHYv/8cTqKc=
-github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
+github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM=
github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
@@ -1375,6 +1397,7 @@ github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
+github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
@@ -1385,6 +1408,7 @@ github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuI
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
+github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
@@ -1408,7 +1432,6 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -1453,10 +1476,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/snowflakedb/gosnowflake v1.6.3/go.mod h1:6hLajn6yxuJ4xUHZegMekpq9rnQbGJ7TMwXjgTmA6lg=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -1501,6 +1522,7 @@ github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
+github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -1525,13 +1547,7 @@ github.com/tdewolff/parse/v2 v2.5.31 h1:PrJN/trWTUYaYxg7jRpKnKXpBK4kBjT9rAFhFAh2
github.com/tdewolff/parse/v2 v2.5.31/go.mod h1:WzaJpRSbwq++EIQHYIRTpbYKNA3gn9it1Ik++q4zyho=
github.com/tdewolff/test v1.0.6 h1:76mzYJQ83Op284kMT+63iCNCI7NEERsIN8dLM+RiKr4=
github.com/tdewolff/test v1.0.6/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE=
-github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161 h1:89CEmDvlq/F7SJEOqkIdNDGJXrQIhuIx9D2DBXjavSU=
-github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU=
-github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b h1:fj5tQ8acgNUr6O8LEplsxDhUIe2573iLkJc+PqnzZTI=
-github.com/templexxx/xor v0.0.0-20191217153810-f85b25db303b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
-github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
-github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -1551,6 +1567,7 @@ github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX
github.com/vektah/gqlparser/v2 v2.4.4 h1:rh9hwZ5Jx9cCq88zXz2YHKmuQBuwY1JErHU8GywFdwE=
github.com/vektah/gqlparser/v2 v2.4.4/go.mod h1:flJWIR04IMQPGz+BXLrORkrARBxv/rtyIAFvd/MceW0=
github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
+github.com/vishvananda/netlink v1.0.1-0.20190930145447-2ec5bdc52b86/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho=
@@ -1579,7 +1596,6 @@ github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/xtaci/lossyconn v0.0.0-20200209145036-adba10fffc37/go.mod h1:HpMP7DB2CyokmAh4lp0EQnnWhmycP/TvwBGzvuie+H0=
github.com/yashtewari/glob-intersection v0.1.0 h1:6gJvMYQlTDOL3dMsPF6J0+26vwX9MB8/1q3uAdhmTrg=
github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
@@ -1686,6 +1702,7 @@ golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -1700,12 +1717,12 @@ golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
@@ -1772,11 +1789,13 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o=
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
+golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -1817,7 +1836,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
@@ -1826,7 +1844,6 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
@@ -1893,6 +1910,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20170830134202-bb24a47a89ea/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180224232135-f6cff0780e54/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180816055513-1c9583448a9c/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1903,6 +1921,7 @@ golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1988,6 +2007,7 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210314195730-07df6a141424/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -2042,6 +2062,7 @@ golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -2155,6 +2176,14 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618=
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY=
+golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
+golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d h1:q4JksJ2n0fmbXC0Aj0eOs6E0AcPqnKglxWXWFqGD6x0=
+golang.zx2c4.com/wireguard v0.0.0-20220407013110-ef5c587f782d/go.mod h1:bVQfyl2sCM/QIIGHpWbFGfHPuDvqnCNkT6MQLTCjO/U=
+golang.zx2c4.com/wireguard/tun/netstack v0.0.0-20220407013110-ef5c587f782d h1:az6oQg96FdInSUqcRqptkepJ6TG4+H7W7KS+IFD/MUg=
+golang.zx2c4.com/wireguard/tun/netstack v0.0.0-20220407013110-ef5c587f782d/go.mod h1:JexL7LSkdvAJ7GXgsGHKpFeOAv+SuJiHPeRahPLZ9Qk=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b h1:9JncmKXcUwE918my+H6xmjBdhK2jM/UTUNXxhRG1BAk=
+golang.zx2c4.com/wireguard/wgctrl v0.0.0-20220504211119-3d4a969bb56b/go.mod h1:yp4gl6zOlnDGOZeWeDfMwQcsdOIQnMdhuPx9mwwWBL4=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=
@@ -2182,6 +2211,7 @@ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ
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.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
+google.golang.org/api v0.42.0/go.mod h1:+Oj4s6ch2SEGtPjGqfUfZonBH0GjQH89gTeKKAEGZKI=
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
@@ -2259,6 +2289,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
+google.golang.org/genproto v0.0.0-20210312152112-fc591d9ea70f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A=
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A=
@@ -2328,6 +2359,7 @@ google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM=
+google.golang.org/grpc v1.39.0-dev.0.20210518002758-2713b77e8526/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE=
google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
@@ -2372,17 +2404,13 @@ gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKW
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
-gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
-gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
@@ -2411,6 +2439,8 @@ gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
gotest.tools/v3 v3.1.0/go.mod h1:fHy7eyTmJFO5bQbUsEGQ1v4m2J3Jz9eWL54TP2/ZuYQ=
gotest.tools/v3 v3.2.0 h1:I0DwBVMGAx26dttAj1BtJLAkVGncrkkUXfJLC4Flt/I=
+gvisor.dev/gvisor v0.0.0-20211020211948-f76a604701b6 h1:lgV5mAyX6S2EZAkZcvFkAs18WZ7yJbRzEv/PCH8iSlw=
+gvisor.dev/gvisor v0.0.0-20211020211948-f76a604701b6/go.mod h1:m1RK/gef4nU1CWOFscQWVk7iUgGH2Hz9Ee+lgeCzOBo=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
@@ -2418,27 +2448,30 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
+honnef.co/go/tools v0.1.1/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las=
+k8s.io/api v0.16.13/go.mod h1:QWu8UWSTiuQZMMeYjwLs6ILu5O74qKSJ0c+4vrchDxs=
k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo=
k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ=
k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8=
-k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU=
k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs=
+k8s.io/apimachinery v0.16.13/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
+k8s.io/apimachinery v0.16.14-rc.0/go.mod h1:4HMHS3mDHtVttspuuhrJ1GGr/0S9B6iWYWZ57KnnZqQ=
k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU=
k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc=
-k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM=
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0=
k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U=
k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU=
k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM=
k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q=
k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ=
+k8s.io/client-go v0.16.13/go.mod h1:UKvVT4cajC2iN7DCjLgT0KVY/cbY6DGdUCyRiIfws5M=
k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y=
k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k=
k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0=
-k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA=
k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y=
k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0=
+k8s.io/component-base v0.16.13/go.mod h1:cNe9ZU2A6tqBG0gPQ4/T/KolI9Cv2NA1+7uvmkA7Cyc=
k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk=
k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI=
k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM=
@@ -2448,21 +2481,25 @@ k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI=
k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc=
k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4=
+k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
+k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk=
+k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
-k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec=
k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-openapi v0.0.0-20200410163147-594e756bea31/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o=
k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM=
-k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
+k8s.io/utils v0.0.0-20190801114015-581e00157fb1/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
@@ -2504,10 +2541,10 @@ rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
+sigs.k8s.io/structured-merge-diff v0.0.0-20190525122527-15d366b2352e/go.mod h1:wWxsB5ozmmv/SG7nM11ayaAW51xMvak/t1r0CSlcokI=
sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
-sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw=
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=
diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go
index 044ad9837445a..639ed8876fba3 100644
--- a/provisioner/terraform/resources.go
+++ b/provisioner/terraform/resources.go
@@ -127,6 +127,10 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res
}
}
+ if agentResource == nil {
+ continue
+ }
+
agents, exists := resourceAgents[agentResource.Label]
if !exists {
agents = make([]*proto.Agent, 0)
diff --git a/site/src/AppRouter.tsx b/site/src/AppRouter.tsx
index 8c8880c9de408..253a3c8e8c63f 100644
--- a/site/src/AppRouter.tsx
+++ b/site/src/AppRouter.tsx
@@ -113,15 +113,6 @@ export const AppRouter: FC = () => (
} />
-
-
-
- }
- />
-
(
}
/>
+
+
+
+
+ }
+ />
diff --git a/site/src/api/api.ts b/site/src/api/api.ts
index 2e32b1ffbe707..09c14645fbffb 100644
--- a/site/src/api/api.ts
+++ b/site/src/api/api.ts
@@ -268,8 +268,14 @@ export const getWorkspaceBuilds = async (workspaceId: string): Promise => {
- const response = await axios.get(`/api/v2/workspacebuilds/${workspaceId}`)
+export const getWorkspaceBuildByNumber = async (
+ username = "me",
+ workspaceName: string,
+ buildNumber: string,
+): Promise => {
+ const response = await axios.get(
+ `/api/v2/users/${username}/workspace/${workspaceName}/builds/${buildNumber}`,
+ )
return response.data
}
diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts
index ce0fae95ce4b0..79423268ac6a2 100644
--- a/site/src/api/typesGenerated.ts
+++ b/site/src/api/typesGenerated.ts
@@ -247,6 +247,8 @@ export interface Template {
readonly description: string
readonly max_ttl_ms: number
readonly min_autostart_interval_ms: number
+ readonly created_by_id?: string
+ readonly created_by_name: string
}
// From codersdk/templateversions.go:14:6
@@ -276,12 +278,12 @@ export interface TemplateVersionParameter {
readonly default_source_value: boolean
}
-// From codersdk/templates.go:98:6
+// From codersdk/templates.go:100:6
export interface TemplateVersionsByTemplateRequest extends Pagination {
readonly template_id: string
}
-// From codersdk/templates.go:30:6
+// From codersdk/templates.go:32:6
export interface UpdateActiveTemplateVersion {
readonly id: string
}
@@ -291,7 +293,7 @@ export interface UpdateRoles {
readonly roles: string[]
}
-// From codersdk/templates.go:34:6
+// From codersdk/templates.go:36:6
export interface UpdateTemplateMeta {
readonly description?: string
readonly max_ttl_ms?: number
diff --git a/site/src/components/BuildsTable/BuildsTable.tsx b/site/src/components/BuildsTable/BuildsTable.tsx
index 2e924c8157f4f..c9de9bd6d14ea 100644
--- a/site/src/components/BuildsTable/BuildsTable.tsx
+++ b/site/src/components/BuildsTable/BuildsTable.tsx
@@ -8,7 +8,7 @@ import TableRow from "@material-ui/core/TableRow"
import KeyboardArrowRight from "@material-ui/icons/KeyboardArrowRight"
import useTheme from "@material-ui/styles/useTheme"
import { FC } from "react"
-import { useNavigate } from "react-router-dom"
+import { useNavigate, useParams } from "react-router-dom"
import * as TypesGen from "../../api/typesGenerated"
import { displayWorkspaceBuildDuration, getDisplayWorkspaceBuildStatus } from "../../util/workspace"
import { EmptyState } from "../EmptyState/EmptyState"
@@ -29,6 +29,7 @@ export interface BuildsTableProps {
}
export const BuildsTable: FC = ({ builds, className }) => {
+ const { username, workspace: workspaceName } = useParams()
const isLoading = !builds
const theme: Theme = useTheme()
const navigate = useNavigate()
@@ -52,7 +53,7 @@ export const BuildsTable: FC = ({ builds, className }) => {
const status = getDisplayWorkspaceBuildStatus(theme, build)
const navigateToBuildPage = () => {
- navigate(`/builds/${build.id}`)
+ navigate(`/@${username}/${workspaceName}/builds/${build.build_number}`)
}
return (
diff --git a/site/src/components/Resources/Resources.tsx b/site/src/components/Resources/Resources.tsx
index 4e36fc17e2fad..7944323eb4738 100644
--- a/site/src/components/Resources/Resources.tsx
+++ b/site/src/components/Resources/Resources.tsx
@@ -9,16 +9,11 @@ import { FC } from "react"
import { Workspace, WorkspaceResource } from "../../api/typesGenerated"
import { getDisplayAgentStatus } from "../../util/workspace"
import { AppLink } from "../AppLink/AppLink"
-import {
- HelpTooltip,
- HelpTooltipLink,
- HelpTooltipLinksGroup,
- HelpTooltipText,
- HelpTooltipTitle,
-} from "../HelpTooltip/HelpTooltip"
import { Stack } from "../Stack/Stack"
import { TableHeaderRow } from "../TableHeaders/TableHeaders"
import { TerminalLink } from "../TerminalLink/TerminalLink"
+import { AgentHelpTooltip } from "../Tooltips/AgentHelpTooltip"
+import { ResourcesHelpTooltip } from "../Tooltips/ResourcesHelpTooltip"
import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
const Language = {
@@ -28,35 +23,6 @@ const Language = {
agentLabel: "Agent",
statusLabel: "Status",
accessLabel: "Access",
- resourceTooltipTitle: "What is a resource?",
- resourceTooltipText: "A resource is an infrastructure object that is create when the workspace is provisioned.",
- resourceTooltipLink: "Persistent and ephemeral resources",
- agentTooltipTitle: "What is an agent?",
- agentTooltipText:
- "The Coder agent runs inside your resource and gives you direct access to the shell via the UI or CLI.",
-}
-
-const ResourcesHelpTooltip: React.FC = () => {
- return (
-
- {Language.resourceTooltipTitle}
- {Language.resourceTooltipText}
-
-
- {Language.resourceTooltipLink}
-
-
-
- )
-}
-
-const AgentHelpTooltip: React.FC = () => {
- return (
-
- {Language.agentTooltipTitle}
- {Language.agentTooltipText}
-
- )
}
interface ResourcesProps {
diff --git a/site/src/components/TemplateResourcesTable/TemplateResourcesTable.test.tsx b/site/src/components/TemplateResourcesTable/TemplateResourcesTable.test.tsx
new file mode 100644
index 0000000000000..96bfa15acd4f1
--- /dev/null
+++ b/site/src/components/TemplateResourcesTable/TemplateResourcesTable.test.tsx
@@ -0,0 +1,35 @@
+import { fireEvent, render, screen } from "@testing-library/react"
+import { FC } from "react"
+import { WrapperComponent } from "../../testHelpers/renderHelpers"
+import { Language as AgentTooltipLanguage } from "../Tooltips/AgentHelpTooltip"
+import { Language as ResourceTooltipLanguage } from "../Tooltips/ResourcesHelpTooltip"
+import { TemplateResourcesProps, TemplateResourcesTable } from "./TemplateResourcesTable"
+
+const Component: FC = (props) => (
+
+
+
+)
+
+describe("TemplateResourcesTable", () => {
+ it("displays resources tooltip", () => {
+ const props: TemplateResourcesProps = {
+ resources: [],
+ }
+ render()
+ const resourceTooltipButton = screen.getAllByRole("button")[0]
+ fireEvent.click(resourceTooltipButton)
+ const resourceTooltipTitle = screen.getByText(ResourceTooltipLanguage.resourceTooltipTitle)
+ expect(resourceTooltipTitle).toBeDefined()
+ })
+ it("displays agent tooltip", () => {
+ const props: TemplateResourcesProps = {
+ resources: [],
+ }
+ render()
+ const agentTooltipButton = screen.getAllByRole("button")[1]
+ fireEvent.click(agentTooltipButton)
+ const agentTooltipTitle = screen.getByText(AgentTooltipLanguage.agentTooltipTitle)
+ expect(agentTooltipTitle).toBeDefined()
+ })
+})
diff --git a/site/src/components/TemplateResourcesTable/TemplateResourcesTable.tsx b/site/src/components/TemplateResourcesTable/TemplateResourcesTable.tsx
index cb8b7ce22f37e..005c473ccdbbb 100644
--- a/site/src/components/TemplateResourcesTable/TemplateResourcesTable.tsx
+++ b/site/src/components/TemplateResourcesTable/TemplateResourcesTable.tsx
@@ -6,14 +6,17 @@ import TableHead from "@material-ui/core/TableHead"
import TableRow from "@material-ui/core/TableRow"
import { FC } from "react"
import { WorkspaceResource } from "../../api/typesGenerated"
+import { Stack } from "../Stack/Stack"
import { TableHeaderRow } from "../TableHeaders/TableHeaders"
+import { AgentHelpTooltip } from "../Tooltips/AgentHelpTooltip"
+import { ResourcesHelpTooltip } from "../Tooltips/ResourcesHelpTooltip"
-const Language = {
+export const Language = {
resourceLabel: "Resource",
agentLabel: "Agent",
}
-interface TemplateResourcesProps {
+export interface TemplateResourcesProps {
resources: WorkspaceResource[]
}
@@ -24,8 +27,18 @@ export const TemplateResourcesTable: FC = ({ resources }
- {Language.resourceLabel}
- {Language.agentLabel}
+
+
+ {Language.resourceLabel}
+
+
+
+
+
+ {Language.agentLabel}
+
+
+
diff --git a/site/src/components/TemplateStats/TemplateStats.stories.tsx b/site/src/components/TemplateStats/TemplateStats.stories.tsx
index 3056187d110d4..fb7f36d894652 100644
--- a/site/src/components/TemplateStats/TemplateStats.stories.tsx
+++ b/site/src/components/TemplateStats/TemplateStats.stories.tsx
@@ -23,3 +23,12 @@ UsedByMany.args = {
},
activeVersion: Mocks.MockTemplateVersion,
}
+
+export const UnknownCreator = Template.bind({})
+UnknownCreator.args = {
+ template: {
+ ...Mocks.MockTemplate,
+ created_by_name: "",
+ },
+ activeVersion: Mocks.MockTemplateVersion,
+}
diff --git a/site/src/components/TemplateStats/TemplateStats.tsx b/site/src/components/TemplateStats/TemplateStats.tsx
index 24da983939975..fed612f45f019 100644
--- a/site/src/components/TemplateStats/TemplateStats.tsx
+++ b/site/src/components/TemplateStats/TemplateStats.tsx
@@ -13,6 +13,8 @@ const Language = {
lastUpdateLabel: "Last updated",
userPlural: "users",
userSingular: "user",
+ createdByLabel: "Created by",
+ defaultTemplateCreator: "",
}
export interface TemplateStatsProps {
@@ -45,6 +47,11 @@ export const TemplateStats: FC = ({ template, activeVersion
{dayjs().to(dayjs(template.updated_at))}
+
+
+ {Language.createdByLabel}
+ {template.created_by_name || Language.defaultTemplateCreator}
+
)
}
@@ -63,7 +70,7 @@ const useStyles = makeStyles((theme) => ({
},
statItem: {
- minWidth: theme.spacing(20),
+ minWidth: "20%",
padding: theme.spacing(2),
paddingTop: theme.spacing(1.75),
},
diff --git a/site/src/components/Tooltips/AgentHelpTooltip.tsx b/site/src/components/Tooltips/AgentHelpTooltip.tsx
new file mode 100644
index 0000000000000..ce250caaf4bb9
--- /dev/null
+++ b/site/src/components/Tooltips/AgentHelpTooltip.tsx
@@ -0,0 +1,16 @@
+import { HelpTooltip, HelpTooltipText, HelpTooltipTitle } from "./HelpTooltip/HelpTooltip"
+
+export const Language = {
+ agentTooltipTitle: "What is an agent?",
+ agentTooltipText:
+ "The Coder agent runs inside your resource and gives you direct access to the shell via the UI or CLI.",
+}
+
+export const AgentHelpTooltip: React.FC = () => {
+ return (
+
+ {Language.agentTooltipTitle}
+ {Language.agentTooltipText}
+
+ )
+}
diff --git a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx
similarity index 100%
rename from site/src/components/HelpTooltip/HelpTooltip.stories.tsx
rename to site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx
diff --git a/site/src/components/HelpTooltip/HelpTooltip.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx
similarity index 98%
rename from site/src/components/HelpTooltip/HelpTooltip.tsx
rename to site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx
index 8d14452ec2421..2a4e6ed4651f1 100644
--- a/site/src/components/HelpTooltip/HelpTooltip.tsx
+++ b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx
@@ -4,7 +4,7 @@ import { makeStyles } from "@material-ui/core/styles"
import HelpIcon from "@material-ui/icons/HelpOutline"
import OpenInNewIcon from "@material-ui/icons/OpenInNew"
import { useState } from "react"
-import { Stack } from "../Stack/Stack"
+import { Stack } from "../../Stack/Stack"
type Size = "small" | "medium"
export interface HelpTooltipProps {
diff --git a/site/src/components/Tooltips/ResourcesHelpTooltip.tsx b/site/src/components/Tooltips/ResourcesHelpTooltip.tsx
new file mode 100644
index 0000000000000..c5728d9faa897
--- /dev/null
+++ b/site/src/components/Tooltips/ResourcesHelpTooltip.tsx
@@ -0,0 +1,27 @@
+import {
+ HelpTooltip,
+ HelpTooltipLink,
+ HelpTooltipLinksGroup,
+ HelpTooltipText,
+ HelpTooltipTitle,
+} from "./HelpTooltip/HelpTooltip"
+
+export const Language = {
+ resourceTooltipTitle: "What is a resource?",
+ resourceTooltipText: "A resource is an infrastructure object that is create when the workspace is provisioned.",
+ resourceTooltipLink: "Persistent and ephemeral resources",
+}
+
+export const ResourcesHelpTooltip: React.FC = () => {
+ return (
+
+ {Language.resourceTooltipTitle}
+ {Language.resourceTooltipText}
+
+
+ {Language.resourceTooltipLink}
+
+
+
+ )
+}
diff --git a/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx b/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx
index 0db8dfc143362..4b00dd0584f55 100644
--- a/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx
+++ b/site/src/components/WorkspaceBuildStats/WorkspaceBuildStats.tsx
@@ -69,7 +69,7 @@ const useStyles = makeStyles((theme) => ({
},
statItem: {
- minWidth: theme.spacing(20),
+ minWidth: "16%",
padding: theme.spacing(2),
paddingTop: theme.spacing(1.75),
},
diff --git a/site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx b/site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx
index 1a5d35a499f11..5d5d1db960c5c 100644
--- a/site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx
+++ b/site/src/components/WorkspaceSchedule/WorkspaceSchedule.tsx
@@ -17,8 +17,10 @@ import { stripTimezone } from "../../util/schedule"
import { isWorkspaceOn } from "../../util/workspace"
import { Stack } from "../Stack/Stack"
-dayjs.extend(advancedFormat)
+// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
+// sorted alphabetically.
dayjs.extend(utc)
+dayjs.extend(advancedFormat)
dayjs.extend(duration)
dayjs.extend(relativeTime)
dayjs.extend(timezone)
@@ -50,7 +52,7 @@ export const Language = {
if (now.isAfter(deadline)) {
return "Workspace is shutting down"
} else {
- return deadline.tz(dayjs.tz.guess()).format("hh:mm A")
+ return deadline.tz(dayjs.tz.guess()).format("MMM D, YYYY h:mm A")
}
} else if (!ttl || ttl < 1) {
// If the workspace is not on, and the ttl is 0 or undefined, then the
diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.stories.tsx b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.stories.tsx
index c9ea6eafa8b9d..5c3126fc74248 100644
--- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.stories.tsx
+++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.stories.tsx
@@ -22,7 +22,7 @@ export const WorkspaceNotRunning = Template.bind({})
WorkspaceNotRunning.args = {
now: dayjs("2022-05-17T17:40:00Z"),
initialValues: {
- ...defaultWorkspaceSchedule(5, "asdfasdf"),
+ ...defaultWorkspaceSchedule(5),
timezone: "UTC",
},
workspace: {
@@ -41,7 +41,7 @@ export const WorkspaceWillNotShutDown = Template.bind({})
WorkspaceWillNotShutDown.args = {
now: dayjs("2022-05-17T17:40:00Z"),
initialValues: {
- ...defaultWorkspaceSchedule(5, "asdfasdf"),
+ ...defaultWorkspaceSchedule(5),
timezone: "UTC",
ttl: 0,
},
@@ -60,7 +60,7 @@ export const WorkspaceWillShutdown = Template.bind({})
WorkspaceWillShutdown.args = {
now: dayjs("2022-05-17T17:40:00Z"),
initialValues: {
- ...defaultWorkspaceSchedule(5, "asdfasdf"),
+ ...defaultWorkspaceSchedule(5),
timezone: "UTC",
},
workspace: {
@@ -76,9 +76,9 @@ WorkspaceWillShutdown.args = {
export const WorkspaceWillShutdownSoon = Template.bind({})
WorkspaceWillShutdownSoon.args = {
- now: dayjs("2022-05-17T18:10:00Z"),
+ now: dayjs("2022-05-17T16:39:00Z"),
initialValues: {
- ...defaultWorkspaceSchedule(5, "asdfasdf"),
+ ...defaultWorkspaceSchedule(2),
timezone: "UTC",
ttl: 1,
},
@@ -86,8 +86,9 @@ WorkspaceWillShutdownSoon.args = {
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
- updated_at: "2022-05-17T17:39:00Z",
+ deadline: "2022-05-17T18:09:00Z",
},
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
onCancel: () => action("onCancel"),
onSubmit: () => action("onSubmit"),
@@ -95,9 +96,9 @@ WorkspaceWillShutdownSoon.args = {
export const WorkspaceWillShutdownImmediately = Template.bind({})
WorkspaceWillShutdownImmediately.args = {
- now: dayjs("2022-05-17T18:40:00Z"),
+ now: dayjs("2022-05-17T17:09:00Z"),
initialValues: {
- ...defaultWorkspaceSchedule(5, "asdfasdf"),
+ ...defaultWorkspaceSchedule(1),
timezone: "UTC",
ttl: 1,
},
@@ -105,8 +106,9 @@ WorkspaceWillShutdownImmediately.args = {
...Mocks.MockWorkspace,
latest_build: {
...Mocks.MockWorkspaceBuild,
- updated_at: "2022-05-17T17:39:00Z",
+ deadline: "2022-05-17T18:09:00Z",
},
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
},
onCancel: () => action("onCancel"),
onSubmit: () => action("onSubmit"),
diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts
index 8fa25cc66abd3..3e37484b9c09b 100644
--- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts
+++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.test.ts
@@ -160,31 +160,99 @@ describe("validationSchema", () => {
})
describe("ttlShutdownAt", () => {
- it.each<[dayjs.Dayjs, Workspace, string, number, string]>([
- [dayjs("2022-05-17T18:09:00Z"), Mocks.MockStoppedWorkspace, "America/Chicago", 1, Language.ttlHelperText],
- [dayjs("2022-05-17T18:09:00Z"), Mocks.MockWorkspace, "America/Chicago", 0, Language.ttlCausesNoShutdownHelperText],
+ it.each<[string, dayjs.Dayjs, Workspace, string, number, string]>([
[
+ "Workspace is stopped --> helper text",
dayjs("2022-05-17T18:09:00Z"),
- Mocks.MockWorkspace,
+ Mocks.MockStoppedWorkspace,
"America/Chicago",
1,
- `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} 01:39 PM CDT.`,
+ Language.ttlHelperText,
],
[
- dayjs("2022-05-17T18:10:00Z"),
+ "TTL is not modified --> helper text",
+ dayjs("2022-05-17T16:09:00Z"),
+ {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ deadline: "2022-05-17T18:09:00Z",
+ },
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
+ },
+ "America/Chicago",
+ 2,
+ Language.ttlHelperText,
+ ],
+ [
+ "TTL becomes 0 --> manual helper text",
+ dayjs("2022-05-17T18:09:00Z"),
Mocks.MockWorkspace,
"America/Chicago",
+ 0,
+ Language.ttlCausesNoShutdownHelperText,
+ ],
+ [
+ "Deadline of 18:09 becomes 17:09 at 17:09 --> immediate shutdown",
+ dayjs("2022-05-17T17:09:00Z"),
+ {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ deadline: "2022-05-17T18:09:00Z",
+ },
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
+ },
+ "America/Chicago",
+ 1,
+ `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`,
+ ],
+ [
+ "Deadline of 18:09 becomes 17:09 at 16:39 --> display shutdown soon",
+ dayjs("2022-05-17T16:39:00Z"),
+ {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ deadline: "2022-05-17T18:09:00Z",
+ },
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
+ },
+ "America/Chicago",
1,
`⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`,
],
[
- dayjs("2022-05-17T18:40:00Z"),
- Mocks.MockWorkspace,
+ "Deadline of 18:09 becomes 17:09 at 16:09 --> display 12:09 CDT",
+ dayjs("2022-05-17T16:09:00Z"),
+ {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ deadline: "2022-05-17T18:09:00Z",
+ },
+ ttl_ms: 2 * 60 * 60 * 1000, // 2 hours = shuts off at 18:09
+ },
"America/Chicago",
1,
- `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`,
+ `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} May 17, 2022 12:09 PM.`,
+ ],
+ [
+ "Manual workspace gets new deadline of 18:09 at 17:09 --> display 1:09 CDT",
+ dayjs("2022-05-17T17:09:00Z"),
+ {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ deadline: "0001-01-01T00:00:00Z",
+ },
+ ttl_ms: 0,
+ },
+ "America/Chicago",
+ 1,
+ `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} May 17, 2022 1:09 PM.`,
],
- ])("ttlShutdownAt(%p, %p, %p, %p) returns %p", (now, workspace, timezone, ttlHours, expected) => {
+ ])("%p", (_, now, workspace, timezone, ttlHours, expected) => {
expect(ttlShutdownAt(now, workspace, timezone, ttlHours)).toEqual(expected)
})
})
diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx
index 465fc65b299c3..4df9181364ada 100644
--- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx
+++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx
@@ -9,6 +9,7 @@ import makeStyles from "@material-ui/core/styles/makeStyles"
import TextField from "@material-ui/core/TextField"
import dayjs from "dayjs"
import advancedFormat from "dayjs/plugin/advancedFormat"
+import isSameOrBefore from "dayjs/plugin/isSameOrBefore"
import timezone from "dayjs/plugin/timezone"
import utc from "dayjs/plugin/utc"
import { useFormik } from "formik"
@@ -23,11 +24,11 @@ import { FullPageForm } from "../FullPageForm/FullPageForm"
import { Stack } from "../Stack/Stack"
import { zones } from "./zones"
-// REMARK: timezone plugin depends on UTC
-//
-// SEE: https://day.js.org/docs/en/timezone/timezone
-dayjs.extend(advancedFormat)
+// REMARK: some plugins depend on utc, so it's listed first. Otherwise they're
+// sorted alphabetically.
dayjs.extend(utc)
+dayjs.extend(advancedFormat)
+dayjs.extend(isSameOrBefore)
dayjs.extend(timezone)
export const Language = {
@@ -282,19 +283,29 @@ export const WorkspaceScheduleForm: FC = ({
)
}
-export const ttlShutdownAt = (now: dayjs.Dayjs, workspace: Workspace, tz: string, newTTL: number): string => {
- const newDeadline = dayjs(workspace.latest_build.updated_at).add(newTTL, "hour")
- if (!isWorkspaceOn(workspace)) {
+export const ttlShutdownAt = (now: dayjs.Dayjs, workspace: Workspace, tz: string, formTTL: number): string => {
+ // a manual shutdown has a deadline of '"0001-01-01T00:00:00Z"'
+ // SEE: #1834
+ const deadline = dayjs(workspace.latest_build.deadline).utc()
+ const hasDeadline = deadline.year() > 1
+ const ttl = workspace.ttl_ms ? workspace.ttl_ms / (1000 * 60 * 60) : 0
+ const delta = formTTL - ttl
+
+ if (delta === 0 || !isWorkspaceOn(workspace)) {
return Language.ttlHelperText
- } else if (newTTL === 0) {
+ } else if (formTTL === 0) {
return Language.ttlCausesNoShutdownHelperText
- } else if (newDeadline.isBefore(now)) {
- return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`
- } else if (newDeadline.isBefore(now.add(30, "minute"))) {
- return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`
} else {
- const newDeadlineString = newDeadline.tz(tz).format("hh:mm A z")
- return `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} ${newDeadlineString}.`
+ const newDeadline = dayjs(hasDeadline ? deadline : now).add(delta, "hours")
+ if (newDeadline.isSameOrBefore(now)) {
+ return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownImmediately} ⚠️`
+ } else if (newDeadline.isSameOrBefore(now.add(30, "minutes"))) {
+ return `⚠️ ${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownSoon} ⚠️`
+ } else {
+ return `${Language.ttlCausesShutdownHelperText} ${Language.ttlCausesShutdownAt} ${newDeadline
+ .tz(tz)
+ .format("MMM D, YYYY h:mm A")}.`
+ }
}
}
diff --git a/site/src/components/WorkspaceStats/WorkspaceStats.tsx b/site/src/components/WorkspaceStats/WorkspaceStats.tsx
index 2858639da2331..1299ab46c9bae 100644
--- a/site/src/components/WorkspaceStats/WorkspaceStats.tsx
+++ b/site/src/components/WorkspaceStats/WorkspaceStats.tsx
@@ -7,10 +7,12 @@ import { Workspace } from "../../api/typesGenerated"
import { CardRadius, MONOSPACE_FONT_FAMILY } from "../../theme/constants"
import { combineClasses } from "../../util/combineClasses"
import { getDisplayStatus } from "../../util/workspace"
+import { WorkspaceSection } from "../WorkspaceSection/WorkspaceSection"
const Language = {
+ workspaceDetails: "Workspace Details",
templateLabel: "Template",
- statusLabel: "Status",
+ statusLabel: "Workspace Status",
versionLabel: "Version",
lastBuiltLabel: "Last Built",
outdated: "Outdated",
@@ -27,7 +29,7 @@ export const WorkspaceStats: FC = ({ workspace }) => {
const status = getDisplayStatus(theme, workspace.latest_build)
return (
-
+
{Language.templateLabel}
= ({ workspace }) => {
-
+
)
}
@@ -79,7 +81,7 @@ const useStyles = makeStyles((theme) => ({
alignItems: "center",
color: theme.palette.text.secondary,
fontFamily: MONOSPACE_FONT_FAMILY,
- border: `1px solid ${theme.palette.divider}`,
+ margin: "0px",
},
statItem: {
diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx
index a27cf2cacf5c1..7acb8cbf5ca6c 100644
--- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx
+++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx
@@ -14,17 +14,17 @@ import * as TypesGen from "../../api/typesGenerated"
import { AvatarData } from "../../components/AvatarData/AvatarData"
import { CodeExample } from "../../components/CodeExample/CodeExample"
import { EmptyState } from "../../components/EmptyState/EmptyState"
+import { Margins } from "../../components/Margins/Margins"
+import { PageHeader, PageHeaderText, PageHeaderTitle } from "../../components/PageHeader/PageHeader"
+import { Stack } from "../../components/Stack/Stack"
+import { TableLoader } from "../../components/TableLoader/TableLoader"
import {
HelpTooltip,
HelpTooltipLink,
HelpTooltipLinksGroup,
HelpTooltipText,
HelpTooltipTitle,
-} from "../../components/HelpTooltip/HelpTooltip"
-import { Margins } from "../../components/Margins/Margins"
-import { PageHeader, PageHeaderText, PageHeaderTitle } from "../../components/PageHeader/PageHeader"
-import { Stack } from "../../components/Stack/Stack"
-import { TableLoader } from "../../components/TableLoader/TableLoader"
+} from "../../components/Tooltips/HelpTooltip/HelpTooltip"
dayjs.extend(relativeTime)
@@ -49,6 +49,8 @@ export const Language = {
templateTooltipTitle: "What is template?",
templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.",
templateTooltipLink: "Manage templates",
+ createdByLabel: "Created by",
+ defaultTemplateCreator: "",
}
const TemplateHelpTooltip: React.FC = () => {
@@ -95,6 +97,7 @@ export const TemplatesPageView: FC = (props) => {
{Language.nameLabel}
{Language.usedByLabel}
{Language.lastUpdatedLabel}
+ {Language.createdByLabel}
@@ -137,6 +140,7 @@ export const TemplatesPageView: FC = (props) => {
{Language.developerCount(template.workspace_owner_count)}
{dayjs().to(dayjs(template.updated_at))}
+ {template.created_by_name || Language.defaultTemplateCreator}
diff --git a/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx b/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx
index cebff84da793d..45d13caa88496 100644
--- a/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx
+++ b/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.test.tsx
@@ -1,6 +1,11 @@
import { screen } from "@testing-library/react"
import * as API from "../../api/api"
-import { MockWorkspaceBuild, MockWorkspaceBuildLogs, renderWithAuth } from "../../testHelpers/renderHelpers"
+import {
+ MockWorkspace,
+ MockWorkspaceBuild,
+ MockWorkspaceBuildLogs,
+ renderWithAuth,
+} from "../../testHelpers/renderHelpers"
import { WorkspaceBuildPage } from "./WorkspaceBuildPage"
describe("WorkspaceBuildPage", () => {
@@ -16,7 +21,10 @@ describe("WorkspaceBuildPage", () => {
closed: Promise.resolve(undefined),
cancel: jest.fn(),
})
- renderWithAuth(, { route: `/builds/${MockWorkspaceBuild.id}`, path: "/builds/:buildId" })
+ renderWithAuth(, {
+ route: `/@${MockWorkspace.owner_name}/${MockWorkspace.name}/builds/${MockWorkspace.latest_build.build_number}`,
+ path: "/@:username/:workspace/builds/:buildNumber",
+ })
await screen.findByText(MockWorkspaceBuild.workspace_name)
await screen.findByText(MockWorkspaceBuildLogs[0].stage)
diff --git a/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.tsx b/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.tsx
index 46550ac62225a..9d570db458dfe 100644
--- a/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.tsx
+++ b/site/src/pages/WorkspaceBuildPage/WorkspaceBuildPage.tsx
@@ -6,19 +6,9 @@ import { pageTitle } from "../../util/page"
import { workspaceBuildMachine } from "../../xServices/workspaceBuild/workspaceBuildXService"
import { WorkspaceBuildPageView } from "./WorkspaceBuildPageView"
-const useBuildId = () => {
- const { buildId } = useParams()
-
- if (!buildId) {
- throw new Error("buildId param is required.")
- }
-
- return buildId
-}
-
export const WorkspaceBuildPage: FC = () => {
- const buildId = useBuildId()
- const [buildState] = useMachine(workspaceBuildMachine, { context: { buildId } })
+ const { username, workspace: workspaceName, buildNumber } = useParams()
+ const [buildState] = useMachine(workspaceBuildMachine, { context: { username, workspaceName, buildNumber } })
const { logs, build } = buildState.context
const isWaitingForLogs = !buildState.matches("logs.loaded")
diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
index c8b06c63c4ac3..7299eea6b2660 100644
--- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
+++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx
@@ -24,17 +24,17 @@ import * as TypesGen from "../../api/typesGenerated"
import { AvatarData } from "../../components/AvatarData/AvatarData"
import { CloseDropdown, OpenDropdown } from "../../components/DropdownArrows/DropdownArrows"
import { EmptyState } from "../../components/EmptyState/EmptyState"
+import { Margins } from "../../components/Margins/Margins"
+import { PageHeader, PageHeaderText, PageHeaderTitle } from "../../components/PageHeader/PageHeader"
+import { Stack } from "../../components/Stack/Stack"
+import { TableLoader } from "../../components/TableLoader/TableLoader"
import {
HelpTooltip,
HelpTooltipLink,
HelpTooltipLinksGroup,
HelpTooltipText,
HelpTooltipTitle,
-} from "../../components/HelpTooltip/HelpTooltip"
-import { Margins } from "../../components/Margins/Margins"
-import { PageHeader, PageHeaderText, PageHeaderTitle } from "../../components/PageHeader/PageHeader"
-import { Stack } from "../../components/Stack/Stack"
-import { TableLoader } from "../../components/TableLoader/TableLoader"
+} from "../../components/Tooltips/HelpTooltip/HelpTooltip"
import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils"
import { getDisplayStatus, workspaceFilterQuery } from "../../util/workspace"
@@ -214,7 +214,7 @@ export const WorkspacesPageView: FC = ({ loading, works
message={Language.emptyCreateWorkspaceMessage}
description={Language.emptyCreateWorkspaceDescription}
cta={
-
+
}>{Language.createFromTemplateButton}
}
diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts
index 53414283e4cc9..b37e038529dbc 100644
--- a/site/src/testHelpers/entities.ts
+++ b/site/src/testHelpers/entities.ts
@@ -114,6 +114,8 @@ export const MockTemplate: TypesGen.Template = {
description: "This is a test description.",
max_ttl_ms: 604800000,
min_autostart_interval_ms: 3600000,
+ created_by_id: "test-creator-id",
+ created_by_name: "test_creator",
}
export const MockWorkspaceAutostartDisabled: TypesGen.UpdateWorkspaceAutostartRequest = {
diff --git a/site/src/testHelpers/handlers.ts b/site/src/testHelpers/handlers.ts
index b77dd09c11aca..bfb8e9be0f4ff 100644
--- a/site/src/testHelpers/handlers.ts
+++ b/site/src/testHelpers/handlers.ts
@@ -115,7 +115,7 @@ export const handlers = [
rest.get("/api/v2/workspaces/:workspaceId/builds", async (req, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockBuilds))
}),
- rest.get("/api/v2/workspacebuilds/:workspaceBuildId", (req, res, ctx) => {
+ rest.get("/api/v2/users/:username/workspace/:workspaceName/builds/:buildNumber", (req, res, ctx) => {
return res(ctx.status(200), ctx.json(M.MockWorkspaceBuild))
}),
rest.get("/api/v2/workspacebuilds/:workspaceBuildId/resources", (req, res, ctx) => {
diff --git a/site/src/xServices/workspaceBuild/workspaceBuildXService.ts b/site/src/xServices/workspaceBuild/workspaceBuildXService.ts
index 88008892fe251..81883b3eaaa08 100644
--- a/site/src/xServices/workspaceBuild/workspaceBuildXService.ts
+++ b/site/src/xServices/workspaceBuild/workspaceBuildXService.ts
@@ -4,6 +4,9 @@ import { ProvisionerJobLog, WorkspaceBuild } from "../../api/typesGenerated"
type LogsContext = {
// Build
+ username: string
+ workspaceName: string
+ buildNumber: string
buildId: string
build?: WorkspaceBuild
getBuildError?: Error | unknown
@@ -36,28 +39,23 @@ export const workspaceBuildMachine = createMachine(
},
},
tsTypes: {} as import("./workspaceBuildXService.typegen").Typegen0,
- type: "parallel",
+ initial: "gettingBuild",
states: {
- build: {
- initial: "gettingBuild",
- states: {
- gettingBuild: {
- entry: "clearGetBuildError",
- invoke: {
- src: "getWorkspaceBuild",
- onDone: {
- target: "idle",
- actions: "assignBuild",
- },
- onError: {
- target: "idle",
- actions: "assignGetBuildError",
- },
- },
+ gettingBuild: {
+ entry: "clearGetBuildError",
+ invoke: {
+ src: "getWorkspaceBuild",
+ onDone: {
+ target: "logs",
+ actions: ["assignBuild", "assignBuildId"],
+ },
+ onError: {
+ target: "idle",
+ actions: "assignGetBuildError",
},
- idle: {},
},
},
+ idle: {},
logs: {
initial: "gettingExistentLogs",
states: {
@@ -95,6 +93,10 @@ export const workspaceBuildMachine = createMachine(
},
{
actions: {
+ // Build ID
+ assignBuildId: assign({
+ buildId: (_, event) => event.data.id,
+ }),
// Build
assignBuild: assign({
build: (_, event) => event.data,
@@ -117,7 +119,7 @@ export const workspaceBuildMachine = createMachine(
}),
},
services: {
- getWorkspaceBuild: (ctx) => API.getWorkspaceBuild(ctx.buildId),
+ getWorkspaceBuild: (ctx) => API.getWorkspaceBuildByNumber(ctx.username, ctx.workspaceName, ctx.buildNumber),
getLogs: async (ctx) => API.getWorkspaceBuildLogs(ctx.buildId),
streamWorkspaceBuildLogs: (ctx) => async (callback) => {
const reader = await API.streamWorkspaceBuildLogs(ctx.buildId)