From 110ea81923f5556d4216ad18dae7d9acba827ee4 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Fri, 10 Jun 2022 11:05:27 -0500 Subject: [PATCH 01/16] chore: update CLI copy --- cli/server.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cli/server.go b/cli/server.go index 2fbc645edb1b9..40d920bd7432a 100644 --- a/cli/server.go +++ b/cli/server.go @@ -181,7 +181,9 @@ func server() *cobra.Command { "Coder requires a URL accessible by workspaces you provision. "+ "A free tunnel can be created for simple setup. This will "+ "expose your Coder deployment to a publicly accessible URL. "+ - cliui.Styles.Field.Render("--access-url")+" can be specified instead.\n", + "If you'd like to use your own domain, you can provide it "+ + "with the "+ + cliui.Styles.Field.Render("--access-url")+" flag.\n", )) // This skips the prompt if the flag is explicitly specified. @@ -252,8 +254,8 @@ func server() *cobra.Command { } } - _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "access-url: %s\n", accessURL) _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "provisioner-daemons: %d\n", provisionerDaemonCount) + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Access your Coder UI in a browser at: %s\n", accessURL) _, _ = fmt.Fprintln(cmd.ErrOrStderr()) if !dev { From ac10e6c87bb667ad3ec9e9d6d4a130076bb0e390 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Fri, 10 Jun 2022 11:12:38 -0500 Subject: [PATCH 02/16] chore: update UI copy --- site/src/components/HelpTooltip/HelpTooltip.stories.tsx | 4 ++-- .../WorkspaceScheduleForm/WorkspaceScheduleForm.tsx | 2 +- site/src/pages/TemplatePage/TemplatePageView.tsx | 2 +- site/src/pages/WorkspacesPage/WorkspacesPageView.tsx | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx index 6780a5700a6d0..d5f77ac72fd97 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx @@ -15,9 +15,9 @@ export default { const Template: Story = (args) => ( - What is template? + What is a template? - With templates you can create a common configuration for your workspaces using Terraform. So, you and your team + With templates, you can create a common configuration for your team's workspaces using Terraform so that everyone can use the same environment to deliver great software. diff --git a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx index e5d5376596c94..465fc65b299c3 100644 --- a/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx +++ b/site/src/components/WorkspaceScheduleForm/WorkspaceScheduleForm.tsx @@ -210,7 +210,7 @@ export const WorkspaceScheduleForm: FC = ({ ] return ( - +
= ({ loading, works Create a new workspace from a{" "} - Template + template . From 0c216517ac95e0f05c6738bd8d09cbcfd31d71d4 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Fri, 10 Jun 2022 11:19:39 -0500 Subject: [PATCH 03/16] chore: escape apostrophe --- site/src/components/HelpTooltip/HelpTooltip.stories.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx index d5f77ac72fd97..1387165f2e90a 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx @@ -17,8 +17,9 @@ const Template: Story = (args) => ( What is a template? - With templates, you can create a common configuration for your team's workspaces using Terraform so that everyone - can use the same environment to deliver great software. + With templates, you can create a common configuration for your team`'`s workspaces + using Terraform so that everyone can use the same environment to deliver great + software. Creating a template From 953c542d39e399b919b58f06a06bf94ae9dbbb8a Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Fri, 10 Jun 2022 15:29:33 -0500 Subject: [PATCH 04/16] chore: lint --- site/src/components/HelpTooltip/HelpTooltip.stories.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx index 1387165f2e90a..19542a6ca63a1 100644 --- a/site/src/components/HelpTooltip/HelpTooltip.stories.tsx +++ b/site/src/components/HelpTooltip/HelpTooltip.stories.tsx @@ -17,9 +17,8 @@ const Template: Story = (args) => ( What is a template? - With templates, you can create a common configuration for your team`'`s workspaces - using Terraform so that everyone can use the same environment to deliver great - software. + With templates, you can create a common configuration for your team`'`s workspaces using Terraform so that + everyone can use the same environment to deliver great software. Creating a template From 2f0be801c5c94e025db34c3bc2464e9d201db289 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Tue, 14 Jun 2022 07:48:54 -0400 Subject: [PATCH 05/16] Add template tooltips/kira pilot (#2308) * feat: update build url to @username/workspace/builds/buildnumber (#2234) * update build url to @username/workspace/builds/buildnumber * update errors thrown from the API * add unit tests for the new API * add t.parallel * get username and workspace name from params * fix: update icon (#2216) * feat: Show template description in `coder template init` (#2238) * fix: workspace schedule time displays (#2249) Summary: Various time displays weren't quite right. Details: - Display date (not just time) of upcoming workspace stop in workspace page - Fix ttlShutdownAt for various cases + tests - manual to non-manual - unchanged/unmodified - isBefore --> isSameOrBefore - use the delta (off by _ error) - pluralize units in dayjs.add * fix: Remove easter egg mentioning competitor (#2250) This is more confusing than helpful! * feat: Warn on coderd startup if access URL is localhost (#2248) * feat: use custom wireguard reverse proxy for dev tunnel (#1975) * fix: use correct link in create from template button (#2253) * feat: store and display template creator (#2228) * design commit * add owner_id to templates table * add owner information in apis and ui * update minWidth for statItem * rename owner to created_by * missing refactor to created_by * handle errors in fetching created_by names * feat: update language on workspace page (#2220) * fix: ensure config dir exists before reading tunnel config (#2259) * fix(devtunnel): close `http.Server` before wireguard interface (#2263) * fix: ensure `agentResource` is non-nil (#2261) * chore: add hero image to OSS docs homepage (#2241) * fix: Do not write 2 errors to api on template fetch error (#2285) * feat: add tooltips to templates page resolves #2242 Co-authored-by: Abhineet Jain Co-authored-by: Joe Previte Co-authored-by: Mathias Fredriksson Co-authored-by: G r e y Co-authored-by: Kyle Carberry Co-authored-by: David Wahler Co-authored-by: Colin Adler Co-authored-by: Garrett Delfosse Co-authored-by: Katie Horne Co-authored-by: Steven Masley --- cli/server.go | 76 ++++- cli/server_test.go | 29 ++ cli/templateinit.go | 9 +- cmd/coder/main.go | 24 -- coderd/audit/diff_test.go | 2 + coderd/audit/table.go | 1 + coderd/coderd.go | 5 +- coderd/coderd_test.go | 6 + coderd/database/databasefake/databasefake.go | 17 + coderd/database/dump.sql | 6 +- .../000022_template_created_by.down.sql | 1 + .../000022_template_created_by.up.sql | 1 + coderd/database/models.go | 1 + coderd/database/querier.go | 1 + coderd/database/queries.sql.go | 57 +++- coderd/database/queries/templates.sql | 5 +- coderd/database/queries/workspacebuilds.sql | 9 + coderd/devtunnel/tunnel.go | 322 ++++++++++++++---- coderd/devtunnel/tunnel_test.go | 59 ++-- coderd/httpmw/templateparam.go | 1 + coderd/templates.go | 83 ++++- coderd/workspacebuilds.go | 77 +++++ coderd/workspacebuilds_test.go | 90 +++++ codersdk/templates.go | 2 + codersdk/workspacebuilds.go | 13 + docs/README.md | 4 + docs/manifest.json | 2 +- go.mod | 33 +- go.sum | 143 +++++--- provisioner/terraform/resources.go | 4 + site/src/AppRouter.tsx | 18 +- site/src/api/api.ts | 10 +- site/src/api/typesGenerated.ts | 8 +- .../components/BuildsTable/BuildsTable.tsx | 5 +- site/src/components/Resources/Resources.tsx | 38 +-- .../TemplateResourcesTable.test.tsx | 35 ++ .../TemplateResourcesTable.tsx | 21 +- .../TemplateStats/TemplateStats.stories.tsx | 9 + .../TemplateStats/TemplateStats.tsx | 9 +- .../components/Tooltips/AgentHelpTooltip.tsx | 16 + .../HelpTooltip/HelpTooltip.stories.tsx | 0 .../HelpTooltip/HelpTooltip.tsx | 2 +- .../Tooltips/ResourcesHelpTooltip.tsx | 27 ++ .../WorkspaceBuildStats.tsx | 2 +- .../WorkspaceSchedule/WorkspaceSchedule.tsx | 6 +- .../WorkspaceScheduleForm.stories.tsx | 20 +- .../WorkspaceScheduleForm.test.ts | 88 ++++- .../WorkspaceScheduleForm.tsx | 39 ++- .../WorkspaceStats/WorkspaceStats.tsx | 10 +- .../pages/TemplatesPage/TemplatesPageView.tsx | 14 +- .../WorkspaceBuildPage.test.tsx | 12 +- .../WorkspaceBuildPage/WorkspaceBuildPage.tsx | 14 +- .../WorkspacesPage/WorkspacesPageView.tsx | 12 +- site/src/testHelpers/entities.ts | 2 + site/src/testHelpers/handlers.ts | 2 +- .../workspaceBuild/workspaceBuildXService.ts | 40 +-- 56 files changed, 1186 insertions(+), 356 deletions(-) create mode 100644 coderd/database/migrations/000022_template_created_by.down.sql create mode 100644 coderd/database/migrations/000022_template_created_by.up.sql create mode 100644 site/src/components/TemplateResourcesTable/TemplateResourcesTable.test.tsx create mode 100644 site/src/components/Tooltips/AgentHelpTooltip.tsx rename site/src/components/{ => Tooltips}/HelpTooltip/HelpTooltip.stories.tsx (100%) rename site/src/components/{ => Tooltips}/HelpTooltip/HelpTooltip.tsx (98%) create mode 100644 site/src/components/Tooltips/ResourcesHelpTooltip.tsx 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={ - + } 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) From dd94acab0f48c250f9445557628c9d5d8f445407 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Tue, 14 Jun 2022 09:41:32 -0500 Subject: [PATCH 06/16] chore: fix issues w/ merge conflict resolution --- site/src/api/typesGenerated.ts | 4 ---- .../TemplateStats/TemplateStats.stories.tsx | 9 -------- .../TemplateStats/TemplateStats.tsx | 8 ------- .../pages/TemplatesPage/TemplatesPageView.tsx | 16 -------------- .../WorkspacesPage/WorkspacesPageView.tsx | 22 ------------------- 5 files changed, 59 deletions(-) diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 7a58570f3b67c..e220103a3eba0 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -247,11 +247,7 @@ export interface Template { readonly description: string readonly max_ttl_ms: number readonly min_autostart_interval_ms: number -<<<<<<< HEAD - readonly created_by_id?: string -======= readonly created_by_id: string ->>>>>>> main readonly created_by_name: string } diff --git a/site/src/components/TemplateStats/TemplateStats.stories.tsx b/site/src/components/TemplateStats/TemplateStats.stories.tsx index fb7f36d894652..3056187d110d4 100644 --- a/site/src/components/TemplateStats/TemplateStats.stories.tsx +++ b/site/src/components/TemplateStats/TemplateStats.stories.tsx @@ -23,12 +23,3 @@ 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 246064f66c957..3309ab7286764 100644 --- a/site/src/components/TemplateStats/TemplateStats.tsx +++ b/site/src/components/TemplateStats/TemplateStats.tsx @@ -14,10 +14,6 @@ const Language = { userPlural: "users", userSingular: "user", createdByLabel: "Created by", -<<<<<<< HEAD - defaultTemplateCreator: "", -======= ->>>>>>> main } export interface TemplateStatsProps { @@ -53,11 +49,7 @@ export const TemplateStats: FC = ({ template, activeVersion
{Language.createdByLabel} -<<<<<<< HEAD - {template.created_by_name || Language.defaultTemplateCreator} -======= {template.created_by_name} ->>>>>>> main
) diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index 08a90c60c675c..acd2a43e76bd8 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -24,15 +24,7 @@ import { HelpTooltipLinksGroup, HelpTooltipText, HelpTooltipTitle, -<<<<<<< HEAD } from "../../components/Tooltips/HelpTooltip/HelpTooltip" -======= -} from "../../components/HelpTooltip/HelpTooltip" -import { Margins } from "../../components/Margins/Margins" -import { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "../../components/PageHeader/PageHeader" -import { Stack } from "../../components/Stack/Stack" -import { TableLoader } from "../../components/TableLoader/TableLoader" ->>>>>>> main dayjs.extend(relativeTime) @@ -58,10 +50,6 @@ export const Language = { templateTooltipText: "With templates you can create a common configuration for your workspaces using Terraform.", templateTooltipLink: "Manage templates", createdByLabel: "Created by", -<<<<<<< HEAD - defaultTemplateCreator: "", -======= ->>>>>>> main } const TemplateHelpTooltip: React.FC = () => { @@ -151,11 +139,7 @@ export const TemplatesPageView: FC = (props) => { {Language.developerCount(template.workspace_owner_count)} {dayjs().to(dayjs(template.updated_at))} -<<<<<<< HEAD - {template.created_by_name || Language.defaultTemplateCreator} -======= {template.created_by_name} ->>>>>>> main
diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx index 50d02b271dafa..3acaf138c526f 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx @@ -34,15 +34,7 @@ import { HelpTooltipLinksGroup, HelpTooltipText, HelpTooltipTitle, -<<<<<<< HEAD } from "../../components/Tooltips/HelpTooltip/HelpTooltip" -======= -} from "../../components/HelpTooltip/HelpTooltip" -import { Margins } from "../../components/Margins/Margins" -import { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "../../components/PageHeader/PageHeader" -import { Stack } from "../../components/Stack/Stack" -import { TableLoader } from "../../components/TableLoader/TableLoader" ->>>>>>> main import { getFormHelpers, onChangeTrimmed } from "../../util/formUtils" import { getDisplayStatus, workspaceFilterQuery } from "../../util/workspace" @@ -138,21 +130,7 @@ export const WorkspacesPageView: FC = ({ loading, works return ( -<<<<<<< HEAD - - Create a new workspace from a{" "} - - template - - . - - } - > -======= ->>>>>>> main Workspaces From d2dcdd8e76c702db23125d950d9030636277caf5 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Tue, 14 Jun 2022 15:19:51 +0000 Subject: [PATCH 07/16] resolving in flight conflicts --- site/src/pages/TemplatesPage/TemplatesPageView.tsx | 2 +- site/src/pages/WorkspacesPage/WorkspacesPageView.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/pages/TemplatesPage/TemplatesPageView.tsx b/site/src/pages/TemplatesPage/TemplatesPageView.tsx index acd2a43e76bd8..bd691e3c7df66 100644 --- a/site/src/pages/TemplatesPage/TemplatesPageView.tsx +++ b/site/src/pages/TemplatesPage/TemplatesPageView.tsx @@ -15,7 +15,7 @@ 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 { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "../../components/PageHeader/PageHeader" import { Stack } from "../../components/Stack/Stack" import { TableLoader } from "../../components/TableLoader/TableLoader" import { diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx index 3acaf138c526f..e6e8a4f7fb936 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx @@ -25,7 +25,7 @@ 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 { PageHeader, PageHeaderSubtitle, PageHeaderTitle } from "../../components/PageHeader/PageHeader" import { Stack } from "../../components/Stack/Stack" import { TableLoader } from "../../components/TableLoader/TableLoader" import { From 4a2900f9efe1017b2afc84b8b12f5e95342bf9a6 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Tue, 14 Jun 2022 15:40:01 +0000 Subject: [PATCH 08/16] formating server.go --- cli/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index b25a0bb7d7de6..3d0af733b19eb 100644 --- a/cli/server.go +++ b/cli/server.go @@ -184,7 +184,7 @@ func server() *cobra.Command { "A free tunnel can be created for simple setup. This will "+ "expose your Coder deployment to a publicly accessible URL. "+ "If you'd like to use your own domain, you can provide it "+ - "with the "+ + "with the "+ cliui.Styles.Field.Render("--access-url")+" flag.\n", )) From f5e73a25f04177054d1964d3ba8bd9f85ef6c36a Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 08:40:24 -0500 Subject: [PATCH 09/16] Apply suggestions from review Co-authored-by: Ammar Bandukwala --- cli/server.go | 2 +- site/src/pages/WorkspacesPage/WorkspacesPageView.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cli/server.go b/cli/server.go index 3d0af733b19eb..9572d3583393a 100644 --- a/cli/server.go +++ b/cli/server.go @@ -183,7 +183,7 @@ func server() *cobra.Command { "Coder requires a URL accessible by workspaces you provision. "+ "A free tunnel can be created for simple setup. This will "+ "expose your Coder deployment to a publicly accessible URL. "+ - "If you'd like to use your own domain, you can provide it "+ + "If you'd like to use your own hostname, you can provide it "+ "with the "+ cliui.Styles.Field.Render("--access-url")+" flag.\n", )) diff --git a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx index e6e8a4f7fb936..efc49d882aa8e 100644 --- a/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx +++ b/site/src/pages/WorkspacesPage/WorkspacesPageView.tsx @@ -50,7 +50,7 @@ export const Language = { allWorkspacesButton: "All workspaces", workspaceTooltipTitle: "What is a workspace?", workspaceTooltipText: - "A workspace is your development environment in the cloud. It includes the compute infrastructure and tools you need to work on your project", + "A workspace is your development environment in the cloud. It includes the infrastructure and tools you need to work on your project.", workspaceTooltipLink1: "Create workspaces", workspaceTooltipLink2: "Connect with SSH", workspaceTooltipLink3: "Editors and IDEs", From 4684bd1f834d5305f4c8c19eef7563dc9869eaff Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 09:15:19 -0500 Subject: [PATCH 10/16] chore: fix typos --- site/src/components/Tooltips/ResourcesHelpTooltip.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/components/Tooltips/ResourcesHelpTooltip.tsx b/site/src/components/Tooltips/ResourcesHelpTooltip.tsx index c5728d9faa897..cb1b6894000e7 100644 --- a/site/src/components/Tooltips/ResourcesHelpTooltip.tsx +++ b/site/src/components/Tooltips/ResourcesHelpTooltip.tsx @@ -8,7 +8,7 @@ import { export const Language = { resourceTooltipTitle: "What is a resource?", - resourceTooltipText: "A resource is an infrastructure object that is create when the workspace is provisioned.", + resourceTooltipText: "A resource is an infrastructure object that is created when the workspace is provisioned.", resourceTooltipLink: "Persistent and ephemeral resources", } @@ -18,7 +18,7 @@ export const ResourcesHelpTooltip: React.FC = () => { {Language.resourceTooltipTitle} {Language.resourceTooltipText} - + {Language.resourceTooltipLink} From 6d4afa2cc6c229c23c91a9062a8cc5dbfcc39e22 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 09:16:00 -0500 Subject: [PATCH 11/16] chore: update template definition Co-authored-by: Ammar Bandukwala --- .../src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx index 19542a6ca63a1..d4ee1372293e5 100644 --- a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx +++ b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx @@ -17,7 +17,7 @@ const Template: Story = (args) => ( What is a template? - With templates, you can create a common configuration for your team`'`s workspaces using Terraform so that + A template is a common configuration for your team`'`s workspaces. everyone can use the same environment to deliver great software. From e4a6c0479e1dc0f7c8ff349a86bca58adcafd258 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 09:24:15 -0500 Subject: [PATCH 12/16] chore: fix wording; lint --- .../components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx index d4ee1372293e5..8d2d3ad802cd7 100644 --- a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx +++ b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.stories.tsx @@ -16,10 +16,7 @@ export default { const Template: Story = (args) => ( What is a template? - - A template is a common configuration for your team`'`s workspaces. - everyone can use the same environment to deliver great software. - + A template is a common configuration for your team`'`s workspaces. Creating a template Updating a template From 21d87a95de3a070f3c4a670f26f3ef58096e7798 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 10:00:54 -0500 Subject: [PATCH 13/16] chore: expand defintion of provisioner-daemons --- cli/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index 9572d3583393a..d617b11b68660 100644 --- a/cli/server.go +++ b/cli/server.go @@ -279,7 +279,7 @@ func server() *cobra.Command { } } - _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "provisioner-daemons: %d\n", provisionerDaemonCount) + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "The number of provisioner daemons to create on start: %d\n", provisionerDaemonCount) _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Access your Coder UI in a browser at: %s\n", accessURL) _, _ = fmt.Fprintln(cmd.ErrOrStderr()) From 3cb014cc93a5b791cc066134ec13deb308c9ecdc Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 10:06:38 -0500 Subject: [PATCH 14/16] chore: update wording --- cli/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index d617b11b68660..fb82eb23626a2 100644 --- a/cli/server.go +++ b/cli/server.go @@ -279,7 +279,7 @@ func server() *cobra.Command { } } - _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "The number of provisioner daemons to create on start: %d\n", provisionerDaemonCount) + _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Create the following number of provisioner daemons on start: %d\n", provisionerDaemonCount) _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Access your Coder UI in a browser at: %s\n", accessURL) _, _ = fmt.Fprintln(cmd.ErrOrStderr()) From 43642edaae58a5c1c6bcb674f216af620863bf93 Mon Sep 17 00:00:00 2001 From: Kira Pilot Date: Wed, 15 Jun 2022 15:38:30 +0000 Subject: [PATCH 15/16] fix test --- site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx b/site/src/components/Tooltips/HelpTooltip/HelpTooltip.tsx index 1ed96af999871..66629943c0961 100644 --- a/site/src/components/Tooltips/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 React, { createContext, useContext, useState } from "react" -import { Stack } from "../Stack/Stack" +import { Stack } from "../../Stack/Stack" type Icon = typeof HelpIcon From 4e5067d864ecbe8240f27dbcfa5c2fb3ab72c972 Mon Sep 17 00:00:00 2001 From: Katie Horne Date: Wed, 15 Jun 2022 16:47:58 -0500 Subject: [PATCH 16/16] chore: remove provisioner daemons line --- cli/server.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cli/server.go b/cli/server.go index fb82eb23626a2..97ceb28146d9f 100644 --- a/cli/server.go +++ b/cli/server.go @@ -279,7 +279,6 @@ func server() *cobra.Command { } } - _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Create the following number of provisioner daemons on start: %d\n", provisionerDaemonCount) _, _ = fmt.Fprintf(cmd.ErrOrStderr(), "Access your Coder UI in a browser at: %s\n", accessURL) _, _ = fmt.Fprintln(cmd.ErrOrStderr())