diff --git a/.vscode/settings.json b/.vscode/settings.json index 2ea7220cd50ab..888ee89c245b6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "codersdk", "cronstrue", "devel", + "apps", "drpc", "drpcconn", "drpcmux", diff --git a/coderd/coderd.go b/coderd/coderd.go index 3a4de3436e1ad..b9115ecf8869f 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -15,6 +15,8 @@ import ( "golang.org/x/xerrors" "google.golang.org/api/idtoken" + "github.com/go-chi/cors" + sdktrace "go.opentelemetry.io/otel/sdk/trace" "cdr.dev/slog" @@ -33,10 +35,11 @@ import ( // Options are requires parameters for Coder to start. type Options struct { - AccessURL *url.URL - Logger slog.Logger - Database database.Store - Pubsub database.Pubsub + AccessURL *url.URL + WildcardURL *url.URL + Logger slog.Logger + Database database.Store + Pubsub database.Pubsub AgentConnectionUpdateFrequency time.Duration // APIRateLimit is the minutely throughput rate limit per user or ip. @@ -95,6 +98,15 @@ func New(options *Options) *API { tracing.HTTPMW(api.TracerProvider, "coderd.http"), ) + r.Route("/{user}/{workspaceagent}/{application}", func(r chi.Router) { + r.Use( + httpmw.RateLimitPerMinute(options.APIRateLimit), + apiKeyMiddleware, + httpmw.ExtractUserParam(api.Database), + authRolesMiddleware, + ) + }) + r.Route("/api/v2", func(r chi.Router) { r.NotFound(func(rw http.ResponseWriter, r *http.Request) { httpapi.Write(rw, http.StatusNotFound, httpapi.Response{ @@ -311,6 +323,9 @@ func New(options *Options) *API { r.Get("/watch", api.watchWorkspace) }) }) + r.Route("/wildcardauth", func(r chi.Router) { + r.Use(cors.Handler(cors.Options{})) + }) r.Route("/workspacebuilds/{workspacebuild}", func(r chi.Router) { r.Use( apiKeyMiddleware, diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index 0e16107a43858..8ebbb9eaf62f0 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -35,6 +35,7 @@ func New() database.Store { templateVersions: make([]database.TemplateVersion, 0), templates: make([]database.Template, 0), workspaceBuilds: make([]database.WorkspaceBuild, 0), + workspaceApps: make([]database.WorkspaceApp, 0), workspaces: make([]database.Workspace, 0), } } @@ -63,6 +64,7 @@ type fakeQuerier struct { templateVersions []database.TemplateVersion templates []database.Template workspaceBuilds []database.WorkspaceBuild + workspaceApps []database.WorkspaceApp workspaces []database.Workspace } @@ -363,6 +365,41 @@ func (q *fakeQuerier) GetWorkspaceByOwnerIDAndName(_ context.Context, arg databa return database.Workspace{}, sql.ErrNoRows } +func (q *fakeQuerier) GetWorkspaceAppsByAgentID(_ context.Context, id uuid.UUID) ([]database.WorkspaceApp, error) { + q.mutex.RLock() + defer q.mutex.RUnlock() + + apps := make([]database.WorkspaceApp, 0) + for _, app := range q.workspaceApps { + if app.AgentID == id { + apps = append(apps, app) + } + } + if len(apps) == 0 { + return nil, sql.ErrNoRows + } + return apps, nil +} + +func (q *fakeQuerier) GetWorkspaceAppsByAgentIDs(_ context.Context, ids []uuid.UUID) ([]database.WorkspaceApp, error) { + q.mutex.RLock() + defer q.mutex.RUnlock() + + apps := make([]database.WorkspaceApp, 0) + for _, app := range q.workspaceApps { + for _, id := range ids { + if app.AgentID.String() == id.String() { + apps = append(apps, app) + break + } + } + } + if len(apps) == 0 { + return nil, sql.ErrNoRows + } + return apps, nil +} + func (q *fakeQuerier) GetWorkspacesAutostart(_ context.Context) ([]database.Workspace, error) { q.mutex.RLock() defer q.mutex.RUnlock() @@ -1491,6 +1528,24 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser return workspaceBuild, nil } +func (q *fakeQuerier) InsertWorkspaceApp(_ context.Context, arg database.InsertWorkspaceAppParams) (database.WorkspaceApp, error) { + q.mutex.Lock() + defer q.mutex.Unlock() + + workspaceApp := database.WorkspaceApp{ + ID: arg.ID, + AgentID: arg.AgentID, + CreatedAt: arg.CreatedAt, + Name: arg.Name, + Icon: arg.Icon, + Command: arg.Command, + Url: arg.Url, + RelativePath: arg.RelativePath, + } + q.workspaceApps = append(q.workspaceApps, workspaceApp) + return workspaceApp, nil +} + func (q *fakeQuerier) UpdateAPIKeyByID(_ context.Context, arg database.UpdateAPIKeyByIDParams) error { q.mutex.Lock() defer q.mutex.Unlock() diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 4cd90454283d7..4bf028644535f 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -281,6 +281,17 @@ CREATE TABLE workspace_agents ( directory character varying(4096) DEFAULT ''::character varying NOT NULL ); +CREATE TABLE workspace_apps ( + id uuid NOT NULL, + created_at timestamp with time zone NOT NULL, + agent_id uuid NOT NULL, + name character varying(64) NOT NULL, + icon character varying(256) NOT NULL, + command character varying(65534), + url character varying(65534), + relative_path boolean DEFAULT false NOT NULL +); + CREATE TABLE workspace_builds ( id uuid NOT NULL, created_at timestamp with time zone NOT NULL, @@ -382,6 +393,12 @@ ALTER TABLE ONLY users ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_pkey PRIMARY KEY (id); +ALTER TABLE ONLY workspace_apps + ADD CONSTRAINT workspace_apps_agent_id_name_key UNIQUE (agent_id, name); + +ALTER TABLE ONLY workspace_apps + ADD CONSTRAINT workspace_apps_pkey PRIMARY KEY (id); + ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_key UNIQUE (job_id); @@ -463,6 +480,9 @@ ALTER TABLE ONLY templates ALTER TABLE ONLY workspace_agents ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspace_apps + ADD CONSTRAINT workspace_apps_agent_id_fkey FOREIGN KEY (agent_id) REFERENCES workspace_agents(id) ON DELETE CASCADE; + ALTER TABLE ONLY workspace_builds ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE; diff --git a/coderd/database/migrations/000014_workspace_apps.down.sql b/coderd/database/migrations/000014_workspace_apps.down.sql new file mode 100644 index 0000000000000..c1c0dabd478da --- /dev/null +++ b/coderd/database/migrations/000014_workspace_apps.down.sql @@ -0,0 +1 @@ +DROP TABLE workspace_apps; diff --git a/coderd/database/migrations/000014_workspace_apps.up.sql b/coderd/database/migrations/000014_workspace_apps.up.sql new file mode 100644 index 0000000000000..7a991c179ee13 --- /dev/null +++ b/coderd/database/migrations/000014_workspace_apps.up.sql @@ -0,0 +1,12 @@ +CREATE TABLE workspace_apps ( + id uuid NOT NULL, + created_at timestamp with time zone NOT NULL, + agent_id uuid NOT NULL REFERENCES workspace_agents (id) ON DELETE CASCADE, + name varchar(64) NOT NULL, + icon varchar(256) NOT NULL, + command varchar(65534), + url varchar(65534), + relative_path boolean NOT NULL DEFAULT false, + PRIMARY KEY (id), + UNIQUE(agent_id, name) +); diff --git a/coderd/database/models.go b/coderd/database/models.go index 3fcf947bf4cae..4253103011acf 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -494,6 +494,17 @@ type WorkspaceAgent struct { Directory string `db:"directory" json:"directory"` } +type WorkspaceApp struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + AgentID uuid.UUID `db:"agent_id" json:"agent_id"` + Name string `db:"name" json:"name"` + Icon string `db:"icon" json:"icon"` + Command sql.NullString `db:"command" json:"command"` + Url sql.NullString `db:"url" json:"url"` + RelativePath bool `db:"relative_path" json:"relative_path"` +} + type WorkspaceBuild struct { ID uuid.UUID `db:"id" json:"id"` CreatedAt time.Time `db:"created_at" json:"created_at"` diff --git a/coderd/database/querier.go b/coderd/database/querier.go index db061cfcb36a1..852e9d27570b6 100644 --- a/coderd/database/querier.go +++ b/coderd/database/querier.go @@ -61,6 +61,8 @@ type querier interface { GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (WorkspaceAgent, error) GetWorkspaceAgentByInstanceID(ctx context.Context, authInstanceID string) (WorkspaceAgent, error) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceAgent, error) + GetWorkspaceAppsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceApp, error) + GetWorkspaceAppsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceApp, error) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (WorkspaceBuild, error) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UUID) (WorkspaceBuild, error) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg GetWorkspaceBuildByWorkspaceIDParams) ([]WorkspaceBuild, error) @@ -90,6 +92,7 @@ type querier interface { InsertUser(ctx context.Context, arg InsertUserParams) (User, error) InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (Workspace, error) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) + InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 57eeb67ac5814..26d6a3f78ffc6 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -2749,6 +2749,130 @@ func (q *sqlQuerier) UpdateWorkspaceAgentConnectionByID(ctx context.Context, arg return err } +const getWorkspaceAppsByAgentID = `-- name: GetWorkspaceAppsByAgentID :many +SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE agent_id = $1 +` + +func (q *sqlQuerier) GetWorkspaceAppsByAgentID(ctx context.Context, agentID uuid.UUID) ([]WorkspaceApp, error) { + rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentID, agentID) + if err != nil { + return nil, err + } + defer rows.Close() + var items []WorkspaceApp + for rows.Next() { + var i WorkspaceApp + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.AgentID, + &i.Name, + &i.Icon, + &i.Command, + &i.Url, + &i.RelativePath, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const getWorkspaceAppsByAgentIDs = `-- name: GetWorkspaceAppsByAgentIDs :many +SELECT id, created_at, agent_id, name, icon, command, url, relative_path FROM workspace_apps WHERE agent_id = ANY($1 :: uuid [ ]) +` + +func (q *sqlQuerier) GetWorkspaceAppsByAgentIDs(ctx context.Context, ids []uuid.UUID) ([]WorkspaceApp, error) { + rows, err := q.db.QueryContext(ctx, getWorkspaceAppsByAgentIDs, pq.Array(ids)) + if err != nil { + return nil, err + } + defer rows.Close() + var items []WorkspaceApp + for rows.Next() { + var i WorkspaceApp + if err := rows.Scan( + &i.ID, + &i.CreatedAt, + &i.AgentID, + &i.Name, + &i.Icon, + &i.Command, + &i.Url, + &i.RelativePath, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + +const insertWorkspaceApp = `-- name: InsertWorkspaceApp :one +INSERT INTO + workspace_apps ( + id, + created_at, + agent_id, + name, + icon, + command, + url, + relative_path + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id, created_at, agent_id, name, icon, command, url, relative_path +` + +type InsertWorkspaceAppParams struct { + ID uuid.UUID `db:"id" json:"id"` + CreatedAt time.Time `db:"created_at" json:"created_at"` + AgentID uuid.UUID `db:"agent_id" json:"agent_id"` + Name string `db:"name" json:"name"` + Icon string `db:"icon" json:"icon"` + Command sql.NullString `db:"command" json:"command"` + Url sql.NullString `db:"url" json:"url"` + RelativePath bool `db:"relative_path" json:"relative_path"` +} + +func (q *sqlQuerier) InsertWorkspaceApp(ctx context.Context, arg InsertWorkspaceAppParams) (WorkspaceApp, error) { + row := q.db.QueryRowContext(ctx, insertWorkspaceApp, + arg.ID, + arg.CreatedAt, + arg.AgentID, + arg.Name, + arg.Icon, + arg.Command, + arg.Url, + arg.RelativePath, + ) + var i WorkspaceApp + err := row.Scan( + &i.ID, + &i.CreatedAt, + &i.AgentID, + &i.Name, + &i.Icon, + &i.Command, + &i.Url, + &i.RelativePath, + ) + return i, err +} + const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one SELECT id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id diff --git a/coderd/database/queries/workspaceapps.sql b/coderd/database/queries/workspaceapps.sql new file mode 100644 index 0000000000000..4b63ba1be5580 --- /dev/null +++ b/coderd/database/queries/workspaceapps.sql @@ -0,0 +1,20 @@ +-- name: GetWorkspaceAppsByAgentID :many +SELECT * FROM workspace_apps WHERE agent_id = $1; + +-- name: GetWorkspaceAppsByAgentIDs :many +SELECT * FROM workspace_apps WHERE agent_id = ANY(@ids :: uuid [ ]); + +-- name: InsertWorkspaceApp :one +INSERT INTO + workspace_apps ( + id, + created_at, + agent_id, + name, + icon, + command, + url, + relative_path + ) +VALUES + ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *; diff --git a/coderd/httpmw/apikey.go b/coderd/httpmw/apikey.go index abf55128d55d7..77a4b00af01be 100644 --- a/coderd/httpmw/apikey.go +++ b/coderd/httpmw/apikey.go @@ -17,7 +17,7 @@ import ( "github.com/coder/coder/coderd/httpapi" ) -// SessionTokenKey represents the name of the cookie or query paramater the API key is stored in. +// SessionTokenKey represents the name of the cookie or query parameter the API key is stored in. const SessionTokenKey = "session_token" type apiKeyContextKey struct{} diff --git a/coderd/httpmw/wildcard.go b/coderd/httpmw/wildcard.go new file mode 100644 index 0000000000000..c2cc5be1f451c --- /dev/null +++ b/coderd/httpmw/wildcard.go @@ -0,0 +1,24 @@ +package httpmw + +import ( + "net/http" + "strings" +) + +// Wildcard routes to the provided handler if the request host has the suffix of hostname. +func Wildcard(hostname string, handler http.HandlerFunc) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var ( + ctx = r.Context() + ) + + if !strings.HasSuffix(r.Host, hostname) { + next.ServeHTTP(w, r) + return + } + + handler(w, r.WithContext(ctx)) + }) + } +} diff --git a/coderd/httpmw/wildcard_test.go b/coderd/httpmw/wildcard_test.go new file mode 100644 index 0000000000000..ba0a7ebd607ca --- /dev/null +++ b/coderd/httpmw/wildcard_test.go @@ -0,0 +1,38 @@ +package httpmw_test + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/coder/coder/coderd/httpmw" +) + +func TestWildcard(t *testing.T) { + t.Parallel() + t.Run("Match", func(t *testing.T) { + t.Parallel() + req := httptest.NewRequest("GET", "http://frogs.bananas.org", nil) + res := httptest.NewRecorder() + httpmw.Wildcard("bananas.org", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusForbidden) + })).ServeHTTP(res, req) + require.Equal(t, http.StatusOK, res.Result().StatusCode) + }) + + t.Run("Passthrough", func(t *testing.T) { + t.Parallel() + req := httptest.NewRequest("GET", "http://frogs.apples.org", nil) + res := httptest.NewRecorder() + httpmw.Wildcard("bananas.org", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + })(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusForbidden) + })).ServeHTTP(res, req) + require.Equal(t, http.StatusForbidden, res.Result().StatusCode) + }) +} diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index 590f3e56264f4..880a239f523ac 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -633,7 +633,7 @@ func insertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. } } - _, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{ + dbAgent, err := db.InsertWorkspaceAgent(ctx, database.InsertWorkspaceAgentParams{ ID: uuid.New(), CreatedAt: database.Now(), UpdatedAt: database.Now(), @@ -653,6 +653,28 @@ func insertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. if err != nil { return xerrors.Errorf("insert agent: %w", err) } + + for _, app := range agent.Apps { + _, err := db.InsertWorkspaceApp(ctx, database.InsertWorkspaceAppParams{ + ID: uuid.New(), + CreatedAt: database.Now(), + AgentID: dbAgent.ID, + Name: app.Name, + Icon: app.Icon, + Command: sql.NullString{ + String: app.Command, + Valid: app.Command != "", + }, + Url: sql.NullString{ + String: app.Url, + Valid: app.Url != "", + }, + RelativePath: app.RelativePath, + }) + if err != nil { + return xerrors.Errorf("insert app: %w", err) + } + } } return nil } diff --git a/coderd/provisionerjobs.go b/coderd/provisionerjobs.go index a47cc15541994..e1ccfcc76368f 100644 --- a/coderd/provisionerjobs.go +++ b/coderd/provisionerjobs.go @@ -209,6 +209,20 @@ func (api *API) provisionerJobResources(rw http.ResponseWriter, r *http.Request, }) return } + resourceAgentIDs := make([]uuid.UUID, 0) + for _, agent := range resourceAgents { + resourceAgentIDs = append(resourceAgentIDs, agent.ID) + } + apps, err := api.Database.GetWorkspaceAppsByAgentIDs(r.Context(), resourceAgentIDs) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get workspace apps: %s", err), + }) + return + } apiResources := make([]codersdk.WorkspaceResource, 0) for _, resource := range resources { @@ -217,7 +231,14 @@ func (api *API) provisionerJobResources(rw http.ResponseWriter, r *http.Request, if agent.ResourceID != resource.ID { continue } - apiAgent, err := convertWorkspaceAgent(agent, api.AgentConnectionUpdateFrequency) + dbApps := make([]database.WorkspaceApp, 0) + for _, app := range apps { + if app.AgentID == agent.ID { + dbApps = append(dbApps, app) + } + } + + apiAgent, err := convertWorkspaceAgent(agent, convertApps(dbApps), api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert provisioner job agent: %s", err), diff --git a/coderd/rbac/README.md b/coderd/rbac/README.md index 69ba5e9f925aa..f2e1283206822 100644 --- a/coderd/rbac/README.md +++ b/coderd/rbac/README.md @@ -51,7 +51,7 @@ This can be represented by the following truth table, where Y represents *positi ## Example Permissions -- `+site.*.*.read`: allowed to perform the `read` action against all objects of type `devurl` in a given Coder deployment. +- `+site.*.*.read`: allowed to perform the `read` action against all objects of type `app` in a given Coder deployment. - `-user.workspace.*.create`: user is not allowed to create workspaces. ## Roles diff --git a/coderd/rbac/object.go b/coderd/rbac/object.go index 9ebbb304935c2..b46fe21a4301f 100644 --- a/coderd/rbac/object.go +++ b/coderd/rbac/object.go @@ -109,7 +109,7 @@ type Object struct { // OrgID specifies which org the object is a part of. OrgID string `json:"org_owner"` - // Type is "workspace", "project", "devurl", etc + // Type is "workspace", "project", "app", etc Type string `json:"type"` // TODO: SharedUsers? } diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index bbda257eb01d5..88e0298d8fb79 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -30,7 +30,14 @@ import ( func (api *API) workspaceAgent(rw http.ResponseWriter, r *http.Request) { workspaceAgent := httpmw.WorkspaceAgentParam(r) - apiAgent, err := convertWorkspaceAgent(workspaceAgent, api.AgentConnectionUpdateFrequency) + dbApps, err := api.Database.GetWorkspaceAppsByAgentID(r.Context(), workspaceAgent.ID) + if err != nil && !xerrors.Is(err, sql.ErrNoRows) { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get workspace agent apps: %s", err), + }) + return + } + apiAgent, err := convertWorkspaceAgent(workspaceAgent, convertApps(dbApps), api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert workspace agent: %s", err), @@ -48,7 +55,7 @@ func (api *API) workspaceAgentDial(rw http.ResponseWriter, r *http.Request) { defer api.websocketWaitGroup.Done() workspaceAgent := httpmw.WorkspaceAgentParam(r) - apiAgent, err := convertWorkspaceAgent(workspaceAgent, api.AgentConnectionUpdateFrequency) + apiAgent, err := convertWorkspaceAgent(workspaceAgent, nil, api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert workspace agent: %s", err), @@ -92,7 +99,7 @@ func (api *API) workspaceAgentDial(rw http.ResponseWriter, r *http.Request) { func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request) { workspaceAgent := httpmw.WorkspaceAgent(r) - apiAgent, err := convertWorkspaceAgent(workspaceAgent, api.AgentConnectionUpdateFrequency) + apiAgent, err := convertWorkspaceAgent(workspaceAgent, nil, api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert workspace agent: %s", err), @@ -331,7 +338,7 @@ func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) { defer api.websocketWaitGroup.Done() workspaceAgent := httpmw.WorkspaceAgentParam(r) - apiAgent, err := convertWorkspaceAgent(workspaceAgent, api.AgentConnectionUpdateFrequency) + apiAgent, err := convertWorkspaceAgent(workspaceAgent, nil, api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert workspace agent: %s", err), @@ -451,7 +458,21 @@ func (api *API) dialWorkspaceAgent(r *http.Request, agentID uuid.UUID) (*agent.C }, nil } -func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency time.Duration) (codersdk.WorkspaceAgent, error) { +func convertApps(dbApps []database.WorkspaceApp) []codersdk.WorkspaceApp { + apps := make([]codersdk.WorkspaceApp, 0) + for _, dbApp := range dbApps { + apps = append(apps, codersdk.WorkspaceApp{ + ID: dbApp.ID, + Name: dbApp.Name, + Command: dbApp.Command.String, + AccessURL: dbApp.Url.String, + Icon: dbApp.Icon, + }) + } + return apps +} + +func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, apps []codersdk.WorkspaceApp, agentUpdateFrequency time.Duration) (codersdk.WorkspaceAgent, error) { var envs map[string]string if dbAgent.EnvironmentVariables.Valid { err := json.Unmarshal(dbAgent.EnvironmentVariables.RawMessage, &envs) @@ -471,6 +492,7 @@ func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency StartupScript: dbAgent.StartupScript.String, EnvironmentVariables: envs, Directory: dbAgent.Directory, + Apps: apps, } if dbAgent.FirstConnectedAt.Valid { workspaceAgent.FirstConnectedAt = &dbAgent.FirstConnectedAt.Time diff --git a/coderd/workspaceapps.go b/coderd/workspaceapps.go new file mode 100644 index 0000000000000..0c2aa8f342bf7 --- /dev/null +++ b/coderd/workspaceapps.go @@ -0,0 +1,9 @@ +package coderd + +import ( + "net/http" +) + +func (api *API) proxyPath(rw http.ResponseWriter, r *http.Request) { + +} diff --git a/coderd/workspaceapps_test.go b/coderd/workspaceapps_test.go new file mode 100644 index 0000000000000..a1bbc0bfabd3f --- /dev/null +++ b/coderd/workspaceapps_test.go @@ -0,0 +1 @@ +package coderd_test diff --git a/coderd/workspaceresources.go b/coderd/workspaceresources.go index a08861971e60e..c72f6add504dc 100644 --- a/coderd/workspaceresources.go +++ b/coderd/workspaceresources.go @@ -8,6 +8,7 @@ import ( "github.com/google/uuid" + "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/httpmw" "github.com/coder/coder/coderd/rbac" @@ -45,9 +46,30 @@ func (api *API) workspaceResource(rw http.ResponseWriter, r *http.Request) { }) return } + agentIDs := make([]uuid.UUID, 0) + for _, agent := range agents { + agentIDs = append(agentIDs, agent.ID) + } + apps, err := api.Database.GetWorkspaceAppsByAgentIDs(r.Context(), agentIDs) + if errors.Is(err, sql.ErrNoRows) { + err = nil + } + if err != nil { + httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ + Message: fmt.Sprintf("get workspace apps: %s", err), + }) + return + } apiAgents := make([]codersdk.WorkspaceAgent, 0) for _, agent := range agents { - convertedAgent, err := convertWorkspaceAgent(agent, api.AgentConnectionUpdateFrequency) + dbApps := make([]database.WorkspaceApp, 0) + for _, app := range apps { + if app.AgentID == agent.ID { + dbApps = append(dbApps, app) + } + } + + convertedAgent, err := convertWorkspaceAgent(agent, convertApps(dbApps), api.AgentConnectionUpdateFrequency) if err != nil { httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{ Message: fmt.Sprintf("convert provisioner job agent: %s", err), diff --git a/coderd/workspaceresources_test.go b/coderd/workspaceresources_test.go index 83d10187562b5..f448c99e51fbd 100644 --- a/coderd/workspaceresources_test.go +++ b/coderd/workspaceresources_test.go @@ -43,4 +43,51 @@ func TestWorkspaceResource(t *testing.T) { _, err = client.WorkspaceResource(context.Background(), resources[0].ID) require.NoError(t, err) }) + + t.Run("Apps", func(t *testing.T) { + t.Parallel() + _, client, coderd := coderdtest.NewWithServer(t, nil) + user := coderdtest.CreateFirstUser(t, client) + coderdtest.NewProvisionerDaemon(t, coderd) + app := &proto.App{ + Name: "code-server", + Command: "some-command", + Url: "http://localhost:3000", + Icon: "/code.svg", + } + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{ + Parse: echo.ParseComplete, + Provision: []*proto.Provision_Response{{ + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Resources: []*proto.Resource{{ + Name: "some", + Type: "example", + Agents: []*proto.Agent{{ + Id: "something", + Auth: &proto.Agent_Token{}, + Apps: []*proto.App{app}, + }}, + }}, + }, + }, + }}, + }) + coderdtest.AwaitTemplateVersionJob(t, client, version.ID) + template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) + workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID) + coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) + resources, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID) + require.NoError(t, err) + resource, err := client.WorkspaceResource(context.Background(), resources[0].ID) + require.NoError(t, err) + require.Len(t, resource.Agents, 1) + agent := resource.Agents[0] + require.Len(t, agent.Apps, 1) + got := agent.Apps[0] + require.Equal(t, app.Command, got.Command) + require.Equal(t, app.Icon, got.Icon) + require.Equal(t, app.Name, got.Name) + require.Equal(t, app.Url, got.AccessURL) + }) } diff --git a/codersdk/workspaceapps.go b/codersdk/workspaceapps.go new file mode 100644 index 0000000000000..ca46e83a33e64 --- /dev/null +++ b/codersdk/workspaceapps.go @@ -0,0 +1,16 @@ +package codersdk + +import "github.com/google/uuid" + +type WorkspaceApp struct { + ID uuid.UUID `json:"id"` + // Name is a unique identifier attached to an agent. + Name string `json:"name"` + Command string `json:"command,omitempty"` + // AccessURL is an address used to access the application. + // If command is specified, this will be omitted. + AccessURL string `json:"access_url,omitempty"` + // Icon is a relative path or external URL that specifies + // an icon to be displayed in the dashboard. + Icon string `json:"icon"` +} diff --git a/codersdk/workspaceresources.go b/codersdk/workspaceresources.go index 97ae03186cf39..3259b342c7a08 100644 --- a/codersdk/workspaceresources.go +++ b/codersdk/workspaceresources.go @@ -44,6 +44,7 @@ type WorkspaceAgent struct { OperatingSystem string `json:"operating_system"` StartupScript string `json:"startup_script,omitempty"` Directory string `json:"directory,omitempty"` + Apps []WorkspaceApp `json:"apps"` } type WorkspaceAgentResourceMetadata struct { diff --git a/go.mod b/go.mod index da981e9874691..6fc8bea5a005f 100644 --- a/go.mod +++ b/go.mod @@ -126,6 +126,8 @@ require ( storj.io/drpc v0.0.30 ) +require github.com/go-chi/cors v1.2.1 + require ( github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect diff --git a/go.sum b/go.sum index 0a6da880d8cd5..141ee7795dc68 100644 --- a/go.sum +++ b/go.sum @@ -570,6 +570,8 @@ github.com/go-chi/chi v1.5.4 h1:QHdzF2szwjqVV4wmByUnTcsbIg7UGaQ0tPF2t5GcAIs= github.com/go-chi/chi v1.5.4/go.mod h1:uaf8YgoFazUOkPBG7fxPftUylNumIev9awIWOENIuEg= github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8= github.com/go-chi/chi/v5 v5.0.7/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= +github.com/go-chi/cors v1.2.1 h1:xEC8UT3Rlp2QuWNEr4Fs/c2EAGVKBwy/1vHx3bppil4= +github.com/go-chi/cors v1.2.1/go.mod h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58= github.com/go-chi/httprate v0.5.3 h1:5HPWb0N6ymIiuotMtCfOGpQKiKeqXVzMexHh1W1yXPc= github.com/go-chi/httprate v0.5.3/go.mod h1:kYR4lorHX3It9tTh4eTdHhcF2bzrYnCrRNlv5+IBm2M= github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8= diff --git a/provisioner/terraform/provision.go b/provisioner/terraform/provision.go index acffae785b759..61e426467dc37 100644 --- a/provisioner/terraform/provision.go +++ b/provisioner/terraform/provision.go @@ -397,7 +397,7 @@ func parseTerraformPlan(ctx context.Context, terraform *tfexec.Terraform, planfi if resource.Mode == tfjson.DataResourceMode { continue } - if resource.Type == "coder_agent" || resource.Type == "coder_agent_instance" { + if resource.Type == "coder_agent" || resource.Type == "coder_agent_instance" || resource.Type == "coder_app" { continue } resources = append(resources, &proto.Resource{ @@ -520,11 +520,47 @@ func parseTerraformApply(ctx context.Context, terraform *tfexec.Terraform, state } } + type appAttributes struct { + AgentID string `mapstructure:"agent_id"` + Name string `mapstructure:"name"` + Icon string `mapstructure:"icon"` + URL string `mapstructure:"url"` + Command string `mapstructure:"command"` + RelativePath bool `mapstructure:"relative_path"` + } + // Associate Apps with agents. + for _, resource := range state.Values.RootModule.Resources { + if resource.Type != "coder_app" { + continue + } + var attrs appAttributes + err = mapstructure.Decode(resource.AttributeValues, &attrs) + if err != nil { + return nil, xerrors.Errorf("decode app attributes: %w", err) + } + if attrs.Name == "" { + // Default to the resource name if none is set! + attrs.Name = resource.Name + } + for _, agent := range agents { + if agent.Id != attrs.AgentID { + continue + } + agent.Apps = append(agent.Apps, &proto.App{ + Name: attrs.Name, + Command: attrs.Command, + Url: attrs.URL, + Icon: attrs.Icon, + RelativePath: attrs.RelativePath, + }) + } + } + for _, resource := range tfResources { if resource.Mode == tfjson.DataResourceMode { continue } - if resource.Type == "coder_agent" || resource.Type == "coder_agent_instance" { + if resource.Type == "coder_agent" || resource.Type == "coder_agent_instance" || resource.Type == "coder_app" { continue } resourceAgents := findAgents(resourceDependencies, agents, convertAddressToLabel(resource.Address)) diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go index 05d781dc8d8ff..294a70d3deb8c 100644 --- a/provisioner/terraform/provision_test.go +++ b/provisioner/terraform/provision_test.go @@ -30,7 +30,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.3.4" + version = "0.4.2" } } } @@ -438,6 +438,52 @@ provider "coder" { }, }, }, + }, { + Name: "agent-with-app", + Files: map[string]string{ + "main.tf": provider + ` + resource "coder_agent" "A" { + os = "darwin" + arch = "amd64" + } + resource "null_resource" "A" { + depends_on = [ + coder_agent.A + ] + } + resource "coder_app" "A" { + agent_id = coder_agent.A.id + command = "vim" + } + `, + }, + Request: &proto.Provision_Request{ + Type: &proto.Provision_Request_Start{ + Start: &proto.Provision_Start{ + Metadata: &proto.Provision_Metadata{}, + }, + }, + }, + Response: &proto.Provision_Response{ + Type: &proto.Provision_Response_Complete{ + Complete: &proto.Provision_Complete{ + Resources: []*proto.Resource{{ + Name: "A", + Type: "null_resource", + Agents: []*proto.Agent{{ + Name: "A", + OperatingSystem: "darwin", + Architecture: "amd64", + Auth: &proto.Agent_Token{}, + Apps: []*proto.App{{ + Name: "A", + Command: "vim", + }}, + }}, + }}, + }, + }, + }, }} { testCase := testCase t.Run(testCase.Name, func(t *testing.T) { diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 01d68d25a8619..eee976e770aa9 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -711,6 +711,7 @@ type Agent struct { OperatingSystem string `protobuf:"bytes,5,opt,name=operating_system,json=operatingSystem,proto3" json:"operating_system,omitempty"` Architecture string `protobuf:"bytes,6,opt,name=architecture,proto3" json:"architecture,omitempty"` Directory string `protobuf:"bytes,7,opt,name=directory,proto3" json:"directory,omitempty"` + Apps []*App `protobuf:"bytes,8,rep,name=apps,proto3" json:"apps,omitempty"` // Types that are assignable to Auth: // *Agent_Token // *Agent_InstanceId @@ -798,6 +799,13 @@ func (x *Agent) GetDirectory() string { return "" } +func (x *Agent) GetApps() []*App { + if x != nil { + return x.Apps + } + return nil +} + func (m *Agent) GetAuth() isAgent_Auth { if m != nil { return m.Auth @@ -824,17 +832,97 @@ type isAgent_Auth interface { } type Agent_Token struct { - Token string `protobuf:"bytes,8,opt,name=token,proto3,oneof"` + Token string `protobuf:"bytes,9,opt,name=token,proto3,oneof"` } type Agent_InstanceId struct { - InstanceId string `protobuf:"bytes,9,opt,name=instance_id,json=instanceId,proto3,oneof"` + InstanceId string `protobuf:"bytes,10,opt,name=instance_id,json=instanceId,proto3,oneof"` } func (*Agent_Token) isAgent_Auth() {} func (*Agent_InstanceId) isAgent_Auth() {} +// App represents a dev-accessible application on the workspace. +type App struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Command string `protobuf:"bytes,2,opt,name=command,proto3" json:"command,omitempty"` + Url string `protobuf:"bytes,3,opt,name=url,proto3" json:"url,omitempty"` + Icon string `protobuf:"bytes,4,opt,name=icon,proto3" json:"icon,omitempty"` + RelativePath bool `protobuf:"varint,5,opt,name=relative_path,json=relativePath,proto3" json:"relative_path,omitempty"` +} + +func (x *App) Reset() { + *x = App{} + if protoimpl.UnsafeEnabled { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *App) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*App) ProtoMessage() {} + +func (x *App) ProtoReflect() protoreflect.Message { + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use App.ProtoReflect.Descriptor instead. +func (*App) Descriptor() ([]byte, []int) { + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{8} +} + +func (x *App) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *App) GetCommand() string { + if x != nil { + return x.Command + } + return "" +} + +func (x *App) GetUrl() string { + if x != nil { + return x.Url + } + return "" +} + +func (x *App) GetIcon() string { + if x != nil { + return x.Icon + } + return "" +} + +func (x *App) GetRelativePath() bool { + if x != nil { + return x.RelativePath + } + return false +} + // Resource represents created infrastructure. type Resource struct { state protoimpl.MessageState @@ -849,7 +937,7 @@ type Resource struct { func (x *Resource) Reset() { *x = Resource{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[8] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -862,7 +950,7 @@ func (x *Resource) String() string { func (*Resource) ProtoMessage() {} func (x *Resource) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[8] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -875,7 +963,7 @@ func (x *Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use Resource.ProtoReflect.Descriptor instead. func (*Resource) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{8} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{9} } func (x *Resource) GetName() string { @@ -909,7 +997,7 @@ type Parse struct { func (x *Parse) Reset() { *x = Parse{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[9] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -922,7 +1010,7 @@ func (x *Parse) String() string { func (*Parse) ProtoMessage() {} func (x *Parse) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[9] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -935,7 +1023,7 @@ func (x *Parse) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse.ProtoReflect.Descriptor instead. func (*Parse) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{9} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10} } // Provision consumes source-code from a directory to produce resources. @@ -948,7 +1036,7 @@ type Provision struct { func (x *Provision) Reset() { *x = Provision{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[10] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -961,7 +1049,7 @@ func (x *Provision) String() string { func (*Provision) ProtoMessage() {} func (x *Provision) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[10] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -974,7 +1062,7 @@ func (x *Provision) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision.ProtoReflect.Descriptor instead. func (*Provision) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11} } type Parse_Request struct { @@ -988,7 +1076,7 @@ type Parse_Request struct { func (x *Parse_Request) Reset() { *x = Parse_Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[12] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1001,7 +1089,7 @@ func (x *Parse_Request) String() string { func (*Parse_Request) ProtoMessage() {} func (x *Parse_Request) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[12] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1014,7 +1102,7 @@ func (x *Parse_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse_Request.ProtoReflect.Descriptor instead. func (*Parse_Request) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{9, 0} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 0} } func (x *Parse_Request) GetDirectory() string { @@ -1035,7 +1123,7 @@ type Parse_Complete struct { func (x *Parse_Complete) Reset() { *x = Parse_Complete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[13] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1048,7 +1136,7 @@ func (x *Parse_Complete) String() string { func (*Parse_Complete) ProtoMessage() {} func (x *Parse_Complete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[13] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1061,7 +1149,7 @@ func (x *Parse_Complete) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse_Complete.ProtoReflect.Descriptor instead. func (*Parse_Complete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{9, 1} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 1} } func (x *Parse_Complete) GetParameterSchemas() []*ParameterSchema { @@ -1085,7 +1173,7 @@ type Parse_Response struct { func (x *Parse_Response) Reset() { *x = Parse_Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[14] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1098,7 +1186,7 @@ func (x *Parse_Response) String() string { func (*Parse_Response) ProtoMessage() {} func (x *Parse_Response) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[14] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1111,7 +1199,7 @@ func (x *Parse_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Parse_Response.ProtoReflect.Descriptor instead. func (*Parse_Response) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{9, 2} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 2} } func (m *Parse_Response) GetType() isParse_Response_Type { @@ -1167,7 +1255,7 @@ type Provision_Metadata struct { func (x *Provision_Metadata) Reset() { *x = Provision_Metadata{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[15] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[16] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1180,7 +1268,7 @@ func (x *Provision_Metadata) String() string { func (*Provision_Metadata) ProtoMessage() {} func (x *Provision_Metadata) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[15] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[16] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1193,7 +1281,7 @@ func (x *Provision_Metadata) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Metadata.ProtoReflect.Descriptor instead. func (*Provision_Metadata) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 0} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 0} } func (x *Provision_Metadata) GetCoderUrl() string { @@ -1253,7 +1341,7 @@ type Provision_Start struct { func (x *Provision_Start) Reset() { *x = Provision_Start{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[16] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1266,7 +1354,7 @@ func (x *Provision_Start) String() string { func (*Provision_Start) ProtoMessage() {} func (x *Provision_Start) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[16] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1279,7 +1367,7 @@ func (x *Provision_Start) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Start.ProtoReflect.Descriptor instead. func (*Provision_Start) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 1} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 1} } func (x *Provision_Start) GetDirectory() string { @@ -1326,7 +1414,7 @@ type Provision_Cancel struct { func (x *Provision_Cancel) Reset() { *x = Provision_Cancel{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1339,7 +1427,7 @@ func (x *Provision_Cancel) String() string { func (*Provision_Cancel) ProtoMessage() {} func (x *Provision_Cancel) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[17] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1352,7 +1440,7 @@ func (x *Provision_Cancel) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Cancel.ProtoReflect.Descriptor instead. func (*Provision_Cancel) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 2} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 2} } type Provision_Request struct { @@ -1369,7 +1457,7 @@ type Provision_Request struct { func (x *Provision_Request) Reset() { *x = Provision_Request{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1382,7 +1470,7 @@ func (x *Provision_Request) String() string { func (*Provision_Request) ProtoMessage() {} func (x *Provision_Request) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[18] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1395,7 +1483,7 @@ func (x *Provision_Request) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Request.ProtoReflect.Descriptor instead. func (*Provision_Request) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 3} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 3} } func (m *Provision_Request) GetType() isProvision_Request_Type { @@ -1448,7 +1536,7 @@ type Provision_Complete struct { func (x *Provision_Complete) Reset() { *x = Provision_Complete{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1461,7 +1549,7 @@ func (x *Provision_Complete) String() string { func (*Provision_Complete) ProtoMessage() {} func (x *Provision_Complete) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[19] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1474,7 +1562,7 @@ func (x *Provision_Complete) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Complete.ProtoReflect.Descriptor instead. func (*Provision_Complete) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 4} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 4} } func (x *Provision_Complete) GetState() []byte { @@ -1512,7 +1600,7 @@ type Provision_Response struct { func (x *Provision_Response) Reset() { *x = Provision_Response{} if protoimpl.UnsafeEnabled { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1525,7 +1613,7 @@ func (x *Provision_Response) String() string { func (*Provision_Response) ProtoMessage() {} func (x *Provision_Response) ProtoReflect() protoreflect.Message { - mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[20] + mi := &file_provisionersdk_proto_provisioner_proto_msgTypes[21] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1538,7 +1626,7 @@ func (x *Provision_Response) ProtoReflect() protoreflect.Message { // Deprecated: Use Provision_Response.ProtoReflect.Descriptor instead. func (*Provision_Response) Descriptor() ([]byte, []int) { - return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{10, 5} + return file_provisionersdk_proto_provisioner_proto_rawDescGZIP(), []int{11, 5} } func (m *Provision_Response) GetType() isProvision_Response_Type { @@ -1660,7 +1748,7 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x70, 0x75, 0x74, 0x22, 0x37, 0x0a, 0x14, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x41, 0x75, 0x74, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0xe9, 0x02, 0x0a, + 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x22, 0x8f, 0x03, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x2d, 0x0a, 0x03, 0x65, 0x6e, @@ -1675,114 +1763,125 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x61, 0x72, 0x63, 0x68, 0x69, 0x74, 0x65, 0x63, 0x74, 0x75, 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, - 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, - 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0b, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, - 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x36, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x42, 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x5e, 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, 0x12, 0x2a, 0x0a, 0x06, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, - 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, - 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 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, 0xfa, 0x06, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x9d, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, - 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, - 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, - 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, - 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, - 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, - 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, - 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, - 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, - 0x6e, 0x65, 0x72, 0x49, 0x64, 0x1a, 0xd9, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, 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, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x18, 0x03, 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, - 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, - 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, - 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x1a, 0x80, 0x01, 0x0a, 0x07, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, - 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x24, 0x0a, + 0x04, 0x61, 0x70, 0x70, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x41, 0x70, 0x70, 0x52, 0x04, 0x61, + 0x70, 0x70, 0x73, 0x12, 0x16, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x21, 0x0a, 0x0b, 0x69, + 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x0a, 0x69, 0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x49, 0x64, 0x1a, 0x36, + 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x06, 0x0a, 0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x7e, + 0x0a, 0x03, 0x41, 0x70, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, + 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x5e, + 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, 0x12, 0x2a, 0x0a, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x52, 0x06, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x73, 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, 0xfa, 0x06, + 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0x9d, 0x02, 0x0a, 0x08, + 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, + 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, + 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, + 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, + 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, + 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, + 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x1a, 0xd9, 0x01, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x72, 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, 0x3b, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 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, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x48, 0x00, 0x52, 0x06, - 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x1a, 0x6b, - 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, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x73, 0x18, 0x03, 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, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, - 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, - 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x02, 0x32, 0xa3, - 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, 0x50, 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, - 0x28, 0x01, 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, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, + 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x1a, 0x80, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x1a, 0x6b, 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, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 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, 0x2a, 0x37, 0x0a, 0x13, 0x57, + 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, + 0x4f, 0x59, 0x10, 0x02, 0x32, 0xa3, 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, 0x50, 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, 0x28, 0x01, 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 ( @@ -1798,7 +1897,7 @@ func file_provisionersdk_proto_provisioner_proto_rawDescGZIP() []byte { } var file_provisionersdk_proto_provisioner_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 21) +var file_provisionersdk_proto_provisioner_proto_msgTypes = make([]protoimpl.MessageInfo, 22) var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (LogLevel)(0), // 0: provisioner.LogLevel (WorkspaceTransition)(0), // 1: provisioner.WorkspaceTransition @@ -1813,19 +1912,20 @@ var file_provisionersdk_proto_provisioner_proto_goTypes = []interface{}{ (*Log)(nil), // 10: provisioner.Log (*InstanceIdentityAuth)(nil), // 11: provisioner.InstanceIdentityAuth (*Agent)(nil), // 12: provisioner.Agent - (*Resource)(nil), // 13: provisioner.Resource - (*Parse)(nil), // 14: provisioner.Parse - (*Provision)(nil), // 15: provisioner.Provision - nil, // 16: provisioner.Agent.EnvEntry - (*Parse_Request)(nil), // 17: provisioner.Parse.Request - (*Parse_Complete)(nil), // 18: provisioner.Parse.Complete - (*Parse_Response)(nil), // 19: provisioner.Parse.Response - (*Provision_Metadata)(nil), // 20: provisioner.Provision.Metadata - (*Provision_Start)(nil), // 21: provisioner.Provision.Start - (*Provision_Cancel)(nil), // 22: provisioner.Provision.Cancel - (*Provision_Request)(nil), // 23: provisioner.Provision.Request - (*Provision_Complete)(nil), // 24: provisioner.Provision.Complete - (*Provision_Response)(nil), // 25: provisioner.Provision.Response + (*App)(nil), // 13: provisioner.App + (*Resource)(nil), // 14: provisioner.Resource + (*Parse)(nil), // 15: provisioner.Parse + (*Provision)(nil), // 16: provisioner.Provision + nil, // 17: provisioner.Agent.EnvEntry + (*Parse_Request)(nil), // 18: provisioner.Parse.Request + (*Parse_Complete)(nil), // 19: provisioner.Parse.Complete + (*Parse_Response)(nil), // 20: provisioner.Parse.Response + (*Provision_Metadata)(nil), // 21: provisioner.Provision.Metadata + (*Provision_Start)(nil), // 22: provisioner.Provision.Start + (*Provision_Cancel)(nil), // 23: provisioner.Provision.Cancel + (*Provision_Request)(nil), // 24: provisioner.Provision.Request + (*Provision_Complete)(nil), // 25: provisioner.Provision.Complete + (*Provision_Response)(nil), // 26: provisioner.Provision.Response } var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{ 2, // 0: provisioner.ParameterSource.scheme:type_name -> provisioner.ParameterSource.Scheme @@ -1835,28 +1935,29 @@ var file_provisionersdk_proto_provisioner_proto_depIdxs = []int32{ 7, // 4: provisioner.ParameterSchema.default_destination:type_name -> provisioner.ParameterDestination 4, // 5: provisioner.ParameterSchema.validation_type_system:type_name -> provisioner.ParameterSchema.TypeSystem 0, // 6: provisioner.Log.level:type_name -> provisioner.LogLevel - 16, // 7: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry - 12, // 8: provisioner.Resource.agents:type_name -> provisioner.Agent - 9, // 9: provisioner.Parse.Complete.parameter_schemas:type_name -> provisioner.ParameterSchema - 10, // 10: provisioner.Parse.Response.log:type_name -> provisioner.Log - 18, // 11: provisioner.Parse.Response.complete:type_name -> provisioner.Parse.Complete - 1, // 12: provisioner.Provision.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition - 8, // 13: provisioner.Provision.Start.parameter_values:type_name -> provisioner.ParameterValue - 20, // 14: provisioner.Provision.Start.metadata:type_name -> provisioner.Provision.Metadata - 21, // 15: provisioner.Provision.Request.start:type_name -> provisioner.Provision.Start - 22, // 16: provisioner.Provision.Request.cancel:type_name -> provisioner.Provision.Cancel - 13, // 17: provisioner.Provision.Complete.resources:type_name -> provisioner.Resource - 10, // 18: provisioner.Provision.Response.log:type_name -> provisioner.Log - 24, // 19: provisioner.Provision.Response.complete:type_name -> provisioner.Provision.Complete - 17, // 20: provisioner.Provisioner.Parse:input_type -> provisioner.Parse.Request - 23, // 21: provisioner.Provisioner.Provision:input_type -> provisioner.Provision.Request - 19, // 22: provisioner.Provisioner.Parse:output_type -> provisioner.Parse.Response - 25, // 23: provisioner.Provisioner.Provision:output_type -> provisioner.Provision.Response - 22, // [22:24] is the sub-list for method output_type - 20, // [20:22] is the sub-list for method input_type - 20, // [20:20] is the sub-list for extension type_name - 20, // [20:20] is the sub-list for extension extendee - 0, // [0:20] is the sub-list for field type_name + 17, // 7: provisioner.Agent.env:type_name -> provisioner.Agent.EnvEntry + 13, // 8: provisioner.Agent.apps:type_name -> provisioner.App + 12, // 9: provisioner.Resource.agents:type_name -> provisioner.Agent + 9, // 10: provisioner.Parse.Complete.parameter_schemas:type_name -> provisioner.ParameterSchema + 10, // 11: provisioner.Parse.Response.log:type_name -> provisioner.Log + 19, // 12: provisioner.Parse.Response.complete:type_name -> provisioner.Parse.Complete + 1, // 13: provisioner.Provision.Metadata.workspace_transition:type_name -> provisioner.WorkspaceTransition + 8, // 14: provisioner.Provision.Start.parameter_values:type_name -> provisioner.ParameterValue + 21, // 15: provisioner.Provision.Start.metadata:type_name -> provisioner.Provision.Metadata + 22, // 16: provisioner.Provision.Request.start:type_name -> provisioner.Provision.Start + 23, // 17: provisioner.Provision.Request.cancel:type_name -> provisioner.Provision.Cancel + 14, // 18: provisioner.Provision.Complete.resources:type_name -> provisioner.Resource + 10, // 19: provisioner.Provision.Response.log:type_name -> provisioner.Log + 25, // 20: provisioner.Provision.Response.complete:type_name -> provisioner.Provision.Complete + 18, // 21: provisioner.Provisioner.Parse:input_type -> provisioner.Parse.Request + 24, // 22: provisioner.Provisioner.Provision:input_type -> provisioner.Provision.Request + 20, // 23: provisioner.Provisioner.Parse:output_type -> provisioner.Parse.Response + 26, // 24: provisioner.Provisioner.Provision:output_type -> provisioner.Provision.Response + 23, // [23:25] is the sub-list for method output_type + 21, // [21:23] is the sub-list for method input_type + 21, // [21:21] is the sub-list for extension type_name + 21, // [21:21] is the sub-list for extension extendee + 0, // [0:21] is the sub-list for field type_name } func init() { file_provisionersdk_proto_provisioner_proto_init() } @@ -1962,7 +2063,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Resource); i { + switch v := v.(*App); i { case 0: return &v.state case 1: @@ -1974,7 +2075,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Parse); i { + switch v := v.(*Resource); i { case 0: return &v.state case 1: @@ -1986,6 +2087,18 @@ func file_provisionersdk_proto_provisioner_proto_init() { } } file_provisionersdk_proto_provisioner_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Parse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_provisionersdk_proto_provisioner_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision); i { case 0: return &v.state @@ -1997,7 +2110,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Parse_Request); i { case 0: return &v.state @@ -2009,7 +2122,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Parse_Complete); i { case 0: return &v.state @@ -2021,7 +2134,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Parse_Response); i { case 0: return &v.state @@ -2033,7 +2146,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Metadata); i { case 0: return &v.state @@ -2045,7 +2158,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Start); i { case 0: return &v.state @@ -2057,7 +2170,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Cancel); i { case 0: return &v.state @@ -2069,7 +2182,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Request); i { case 0: return &v.state @@ -2081,7 +2194,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Complete); i { case 0: return &v.state @@ -2093,7 +2206,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { return nil } } - file_provisionersdk_proto_provisioner_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + file_provisionersdk_proto_provisioner_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*Provision_Response); i { case 0: return &v.state @@ -2110,15 +2223,15 @@ func file_provisionersdk_proto_provisioner_proto_init() { (*Agent_Token)(nil), (*Agent_InstanceId)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[14].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[15].OneofWrappers = []interface{}{ (*Parse_Response_Log)(nil), (*Parse_Response_Complete)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[18].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[19].OneofWrappers = []interface{}{ (*Provision_Request_Start)(nil), (*Provision_Request_Cancel)(nil), } - file_provisionersdk_proto_provisioner_proto_msgTypes[20].OneofWrappers = []interface{}{ + file_provisionersdk_proto_provisioner_proto_msgTypes[21].OneofWrappers = []interface{}{ (*Provision_Response_Log)(nil), (*Provision_Response_Complete)(nil), } @@ -2128,7 +2241,7 @@ func file_provisionersdk_proto_provisioner_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_provisionersdk_proto_provisioner_proto_rawDesc, NumEnums: 5, - NumMessages: 21, + NumMessages: 22, NumExtensions: 0, NumServices: 1, }, diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index 66bfee737a00a..86e61ca8d9884 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -80,12 +80,22 @@ message Agent { string operating_system = 5; string architecture = 6; string directory = 7; + repeated App apps = 8; oneof auth { - string token = 8; - string instance_id = 9; + string token = 9; + string instance_id = 10; } } +// App represents a dev-accessible application on the workspace. +message App { + string name = 1; + string command = 2; + string url = 3; + string icon = 4; + bool relative_path = 5; +} + // Resource represents created infrastructure. message Resource { string name = 1; diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index de1d984461c5b..e69de29bb2d1d 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1,485 +0,0 @@ -// Code generated by 'make coder/scripts/apitypings/main.go'. DO NOT EDIT. - -// From codersdk/workspaceagents.go:35:6 -export interface AWSInstanceIdentityToken { - readonly signature: string - readonly document: string -} - -// From codersdk/gitsshkey.go:21:6 -export interface AgentGitSSHKey { - readonly public_key: string - readonly private_key: string -} - -// From codersdk/users.go:151:6 -export interface AuthMethods { - readonly password: boolean - readonly github: boolean -} - -// From codersdk/workspaceagents.go:40:6 -export interface AzureInstanceIdentityToken { - readonly signature: string - readonly encoding: string -} - -// From codersdk/buildinfo.go:10:6 -export interface BuildInfoResponse { - readonly external_url: string - readonly version: string -} - -// From codersdk/users.go:42:6 -export interface CreateFirstUserRequest { - readonly email: string - readonly username: string - readonly password: string - readonly organization: string -} - -// From codersdk/users.go:50:6 -export interface CreateFirstUserResponse { - readonly user_id: string - readonly organization_id: string -} - -// From codersdk/users.go:146:6 -export interface CreateOrganizationRequest { - readonly name: string -} - -// From codersdk/parameters.go:81:6 -export interface CreateParameterRequest { - readonly name: string - readonly source_value: string - readonly source_scheme: ParameterSourceScheme - readonly destination_scheme: ParameterDestinationScheme -} - -// From codersdk/organizations.go:49:6 -export interface CreateTemplateRequest { - readonly name: string - readonly description?: string - readonly template_version_id: string - readonly parameter_values?: CreateParameterRequest[] -} - -// From codersdk/organizations.go:36:6 -export interface CreateTemplateVersionRequest { - readonly template_id?: string - readonly storage_method: ProvisionerStorageMethod - readonly storage_source: string - readonly provisioner: ProvisionerType - readonly parameter_values?: CreateParameterRequest[] -} - -// From codersdk/users.go:55:6 -export interface CreateUserRequest { - readonly email: string - readonly username: string - readonly password: string - readonly organization_id: string -} - -// From codersdk/workspaces.go:34:6 -export interface CreateWorkspaceBuildRequest { - readonly template_version_id?: string - readonly transition: WorkspaceTransition - readonly dry_run?: boolean - readonly state?: string -} - -// From codersdk/organizations.go:67:6 -export interface CreateWorkspaceRequest { - readonly template_id: string - readonly name: string - readonly autostart_schedule?: string - // This is likely an enum in an external package ("time.Duration") - readonly ttl?: number - readonly parameter_values?: CreateParameterRequest[] -} - -// From codersdk/users.go:142:6 -export interface GenerateAPIKeyResponse { - readonly key: string -} - -// From codersdk/gitsshkey.go:14:6 -export interface GitSSHKey { - readonly user_id: string - readonly created_at: string - readonly updated_at: string - readonly public_key: string -} - -// From codersdk/workspaceagents.go:31:6 -export interface GoogleInstanceIdentityToken { - readonly json_web_token: string -} - -// From codersdk/users.go:131:6 -export interface LoginWithPasswordRequest { - readonly email: string - readonly password: string -} - -// From codersdk/users.go:137:6 -export interface LoginWithPasswordResponse { - readonly session_token: string -} - -// From codersdk/organizations.go:28:6 -export interface Organization { - readonly id: string - readonly name: string - readonly created_at: string - readonly updated_at: string -} - -// From codersdk/organizationmember.go:9:6 -export interface OrganizationMember { - readonly user_id: string - readonly organization_id: string - readonly created_at: string - readonly updated_at: string - readonly roles: string[] -} - -// From codersdk/pagination.go:11:6 -export interface Pagination { - readonly after_id?: string - readonly limit?: number - readonly offset?: number -} - -// From codersdk/parameters.go:46:6 -export interface Parameter { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly scope: ParameterScope - readonly scope_id: string - readonly name: string - readonly source_scheme: ParameterSourceScheme - readonly destination_scheme: ParameterDestinationScheme -} - -// From codersdk/parameters.go:57:6 -export interface ParameterSchema { - readonly id: string - readonly created_at: string - readonly job_id: string - readonly name: string - readonly description: string - readonly default_source_scheme: ParameterSourceScheme - readonly default_source_value: string - readonly allow_override_source: boolean - readonly default_destination_scheme: ParameterDestinationScheme - readonly allow_override_destination: boolean - readonly default_refresh: string - readonly redisplay_value: boolean - readonly validation_error: string - readonly validation_condition: string - readonly validation_type_system: string - readonly validation_value_type: string - readonly validation_contains: string[] -} - -// From codersdk/provisionerdaemons.go:33:6 -export interface ProvisionerDaemon { - readonly id: string - readonly created_at: string - readonly updated_at?: string - readonly organization_id?: string - readonly name: string - readonly provisioners: ProvisionerType[] -} - -// From codersdk/provisionerdaemons.go:63:6 -export interface ProvisionerJob { - readonly id: string - readonly created_at: string - readonly started_at?: string - readonly completed_at?: string - readonly error?: string - readonly status: ProvisionerJobStatus - readonly worker_id?: string -} - -// From codersdk/provisionerdaemons.go:73:6 -export interface ProvisionerJobLog { - readonly id: string - readonly created_at: string - readonly log_source: LogSource - readonly log_level: LogLevel - readonly stage: string - readonly output: string -} - -// From codersdk/roles.go:12:6 -export interface Role { - readonly name: string - readonly display_name: string -} - -// From codersdk/templates.go:15:6 -export interface Template { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly organization_id: string - readonly name: string - readonly provisioner: ProvisionerType - readonly active_version_id: string - readonly workspace_owner_count: number - readonly description: string -} - -// From codersdk/templateversions.go:14:6 -export interface TemplateVersion { - readonly id: string - readonly template_id?: string - readonly created_at: string - readonly updated_at: string - readonly name: string - readonly job: ProvisionerJob - readonly readme: string -} - -// From codersdk/templateversions.go:25:6 -export interface TemplateVersionParameter { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly scope: ParameterScope - readonly scope_id: string - readonly name: string - readonly source_scheme: ParameterSourceScheme - readonly source_value: string - readonly destination_scheme: ParameterDestinationScheme - readonly schema_id: string - readonly default_source_value: boolean -} - -// From codersdk/templates.go:73:6 -export interface TemplateVersionsByTemplateRequest extends Pagination { - readonly template_id: string -} - -// From codersdk/templates.go:27:6 -export interface UpdateActiveTemplateVersion { - readonly id: string -} - -// From codersdk/users.go:71:6 -export interface UpdateRoles { - readonly roles: string[] -} - -// From codersdk/users.go:67:6 -export interface UpdateUserPasswordRequest { - readonly password: string -} - -// From codersdk/users.go:62:6 -export interface UpdateUserProfileRequest { - readonly email: string - readonly username: string -} - -// From codersdk/workspaces.go:141:6 -export interface UpdateWorkspaceAutostartRequest { - readonly schedule: string -} - -// From codersdk/workspaces.go:161:6 -export interface UpdateWorkspaceTTLRequest { - // This is likely an enum in an external package ("time.Duration") - readonly ttl?: number -} - -// From codersdk/files.go:16:6 -export interface UploadResponse { - readonly hash: string -} - -// From codersdk/users.go:32:6 -export interface User { - readonly id: string - readonly email: string - readonly created_at: string - readonly username: string - readonly status: UserStatus - readonly organization_ids: string[] - readonly roles: Role[] -} - -// From codersdk/users.go:96:6 -export interface UserAuthorization { - readonly object: UserAuthorizationObject - readonly action: string -} - -// From codersdk/users.go:112:6 -export interface UserAuthorizationObject { - readonly resource_type: string - readonly owner_id?: string - readonly organization_id?: string - readonly resource_id?: string -} - -// From codersdk/users.go:85:6 -export interface UserAuthorizationRequest { - readonly checks: Record -} - -// From codersdk/users.go:80:6 -export type UserAuthorizationResponse = Record - -// From codersdk/users.go:75:6 -export interface UserRoles { - readonly roles: string[] - readonly organization_roles: Record -} - -// From codersdk/users.go:24:6 -export interface UsersRequest extends Pagination { - readonly search?: string - readonly status?: string -} - -// From codersdk/workspaces.go:18:6 -export interface Workspace { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly owner_id: string - readonly owner_name: string - readonly template_id: string - readonly template_name: string - readonly latest_build: WorkspaceBuild - readonly outdated: boolean - readonly name: string - readonly autostart_schedule: string - // This is likely an enum in an external package ("time.Duration") - readonly ttl?: number -} - -// From codersdk/workspaceresources.go:31:6 -export interface WorkspaceAgent { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly first_connected_at?: string - readonly last_connected_at?: string - readonly disconnected_at?: string - readonly status: WorkspaceAgentStatus - readonly name: string - readonly resource_id: string - readonly instance_id?: string - readonly architecture: string - readonly environment_variables: Record - readonly operating_system: string - readonly startup_script?: string - readonly directory?: string -} - -// From codersdk/workspaceagents.go:47:6 -export interface WorkspaceAgentAuthenticateResponse { - readonly session_token: string -} - -// From codersdk/workspaceresources.go:57:6 -export interface WorkspaceAgentInstanceMetadata { - readonly jail_orchestrator: string - readonly operating_system: string - readonly platform: string - readonly platform_family: string - readonly kernel_version: string - readonly kernel_architecture: string - readonly cloud: string - readonly jail: string - readonly vnc: boolean -} - -// From codersdk/workspaceresources.go:49:6 -export interface WorkspaceAgentResourceMetadata { - readonly memory_total: number - readonly disk_total: number - readonly cpu_cores: number - readonly cpu_model: string - readonly cpu_mhz: number -} - -// From codersdk/workspacebuilds.go:24:6 -export interface WorkspaceBuild { - readonly id: string - readonly created_at: string - readonly updated_at: string - readonly workspace_id: string - readonly template_version_id: string - readonly build_number: number - readonly name: string - readonly transition: WorkspaceTransition - readonly initiator_id: string - readonly job: ProvisionerJob -} - -// From codersdk/workspaces.go:64:6 -export interface WorkspaceBuildsRequest extends Pagination { - readonly WorkspaceID: string -} - -// From codersdk/workspaces.go:180:6 -export interface WorkspaceFilter { - readonly OrganizationID: string - readonly Owner: string -} - -// From codersdk/workspaceresources.go:21:6 -export interface WorkspaceResource { - readonly id: string - readonly created_at: string - readonly job_id: string - readonly workspace_transition: WorkspaceTransition - readonly type: string - readonly name: string - readonly agents?: WorkspaceAgent[] -} - -// From codersdk/provisionerdaemons.go:23:6 -export type LogLevel = "debug" | "error" | "info" | "trace" | "warn" - -// From codersdk/provisionerdaemons.go:16:6 -export type LogSource = "provisioner" | "provisioner_daemon" - -// From codersdk/parameters.go:30:6 -export type ParameterDestinationScheme = "environment_variable" | "none" | "provisioner_variable" - -// From codersdk/parameters.go:14:6 -export type ParameterScope = "organization" | "template" | "user" | "workspace" - -// From codersdk/parameters.go:23:6 -export type ParameterSourceScheme = "data" | "none" - -// From codersdk/parameters.go:38:6 -export type ParameterTypeSystem = "hcl" | "none" - -// From codersdk/provisionerdaemons.go:43:6 -export type ProvisionerJobStatus = "canceled" | "canceling" | "failed" | "pending" | "running" | "succeeded" - -// From codersdk/organizations.go:14:6 -export type ProvisionerStorageMethod = "file" - -// From codersdk/organizations.go:20:6 -export type ProvisionerType = "echo" | "terraform" - -// From codersdk/users.go:17:6 -export type UserStatus = "active" | "suspended" - -// From codersdk/workspaceresources.go:13:6 -export type WorkspaceAgentStatus = "connected" | "connecting" | "disconnected" - -// From codersdk/workspacebuilds.go:14:6 -export type WorkspaceTransition = "delete" | "start" | "stop"