diff --git a/.vscode/settings.json b/.vscode/settings.json index 02c3b05cc42c5..8c642faa6402b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -36,11 +36,13 @@ "gossh", "hashicorp", "httpmw", + "idtoken", "isatty", "Jobf", "kirsle", "manifoldco", "mattn", + "mitchellh", "moby", "nhooyr", "nolint", diff --git a/cli/clitest/clitest_test.go b/cli/clitest/clitest_test.go index b1bd908bf6128..57c1173ea344d 100644 --- a/cli/clitest/clitest_test.go +++ b/cli/clitest/clitest_test.go @@ -18,7 +18,7 @@ func TestMain(m *testing.M) { func TestCli(t *testing.T) { t.Parallel() clitest.CreateProjectVersionSource(t, nil) - client := coderdtest.New(t) + client := coderdtest.New(t, nil) cmd, config := clitest.New(t) clitest.SetupConfig(t, client, config) pty := ptytest.New(t) diff --git a/cli/login_test.go b/cli/login_test.go index 08b7f8f69370a..ee3dcdce9c090 100644 --- a/cli/login_test.go +++ b/cli/login_test.go @@ -16,7 +16,7 @@ func TestLogin(t *testing.T) { t.Parallel() t.Run("InitialUserNoTTY", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) root, _ := clitest.New(t, "login", client.URL.String()) err := root.Execute() require.Error(t, err) @@ -24,7 +24,7 @@ func TestLogin(t *testing.T) { t.Run("InitialUserTTY", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) // The --force-tty flag is required on Windows, because the `isatty` library does not // accurately detect Windows ptys when they are not attached to a process: // https://github.com/mattn/go-isatty/issues/59 @@ -55,7 +55,7 @@ func TestLogin(t *testing.T) { t.Run("ExistingUserValidTokenTTY", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{ Username: "test-user", Email: "test-user@coder.com", @@ -85,7 +85,7 @@ func TestLogin(t *testing.T) { t.Run("ExistingUserInvalidTokenTTY", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{ Username: "test-user", Email: "test-user@coder.com", diff --git a/cli/projectcreate_test.go b/cli/projectcreate_test.go index 873a276263e5a..29cd674601c1b 100644 --- a/cli/projectcreate_test.go +++ b/cli/projectcreate_test.go @@ -17,7 +17,7 @@ func TestProjectCreate(t *testing.T) { t.Parallel() t.Run("NoParameters", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) coderdtest.CreateInitialUser(t, client) source := clitest.CreateProjectVersionSource(t, &echo.Responses{ Parse: echo.ParseComplete, @@ -53,7 +53,7 @@ func TestProjectCreate(t *testing.T) { t.Run("Parameter", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) coderdtest.CreateInitialUser(t, client) source := clitest.CreateProjectVersionSource(t, &echo.Responses{ Parse: []*proto.Parse_Response{{ diff --git a/cli/projectlist_test.go b/cli/projectlist_test.go index 1c1a641a685de..a1340989946b2 100644 --- a/cli/projectlist_test.go +++ b/cli/projectlist_test.go @@ -14,7 +14,7 @@ func TestProjectList(t *testing.T) { t.Parallel() t.Run("None", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) coderdtest.CreateInitialUser(t, client) cmd, root := clitest.New(t, "projects", "list") clitest.SetupConfig(t, client, root) @@ -32,7 +32,7 @@ func TestProjectList(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) daemon := coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) diff --git a/cli/workspacecreate_test.go b/cli/workspacecreate_test.go index b3b1ca26915f7..812f59db38d7f 100644 --- a/cli/workspacecreate_test.go +++ b/cli/workspacecreate_test.go @@ -16,7 +16,7 @@ func TestWorkspaceCreate(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ diff --git a/coderd/coderd.go b/coderd/coderd.go index 765e4b0f1951c..ab9f207fe1e15 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -5,6 +5,7 @@ import ( "sync" "github.com/go-chi/chi/v5" + "google.golang.org/api/idtoken" "cdr.dev/slog" "github.com/coder/coder/database" @@ -18,6 +19,8 @@ type Options struct { Logger slog.Logger Database database.Store Pubsub database.Pubsub + + GoogleTokenValidator *idtoken.Validator } // New constructs the Coder API into an HTTP handler. @@ -107,6 +110,12 @@ func New(options *Options) (http.Handler, func()) { }) }) + r.Route("/workspaceagent", func(r chi.Router) { + r.Route("/authenticate", func(r chi.Router) { + r.Post("/google-instance-identity", api.postAuthenticateWorkspaceAgentUsingGoogleInstanceIdentity) + }) + }) + r.Route("/files", func(r chi.Router) { r.Use(httpmw.ExtractAPIKey(options.Database, nil)) r.Post("/", api.postFiles) diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index ff05abb63a78a..01cb3aa9759f6 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -15,6 +15,9 @@ import ( "github.com/google/uuid" "github.com/moby/moby/pkg/namesgenerator" "github.com/stretchr/testify/require" + "go.opencensus.io/stats/view" + "google.golang.org/api/idtoken" + "google.golang.org/api/option" "cdr.dev/slog" "cdr.dev/slog/sloggers/slogtest" @@ -29,9 +32,31 @@ import ( "github.com/coder/coder/provisionersdk/proto" ) +type Options struct { + GoogleTokenValidator *idtoken.Validator +} + // New constructs an in-memory coderd instance and returns // the connected client. -func New(t *testing.T) *codersdk.Client { +func New(t *testing.T, options *Options) *codersdk.Client { + // Stops the opencensus.io worker from leaking a goroutine. + // The worker isn't used anyways, and is an indirect dependency + // of the Google Cloud SDK. + t.Cleanup(func() { + view.Stop() + }) + + if options == nil { + options = &Options{} + } + if options.GoogleTokenValidator == nil { + ctx, cancelFunc := context.WithCancel(context.Background()) + t.Cleanup(cancelFunc) + var err error + options.GoogleTokenValidator, err = idtoken.NewValidator(ctx, option.WithoutAuthentication()) + require.NoError(t, err) + } + // This can be hotswapped for a live database instance. db := databasefake.New() pubsub := database.NewPubsubInMemory() @@ -59,6 +84,8 @@ func New(t *testing.T) *codersdk.Client { Logger: slogtest.Make(t, nil).Leveled(slog.LevelDebug), Database: db, Pubsub: pubsub, + + GoogleTokenValidator: options.GoogleTokenValidator, }) srv := httptest.NewUnstartedServer(handler) srv.Config.BaseContext = func(_ net.Listener) context.Context { diff --git a/coderd/coderdtest/coderdtest_test.go b/coderd/coderdtest/coderdtest_test.go index f351bb4a4d5a4..cab9fe5a9decc 100644 --- a/coderd/coderdtest/coderdtest_test.go +++ b/coderd/coderdtest/coderdtest_test.go @@ -19,7 +19,7 @@ func TestMain(m *testing.M) { func TestNew(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) closer := coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) diff --git a/coderd/files_test.go b/coderd/files_test.go index d14c1aff99fed..77f4085832771 100644 --- a/coderd/files_test.go +++ b/coderd/files_test.go @@ -14,7 +14,7 @@ func TestPostFiles(t *testing.T) { t.Parallel() t.Run("BadContentType", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.UploadFile(context.Background(), "bad", []byte{'a'}) require.Error(t, err) @@ -22,7 +22,7 @@ func TestPostFiles(t *testing.T) { t.Run("Insert", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.UploadFile(context.Background(), codersdk.ContentTypeTar, make([]byte, 1024)) require.NoError(t, err) @@ -30,7 +30,7 @@ func TestPostFiles(t *testing.T) { t.Run("InsertAlreadyExists", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) data := make([]byte, 1024) _, err := client.UploadFile(context.Background(), codersdk.ContentTypeTar, data) diff --git a/coderd/projectimport_test.go b/coderd/projectimport_test.go index b9df691233576..e253f1ccdc929 100644 --- a/coderd/projectimport_test.go +++ b/coderd/projectimport_test.go @@ -19,7 +19,7 @@ func TestPostProjectImportByOrganization(t *testing.T) { t.Parallel() t.Run("FileNotFound", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _, err := client.CreateProjectImportJob(context.Background(), user.Organization, coderd.CreateProjectImportJobRequest{ StorageMethod: database.ProvisionerStorageMethodFile, @@ -30,7 +30,7 @@ func TestPostProjectImportByOrganization(t *testing.T) { }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) }) @@ -40,7 +40,7 @@ func TestProjectImportJobSchemasByID(t *testing.T) { t.Parallel() t.Run("ListRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _, err := client.ProjectImportJobSchemas(context.Background(), user.Organization, job.ID) @@ -50,7 +50,7 @@ func TestProjectImportJobSchemasByID(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -80,7 +80,7 @@ func TestProjectImportJobParametersByID(t *testing.T) { t.Parallel() t.Run("ListRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _, err := client.ProjectImportJobSchemas(context.Background(), user.Organization, job.ID) @@ -90,7 +90,7 @@ func TestProjectImportJobParametersByID(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -126,7 +126,7 @@ func TestProjectImportJobResourcesByID(t *testing.T) { t.Parallel() t.Run("ListRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _, err := client.ProjectImportJobResources(context.Background(), user.Organization, job.ID) @@ -136,7 +136,7 @@ func TestProjectImportJobResourcesByID(t *testing.T) { }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ diff --git a/coderd/projects_test.go b/coderd/projects_test.go index cc4c4161f0d89..db1daafea4979 100644 --- a/coderd/projects_test.go +++ b/coderd/projects_test.go @@ -18,7 +18,7 @@ func TestProjects(t *testing.T) { t.Run("ListEmpty", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) projects, err := client.Projects(context.Background(), "") require.NoError(t, err) @@ -28,7 +28,7 @@ func TestProjects(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _ = coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -39,7 +39,7 @@ func TestProjects(t *testing.T) { t.Run("ListWorkspaceOwnerCount", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -58,7 +58,7 @@ func TestProjectsByOrganization(t *testing.T) { t.Parallel() t.Run("ListEmpty", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) projects, err := client.Projects(context.Background(), user.Organization) require.NoError(t, err) @@ -68,7 +68,7 @@ func TestProjectsByOrganization(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _ = coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -82,7 +82,7 @@ func TestPostProjectsByOrganization(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _ = coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -90,7 +90,7 @@ func TestPostProjectsByOrganization(t *testing.T) { t.Run("AlreadyExists", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -108,7 +108,7 @@ func TestProjectByOrganization(t *testing.T) { t.Parallel() t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -121,7 +121,7 @@ func TestPostParametersByProject(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -139,7 +139,7 @@ func TestParametersByProject(t *testing.T) { t.Parallel() t.Run("ListEmpty", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -150,7 +150,7 @@ func TestParametersByProject(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) diff --git a/coderd/projectversion_test.go b/coderd/projectversion_test.go index d288b53552086..e9937d4ba4f2c 100644 --- a/coderd/projectversion_test.go +++ b/coderd/projectversion_test.go @@ -14,7 +14,7 @@ func TestProjectVersionsByOrganization(t *testing.T) { t.Parallel() t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -29,7 +29,7 @@ func TestProjectVersionByOrganizationAndName(t *testing.T) { t.Parallel() t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -42,7 +42,7 @@ func TestPostProjectVersionByOrganization(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index d95e6e62c0f9d..9f45ff2d6027a 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -52,6 +52,9 @@ func (api *api) provisionerDaemons(rw http.ResponseWriter, r *http.Request) { // Serves the provisioner daemon protobuf API over a WebSocket. func (api *api) provisionerDaemonsServe(rw http.ResponseWriter, r *http.Request) { + api.websocketWaitGroup.Add(1) + defer api.websocketWaitGroup.Done() + conn, err := websocket.Accept(rw, r, &websocket.AcceptOptions{ // Need to disable compression to avoid a data-race. CompressionMode: websocket.CompressionDisabled, @@ -62,8 +65,6 @@ func (api *api) provisionerDaemonsServe(rw http.ResponseWriter, r *http.Request) }) return } - api.websocketWaitGroup.Add(1) - defer api.websocketWaitGroup.Done() daemon, err := api.Database.InsertProvisionerDaemon(r.Context(), database.InsertProvisionerDaemonParams{ ID: uuid.New(), @@ -519,8 +520,12 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr ID: uuid.New(), CreatedAt: database.Now(), WorkspaceHistoryID: input.WorkspaceHistoryID, - Type: protoResource.Type, - Name: protoResource.Name, + InstanceID: sql.NullString{ + Valid: protoResource.InstanceId != "", + String: protoResource.InstanceId, + }, + Type: protoResource.Type, + Name: protoResource.Name, // TODO: Generate this at the variable validation phase. // Set the value in `default_source`, and disallow overwrite. WorkspaceAgentToken: uuid.NewString(), diff --git a/coderd/provisionerdaemons_test.go b/coderd/provisionerdaemons_test.go index b0f1ff54c9b65..22584d03b5853 100644 --- a/coderd/provisionerdaemons_test.go +++ b/coderd/provisionerdaemons_test.go @@ -15,7 +15,7 @@ func TestProvisionerDaemons(t *testing.T) { // in their respective files. t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.NewProvisionerDaemon(t, client) require.Eventually(t, func() bool { daemons, err := client.ProvisionerDaemons(context.Background()) diff --git a/coderd/provisionerjobs_test.go b/coderd/provisionerjobs_test.go index 8a45d7b97f42e..355f601ddb2d9 100644 --- a/coderd/provisionerjobs_test.go +++ b/coderd/provisionerjobs_test.go @@ -21,7 +21,7 @@ func TestPostProvisionerImportJobByOrganization(t *testing.T) { t.Parallel() t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) before := time.Now() @@ -57,7 +57,7 @@ func TestPostProvisionerImportJobByOrganization(t *testing.T) { t.Run("CreateWithParameters", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) data, err := echo.Tar(&echo.Responses{ @@ -99,7 +99,7 @@ func TestProvisionerJobParametersByID(t *testing.T) { t.Parallel() t.Run("NotImported", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _, err := client.ProjectImportJobParameters(context.Background(), user.Organization, job.ID) @@ -110,7 +110,7 @@ func TestProvisionerJobParametersByID(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -140,7 +140,7 @@ func TestProvisionerJobParametersByID(t *testing.T) { t.Run("ListNoRedisplay", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -174,9 +174,9 @@ func TestProvisionerJobParametersByID(t *testing.T) { func TestProvisionerJobResourcesByID(t *testing.T) { t.Parallel() - t.Run("Something", func(t *testing.T) { + t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -212,7 +212,7 @@ func TestProvisionerJobLogsByName(t *testing.T) { t.Parallel() t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -248,7 +248,7 @@ func TestProvisionerJobLogsByName(t *testing.T) { t.Run("StreamAfterComplete", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -289,7 +289,7 @@ func TestProvisionerJobLogsByName(t *testing.T) { t.Run("StreamWhileRunning", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ diff --git a/coderd/users_test.go b/coderd/users_test.go index 3a3a5ee8eac76..5316b781a04b3 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -17,7 +17,7 @@ func TestUser(t *testing.T) { t.Parallel() t.Run("NotFound", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) has, err := client.HasInitialUser(context.Background()) require.NoError(t, err) require.False(t, has) @@ -25,7 +25,7 @@ func TestUser(t *testing.T) { t.Run("Found", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) has, err := client.HasInitialUser(context.Background()) require.NoError(t, err) @@ -37,14 +37,14 @@ func TestPostUser(t *testing.T) { t.Parallel() t.Run("BadRequest", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{}) require.Error(t, err) }) t.Run("AlreadyExists", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{ Email: "some@email.com", @@ -59,7 +59,7 @@ func TestPostUser(t *testing.T) { t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) }) } @@ -68,14 +68,14 @@ func TestPostUsers(t *testing.T) { t.Parallel() t.Run("BadRequest", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{}) require.Error(t, err) }) t.Run("Conflicting", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{ Email: user.Email, @@ -90,7 +90,7 @@ func TestPostUsers(t *testing.T) { t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.CreateUser(context.Background(), coderd.CreateUserRequest{ Email: "another@user.org", @@ -103,7 +103,7 @@ func TestPostUsers(t *testing.T) { func TestUserByName(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.User(context.Background(), "") require.NoError(t, err) @@ -111,7 +111,7 @@ func TestUserByName(t *testing.T) { func TestOrganizationsByUser(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) orgs, err := client.UserOrganizations(context.Background(), "") require.NoError(t, err) @@ -123,7 +123,7 @@ func TestPostKey(t *testing.T) { t.Parallel() t.Run("InvalidUser", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) // Clear session token @@ -137,7 +137,7 @@ func TestPostKey(t *testing.T) { t.Run("Success", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) apiKey, err := client.CreateAPIKey(context.Background()) require.NotNil(t, apiKey) @@ -150,7 +150,7 @@ func TestPostLogin(t *testing.T) { t.Parallel() t.Run("InvalidUser", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{ Email: "my@email.org", Password: "password", @@ -162,7 +162,7 @@ func TestPostLogin(t *testing.T) { t.Run("BadPassword", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{ Email: user.Email, @@ -175,7 +175,7 @@ func TestPostLogin(t *testing.T) { t.Run("Success", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{ Email: user.Email, @@ -191,7 +191,7 @@ func TestPostLogout(t *testing.T) { t.Run("ClearCookie", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) fullURL, err := client.URL.Parse("/api/v2/logout") require.NoError(t, err, "Server URL should parse successfully") diff --git a/coderd/workspaceagent.go b/coderd/workspaceagent.go new file mode 100644 index 0000000000000..4f4c88baddc1e --- /dev/null +++ b/coderd/workspaceagent.go @@ -0,0 +1,91 @@ +package coderd + +import ( + "database/sql" + "errors" + "fmt" + "net/http" + + "github.com/go-chi/render" + + "github.com/coder/coder/httpapi" + + "github.com/mitchellh/mapstructure" +) + +type GoogleInstanceIdentityToken struct { + JSONWebToken string `json:"json_web_token" validate:"required"` +} + +// WorkspaceAgentAuthenticateResponse is returned when an instance ID +// has been exchanged for a session token. +type WorkspaceAgentAuthenticateResponse struct { + SessionToken string `json:"session_token"` +} + +// Google Compute Engine supports instance identity verification: +// https://cloud.google.com/compute/docs/instances/verifying-instance-identity +// Using this, we can exchange a signed instance payload for an agent token. +func (api *api) postAuthenticateWorkspaceAgentUsingGoogleInstanceIdentity(rw http.ResponseWriter, r *http.Request) { + var req GoogleInstanceIdentityToken + if !httpapi.Read(rw, r, &req) { + return + } + + // We leave the audience blank. It's not important we validate who made the token. + payload, err := api.GoogleTokenValidator.Validate(r.Context(), req.JSONWebToken, "") + if err != nil { + httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{ + Message: fmt.Sprintf("validate: %s", err), + }) + return + } + claims := struct { + Google struct { + ComputeEngine struct { + InstanceID string `mapstructure:"instance_id"` + } `mapstructure:"compute_engine"` + } `mapstructure:"google"` + }{} + err = mapstructure.Decode(payload.Claims, &claims) + if err != nil { + httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{ + Message: fmt.Sprintf("decode jwt claims: %s", err), + }) + return + } + resource, err := api.Database.GetWorkspaceResourceByInstanceID(r.Context(), claims.Google.ComputeEngine.InstanceID) + if errors.Is(err, sql.ErrNoRows) { + httpapi.Write(rw, http.StatusNotFound, httpapi.Response{ + Message: fmt.Sprintf("instance with id %q not found", claims.Google.ComputeEngine.InstanceID), + }) + return + } + resourceHistory, err := api.Database.GetWorkspaceHistoryByID(r.Context(), resource.WorkspaceHistoryID) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get workspace history: %s", err), + }) + return + } + // This token should only be exchanged if the instance ID is valid + // for the latest history. If an instance ID is recycled by a cloud, + // we'd hate to leak access to a user's workspace. + latestHistory, err := api.Database.GetWorkspaceHistoryByWorkspaceIDWithoutAfter(r.Context(), resourceHistory.WorkspaceID) + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get latest workspace history: %s", err), + }) + return + } + if latestHistory.ID.String() != resourceHistory.ID.String() { + httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{ + Message: fmt.Sprintf("resource found for id %q, but isn't registered on the latest history", claims.Google.ComputeEngine.InstanceID), + }) + return + } + render.Status(r, http.StatusOK) + render.JSON(rw, r, WorkspaceAgentAuthenticateResponse{ + SessionToken: resource.WorkspaceAgentToken, + }) +} diff --git a/coderd/workspaceagent_test.go b/coderd/workspaceagent_test.go new file mode 100644 index 0000000000000..86487c4c90275 --- /dev/null +++ b/coderd/workspaceagent_test.go @@ -0,0 +1,176 @@ +package coderd_test + +import ( + "bytes" + "context" + "crypto/rand" + "crypto/rsa" + "encoding/base64" + "encoding/json" + "io/ioutil" + "math/big" + "net/http" + "testing" + "time" + + "cloud.google.com/go/compute/metadata" + "github.com/golang-jwt/jwt" + "github.com/stretchr/testify/require" + "google.golang.org/api/idtoken" + "google.golang.org/api/option" + + "github.com/coder/coder/coderd" + "github.com/coder/coder/coderd/coderdtest" + "github.com/coder/coder/codersdk" + "github.com/coder/coder/cryptorand" + "github.com/coder/coder/database" + "github.com/coder/coder/provisioner/echo" + "github.com/coder/coder/provisionersdk/proto" +) + +func TestPostWorkspaceAgentAuthenticateGoogleInstanceIdentity(t *testing.T) { + t.Parallel() + t.Run("Expired", func(t *testing.T) { + t.Parallel() + instanceID := "instanceidentifier" + signedKey, keyID, privateKey := createSignedToken(t, instanceID, &jwt.MapClaims{}) + validator := createValidator(t, keyID, privateKey) + client := coderdtest.New(t, &coderdtest.Options{ + GoogleTokenValidator: validator, + }) + _, err := client.AuthenticateWorkspaceAgentUsingGoogleCloudIdentity(context.Background(), "", createMetadataClient(signedKey)) + var apiErr *codersdk.Error + require.ErrorAs(t, err, &apiErr) + require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode()) + }) + + t.Run("InstanceNotFound", func(t *testing.T) { + t.Parallel() + instanceID := "instanceidentifier" + signedKey, keyID, privateKey := createSignedToken(t, instanceID, nil) + validator := createValidator(t, keyID, privateKey) + client := coderdtest.New(t, &coderdtest.Options{ + GoogleTokenValidator: validator, + }) + _, err := client.AuthenticateWorkspaceAgentUsingGoogleCloudIdentity(context.Background(), "", createMetadataClient(signedKey)) + var apiErr *codersdk.Error + require.ErrorAs(t, err, &apiErr) + require.Equal(t, http.StatusNotFound, apiErr.StatusCode()) + }) + + t.Run("Success", func(t *testing.T) { + t.Parallel() + instanceID := "instanceidentifier" + signedKey, keyID, privateKey := createSignedToken(t, instanceID, nil) + validator := createValidator(t, keyID, privateKey) + client := coderdtest.New(t, &coderdtest.Options{ + GoogleTokenValidator: validator, + }) + user := coderdtest.CreateInitialUser(t, client) + coderdtest.NewProvisionerDaemon(t, client) + job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Resources: []*proto.Resource{{ + Name: "somename", + Type: "someinstance", + InstanceId: instanceID, + }}, + }, + }, + }}, + }) + project := coderdtest.CreateProject(t, client, user.Organization, job.ID) + coderdtest.AwaitProjectImportJob(t, client, user.Organization, job.ID) + workspace := coderdtest.CreateWorkspace(t, client, "me", project.ID) + firstHistory, err := client.CreateWorkspaceHistory(context.Background(), "", workspace.Name, coderd.CreateWorkspaceHistoryRequest{ + ProjectVersionID: project.ActiveVersionID, + Transition: database.WorkspaceTransitionStart, + }) + require.NoError(t, err) + coderdtest.AwaitWorkspaceProvisionJob(t, client, user.Organization, firstHistory.ProvisionJobID) + + _, err = client.AuthenticateWorkspaceAgentUsingGoogleCloudIdentity(context.Background(), "", createMetadataClient(signedKey)) + require.NoError(t, err) + }) +} + +// Used to easily create an HTTP transport! +type roundTripper func(req *http.Request) (*http.Response, error) + +func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return r(req) +} + +// Create's a new Google metadata client to authenticate. +func createMetadataClient(signedKey string) *metadata.Client { + return metadata.NewClient(&http.Client{ + Transport: roundTripper(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewReader([]byte(signedKey))), + Header: make(http.Header), + }, nil + }), + }) +} + +// Create's a signed JWT with a randomly generated private key. +func createSignedToken(t *testing.T, instanceID string, claims *jwt.MapClaims) (signedKey string, keyID string, privateKey *rsa.PrivateKey) { + keyID, err := cryptorand.String(12) + require.NoError(t, err) + if claims == nil { + claims = &jwt.MapClaims{ + "exp": time.Now().AddDate(1, 0, 0).Unix(), + "google": map[string]interface{}{ + "compute_engine": map[string]string{ + "instance_id": instanceID, + }, + }, + } + } + token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims) + token.Header["kid"] = keyID + privateKey, err = rsa.GenerateKey(rand.Reader, 2048) + require.NoError(t, err) + signedKey, err = token.SignedString(privateKey) + require.NoError(t, err) + return signedKey, keyID, privateKey +} + +// Create's a validator that verifies against the provided private key. +// In a production scenario, the validator calls against the Google OAuth API +// to obtain certificates. +func createValidator(t *testing.T, keyID string, privateKey *rsa.PrivateKey) *idtoken.Validator { + // Taken from: https://github.com/googleapis/google-api-go-client/blob/4bb729045d611fa77bdbeb971f6a1204ba23161d/idtoken/validate.go#L57-L75 + type jwk struct { + Kid string `json:"kid"` + N string `json:"n"` + E string `json:"e"` + } + type certResponse struct { + Keys []jwk `json:"keys"` + } + + validator, err := idtoken.NewValidator(context.Background(), option.WithHTTPClient(&http.Client{ + Transport: roundTripper(func(r *http.Request) (*http.Response, error) { + data, err := json.Marshal(certResponse{ + Keys: []jwk{{ + Kid: keyID, + N: base64.RawURLEncoding.EncodeToString(privateKey.N.Bytes()), + E: base64.RawURLEncoding.EncodeToString(new(big.Int).SetInt64(int64(privateKey.E)).Bytes()), + }}, + }) + require.NoError(t, err) + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewReader(data)), + Header: make(http.Header), + }, nil + }), + })) + require.NoError(t, err) + return validator +} diff --git a/coderd/workspacehistory_test.go b/coderd/workspacehistory_test.go index 987955b7a336f..f00ebdaff5679 100644 --- a/coderd/workspacehistory_test.go +++ b/coderd/workspacehistory_test.go @@ -20,7 +20,7 @@ func TestPostWorkspaceHistoryByUser(t *testing.T) { t.Parallel() t.Run("NoProjectVersion", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -37,7 +37,7 @@ func TestPostWorkspaceHistoryByUser(t *testing.T) { t.Run("ProjectVersionFailedImport", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -58,7 +58,7 @@ func TestPostWorkspaceHistoryByUser(t *testing.T) { t.Run("AlreadyActive", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) closeDaemon := coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -84,7 +84,7 @@ func TestPostWorkspaceHistoryByUser(t *testing.T) { t.Run("UpdatePriorAfterField", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -114,7 +114,7 @@ func TestWorkspaceHistoryByUser(t *testing.T) { t.Parallel() t.Run("ListEmpty", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -128,7 +128,7 @@ func TestWorkspaceHistoryByUser(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -149,7 +149,7 @@ func TestWorkspaceHistoryByUser(t *testing.T) { func TestWorkspaceHistoryByName(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index cdc6bc353cde7..5591a2947221f 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -17,7 +17,7 @@ func TestWorkspaces(t *testing.T) { t.Parallel() t.Run("ListNone", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) workspaces, err := client.Workspaces(context.Background(), "") require.NoError(t, err) @@ -27,7 +27,7 @@ func TestWorkspaces(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -42,7 +42,7 @@ func TestPostWorkspaceByUser(t *testing.T) { t.Parallel() t.Run("InvalidProject", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.CreateWorkspace(context.Background(), "", coderd.CreateWorkspaceRequest{ ProjectID: uuid.New(), @@ -56,7 +56,7 @@ func TestPostWorkspaceByUser(t *testing.T) { t.Run("NoProjectAccess", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -88,7 +88,7 @@ func TestPostWorkspaceByUser(t *testing.T) { t.Run("AlreadyExists", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -105,7 +105,7 @@ func TestPostWorkspaceByUser(t *testing.T) { t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -115,7 +115,7 @@ func TestPostWorkspaceByUser(t *testing.T) { func TestWorkspaceByUser(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -128,7 +128,7 @@ func TestWorkspacesByProject(t *testing.T) { t.Parallel() t.Run("ListEmpty", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -139,7 +139,7 @@ func TestWorkspacesByProject(t *testing.T) { t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) diff --git a/codersdk/files_test.go b/codersdk/files_test.go index 88aac04a44794..8a85cee963396 100644 --- a/codersdk/files_test.go +++ b/codersdk/files_test.go @@ -14,13 +14,13 @@ func TestUpload(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.UploadFile(context.Background(), "wow", []byte{}) require.Error(t, err) }) t.Run("Upload", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.UploadFile(context.Background(), codersdk.ContentTypeTar, []byte{'a'}) require.NoError(t, err) diff --git a/codersdk/projectimport_test.go b/codersdk/projectimport_test.go index ccbe01345845a..99039c29c68b0 100644 --- a/codersdk/projectimport_test.go +++ b/codersdk/projectimport_test.go @@ -18,14 +18,14 @@ func TestCreateProjectImportJob(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateProjectImportJob(context.Background(), "", coderd.CreateProjectImportJobRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) }) @@ -35,14 +35,14 @@ func TestProjectImportJob(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJob(context.Background(), "", uuid.New()) require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _, err := client.ProjectImportJob(context.Background(), user.Organization, job.ID) @@ -54,14 +54,14 @@ func TestProjectImportJobLogsBefore(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJobLogsBefore(context.Background(), "", uuid.New(), time.Time{}) require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) before := time.Now() @@ -85,14 +85,14 @@ func TestProjectImportJobLogsAfter(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJobLogsAfter(context.Background(), "", uuid.New(), time.Time{}) require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, &echo.Responses{ @@ -120,7 +120,7 @@ func TestProjectImportJobSchemas(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJobSchemas(context.Background(), "", uuid.New()) require.Error(t, err) }) @@ -130,7 +130,7 @@ func TestProjectImportJobParameters(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJobParameters(context.Background(), "", uuid.New()) require.Error(t, err) }) @@ -140,7 +140,7 @@ func TestProjectImportJobResources(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectImportJobResources(context.Background(), "", uuid.New()) require.Error(t, err) }) diff --git a/codersdk/projects_test.go b/codersdk/projects_test.go index 4b5459fbede15..694dcb60136f0 100644 --- a/codersdk/projects_test.go +++ b/codersdk/projects_test.go @@ -16,14 +16,14 @@ func TestProjects(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.Projects(context.Background(), "") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.Projects(context.Background(), "") require.NoError(t, err) @@ -34,14 +34,14 @@ func TestProject(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.Project(context.Background(), "", "") require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -54,7 +54,7 @@ func TestCreateProject(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateProject(context.Background(), "org", coderd.CreateProjectRequest{ Name: "something", VersionImportJobID: uuid.New(), @@ -64,7 +64,7 @@ func TestCreateProject(t *testing.T) { t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) _ = coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -75,14 +75,14 @@ func TestProjectVersions(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectVersions(context.Background(), "some", "project") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -95,14 +95,14 @@ func TestProjectVersion(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectVersion(context.Background(), "some", "project", "version") require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -115,14 +115,14 @@ func TestCreateProjectVersion(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateProjectVersion(context.Background(), "some", "project", coderd.CreateProjectVersionRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -137,14 +137,14 @@ func TestProjectParameters(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProjectParameters(context.Background(), "some", "project") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -157,14 +157,14 @@ func TestCreateProjectParameter(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateProjectParameter(context.Background(), "some", "project", coderd.CreateParameterValueRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) diff --git a/codersdk/provisioners_test.go b/codersdk/provisioners_test.go index 9bb4528ebec1e..9fbea9469303e 100644 --- a/codersdk/provisioners_test.go +++ b/codersdk/provisioners_test.go @@ -14,7 +14,7 @@ func TestProvisionerDaemons(t *testing.T) { t.Parallel() t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ProvisionerDaemons(context.Background()) require.NoError(t, err) }) @@ -24,7 +24,7 @@ func TestProvisionerDaemonClient(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) ctx, cancelFunc := context.WithCancel(context.Background()) daemon, err := client.ProvisionerDaemonClient(ctx) require.NoError(t, err) @@ -35,7 +35,7 @@ func TestProvisionerDaemonClient(t *testing.T) { t.Run("Connect", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) ctx, cancelFunc := context.WithCancel(context.Background()) defer cancelFunc() daemon, err := client.ProvisionerDaemonClient(ctx) diff --git a/codersdk/users_test.go b/codersdk/users_test.go index 8e2fcd6881483..74f4eca6ebda5 100644 --- a/codersdk/users_test.go +++ b/codersdk/users_test.go @@ -14,7 +14,7 @@ func TestHasInitialUser(t *testing.T) { t.Parallel() t.Run("NotFound", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) has, err := client.HasInitialUser(context.Background()) require.NoError(t, err) require.False(t, has) @@ -22,7 +22,7 @@ func TestHasInitialUser(t *testing.T) { t.Run("Found", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) has, err := client.HasInitialUser(context.Background()) require.NoError(t, err) @@ -34,14 +34,14 @@ func TestCreateInitialUser(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateInitialUser(context.Background(), coderd.CreateInitialUserRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) }) } @@ -50,14 +50,14 @@ func TestCreateUser(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateUser(context.Background(), coderd.CreateUserRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.CreateUser(context.Background(), coderd.CreateUserRequest{ Email: "example@coder.com", @@ -72,14 +72,14 @@ func TestLoginWithPassword(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{}) require.Error(t, err) }) t.Run("Success", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _, err := client.LoginWithPassword(context.Background(), coderd.LoginWithPasswordRequest{ Email: user.Email, @@ -91,7 +91,7 @@ func TestLoginWithPassword(t *testing.T) { func TestLogout(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) err := client.Logout(context.Background()) require.NoError(t, err) } @@ -100,14 +100,14 @@ func TestUser(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.User(context.Background(), "") require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.User(context.Background(), "") require.NoError(t, err) @@ -118,14 +118,14 @@ func TestUserOrganizations(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.UserOrganizations(context.Background(), "") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.UserOrganizations(context.Background(), "") require.NoError(t, err) diff --git a/codersdk/workspaceagent.go b/codersdk/workspaceagent.go new file mode 100644 index 0000000000000..7bfcab9202bfb --- /dev/null +++ b/codersdk/workspaceagent.go @@ -0,0 +1,44 @@ +package codersdk + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + "cloud.google.com/go/compute/metadata" + "golang.org/x/xerrors" + + "github.com/coder/coder/coderd" +) + +// AuthenticateWorkspaceAgentUsingGoogleCloudIdentity uses the Google Compute Engine Metadata API to +// fetch a signed JWT, and exchange it for a session token for a workspace agent. +// +// The requesting instance must be registered as a resource in the latest history for a workspace. +func (c *Client) AuthenticateWorkspaceAgentUsingGoogleCloudIdentity(ctx context.Context, serviceAccount string, gcpClient *metadata.Client) (coderd.WorkspaceAgentAuthenticateResponse, error) { + if serviceAccount == "" { + // This is the default name specified by Google. + serviceAccount = "default" + } + if gcpClient == nil { + gcpClient = metadata.NewClient(c.httpClient) + } + // "format=full" is required, otherwise the responding payload will be missing "instance_id". + jwt, err := gcpClient.Get(fmt.Sprintf("instance/service-accounts/%s/identity?audience=coder&format=full", serviceAccount)) + if err != nil { + return coderd.WorkspaceAgentAuthenticateResponse{}, xerrors.Errorf("get metadata identity: %w", err) + } + res, err := c.request(ctx, http.MethodPost, "/api/v2/workspaceagent/authenticate/google-instance-identity", coderd.GoogleInstanceIdentityToken{ + JSONWebToken: jwt, + }) + if err != nil { + return coderd.WorkspaceAgentAuthenticateResponse{}, err + } + defer res.Body.Close() + if res.StatusCode != http.StatusOK { + return coderd.WorkspaceAgentAuthenticateResponse{}, readBodyAsError(res) + } + var resp coderd.WorkspaceAgentAuthenticateResponse + return resp, json.NewDecoder(res.Body).Decode(&resp) +} diff --git a/codersdk/workspaceagent_test.go b/codersdk/workspaceagent_test.go new file mode 100644 index 0000000000000..6c09f54e828ee --- /dev/null +++ b/codersdk/workspaceagent_test.go @@ -0,0 +1,37 @@ +package codersdk_test + +import ( + "bytes" + "context" + "io" + "net/http" + "testing" + + "cloud.google.com/go/compute/metadata" + "github.com/stretchr/testify/require" + + "github.com/coder/coder/coderd/coderdtest" +) + +func TestAuthenticateWorkspaceAgentUsingGoogleCloudIdentity(t *testing.T) { + t.Parallel() + t.Run("Error", func(t *testing.T) { + t.Parallel() + client := coderdtest.New(t, nil) + _, err := client.AuthenticateWorkspaceAgentUsingGoogleCloudIdentity(context.Background(), "", metadata.NewClient(&http.Client{ + Transport: roundTripper(func(req *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(bytes.NewReader([]byte("sometoken"))), + }, nil + }), + })) + require.Error(t, err) + }) +} + +type roundTripper func(req *http.Request) (*http.Response, error) + +func (r roundTripper) RoundTrip(req *http.Request) (*http.Response, error) { + return r(req) +} diff --git a/codersdk/workspaces_test.go b/codersdk/workspaces_test.go index 503895243dbcb..74d7a21e10bf2 100644 --- a/codersdk/workspaces_test.go +++ b/codersdk/workspaces_test.go @@ -15,14 +15,14 @@ func TestWorkspaces(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.Workspaces(context.Background(), "") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _ = coderdtest.CreateInitialUser(t, client) _, err := client.Workspaces(context.Background(), "") require.NoError(t, err) @@ -33,14 +33,14 @@ func TestWorkspacesByProject(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.WorkspacesByProject(context.Background(), "", "") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -53,14 +53,14 @@ func TestWorkspace(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.Workspace(context.Background(), "", "") require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -74,14 +74,14 @@ func TestListWorkspaceHistory(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.ListWorkspaceHistory(context.Background(), "", "") require.Error(t, err) }) t.Run("List", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -95,14 +95,14 @@ func TestWorkspaceHistory(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.WorkspaceHistory(context.Background(), "", "", "") require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) @@ -121,14 +121,14 @@ func TestCreateWorkspace(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateWorkspace(context.Background(), "", coderd.CreateWorkspaceRequest{}) require.Error(t, err) }) t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) project := coderdtest.CreateProject(t, client, user.Organization, job.ID) @@ -140,14 +140,14 @@ func TestCreateWorkspaceHistory(t *testing.T) { t.Parallel() t.Run("Error", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) _, err := client.CreateWorkspaceHistory(context.Background(), "", "", coderd.CreateWorkspaceHistoryRequest{}) require.Error(t, err) }) t.Run("Create", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t) + client := coderdtest.New(t, nil) user := coderdtest.CreateInitialUser(t, client) _ = coderdtest.NewProvisionerDaemon(t, client) job := coderdtest.CreateProjectImportJob(t, client, user.Organization, nil) diff --git a/database/databasefake/databasefake.go b/database/databasefake/databasefake.go index fb639082acbdd..f8d1ed2c5fefc 100644 --- a/database/databasefake/databasefake.go +++ b/database/databasefake/databasefake.go @@ -195,6 +195,18 @@ func (q *fakeQuerier) GetWorkspaceByUserIDAndName(_ context.Context, arg databas return database.Workspace{}, sql.ErrNoRows } +func (q *fakeQuerier) GetWorkspaceResourceByInstanceID(_ context.Context, instanceID string) (database.WorkspaceResource, error) { + q.mutex.Lock() + defer q.mutex.Unlock() + + for _, workspaceResource := range q.workspaceResource { + if workspaceResource.InstanceID.String == instanceID { + return workspaceResource, nil + } + } + return database.WorkspaceResource{}, sql.ErrNoRows +} + func (q *fakeQuerier) GetWorkspaceOwnerCountsByProjectIDs(_ context.Context, projectIDs []uuid.UUID) ([]database.GetWorkspaceOwnerCountsByProjectIDsRow, error) { counts := map[string]map[string]struct{}{} for _, projectID := range projectIDs { @@ -916,6 +928,7 @@ func (q *fakeQuerier) InsertWorkspaceResource(_ context.Context, arg database.In ID: arg.ID, CreatedAt: arg.CreatedAt, WorkspaceHistoryID: arg.WorkspaceHistoryID, + InstanceID: arg.InstanceID, Type: arg.Type, Name: arg.Name, WorkspaceAgentToken: arg.WorkspaceAgentToken, diff --git a/database/dump.sql b/database/dump.sql index d0b1d194b3099..371ad221e3b57 100644 --- a/database/dump.sql +++ b/database/dump.sql @@ -276,6 +276,7 @@ CREATE TABLE workspace_resource ( id uuid NOT NULL, created_at timestamp with time zone NOT NULL, workspace_history_id uuid NOT NULL, + instance_id character varying(64), type character varying(256) NOT NULL, name character varying(64) NOT NULL, workspace_agent_token character varying(128) NOT NULL, diff --git a/database/migrations/000003_workspaces.up.sql b/database/migrations/000003_workspaces.up.sql index ae8409c20eba1..81e894caa3ae3 100644 --- a/database/migrations/000003_workspaces.up.sql +++ b/database/migrations/000003_workspaces.up.sql @@ -38,6 +38,9 @@ CREATE TABLE workspace_resource ( id uuid NOT NULL UNIQUE, created_at timestamptz NOT NULL, workspace_history_id uuid NOT NULL REFERENCES workspace_history (id) ON DELETE CASCADE, + -- A unique identifier for the resource. This can be used + -- to exchange for an agent token with various providers. + instance_id varchar(64), -- Resource type produced by a provisioner. -- eg. "google_compute_instance" type varchar(256) NOT NULL, diff --git a/database/models.go b/database/models.go index a0e60915feb23..82154d2c2f54b 100644 --- a/database/models.go +++ b/database/models.go @@ -452,11 +452,12 @@ type WorkspaceHistory struct { } type WorkspaceResource struct { - ID uuid.UUID `db:"id" json:"id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - WorkspaceHistoryID uuid.UUID `db:"workspace_history_id" json:"workspace_history_id"` - Type string `db:"type" json:"type"` - Name string `db:"name" json:"name"` - WorkspaceAgentToken string `db:"workspace_agent_token" json:"workspace_agent_token"` - WorkspaceAgentID uuid.NullUUID `db:"workspace_agent_id" json:"workspace_agent_id"` + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + WorkspaceHistoryID uuid.UUID `db:"workspace_history_id" json:"workspace_history_id"` + InstanceID sql.NullString `db:"instance_id" json:"instance_id"` + Type string `db:"type" json:"type"` + Name string `db:"name" json:"name"` + WorkspaceAgentToken string `db:"workspace_agent_token" json:"workspace_agent_token"` + WorkspaceAgentID uuid.NullUUID `db:"workspace_agent_id" json:"workspace_agent_id"` } diff --git a/database/querier.go b/database/querier.go index 9109b8130760f..0c3445d31d1eb 100644 --- a/database/querier.go +++ b/database/querier.go @@ -40,6 +40,7 @@ type querier interface { GetWorkspaceHistoryByWorkspaceIDAndName(ctx context.Context, arg GetWorkspaceHistoryByWorkspaceIDAndNameParams) (WorkspaceHistory, error) GetWorkspaceHistoryByWorkspaceIDWithoutAfter(ctx context.Context, workspaceID uuid.UUID) (WorkspaceHistory, error) GetWorkspaceOwnerCountsByProjectIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByProjectIDsRow, error) + GetWorkspaceResourceByInstanceID(ctx context.Context, instanceID string) (WorkspaceResource, error) GetWorkspaceResourcesByHistoryID(ctx context.Context, workspaceHistoryID uuid.UUID) ([]WorkspaceResource, error) GetWorkspacesByProjectAndUserID(ctx context.Context, arg GetWorkspacesByProjectAndUserIDParams) ([]Workspace, error) GetWorkspacesByUserID(ctx context.Context, ownerID string) ([]Workspace, error) diff --git a/database/query.sql b/database/query.sql index 79c4e231a6994..5f950404b1014 100644 --- a/database/query.sql +++ b/database/query.sql @@ -328,6 +328,16 @@ WHERE LIMIT 1; +-- name: GetWorkspaceResourceByInstanceID :one +SELECT + * +FROM + workspace_resource +WHERE + instance_id = @instance_id :: text +ORDER BY + created_at; + -- name: GetWorkspaceResourcesByHistoryID :many SELECT * @@ -596,12 +606,13 @@ INSERT INTO id, created_at, workspace_history_id, + instance_id, type, name, workspace_agent_token ) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: UpdateAPIKeyByID :exec UPDATE diff --git a/database/query.sql.go b/database/query.sql.go index f956e0b51b9e0..a8f4c4b5f418e 100644 --- a/database/query.sql.go +++ b/database/query.sql.go @@ -1111,9 +1111,36 @@ func (q *sqlQuerier) GetWorkspaceOwnerCountsByProjectIDs(ctx context.Context, id return items, nil } +const getWorkspaceResourceByInstanceID = `-- name: GetWorkspaceResourceByInstanceID :one +SELECT + id, created_at, workspace_history_id, instance_id, type, name, workspace_agent_token, workspace_agent_id +FROM + workspace_resource +WHERE + instance_id = $1 :: text +ORDER BY + created_at +` + +func (q *sqlQuerier) GetWorkspaceResourceByInstanceID(ctx context.Context, instanceID string) (WorkspaceResource, error) { + row := q.db.QueryRowContext(ctx, getWorkspaceResourceByInstanceID, instanceID) + var i WorkspaceResource + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.WorkspaceHistoryID, + &i.InstanceID, + &i.Type, + &i.Name, + &i.WorkspaceAgentToken, + &i.WorkspaceAgentID, + ) + return i, err +} + const getWorkspaceResourcesByHistoryID = `-- name: GetWorkspaceResourcesByHistoryID :many SELECT - id, created_at, workspace_history_id, type, name, workspace_agent_token, workspace_agent_id + id, created_at, workspace_history_id, instance_id, type, name, workspace_agent_token, workspace_agent_id FROM workspace_resource WHERE @@ -1133,6 +1160,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByHistoryID(ctx context.Context, works &i.ID, &i.CreatedAt, &i.WorkspaceHistoryID, + &i.InstanceID, &i.Type, &i.Name, &i.WorkspaceAgentToken, @@ -2112,21 +2140,23 @@ INSERT INTO id, created_at, workspace_history_id, + instance_id, type, name, workspace_agent_token ) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING id, created_at, workspace_history_id, type, name, workspace_agent_token, workspace_agent_id + ($1, $2, $3, $4, $5, $6, $7) RETURNING id, created_at, workspace_history_id, instance_id, type, name, workspace_agent_token, workspace_agent_id ` type InsertWorkspaceResourceParams struct { - ID uuid.UUID `db:"id" json:"id"` - CreatedAt time.Time `db:"created_at" json:"created_at"` - WorkspaceHistoryID uuid.UUID `db:"workspace_history_id" json:"workspace_history_id"` - Type string `db:"type" json:"type"` - Name string `db:"name" json:"name"` - WorkspaceAgentToken string `db:"workspace_agent_token" json:"workspace_agent_token"` + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + WorkspaceHistoryID uuid.UUID `db:"workspace_history_id" json:"workspace_history_id"` + InstanceID sql.NullString `db:"instance_id" json:"instance_id"` + Type string `db:"type" json:"type"` + Name string `db:"name" json:"name"` + WorkspaceAgentToken string `db:"workspace_agent_token" json:"workspace_agent_token"` } func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) { @@ -2134,6 +2164,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork arg.ID, arg.CreatedAt, arg.WorkspaceHistoryID, + arg.InstanceID, arg.Type, arg.Name, arg.WorkspaceAgentToken, @@ -2143,6 +2174,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork &i.ID, &i.CreatedAt, &i.WorkspaceHistoryID, + &i.InstanceID, &i.Type, &i.Name, &i.WorkspaceAgentToken, diff --git a/go.mod b/go.mod index f27f9842d822a..4839eac1fafa1 100644 --- a/go.mod +++ b/go.mod @@ -14,11 +14,15 @@ replace github.com/hashicorp/terraform-config-inspect => github.com/kylecarbs/te // Required until https://github.com/chzyer/readline/pull/198 is merged. replace github.com/chzyer/readline => github.com/kylecarbs/readline v0.0.0-20220211054233-0d62993714c8 +// Required until https://github.com/census-instrumentation/opencensus-go/pull/1272 is merged. +replace go.opencensus.io => github.com/kylecarbs/opencensus-go v0.23.1-0.20220220184033-4441763886a2 + // Required until https://github.com/pion/ice/pull/425 is merged. replace github.com/pion/ice/v2 => github.com/kylecarbs/ice/v2 v2.1.8-0.20220221162453-b262a62902c3 require ( cdr.dev/slog v1.4.1 + cloud.google.com/go/compute v1.3.0 github.com/briandowns/spinner v1.18.1 github.com/coder/retry v1.3.0 github.com/creack/pty v1.1.17 @@ -27,6 +31,7 @@ require ( github.com/go-chi/chi/v5 v5.0.7 github.com/go-chi/render v1.0.1 github.com/go-playground/validator/v10 v10.10.0 + github.com/golang-jwt/jwt v3.2.2+incompatible github.com/golang-migrate/migrate/v4 v4.15.1 github.com/google/uuid v1.3.0 github.com/hashicorp/go-version v1.4.0 @@ -38,6 +43,7 @@ require ( github.com/lib/pq v1.10.4 github.com/manifoldco/promptui v0.9.0 github.com/mattn/go-isatty v0.0.14 + github.com/mitchellh/mapstructure v1.4.3 github.com/moby/moby v20.10.12+incompatible github.com/ory/dockertest/v3 v3.8.1 github.com/pion/datachannel v1.5.2 @@ -50,21 +56,22 @@ require ( github.com/stretchr/testify v1.7.0 github.com/unrolled/secure v1.10.0 github.com/xlab/treeprint v1.1.0 + go.opencensus.io v0.23.0 go.uber.org/atomic v1.9.0 go.uber.org/goleak v1.1.12 - golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 + golang.org/x/crypto v0.0.0-20220214200702-86341886e292 golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 - golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 + golang.org/x/sys v0.0.0-20220209214540-3681064d5158 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 + google.golang.org/api v0.69.0 google.golang.org/protobuf v1.27.1 nhooyr.io/websocket v1.8.7 storj.io/drpc v0.0.29 ) require ( - cloud.google.com/go/compute v0.1.0 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect - github.com/Microsoft/go-winio v0.5.1 // indirect + github.com/Microsoft/go-winio v0.5.2 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect github.com/agext/levenshtein v1.2.3 // indirect github.com/alecthomas/chroma v0.10.0 // indirect @@ -95,13 +102,12 @@ require ( github.com/hashicorp/terraform-json v0.13.0 // indirect github.com/imdario/mergo v0.3.12 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect - github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a // indirect - github.com/klauspost/compress v1.13.6 // indirect + github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc // indirect + github.com/klauspost/compress v1.14.3 // indirect github.com/leodido/go-urn v1.2.1 // indirect - github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a // indirect + github.com/lunixbochs/vtclean v1.0.0 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect - github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect @@ -128,12 +134,11 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 // 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 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 // indirect + google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c // indirect google.golang.org/grpc v1.44.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect diff --git a/go.sum b/go.sum index 907aeb89c4e62..0c8e37af8ceee 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,10 @@ cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvf cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v0.1.0 h1:rSUBvAyVwNJ5uQCKNJFMwPtTvJkfN38b6Pvb9zZoqJ8= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= +cloud.google.com/go/compute v1.3.0 h1:mPL/MzDDYHsh5tHRS9mhmhWlcgClCrCa6ApQCU6wnHI= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= @@ -89,8 +91,9 @@ github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JP 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 h1:aPJp2QD7OOrhO5tQXqQoGSJc+DjDtWTGLOmNyAm6FgY= 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= github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= @@ -546,6 +549,8 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= +github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-migrate/migrate/v4 v4.15.1 h1:Sakl3Nm6+wQKq0Q62tpFMi5a503bgGhceo2icrgQ9vM= github.com/golang-migrate/migrate/v4 v4.15.1/go.mod h1:/CrBenUbcDqsW29jGTR/XFqCfVi/Y6mHXlooCcSOJMQ= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -553,7 +558,6 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= @@ -796,8 +800,9 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm 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/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a h1:FaWFmfWdAUKbSCtOU2QjDaorUexogfaMgbipgYATUMU= github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU= +github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc h1:ZQrgZFsLzkw7o3CoDzsfBhx0bf/1rVBXrLy8dXKRe8o= +github.com/juju/ansiterm v0.0.0-20210929141451-8b71cc96ebdc/go.mod h1:PyXUpnI3olx3bsPcHt98FGPX/KCFZ1Fi+hw1XLI6384= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= @@ -823,8 +828,9 @@ github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= -github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.14.3 h1:DQv1WP+iS4srNjibdnHtqu8JNWCDMluj5NzPnFJsnvk= +github.com/klauspost/compress v1.14.3/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= 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= @@ -844,6 +850,8 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4= github.com/kylecarbs/ice/v2 v2.1.8-0.20220221162453-b262a62902c3 h1:/SkVJxNTLozVOnU5OAQhnwt5Nb7h15c1BHad6t4h5MM= github.com/kylecarbs/ice/v2 v2.1.8-0.20220221162453-b262a62902c3/go.mod h1:Op8jlPtjeiycsXh93Cs4jK82C9j/kh7vef6ztIOvtIQ= +github.com/kylecarbs/opencensus-go v0.23.1-0.20220220184033-4441763886a2 h1:tvKg/uBu9IqevKJECOWdHWnFxuyQZo7dBeilpx+FugY= +github.com/kylecarbs/opencensus-go v0.23.1-0.20220220184033-4441763886a2/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= github.com/kylecarbs/promptui v0.8.1-0.20201231190244-d8f2159af2b2 h1:MUREBTh4kybLY1KyuBfSx+QPfTB8XiUHs6ZxUhOPTnU= github.com/kylecarbs/promptui v0.8.1-0.20201231190244-d8f2159af2b2/go.mod h1:n4zTdgP0vr0S3w7/O/g98U+e0gwLScEXGwov2nIKuGQ= github.com/kylecarbs/readline v0.0.0-20220211054233-0d62993714c8 h1:Y7O3Z3YeNRtw14QrtHpevU4dSjCkov0J40MtQ7Nc0n8= @@ -867,8 +875,9 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.4 h1:SO9z7FRPzA03QhHKJrH5BXA6HU1rS4V2nIVrrNC1iYk= github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a h1:weJVJJRzAJBFRlAiJQROKQs8oC9vOxvm4rZmBBk0ONw= github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= +github.com/lunixbochs/vtclean v1.0.0 h1:xu2sLAri4lGiovBDQKxl5mrXyESr3gUr5m5SM5+LVb8= +github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= @@ -887,6 +896,7 @@ github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVc github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.10/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= @@ -1273,14 +1283,6 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3 go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= -go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1326,8 +1328,9 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838 h1:71vQrMauZZhcTVK6KdYM+rklehEEwb3E+ZhaE5jrPrE= golang.org/x/crypto v0.0.0-20220131195533-30dcbda58838/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1391,7 +1394,6 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20190225153610-fe579d43d832/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= @@ -1492,7 +1494,6 @@ golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502175342-a43fa875dd82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1598,8 +1599,10 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158 h1:rm+CHSpPEEW2IsXUib1ThaHIjuBVZjxNgSKmBLFfD4c= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 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= @@ -1738,6 +1741,10 @@ google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUb google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.69.0 h1:yHW5s2SFyDapr/43kYtIQmoaaFVW4baLMLwqV4auj2A= +google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1752,7 +1759,6 @@ google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11K google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1822,8 +1828,13 @@ google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5 h1:zzNejm+EgrbLfDZ6lu9Uud2IVvHySPl8vQzf04laR5Q= -google.golang.org/genproto v0.0.0-20220118154757-00ab72f36ad5/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c h1:TU4rFa5APdKTq0s6B7WTsH6Xmx0Knj86s6Biz56mErE= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index 3e82f568023b1..cf83fbf700292 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -8,6 +8,7 @@ import ( "io" "os" "path/filepath" + "reflect" "strings" "github.com/hashicorp/terraform-exec/tfexec" @@ -245,9 +246,17 @@ func (t *terraform) runTerraformApply(ctx context.Context, terraform *tfexec.Ter resources := make([]*proto.Resource, 0) if state.Values != nil { for _, resource := range state.Values.RootModule.Resources { + var instanceID string + if gcpInstanceID, ok := resource.AttributeValues["instance_id"]; ok { + instanceID, ok = gcpInstanceID.(string) + if !ok { + return xerrors.Errorf("invalid type for instance_id property: %s", reflect.TypeOf(gcpInstanceID).String()) + } + } resources = append(resources, &proto.Resource{ - Name: resource.Name, - Type: resource.Type, + Name: resource.Name, + Type: resource.Type, + InstanceId: instanceID, }) } } diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 18f034e0c7fd4..1912c35f9044f 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -571,6 +571,13 @@ type Resource struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` + // An optional identifier used for automating Workspace Agent authentication. + // Each cloud has it's own unique instance identity signatures, which can be + // used for zero-token authentication. See: + // GCP: https://cloud.google.com/compute/docs/instances/verifying-instance-identity + // AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html + // Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux#get-attested-data + InstanceId string `protobuf:"bytes,3,opt,name=instance_id,json=instanceId,proto3" json:"instance_id,omitempty"` } func (x *Resource) Reset() { @@ -619,6 +626,13 @@ func (x *Resource) GetType() string { return "" } +func (x *Resource) GetInstanceId() string { + if x != nil { + return x.InstanceId + } + return "" +} + // Parse consumes source-code from a directory to produce inputs. type Parse struct { state protoimpl.MessageState @@ -1155,68 +1169,70 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x32, 0x0a, 0x08, 0x52, 0x65, + 0x28, 0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x53, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfc, - 0x01, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, - 0x79, 0x1a, 0x55, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, 0x0a, - 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, - 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, - 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x6f, - 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, + 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, + 0xfc, 0x01, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x1a, 0x55, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, + 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, + 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfc, + 0x02, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x9e, 0x01, 0x0a, + 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, + 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, + 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, + 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, + 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x14, + 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x55, 0x0a, + 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, + 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x73, 0x1a, 0x77, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, + 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xfc, 0x02, - 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x9e, 0x01, 0x0a, 0x07, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, - 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x55, 0x0a, 0x08, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, - 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, - 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x1a, 0x77, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, - 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, - 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, - 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, - 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, - 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, - 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, - 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, 0xa1, 0x01, - 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x42, 0x0a, - 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, - 0x01, 0x12, 0x4e, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, - 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, - 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, + 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, + 0x43, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, + 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, + 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x32, 0xa1, + 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x42, + 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, + 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x30, 0x01, 0x12, 0x4e, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 0b999dffbc4fe..bcad8d7b312b1 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -68,6 +68,13 @@ message Log { message Resource { string name = 1; string type = 2; + // An optional identifier used for automating Workspace Agent authentication. + // Each cloud has it's own unique instance identity signatures, which can be + // used for zero-token authentication. See: + // GCP: https://cloud.google.com/compute/docs/instances/verifying-instance-identity + // AWS: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html + // Azure: https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service?tabs=linux#get-attested-data + string instance_id = 3; } // Parse consumes source-code from a directory to produce inputs.