feat: allow configuring display apps from template (#9100)

This commit is contained in:
Jon Ayers 2023-08-30 14:53:42 -05:00 committed by GitHub
parent 9c9d035354
commit ee24260614
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
68 changed files with 1975 additions and 564 deletions

23
coderd/apidoc/docs.go generated
View File

@ -8068,6 +8068,23 @@ const docTemplate = `{
}
}
},
"codersdk.DisplayApp": {
"type": "string",
"enum": [
"vscode",
"vscode_insiders",
"web_terminal",
"port_forwarding_helper",
"ssh_helper"
],
"x-enum-varnames": [
"DisplayAppVSCodeDesktop",
"DisplayAppVSCodeInsiders",
"DisplayAppWebTerminal",
"DisplayAppPortForward",
"DisplayAppSSH"
]
},
"codersdk.Entitlement": {
"type": "string",
"enum": [
@ -10611,6 +10628,12 @@ const docTemplate = `{
"type": "string",
"format": "date-time"
},
"display_apps": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.DisplayApp"
}
},
"environment_variables": {
"type": "object",
"additionalProperties": {

View File

@ -7223,6 +7223,23 @@
}
}
},
"codersdk.DisplayApp": {
"type": "string",
"enum": [
"vscode",
"vscode_insiders",
"web_terminal",
"port_forwarding_helper",
"ssh_helper"
],
"x-enum-varnames": [
"DisplayAppVSCodeDesktop",
"DisplayAppVSCodeInsiders",
"DisplayAppWebTerminal",
"DisplayAppPortForward",
"DisplayAppSSH"
]
},
"codersdk.Entitlement": {
"type": "string",
"enum": ["entitled", "grace_period", "not_entitled"],
@ -9613,6 +9630,12 @@
"type": "string",
"format": "date-time"
},
"display_apps": {
"type": "array",
"items": {
"$ref": "#/definitions/codersdk.DisplayApp"
}
},
"environment_variables": {
"type": "object",
"additionalProperties": {

View File

@ -4428,6 +4428,7 @@ func (q *FakeQuerier) InsertWorkspaceAgent(_ context.Context, arg database.Inser
MOTDFile: arg.MOTDFile,
LifecycleState: database.WorkspaceAgentLifecycleStateCreated,
ShutdownScript: arg.ShutdownScript,
DisplayApps: arg.DisplayApps,
}
q.workspaceAgents = append(q.workspaceAgents, agent)

View File

@ -31,6 +31,14 @@ CREATE TYPE build_reason AS ENUM (
'autodelete'
);
CREATE TYPE display_app AS ENUM (
'vscode',
'vscode_insiders',
'web_terminal',
'ssh_helper',
'port_forwarding_helper'
);
CREATE TYPE group_source AS ENUM (
'user',
'oidc'
@ -780,6 +788,7 @@ CREATE TABLE workspace_agents (
started_at timestamp with time zone,
ready_at timestamp with time zone,
subsystems workspace_agent_subsystem[] DEFAULT '{}'::workspace_agent_subsystem[],
display_apps display_app[] DEFAULT '{vscode,vscode_insiders,web_terminal,ssh_helper,port_forwarding_helper}'::display_app[],
CONSTRAINT max_logs_length CHECK ((logs_length <= 1048576)),
CONSTRAINT subsystems_not_none CHECK ((NOT ('none'::workspace_agent_subsystem = ANY (subsystems))))
);

View File

@ -0,0 +1,5 @@
BEGIN;
ALTER TABLE workspace_agents DROP COLUMN display_apps;
DROP TYPE display_app;
COMMIT;

View File

@ -0,0 +1,4 @@
BEGIN;
CREATE TYPE display_app AS ENUM ('vscode', 'vscode_insiders', 'web_terminal', 'ssh_helper', 'port_forwarding_helper');
ALTER TABLE workspace_agents ADD column display_apps display_app[] DEFAULT '{vscode, vscode_insiders, web_terminal, ssh_helper, port_forwarding_helper}';
COMMIT;

View File

@ -281,6 +281,73 @@ func AllBuildReasonValues() []BuildReason {
}
}
type DisplayApp string
const (
DisplayAppVscode DisplayApp = "vscode"
DisplayAppVscodeInsiders DisplayApp = "vscode_insiders"
DisplayAppWebTerminal DisplayApp = "web_terminal"
DisplayAppSSHHelper DisplayApp = "ssh_helper"
DisplayAppPortForwardingHelper DisplayApp = "port_forwarding_helper"
)
func (e *DisplayApp) Scan(src interface{}) error {
switch s := src.(type) {
case []byte:
*e = DisplayApp(s)
case string:
*e = DisplayApp(s)
default:
return fmt.Errorf("unsupported scan type for DisplayApp: %T", src)
}
return nil
}
type NullDisplayApp struct {
DisplayApp DisplayApp `json:"display_app"`
Valid bool `json:"valid"` // Valid is true if DisplayApp is not NULL
}
// Scan implements the Scanner interface.
func (ns *NullDisplayApp) Scan(value interface{}) error {
if value == nil {
ns.DisplayApp, ns.Valid = "", false
return nil
}
ns.Valid = true
return ns.DisplayApp.Scan(value)
}
// Value implements the driver Valuer interface.
func (ns NullDisplayApp) Value() (driver.Value, error) {
if !ns.Valid {
return nil, nil
}
return string(ns.DisplayApp), nil
}
func (e DisplayApp) Valid() bool {
switch e {
case DisplayAppVscode,
DisplayAppVscodeInsiders,
DisplayAppWebTerminal,
DisplayAppSSHHelper,
DisplayAppPortForwardingHelper:
return true
}
return false
}
func AllDisplayAppValues() []DisplayApp {
return []DisplayApp{
DisplayAppVscode,
DisplayAppVscodeInsiders,
DisplayAppWebTerminal,
DisplayAppSSHHelper,
DisplayAppPortForwardingHelper,
}
}
type GroupSource string
const (
@ -1953,8 +2020,9 @@ type WorkspaceAgent struct {
// The time the agent entered the starting lifecycle state
StartedAt sql.NullTime `db:"started_at" json:"started_at"`
// The time the agent entered the ready or start_error lifecycle state
ReadyAt sql.NullTime `db:"ready_at" json:"ready_at"`
Subsystems []WorkspaceAgentSubsystem `db:"subsystems" json:"subsystems"`
ReadyAt sql.NullTime `db:"ready_at" json:"ready_at"`
Subsystems []WorkspaceAgentSubsystem `db:"subsystems" json:"subsystems"`
DisplayApps []DisplayApp `db:"display_apps" json:"display_apps"`
}
type WorkspaceAgentLog struct {

View File

@ -6362,7 +6362,7 @@ func (q *sqlQuerier) DeleteOldWorkspaceAgentLogs(ctx context.Context) error {
const getWorkspaceAgentAndOwnerByAuthToken = `-- name: GetWorkspaceAgentAndOwnerByAuthToken :one
SELECT
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems,
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps,
workspaces.id AS workspace_id,
users.id AS owner_id,
users.username AS owner_name,
@ -6461,6 +6461,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndOwnerByAuthToken(ctx context.Context, a
&i.WorkspaceAgent.StartedAt,
&i.WorkspaceAgent.ReadyAt,
pq.Array(&i.WorkspaceAgent.Subsystems),
pq.Array(&i.WorkspaceAgent.DisplayApps),
&i.WorkspaceID,
&i.OwnerID,
&i.OwnerName,
@ -6473,7 +6474,7 @@ func (q *sqlQuerier) GetWorkspaceAgentAndOwnerByAuthToken(ctx context.Context, a
const getWorkspaceAgentByID = `-- name: GetWorkspaceAgentByID :one
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems, display_apps
FROM
workspace_agents
WHERE
@ -6517,13 +6518,14 @@ func (q *sqlQuerier) GetWorkspaceAgentByID(ctx context.Context, id uuid.UUID) (W
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
)
return i, err
}
const getWorkspaceAgentByInstanceID = `-- name: GetWorkspaceAgentByInstanceID :one
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems, display_apps
FROM
workspace_agents
WHERE
@ -6569,6 +6571,7 @@ func (q *sqlQuerier) GetWorkspaceAgentByInstanceID(ctx context.Context, authInst
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
)
return i, err
}
@ -6688,7 +6691,7 @@ func (q *sqlQuerier) GetWorkspaceAgentMetadata(ctx context.Context, workspaceAge
const getWorkspaceAgentsByResourceIDs = `-- name: GetWorkspaceAgentsByResourceIDs :many
SELECT
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems, display_apps
FROM
workspace_agents
WHERE
@ -6738,6 +6741,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
); err != nil {
return nil, err
}
@ -6753,7 +6757,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsByResourceIDs(ctx context.Context, ids []
}
const getWorkspaceAgentsCreatedAfter = `-- name: GetWorkspaceAgentsCreatedAfter :many
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems FROM workspace_agents WHERE created_at > $1
SELECT id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems, display_apps FROM workspace_agents WHERE created_at > $1
`
func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceAgent, error) {
@ -6799,6 +6803,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
); err != nil {
return nil, err
}
@ -6815,7 +6820,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsCreatedAfter(ctx context.Context, created
const getWorkspaceAgentsInLatestBuildByWorkspaceID = `-- name: GetWorkspaceAgentsInLatestBuildByWorkspaceID :many
SELECT
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems
workspace_agents.id, workspace_agents.created_at, workspace_agents.updated_at, workspace_agents.name, workspace_agents.first_connected_at, workspace_agents.last_connected_at, workspace_agents.disconnected_at, workspace_agents.resource_id, workspace_agents.auth_token, workspace_agents.auth_instance_id, workspace_agents.architecture, workspace_agents.environment_variables, workspace_agents.operating_system, workspace_agents.startup_script, workspace_agents.instance_metadata, workspace_agents.resource_metadata, workspace_agents.directory, workspace_agents.version, workspace_agents.last_connected_replica_id, workspace_agents.connection_timeout_seconds, workspace_agents.troubleshooting_url, workspace_agents.motd_file, workspace_agents.lifecycle_state, workspace_agents.startup_script_timeout_seconds, workspace_agents.expanded_directory, workspace_agents.shutdown_script, workspace_agents.shutdown_script_timeout_seconds, workspace_agents.logs_length, workspace_agents.logs_overflowed, workspace_agents.startup_script_behavior, workspace_agents.started_at, workspace_agents.ready_at, workspace_agents.subsystems, workspace_agents.display_apps
FROM
workspace_agents
JOIN
@ -6877,6 +6882,7 @@ func (q *sqlQuerier) GetWorkspaceAgentsInLatestBuildByWorkspaceID(ctx context.Co
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
); err != nil {
return nil, err
}
@ -6914,10 +6920,11 @@ INSERT INTO
startup_script_behavior,
startup_script_timeout_seconds,
shutdown_script,
shutdown_script_timeout_seconds
shutdown_script_timeout_seconds,
display_apps
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22) RETURNING id, created_at, updated_at, name, first_connected_at, last_connected_at, disconnected_at, resource_id, auth_token, auth_instance_id, architecture, environment_variables, operating_system, startup_script, instance_metadata, resource_metadata, directory, version, last_connected_replica_id, connection_timeout_seconds, troubleshooting_url, motd_file, lifecycle_state, startup_script_timeout_seconds, expanded_directory, shutdown_script, shutdown_script_timeout_seconds, logs_length, logs_overflowed, startup_script_behavior, started_at, ready_at, subsystems, display_apps
`
type InsertWorkspaceAgentParams struct {
@ -6942,6 +6949,7 @@ type InsertWorkspaceAgentParams struct {
StartupScriptTimeoutSeconds int32 `db:"startup_script_timeout_seconds" json:"startup_script_timeout_seconds"`
ShutdownScript sql.NullString `db:"shutdown_script" json:"shutdown_script"`
ShutdownScriptTimeoutSeconds int32 `db:"shutdown_script_timeout_seconds" json:"shutdown_script_timeout_seconds"`
DisplayApps []DisplayApp `db:"display_apps" json:"display_apps"`
}
func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error) {
@ -6967,6 +6975,7 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa
arg.StartupScriptTimeoutSeconds,
arg.ShutdownScript,
arg.ShutdownScriptTimeoutSeconds,
pq.Array(arg.DisplayApps),
)
var i WorkspaceAgent
err := row.Scan(
@ -7003,6 +7012,7 @@ func (q *sqlQuerier) InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspa
&i.StartedAt,
&i.ReadyAt,
pq.Array(&i.Subsystems),
pq.Array(&i.DisplayApps),
)
return i, err
}

View File

@ -50,10 +50,11 @@ INSERT INTO
startup_script_behavior,
startup_script_timeout_seconds,
shutdown_script,
shutdown_script_timeout_seconds
shutdown_script_timeout_seconds,
display_apps
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21) RETURNING *;
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22) RETURNING *;
-- name: UpdateWorkspaceAgentConnectionByID :exec
UPDATE

View File

@ -71,6 +71,7 @@ overrides:
eof: EOF
template_ids: TemplateIDs
active_user_ids: ActiveUserIDs
display_app_ssh_helper: DisplayAppSSHHelper
sql:
- schema: "./dump.sql"

View File

@ -1274,6 +1274,7 @@ func InsertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid.
Valid: prAgent.ShutdownScript != "",
},
ShutdownScriptTimeoutSeconds: prAgent.GetShutdownScriptTimeoutSeconds(),
DisplayApps: convertDisplayApps(prAgent.GetDisplayApps()),
})
if err != nil {
return xerrors.Errorf("insert agent: %w", err)
@ -1611,3 +1612,28 @@ func redactTemplateVariable(templateVariable *sdkproto.TemplateVariable) *sdkpro
}
return maybeRedacted
}
func convertDisplayApps(apps *sdkproto.DisplayApps) []database.DisplayApp {
// This shouldn't happen but let's avoid panicking. It also makes
// writing tests a bit easier.
if apps == nil {
return nil
}
dapps := make([]database.DisplayApp, 0, 5)
if apps.Vscode {
dapps = append(dapps, database.DisplayAppVscode)
}
if apps.VscodeInsiders {
dapps = append(dapps, database.DisplayAppVscodeInsiders)
}
if apps.SshHelper {
dapps = append(dapps, database.DisplayAppSSHHelper)
}
if apps.PortForwardingHelper {
dapps = append(dapps, database.DisplayAppPortForwardingHelper)
}
if apps.WebTerminal {
dapps = append(dapps, database.DisplayAppWebTerminal)
}
return dapps
}

View File

@ -1565,6 +1565,11 @@ func TestInsertWorkspaceResource(t *testing.T) {
Slug: "a",
}},
ShutdownScript: "shutdown",
DisplayApps: &sdkproto.DisplayApps{
Vscode: true,
PortForwardingHelper: true,
SshHelper: true,
},
}},
})
require.NoError(t, err)
@ -1587,6 +1592,63 @@ func TestInsertWorkspaceResource(t *testing.T) {
got, err := agent.EnvironmentVariables.RawMessage.MarshalJSON()
require.NoError(t, err)
require.Equal(t, want, got)
require.ElementsMatch(t, []database.DisplayApp{
database.DisplayAppPortForwardingHelper,
database.DisplayAppSSHHelper,
database.DisplayAppVscode,
}, agent.DisplayApps)
})
t.Run("AllDisplayApps", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
Type: "aws_instance",
Agents: []*sdkproto.Agent{{
DisplayApps: &sdkproto.DisplayApps{
Vscode: true,
VscodeInsiders: true,
SshHelper: true,
PortForwardingHelper: true,
WebTerminal: true,
},
}},
})
require.NoError(t, err)
resources, err := db.GetWorkspaceResourcesByJobID(ctx, job)
require.NoError(t, err)
require.Len(t, resources, 1)
agents, err := db.GetWorkspaceAgentsByResourceIDs(ctx, []uuid.UUID{resources[0].ID})
require.NoError(t, err)
require.Len(t, agents, 1)
agent := agents[0]
require.ElementsMatch(t, database.AllDisplayAppValues(), agent.DisplayApps)
})
t.Run("DisableDefaultApps", func(t *testing.T) {
t.Parallel()
db := dbfake.New()
job := uuid.New()
err := insert(db, job, &sdkproto.Resource{
Name: "something",
Type: "aws_instance",
Agents: []*sdkproto.Agent{{
DisplayApps: &sdkproto.DisplayApps{},
}},
})
require.NoError(t, err)
resources, err := db.GetWorkspaceResourcesByJobID(ctx, job)
require.NoError(t, err)
require.Len(t, resources, 1)
agents, err := db.GetWorkspaceAgentsByResourceIDs(ctx, []uuid.UUID{resources[0].ID})
require.NoError(t, err)
require.Len(t, agents, 1)
agent := agents[0]
// An empty array (as opposed to nil) should be returned to indicate
// that all apps are disabled.
require.Equal(t, []database.DisplayApp{}, agent.DisplayApps)
})
}

View File

@ -1360,6 +1360,7 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin
ShutdownScript: dbAgent.ShutdownScript.String,
ShutdownScriptTimeoutSeconds: dbAgent.ShutdownScriptTimeoutSeconds,
Subsystems: subsystems,
DisplayApps: convertDisplayApps(dbAgent.DisplayApps),
}
node := coordinator.Node(dbAgent.ID)
if node != nil {
@ -1421,6 +1422,18 @@ func convertWorkspaceAgent(derpMap *tailcfg.DERPMap, coordinator tailnet.Coordin
return workspaceAgent, nil
}
func convertDisplayApps(apps []database.DisplayApp) []codersdk.DisplayApp {
dapps := make([]codersdk.DisplayApp, 0, len(apps))
for _, app := range apps {
switch codersdk.DisplayApp(app) {
case codersdk.DisplayAppVSCodeDesktop, codersdk.DisplayAppVSCodeInsiders, codersdk.DisplayAppPortForward, codersdk.DisplayAppWebTerminal, codersdk.DisplayAppSSH:
dapps = append(dapps, codersdk.DisplayApp(app))
}
}
return dapps
}
// @Summary Submit workspace agent stats
// @ID submit-workspace-agent-stats
// @Security CoderSessionToken

View File

@ -174,6 +174,97 @@ func TestWorkspaceAgent(t *testing.T) {
require.False(t, workspace.LatestBuild.Resources[0].Agents[0].Health.Healthy)
require.NotEmpty(t, workspace.LatestBuild.Resources[0].Agents[0].Health.Reason)
})
t.Run("DisplayApps", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{
IncludeProvisionerDaemon: true,
})
user := coderdtest.CreateFirstUser(t, client)
authToken := uuid.NewString()
tmpDir := t.TempDir()
apps := &proto.DisplayApps{
Vscode: true,
VscodeInsiders: true,
WebTerminal: true,
PortForwardingHelper: true,
SshHelper: true,
}
echoResp := &echo.Responses{
Parse: echo.ParseComplete,
ProvisionPlan: echo.PlanComplete,
ProvisionApply: []*proto.Response{{
Type: &proto.Response_Apply{
Apply: &proto.ApplyComplete{
Resources: []*proto.Resource{
{
Name: "example",
Type: "aws_instance",
Agents: []*proto.Agent{
{
Id: uuid.NewString(),
Directory: tmpDir,
Auth: &proto.Agent_Token{
Token: authToken,
},
DisplayApps: apps,
},
},
},
},
},
},
}},
}
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, echoResp)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()
workspace, err := client.Workspace(ctx, workspace.ID)
require.NoError(t, err)
agent, err := client.WorkspaceAgent(ctx, workspace.LatestBuild.Resources[0].Agents[0].ID)
require.NoError(t, err)
expectedApps := []codersdk.DisplayApp{
codersdk.DisplayAppPortForward,
codersdk.DisplayAppSSH,
codersdk.DisplayAppVSCodeDesktop,
codersdk.DisplayAppVSCodeInsiders,
codersdk.DisplayAppWebTerminal,
}
require.ElementsMatch(t, expectedApps, agent.DisplayApps)
// Flips all the apps to false.
apps.PortForwardingHelper = false
apps.Vscode = false
apps.VscodeInsiders = false
apps.SshHelper = false
apps.WebTerminal = false
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, echoResp,
func(req *codersdk.CreateTemplateVersionRequest) {
req.TemplateID = template.ID
})
err = client.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{
ID: version.ID,
})
require.NoError(t, err)
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
// Creating another workspace is just easier.
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)
build := coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
require.NoError(t, err)
agent, err = client.WorkspaceAgent(ctx, build.Resources[0].Agents[0].ID)
require.NoError(t, err)
require.Len(t, agent.DisplayApps, 0)
})
}
func TestWorkspaceAgentStartupLogs(t *testing.T) {

View File

@ -133,6 +133,16 @@ type WorkspaceAgentMetadata struct {
Description WorkspaceAgentMetadataDescription `json:"description"`
}
type DisplayApp string
const (
DisplayAppVSCodeDesktop DisplayApp = "vscode"
DisplayAppVSCodeInsiders DisplayApp = "vscode_insiders"
DisplayAppWebTerminal DisplayApp = "web_terminal"
DisplayAppPortForward DisplayApp = "port_forwarding_helper"
DisplayAppSSH DisplayApp = "ssh_helper"
)
type WorkspaceAgent struct {
ID uuid.UUID `json:"id" format:"uuid"`
CreatedAt time.Time `json:"created_at" format:"date-time"`
@ -169,6 +179,7 @@ type WorkspaceAgent struct {
ShutdownScriptTimeoutSeconds int32 `json:"shutdown_script_timeout_seconds"`
Subsystems []AgentSubsystem `json:"subsystems"`
Health WorkspaceAgentHealth `json:"health"` // Health reports the health of the agent.
DisplayApps []DisplayApp `json:"display_apps"`
}
type WorkspaceAgentHealth struct {

1
docs/api/agents.md generated
View File

@ -666,6 +666,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaceagents/{workspaceagent} \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"

8
docs/api/builds.md generated
View File

@ -82,6 +82,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -244,6 +245,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild} \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -545,6 +547,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/res
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -643,6 +646,7 @@ Status Code **200**
| `»» created_at` | string(date-time) | false | | |
| `»» directory` | string | false | | |
| `»» disconnected_at` | string(date-time) | false | | |
| `»» display_apps` | array | false | | |
| `»» environment_variables` | object | false | | |
| `»»» [any property]` | string | false | | |
| `»» expanded_directory` | string | false | | |
@ -802,6 +806,7 @@ curl -X GET http://coder-server:8080/api/v2/workspacebuilds/{workspacebuild}/sta
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -969,6 +974,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -1103,6 +1109,7 @@ Status Code **200**
| `»»» created_at` | string(date-time) | false | | |
| `»»» directory` | string | false | | |
| `»»» disconnected_at` | string(date-time) | false | | |
| `»»» display_apps` | array | false | | |
| `»»» environment_variables` | object | false | | |
| `»»»» [any property]` | string | false | | |
| `»»» expanded_directory` | string | false | | |
@ -1315,6 +1322,7 @@ curl -X POST http://coder-server:8080/api/v2/workspaces/{workspace}/builds \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"

24
docs/api/schemas.md generated
View File

@ -2647,6 +2647,24 @@ AuthorizationObject can represent a "set" of objects, such as: all workspaces in
| `wildcard_access_url` | [clibase.URL](#clibaseurl) | false | | |
| `write_config` | boolean | false | | |
## codersdk.DisplayApp
```json
"vscode"
```
### Properties
#### Enumerated Values
| Value |
| ------------------------ |
| `vscode` |
| `vscode_insiders` |
| `web_terminal` |
| `port_forwarding_helper` |
| `ssh_helper` |
## codersdk.Entitlement
```json
@ -5423,6 +5441,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -5565,6 +5584,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -5620,6 +5640,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
| `created_at` | string | false | | |
| `directory` | string | false | | |
| `disconnected_at` | string | false | | |
| `display_apps` | array of [codersdk.DisplayApp](#codersdkdisplayapp) | false | | |
| `environment_variables` | object | false | | |
| » `[any property]` | string | false | | |
| `expanded_directory` | string | false | | |
@ -6033,6 +6054,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -6344,6 +6366,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -6557,6 +6580,7 @@ If the schedule is empty, the user will be updated to use the default schedule.|
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"

4
docs/api/templates.md generated
View File

@ -1593,6 +1593,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/d
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -1691,6 +1692,7 @@ Status Code **200**
| `»» created_at` | string(date-time) | false | | |
| `»» directory` | string | false | | |
| `»» disconnected_at` | string(date-time) | false | | |
| `»» display_apps` | array | false | | |
| `»» environment_variables` | object | false | | |
| `»»» [any property]` | string | false | | |
| `»» expanded_directory` | string | false | | |
@ -1984,6 +1986,7 @@ curl -X GET http://coder-server:8080/api/v2/templateversions/{templateversion}/r
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -2082,6 +2085,7 @@ Status Code **200**
| `»» created_at` | string(date-time) | false | | |
| `»» directory` | string | false | | |
| `»» disconnected_at` | string(date-time) | false | | |
| `»» display_apps` | array | false | | |
| `»» environment_variables` | object | false | | |
| `»»» [any property]` | string | false | | |
| `»» expanded_directory` | string | false | | |

View File

@ -111,6 +111,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -300,6 +301,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -488,6 +490,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -678,6 +681,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"
@ -947,6 +951,7 @@ curl -X PUT http://coder-server:8080/api/v2/workspaces/{workspace}/dormant \
"created_at": "2019-08-24T14:15:22Z",
"directory": "string",
"disconnected_at": "2019-08-24T14:15:22Z",
"display_apps": ["vscode"],
"environment_variables": {
"property1": "string",
"property2": "string"

View File

@ -15,6 +15,7 @@ import (
stringutil "github.com/coder/coder/v2/coderd/util/strings"
"github.com/coder/coder/v2/codersdk"
"github.com/coder/coder/v2/provisioner"
"github.com/coder/coder/v2/provisionersdk"
"github.com/coder/coder/v2/provisionersdk/proto"
)
@ -40,12 +41,21 @@ type agentAttributes struct {
TroubleshootingURL string `mapstructure:"troubleshooting_url"`
MOTDFile string `mapstructure:"motd_file"`
// Deprecated, but remains here for backwards compatibility.
LoginBeforeReady bool `mapstructure:"login_before_ready"`
StartupScriptBehavior string `mapstructure:"startup_script_behavior"`
StartupScriptTimeoutSeconds int32 `mapstructure:"startup_script_timeout"`
ShutdownScript string `mapstructure:"shutdown_script"`
ShutdownScriptTimeoutSeconds int32 `mapstructure:"shutdown_script_timeout"`
Metadata []agentMetadata `mapstructure:"metadata"`
LoginBeforeReady bool `mapstructure:"login_before_ready"`
StartupScriptBehavior string `mapstructure:"startup_script_behavior"`
StartupScriptTimeoutSeconds int32 `mapstructure:"startup_script_timeout"`
ShutdownScript string `mapstructure:"shutdown_script"`
ShutdownScriptTimeoutSeconds int32 `mapstructure:"shutdown_script_timeout"`
Metadata []agentMetadata `mapstructure:"metadata"`
DisplayApps []agentDisplayAppsAttributes `mapstructure:"display_apps"`
}
type agentDisplayAppsAttributes struct {
VSCode bool `mapstructure:"vscode"`
VSCodeInsiders bool `mapstructure:"vscode_insiders"`
WebTerminal bool `mapstructure:"web_terminal"`
SSHHelper bool `mapstructure:"ssh_helper"`
PortForwardingHelper bool `mapstructure:"port_forwarding_helper"`
}
// A mapping of attributes on the "coder_app" resource.
@ -181,6 +191,20 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
})
}
// If a user doesn't specify 'display_apps' then they default
// into all apps except VSCode Insiders.
displayApps := provisionersdk.DefaultDisplayApps()
if len(attrs.DisplayApps) != 0 {
displayApps = &proto.DisplayApps{
Vscode: attrs.DisplayApps[0].VSCode,
VscodeInsiders: attrs.DisplayApps[0].VSCodeInsiders,
WebTerminal: attrs.DisplayApps[0].WebTerminal,
PortForwardingHelper: attrs.DisplayApps[0].PortForwardingHelper,
SshHelper: attrs.DisplayApps[0].SSHHelper,
}
}
agent := &proto.Agent{
Name: tfResource.Name,
Id: attrs.ID,
@ -197,6 +221,7 @@ func ConvertState(modules []*tfjson.StateModule, rawGraph string) (*State, error
ShutdownScript: attrs.ShutdownScript,
ShutdownScriptTimeoutSeconds: attrs.ShutdownScriptTimeoutSeconds,
Metadata: metadata,
DisplayApps: displayApps,
}
switch attrs.Auth {
case "token":

View File

@ -27,6 +27,17 @@ func TestConvertResources(t *testing.T) {
parameters []*proto.RichParameter
gitAuthProviders []string
}
// If a user doesn't specify 'display_apps' then they default
// into all apps except VSCode Insiders.
displayApps := proto.DisplayApps{
Vscode: true,
VscodeInsiders: false,
WebTerminal: true,
PortForwardingHelper: true,
SshHelper: true,
}
// nolint:paralleltest
for folderName, expected := range map[string]testCase{
// When a resource depends on another, the shortest route
@ -45,6 +56,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -62,6 +74,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}, {
Name: "second",
@ -80,6 +93,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_InstanceId{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -96,6 +110,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -114,6 +129,7 @@ func TestConvertResources(t *testing.T) {
StartupScriptBehavior: "non-blocking",
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &displayApps,
}, {
Name: "dev2",
OperatingSystem: "darwin",
@ -125,6 +141,7 @@ func TestConvertResources(t *testing.T) {
StartupScriptTimeoutSeconds: 30,
ShutdownScript: "echo bye bye",
ShutdownScriptTimeoutSeconds: 30,
DisplayApps: &displayApps,
}, {
Name: "dev3",
OperatingSystem: "windows",
@ -135,6 +152,7 @@ func TestConvertResources(t *testing.T) {
StartupScriptBehavior: "blocking",
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &displayApps,
}, {
Name: "dev4",
OperatingSystem: "linux",
@ -144,6 +162,7 @@ func TestConvertResources(t *testing.T) {
StartupScriptBehavior: "blocking",
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &displayApps,
}},
}},
},
@ -182,6 +201,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -206,6 +226,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -246,6 +267,7 @@ func TestConvertResources(t *testing.T) {
StartupScriptTimeoutSeconds: 300,
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
},
@ -297,6 +319,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
},
},
@ -314,6 +337,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
parameters: []*proto.RichParameter{{
@ -395,6 +419,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
parameters: []*proto.RichParameter{{
@ -423,6 +448,7 @@ func TestConvertResources(t *testing.T) {
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
DisplayApps: &displayApps,
}},
}},
parameters: []*proto.RichParameter{{
@ -478,10 +504,48 @@ func TestConvertResources(t *testing.T) {
ConnectionTimeoutSeconds: 120,
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &displayApps,
}},
}},
gitAuthProviders: []string{"github", "gitlab"},
},
"display-apps": {
resources: []*proto.Resource{{
Name: "dev",
Type: "null_resource",
Agents: []*proto.Agent{{
Name: "main",
OperatingSystem: "linux",
Architecture: "amd64",
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &proto.DisplayApps{
VscodeInsiders: true,
WebTerminal: true,
},
}},
}},
},
"display-apps-disabled": {
resources: []*proto.Resource{{
Name: "dev",
Type: "null_resource",
Agents: []*proto.Agent{{
Name: "main",
OperatingSystem: "linux",
Architecture: "amd64",
Auth: &proto.Agent_Token{},
StartupScriptBehavior: "non-blocking",
ConnectionTimeoutSeconds: 120,
StartupScriptTimeoutSeconds: 300,
ShutdownScriptTimeoutSeconds: 300,
DisplayApps: &proto.DisplayApps{},
}},
}},
},
} {
folderName := folderName
expected := expected

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -235,5 +235,6 @@
"init_script"
]
}
]
],
"timestamp": "2023-08-30T19:24:59Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "2d84db09-c3c3-4272-8119-1847e68e2dbe",
"id": "c6fd4a45-dc64-4830-8ff1-9a6c8074fca8",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "d5d46d6a-5e4b-493f-9b68-dd8c78727cac",
"token": "2559767b-afc6-4293-92cf-d57d98bda13a",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
}
],
"child_modules": [
@ -46,7 +48,7 @@
"outputs": {
"script": ""
},
"random": "6336115403873146745"
"random": "5659889568915200015"
},
"sensitive_values": {
"inputs": {},
@ -61,7 +63,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3671991160538447687",
"id": "4052095409343470524",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -180,5 +180,6 @@
}
]
}
}
},
"timestamp": "2023-08-30T19:25:02Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "36c5629c-8ac4-4e6b-ae6e-94b8f1bbb0bc",
"id": "9fb263ae-2d96-414f-abfa-7874e73695d2",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "9ed706cc-8b11-4b05-b6c3-ea943af2c60c",
"token": "4f391c60-20f9-4d57-906e-92e2f3e1e3c1",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
},
{
"address": "null_resource.a",
@ -34,7 +36,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "4876594853562919335",
"id": "2616597461049838347",
"triggers": null
},
"sensitive_values": {},
@ -51,7 +53,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3012307200839131913",
"id": "6759504907417146954",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -180,5 +180,6 @@
}
]
}
}
},
"timestamp": "2023-08-30T19:25:04Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "a79d53f2-f616-4be2-b1bf-6f6ce7409e23",
"id": "56d6f6e2-a7f8-4594-9bc3-044a4fd3b021",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "bb333041-5225-490d-86a0-69d1b5afd0db",
"token": "715216d1-fca1-4652-9032-d5367072706f",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
},
{
"address": "null_resource.first",
@ -34,7 +36,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3651093174168180448",
"id": "7470209964325643389",
"triggers": null
},
"sensitive_values": {},
@ -50,7 +52,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3820948743929828676",
"id": "251158623761758523",
"triggers": null
},
"sensitive_values": {},

View File

@ -0,0 +1,26 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.11.2"
}
}
}
resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
display_apps {
vscode = false
vscode_insiders = false
web_terminal = false
ssh_helper = false
port_forwarding_helper = false
}
}
resource "null_resource" "dev" {
depends_on = [
coder_agent.main
]
}

View File

@ -0,0 +1,18 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.main (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.main (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -0,0 +1,205 @@
{
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": false,
"web_terminal": false
}
],
"env": null,
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"troubleshooting_url": null
},
"sensitive_values": {
"display_apps": [
{}
],
"metadata": []
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"triggers": null
},
"sensitive_values": {}
}
]
}
},
"resource_changes": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": false,
"web_terminal": false
}
],
"env": null,
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"troubleshooting_url": null
},
"after_unknown": {
"display_apps": [
{}
],
"id": true,
"init_script": true,
"metadata": [],
"token": true
},
"before_sensitive": false,
"after_sensitive": {
"display_apps": [
{}
],
"metadata": [],
"token": true
}
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"triggers": null
},
"after_unknown": {
"id": true
},
"before_sensitive": false,
"after_sensitive": {}
}
}
],
"configuration": {
"provider_config": {
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.11.2"
},
"null": {
"name": "null",
"full_name": "registry.terraform.io/hashicorp/null"
}
},
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_config_key": "coder",
"expressions": {
"arch": {
"constant_value": "amd64"
},
"display_apps": [
{
"port_forwarding_helper": {
"constant_value": false
},
"ssh_helper": {
"constant_value": false
},
"vscode": {
"constant_value": false
},
"vscode_insiders": {
"constant_value": false
},
"web_terminal": {
"constant_value": false
}
}
],
"os": {
"constant_value": "linux"
}
},
"schema_version": 0
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_config_key": "null",
"schema_version": 0,
"depends_on": [
"coder_agent.main"
]
}
]
}
},
"timestamp": "2023-08-30T19:25:10Z"
}

View File

@ -0,0 +1,18 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.main (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.main (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -0,0 +1,70 @@
{
"format_version": "1.0",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": false,
"web_terminal": false
}
],
"env": null,
"id": "ba0faeb0-5a14-4908-946e-360329a8c852",
"init_script": "",
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "010c13b9-95aa-4b66-a2ad-5937e467134a",
"troubleshooting_url": null
},
"sensitive_values": {
"display_apps": [
{}
],
"metadata": [],
"token": true
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "7220106781059326067",
"triggers": null
},
"sensitive_values": {},
"depends_on": [
"coder_agent.main"
]
}
]
}
}
}

View File

@ -0,0 +1,26 @@
terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.11.2"
}
}
}
resource "coder_agent" "main" {
os = "linux"
arch = "amd64"
display_apps {
vscode = false
vscode_insiders = true
web_terminal = true
port_forwarding_helper = false
ssh_helper = false
}
}
resource "null_resource" "dev" {
depends_on = [
coder_agent.main
]
}

View File

@ -0,0 +1,18 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.main (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.main (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -0,0 +1,205 @@
{
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": true,
"web_terminal": true
}
],
"env": null,
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"troubleshooting_url": null
},
"sensitive_values": {
"display_apps": [
{}
],
"metadata": []
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"triggers": null
},
"sensitive_values": {}
}
]
}
},
"resource_changes": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": true,
"web_terminal": true
}
],
"env": null,
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"troubleshooting_url": null
},
"after_unknown": {
"display_apps": [
{}
],
"id": true,
"init_script": true,
"metadata": [],
"token": true
},
"before_sensitive": false,
"after_sensitive": {
"display_apps": [
{}
],
"metadata": [],
"token": true
}
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"change": {
"actions": [
"create"
],
"before": null,
"after": {
"triggers": null
},
"after_unknown": {
"id": true
},
"before_sensitive": false,
"after_sensitive": {}
}
}
],
"configuration": {
"provider_config": {
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.11.2"
},
"null": {
"name": "null",
"full_name": "registry.terraform.io/hashicorp/null"
}
},
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_config_key": "coder",
"expressions": {
"arch": {
"constant_value": "amd64"
},
"display_apps": [
{
"port_forwarding_helper": {
"constant_value": false
},
"ssh_helper": {
"constant_value": false
},
"vscode": {
"constant_value": false
},
"vscode_insiders": {
"constant_value": true
},
"web_terminal": {
"constant_value": true
}
}
],
"os": {
"constant_value": "linux"
}
},
"schema_version": 0
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_config_key": "null",
"schema_version": 0,
"depends_on": [
"coder_agent.main"
]
}
]
}
},
"timestamp": "2023-08-30T19:25:07Z"
}

View File

@ -0,0 +1,18 @@
digraph {
compound = "true"
newrank = "true"
subgraph "root" {
"[root] coder_agent.main (expand)" [label = "coder_agent.main", shape = "box"]
"[root] null_resource.dev (expand)" [label = "null_resource.dev", shape = "box"]
"[root] provider[\"registry.terraform.io/coder/coder\"]" [label = "provider[\"registry.terraform.io/coder/coder\"]", shape = "diamond"]
"[root] provider[\"registry.terraform.io/hashicorp/null\"]" [label = "provider[\"registry.terraform.io/hashicorp/null\"]", shape = "diamond"]
"[root] coder_agent.main (expand)" -> "[root] provider[\"registry.terraform.io/coder/coder\"]"
"[root] null_resource.dev (expand)" -> "[root] coder_agent.main (expand)"
"[root] null_resource.dev (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"]"
"[root] provider[\"registry.terraform.io/coder/coder\"] (close)" -> "[root] coder_agent.main (expand)"
"[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)" -> "[root] null_resource.dev (expand)"
"[root] root" -> "[root] provider[\"registry.terraform.io/coder/coder\"] (close)"
"[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/null\"] (close)"
}
}

View File

@ -0,0 +1,70 @@
{
"format_version": "1.0",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"display_apps": [
{
"port_forwarding_helper": false,
"ssh_helper": false,
"vscode": false,
"vscode_insiders": true,
"web_terminal": true
}
],
"env": null,
"id": "a7b8ff17-66ba-47b4-a4b4-51da1ad835fc",
"init_script": "",
"login_before_ready": true,
"metadata": [],
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "75fc044a-b120-4e86-be94-056cec981bd9",
"troubleshooting_url": null
},
"sensitive_values": {
"display_apps": [
{}
],
"metadata": [],
"token": true
}
},
{
"address": "null_resource.dev",
"mode": "managed",
"type": "null_resource",
"name": "dev",
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "4184951391452107661",
"triggers": null
},
"sensitive_values": {},
"depends_on": [
"coder_agent.main"
]
}
]
}
}
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -105,7 +105,7 @@
],
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -208,5 +208,6 @@
}
]
}
}
},
"timestamp": "2023-08-30T19:25:13Z"
}

View File

@ -1,36 +1,9 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "7060319c-a8bf-44b7-8fb9-5a4dc3bd35fe",
"init_script": "",
"login_before_ready": true,
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_timeout": 300,
"token": "9ea68982-fd51-4510-9c23-9e9ad1ce1ef7",
"troubleshooting_url": null
},
"sensitive_values": {}
},
{
"address": "data.coder_git_auth.github",
"mode": "data",
@ -57,6 +30,35 @@
},
"sensitive_values": {}
},
{
"address": "coder_agent.main",
"mode": "managed",
"type": "coder_agent",
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"arch": "amd64",
"auth": "token",
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "a8139f31-219b-4ee5-9e64-60d8dd94be27",
"init_script": "",
"login_before_ready": true,
"motd_file": null,
"os": "linux",
"shutdown_script": null,
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_timeout": 300,
"token": "20cdf0ee-2da9-432e-a3ad-674b900ed3c1",
"troubleshooting_url": null
},
"sensitive_values": {
"token": true
}
},
{
"address": "null_resource.dev",
"mode": "managed",
@ -65,7 +67,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "4918728983070449527",
"id": "8246789295692160686",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -200,5 +200,6 @@
"id"
]
}
]
],
"timestamp": "2023-08-30T19:25:15Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "facfb2ad-417d-412c-8304-ce50ff8a886e",
"id": "07c39e97-3461-4912-87c6-aab06714fb79",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "f1b3312a-af1c-45a8-9695-23d92c4cb68d",
"token": "4d389c4e-479b-4004-8ad1-b10da989bbdb",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
},
{
"address": "coder_agent_instance.main",
@ -34,8 +36,8 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "facfb2ad-417d-412c-8304-ce50ff8a886e",
"id": "6ce4c6f4-1b93-4b22-9b17-1dcb50a36e77",
"agent_id": "07c39e97-3461-4912-87c6-aab06714fb79",
"id": "13ac93bd-54bf-4e93-b2a1-35534139e255",
"instance_id": "example"
},
"sensitive_values": {},
@ -51,7 +53,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "2761080386857837319",
"id": "8984327635720248545",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -294,5 +294,6 @@
"id"
]
}
]
],
"timestamp": "2023-08-30T19:25:17Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "441cfb02-3044-4d2b-ac2c-1ac150ec8c58",
"id": "9a8356cf-b5ef-4da0-9b4e-cfeaca1fbfcf",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "75ee44b6-4cbb-4615-acb2-19c53f82dc58",
"token": "7116ebd2-5205-4427-8cdb-5f86ec819911",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
},
{
"address": "coder_app.apps[\"app1\"]",
@ -35,12 +37,12 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "441cfb02-3044-4d2b-ac2c-1ac150ec8c58",
"agent_id": "9a8356cf-b5ef-4da0-9b4e-cfeaca1fbfcf",
"command": null,
"display_name": "app1",
"healthcheck": [],
"icon": null,
"id": "abbc4449-5dd1-4ee0-ac58-3055a6da206b",
"id": "8ad9b3c3-0951-4612-adea-5c89ac12642a",
"name": null,
"relative_path": null,
"share": "owner",
@ -64,12 +66,12 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "441cfb02-3044-4d2b-ac2c-1ac150ec8c58",
"agent_id": "9a8356cf-b5ef-4da0-9b4e-cfeaca1fbfcf",
"command": null,
"display_name": "app2",
"healthcheck": [],
"icon": null,
"id": "ff87411e-4edb-48ce-b62f-6f792d02b25c",
"id": "b3cbb3eb-62d8-485f-8378-2d2ed751aa38",
"name": null,
"relative_path": null,
"share": "owner",
@ -92,7 +94,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3464468981645058362",
"id": "5757307222275435634",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -439,5 +439,6 @@
}
]
}
}
},
"timestamp": "2023-08-30T19:25:20Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,7 +17,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "ff8b851f-127f-452f-9180-4e619b0093f2",
"id": "094d300c-f07a-4357-870f-6ca1fc9154a2",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -28,11 +28,12 @@
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "36dbfd5d-adf5-4e3e-9d92-190be56773fa",
"token": "27bd44bc-0126-4c8d-9b98-8f27619e3656",
"troubleshooting_url": null
},
"sensitive_values": {
"metadata": []
"metadata": [],
"token": true
}
},
{
@ -48,7 +49,7 @@
"connection_timeout": 1,
"dir": null,
"env": null,
"id": "a4951d98-2e07-4144-8942-a6f7584a6da0",
"id": "bb844516-2cdd-419c-87e1-d0d3ea69fe78",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -59,11 +60,12 @@
"startup_script": null,
"startup_script_behavior": "non-blocking",
"startup_script_timeout": 30,
"token": "f101a336-401d-4744-848f-437fe635f832",
"token": "8a31b688-d3d2-4c22-b37e-c9810b9b329a",
"troubleshooting_url": null
},
"sensitive_values": {
"metadata": []
"metadata": [],
"token": true
}
},
{
@ -79,7 +81,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "a3e1eaae-4bfd-4240-bc0a-0e940c3dd861",
"id": "c6123c01-0543-4102-bdcf-f0ee2a9c1269",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -90,11 +92,12 @@
"startup_script": null,
"startup_script_behavior": "blocking",
"startup_script_timeout": 300,
"token": "1551c374-aae3-4be8-8fa2-6082921b837f",
"token": "64185462-292f-4b75-b350-625326ba596e",
"troubleshooting_url": "https://coder.com/troubleshoot"
},
"sensitive_values": {
"metadata": []
"metadata": [],
"token": true
}
},
{
@ -110,7 +113,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "fb94747b-e187-4c69-9c95-fb09c0832664",
"id": "85d0614c-3e44-4f20-b4bf-a015c8dfcaac",
"init_script": "",
"login_before_ready": false,
"metadata": [],
@ -121,11 +124,12 @@
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "714bf65d-92ff-4e7c-adbe-211b15a21085",
"token": "021b1139-fa63-42ba-be1a-85f8456f3c28",
"troubleshooting_url": null
},
"sensitive_values": {
"metadata": []
"metadata": [],
"token": true
}
},
{
@ -136,7 +140,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3687348305461113369",
"id": "6753149467284740901",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -409,5 +409,6 @@
"id"
]
}
]
],
"timestamp": "2023-08-30T19:25:22Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,14 +17,16 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "54519a12-e34b-4c4f-aef9-7dfac5f4949b",
"id": "c8dab94d-651c-4d9b-a19a-1c067a2976ea",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "bf339e89-0594-4f44-83f0-fc7cde9ceb0c",
"token": "96745539-f607-45f5-aa71-4f70f593ca6a",
"troubleshooting_url": null
},
"sensitive_values": {}
"sensitive_values": {
"token": true
}
},
{
"address": "coder_app.app1",
@ -34,12 +36,12 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "54519a12-e34b-4c4f-aef9-7dfac5f4949b",
"agent_id": "c8dab94d-651c-4d9b-a19a-1c067a2976ea",
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"id": "13101247-bdf1-409e-81e2-51a4ff45576b",
"id": "de5959cb-248c-44a0-bd04-9d5f28dfb415",
"name": null,
"relative_path": null,
"share": "owner",
@ -62,7 +64,7 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "54519a12-e34b-4c4f-aef9-7dfac5f4949b",
"agent_id": "c8dab94d-651c-4d9b-a19a-1c067a2976ea",
"command": null,
"display_name": null,
"healthcheck": [
@ -73,7 +75,7 @@
}
],
"icon": null,
"id": "ef508497-0437-43eb-b773-c0622582ab5d",
"id": "60aaa860-01d1-4d42-804b-2dc689676307",
"name": null,
"relative_path": null,
"share": "owner",
@ -98,12 +100,12 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "54519a12-e34b-4c4f-aef9-7dfac5f4949b",
"agent_id": "c8dab94d-651c-4d9b-a19a-1c067a2976ea",
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"id": "2c187306-80cc-46ba-a75c-42d4648ff94a",
"id": "3455e899-9bf9-4c0e-ac5b-6f861d5541a0",
"name": null,
"relative_path": null,
"share": "owner",
@ -126,7 +128,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "1264552698255765246",
"id": "7562947701260361048",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.2",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -424,5 +424,5 @@
]
}
],
"timestamp": "2023-07-05T10:28:42Z"
"timestamp": "2023-08-30T19:25:27Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,7 +17,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "d211806f-511a-4ced-aa68-c70ca3eeab60",
"id": "4d2791c5-e623-4c79-9c3a-81d70fde0f1d",
"init_script": "",
"login_before_ready": true,
"metadata": [
@ -36,7 +36,7 @@
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "746a2a79-b575-4eab-9e03-ec95d53a810c",
"token": "b068b430-4ecb-4116-a103-de3aaa1abd3e",
"troubleshooting_url": null
},
"sensitive_values": {
@ -57,7 +57,7 @@
"daily_cost": 29,
"hide": true,
"icon": "/icon/server.svg",
"id": "0ddb64e0-ed2f-493a-a305-bd617837faad",
"id": "0a46d060-c676-4324-a016-8dcdc7581d36",
"item": [
{
"is_null": false,
@ -72,7 +72,7 @@
"value": ""
}
],
"resource_id": "799423861826055007"
"resource_id": "6477445272839759515"
},
"sensitive_values": {
"item": [
@ -96,7 +96,7 @@
"daily_cost": 20,
"hide": true,
"icon": "/icon/server.svg",
"id": "305c001c-28d4-4d90-adc7-655a3a89eb2e",
"id": "77a107bc-073e-4180-9f7f-0e60fc42b6c2",
"item": [
{
"is_null": false,
@ -105,7 +105,7 @@
"value": "world"
}
],
"resource_id": "799423861826055007"
"resource_id": "6477445272839759515"
},
"sensitive_values": {
"item": [
@ -125,7 +125,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "799423861826055007",
"id": "6477445272839759515",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.3.7",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -246,7 +246,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.7.0-rc0"
"version_constraint": "0.7.0"
},
"null": {
"name": "null",
@ -370,5 +370,6 @@
"id"
]
}
]
],
"timestamp": "2023-08-30T19:25:25Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.3.7",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,7 +17,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "2090d6c6-c4c1-4219-b8f8-9df6db6d5864",
"id": "6b3b30af-2ac4-4e70-a162-42008b6f7b61",
"init_script": "",
"login_before_ready": true,
"metadata": [
@ -35,13 +35,14 @@
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_timeout": 300,
"token": "a984d85d-eff6-4366-9658-9719fb3dd82e",
"token": "fd450209-d2ce-4d89-8a48-b937de972e41",
"troubleshooting_url": null
},
"sensitive_values": {
"metadata": [
{}
]
],
"token": true
}
},
{
@ -55,7 +56,7 @@
"daily_cost": 29,
"hide": true,
"icon": "/icon/server.svg",
"id": "9e239cb2-e381-423a-bf16-74ece8254eff",
"id": "0bd3be9b-5733-48ee-807a-dadf70117512",
"item": [
{
"is_null": false,
@ -82,7 +83,7 @@
"value": "squirrel"
}
],
"resource_id": "3104684855633455084"
"resource_id": "5418245869413214440"
},
"sensitive_values": {
"item": [
@ -105,7 +106,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3104684855633455084",
"id": "5418245869413214440",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.2",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -113,7 +113,7 @@
],
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -129,7 +129,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "0d872aa0-e755-48a7-986d-4d6aa8ad9a17",
"id": "245304bd-d7c0-4dc0-b4b2-90a036245af0",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -157,7 +157,7 @@
"description": "blah blah",
"display_name": null,
"icon": null,
"id": "76eff4ae-28f0-409f-b002-58ebced3fdcb",
"id": "bccaddc6-97f1-48aa-a1c0-3438cc96139d",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -265,5 +265,5 @@
]
}
},
"timestamp": "2023-06-30T08:41:59Z"
"timestamp": "2023-08-30T19:25:32Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -16,7 +16,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "885aeb22-be2b-486a-8e0d-1883c7e27b3c",
"id": "20e486cd-35aa-4916-8cbf-c8b6fd235cd1",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -44,7 +44,7 @@
"description": "blah blah",
"display_name": null,
"icon": null,
"id": "be62f5ff-0e46-44f1-84e2-3fe0e57bb16f",
"id": "6c077b3f-ba6c-482b-9232-12a3d4892700",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -73,7 +73,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "7fe5bde1-7063-4426-9acc-76f5a8834fa6",
"id": "1414c0f9-be31-4efa-b1c9-57ab7c951b97",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -84,7 +84,7 @@
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "9b835c2c-fbb1-4824-a79f-12017badf015",
"token": "712872cf-fde6-4683-91a3-9ad9fc759e14",
"troubleshooting_url": null
},
"sensitive_values": {
@ -100,7 +100,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "2516512654554147618",
"id": "9132401905565595068",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.2",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -113,7 +113,7 @@
],
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -130,7 +130,7 @@
"display_name": null,
"ephemeral": true,
"icon": null,
"id": "2ef43cec-ce06-45d0-9dc2-5e9dcc5e506a",
"id": "858cb978-eef0-47e6-b7b8-7f9093303ad9",
"mutable": true,
"name": "number_example",
"option": null,
@ -157,7 +157,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "240d3feb-e553-4ec9-b72d-644f4937caae",
"id": "0add04ee-5c08-4702-b32e-727fc8c3fcd7",
"mutable": false,
"name": "number_example_max",
"option": null,
@ -196,7 +196,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "006306f8-3541-4a3c-9bd5-ddc9acac22da",
"id": "90bc3085-b65d-496a-b52c-2a6bfda1c439",
"mutable": false,
"name": "number_example_max_zero",
"option": null,
@ -235,7 +235,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "2cc53ecc-6086-461a-989d-77b5c40be5d7",
"id": "2499264c-7fa4-41da-9c78-6b5c86ddfd9c",
"mutable": false,
"name": "number_example_min",
"option": null,
@ -274,7 +274,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "691a525b-9424-4c38-a6da-d6029ab9c3ac",
"id": "dd6c2f30-6320-4e4a-ba82-deef628330f1",
"mutable": false,
"name": "number_example_min_max",
"option": null,
@ -313,7 +313,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "a7c46d06-44dd-4df2-8d16-a1130298dc59",
"id": "8e04ddc9-c245-408d-92b0-dec669259b4a",
"mutable": false,
"name": "number_example_min_zero",
"option": null,
@ -545,5 +545,5 @@
]
}
},
"timestamp": "2023-07-10T08:58:27Z"
"timestamp": "2023-08-30T19:25:35Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.5.1",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -17,7 +17,7 @@
"display_name": null,
"ephemeral": true,
"icon": null,
"id": "dcde525b-5871-486a-b731-f0c4d874bf5b",
"id": "3eac44eb-b74f-471e-ae3a-783083f33b58",
"mutable": true,
"name": "number_example",
"option": null,
@ -44,7 +44,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "756214c3-1df4-4438-ab8b-1f116bda1a91",
"id": "b767a52b-0b1d-4bea-a1b1-23180308a25d",
"mutable": false,
"name": "number_example_max",
"option": null,
@ -83,7 +83,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "073d8a2b-abc0-4a8d-a7a8-9e1f934e50fc",
"id": "f6857c45-04cf-47ae-85bc-caab3341ead5",
"mutable": false,
"name": "number_example_max_zero",
"option": null,
@ -122,7 +122,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "f6891e4d-d281-4af2-9459-9c5c7c1fb4f1",
"id": "634a2e89-47c0-4d4b-aed6-b20177c959d5",
"mutable": false,
"name": "number_example_min",
"option": null,
@ -161,7 +161,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "cf54b361-5505-4997-8eef-0d6216097927",
"id": "9ae1f0ff-2fe9-460c-97b8-6bb0cb7fb2c7",
"mutable": false,
"name": "number_example_min_max",
"option": null,
@ -200,7 +200,7 @@
"display_name": null,
"ephemeral": false,
"icon": null,
"id": "069f66cf-0098-44c0-9af3-c0ee5a93f110",
"id": "e6951857-18a9-44b8-bc0d-d78375fdf92d",
"mutable": false,
"name": "number_example_min_zero",
"option": null,
@ -239,7 +239,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "45694bbb-29e4-41c7-8172-7f0c17835578",
"id": "870767c4-6479-414c-aa08-a3f659ea3ec2",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -250,7 +250,7 @@
"startup_script": null,
"startup_script_behavior": null,
"startup_script_timeout": 300,
"token": "8fa25787-7aba-4d94-ac1c-7181faea0519",
"token": "59f08143-3fcb-48d6-a80d-3a87863cd865",
"troubleshooting_url": null
},
"sensitive_values": {
@ -266,7 +266,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "2669634748288884064",
"id": "643597385910559727",
"triggers": null
},
"sensitive_values": {},

View File

@ -1,6 +1,6 @@
{
"format_version": "1.1",
"terraform_version": "1.4.0",
"format_version": "1.2",
"terraform_version": "1.5.5",
"planned_values": {
"root_module": {
"resources": [
@ -111,7 +111,7 @@
],
"prior_state": {
"format_version": "1.0",
"terraform_version": "1.4.0",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -127,7 +127,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "5b7b6210-ce5d-4cc4-bbd6-0b329ca1c04f",
"id": "67c923e2-cb0c-4955-b7bb-cdb8b7fab8be",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -170,7 +170,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "72a5396c-0b3f-427d-b491-2700b025b3a1",
"id": "69ab9bf0-dadf-47ed-8486-b38b8d521c67",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -195,7 +195,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "63769975-a1e0-42ed-92c1-e003af6b4c54",
"id": "4dcc41e1-8d07-4018-98df-de5fadce5aa3",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -232,7 +232,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "2fce5c05-7018-402b-b653-98d75ad076a2",
"id": "c64e111c-496f-458d-924c-5ee13460f2ee",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -269,7 +269,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "4408d7e5-3353-4434-810c-d8c913f29edd",
"id": "ecc13f6b-a8bd-423a-8585-ac08882cd25c",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -306,7 +306,7 @@
"description": "blah blah",
"display_name": null,
"icon": null,
"id": "2b05e465-b243-4ae0-9210-634cf0f65d20",
"id": "ea6bbb0a-fdf5-46b4-8c68-22b59283fa6d",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -335,7 +335,7 @@
"description": "First parameter from module",
"display_name": null,
"icon": null,
"id": "fc0491e2-ea2e-4fa7-9b0b-08298fb768f4",
"id": "69e9bbe9-114a-43df-a050-a030efb3b89a",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -360,7 +360,7 @@
"description": "Second parameter from module",
"display_name": null,
"icon": null,
"id": "693fb916-39ed-4798-8724-0e751a2458e4",
"id": "607e122d-a7fd-4200-834f-c24e0e9a12c5",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -390,7 +390,7 @@
"description": "First parameter from child module",
"display_name": null,
"icon": null,
"id": "8014f515-a467-4dfe-ac63-8c7eadfc3521",
"id": "8cc5d1b7-391f-43ff-91e6-0293724a915b",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -415,7 +415,7 @@
"description": "Second parameter from child module",
"display_name": null,
"icon": null,
"id": "e94a306e-c1aa-47f5-833f-19719868d9ce",
"id": "dfb6a1c4-82fd-47d3-b58c-65beddcd8b0d",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -766,5 +766,6 @@
}
}
}
}
},
"timestamp": "2023-08-30T19:25:30Z"
}

View File

@ -1,6 +1,6 @@
{
"format_version": "1.0",
"terraform_version": "1.4.0",
"terraform_version": "1.5.5",
"values": {
"root_module": {
"resources": [
@ -16,7 +16,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "ca194a3d-90c5-4a74-8b9f-c299bc4dad33",
"id": "3d3a933a-b52b-4b38-bf91-0937615b1b29",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -59,7 +59,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "c1a68d9c-5a5e-4560-9319-053addb068af",
"id": "f8b06fc2-f0c6-4483-8d10-d4601dfdd787",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -84,7 +84,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "04492d05-0c3b-4fc1-a8b7-da70499ff7b6",
"id": "886575fc-1863-49be-9a7d-125077df0ca5",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -121,7 +121,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "852d5fc8-6d3b-4279-8165-fc6942e361f3",
"id": "feb32685-cfdc-4aed-b8bd-290d7e41822f",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -158,7 +158,7 @@
"description": null,
"display_name": null,
"icon": null,
"id": "b811e107-17b2-44bd-a2aa-58586ba3725f",
"id": "a5e72ae7-67f8-442c-837e-cce15f49fff0",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -195,7 +195,7 @@
"description": "blah blah",
"display_name": null,
"icon": null,
"id": "60d8c0b7-8442-4751-a4b3-0bff927fdbcb",
"id": "1dcf470f-25f5-4c1d-a68e-1833f8239591",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": false,
@ -221,7 +221,7 @@
"connection_timeout": 120,
"dir": null,
"env": null,
"id": "4c9d79a7-73e9-4f4f-8efb-464a393d64cd",
"id": "126f2d92-9556-4187-be69-5827ba3e7ddd",
"init_script": "",
"login_before_ready": true,
"metadata": [],
@ -231,11 +231,12 @@
"shutdown_script_timeout": 300,
"startup_script": null,
"startup_script_timeout": 300,
"token": "c31a5e7a-f0f2-4e61-aae8-82ae2456358b",
"token": "e2021a4f-4db5-4e26-8ecd-c4b6c6e79e92",
"troubleshooting_url": null
},
"sensitive_values": {
"metadata": []
"metadata": [],
"token": true
}
},
{
@ -246,7 +247,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3848665340553657624",
"id": "3170372688900630060",
"triggers": null
},
"sensitive_values": {},
@ -270,7 +271,7 @@
"description": "First parameter from module",
"display_name": null,
"icon": null,
"id": "3f49f2f3-0a0a-49ff-9b7d-e34867f0f515",
"id": "24874d90-5faf-4574-b54d-01a12e25159d",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -295,7 +296,7 @@
"description": "Second parameter from module",
"display_name": null,
"icon": null,
"id": "d1a6e987-b032-4107-88fd-f0aee0f3c1d3",
"id": "015a8629-347a-43f9-ba79-33d895f3b5b7",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -325,7 +326,7 @@
"description": "First parameter from child module",
"display_name": null,
"icon": null,
"id": "79d7a875-18e2-4fcd-ac9a-ad6de9f00c20",
"id": "85793115-42a5-4e52-be7b-77dcf337ffb6",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,
@ -350,7 +351,7 @@
"description": "Second parameter from child module",
"display_name": null,
"icon": null,
"id": "b71db658-46c0-4dca-8530-1d4f464b7ad6",
"id": "7754596b-a8b1-4a64-9ff1-27dd9473924c",
"legacy_variable": null,
"legacy_variable_name": null,
"mutable": true,

View File

@ -4,6 +4,8 @@ import (
_ "embed"
"fmt"
"strings"
"github.com/coder/coder/v2/provisionersdk/proto"
)
var (
@ -50,3 +52,15 @@ func AgentScriptEnv() map[string]string {
}
return env
}
// DefaultDisplayApps returns the default display applications to enable
// if none are specified in a template.
func DefaultDisplayApps() *proto.DisplayApps {
return &proto.DisplayApps{
Vscode: true,
VscodeInsiders: false,
WebTerminal: true,
PortForwardingHelper: true,
SshHelper: true,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -119,6 +119,7 @@ message Agent {
int32 shutdown_script_timeout_seconds = 17;
repeated Metadata metadata = 18;
string startup_script_behavior = 19;
DisplayApps display_apps = 20;
}
enum AppSharingLevel {
@ -127,6 +128,14 @@ enum AppSharingLevel {
PUBLIC = 2;
}
message DisplayApps {
bool vscode = 1;
bool vscode_insiders = 2;
bool web_terminal = 3;
bool ssh_helper = 4;
bool port_forwarding_helper = 5;
}
// App represents a dev-accessible application on the workspace.
message App {
// slug is the unique identifier for the app, usually the name from the

View File

@ -120,6 +120,7 @@ export interface Agent {
shutdownScriptTimeoutSeconds: number
metadata: Agent_Metadata[]
startupScriptBehavior: string
displayApps: DisplayApps | undefined
}
export interface Agent_Metadata {
@ -135,6 +136,14 @@ export interface Agent_EnvEntry {
value: string
}
export interface DisplayApps {
vscode: boolean
vscodeInsiders: boolean
webTerminal: boolean
sshHelper: boolean
portForwardingHelper: boolean
}
/** App represents a dev-accessible application on the workspace. */
export interface App {
/**
@ -505,6 +514,12 @@ export const Agent = {
if (message.startupScriptBehavior !== "") {
writer.uint32(154).string(message.startupScriptBehavior)
}
if (message.displayApps !== undefined) {
DisplayApps.encode(
message.displayApps,
writer.uint32(162).fork(),
).ldelim()
}
return writer
},
}
@ -548,6 +563,30 @@ export const Agent_EnvEntry = {
},
}
export const DisplayApps = {
encode(
message: DisplayApps,
writer: _m0.Writer = _m0.Writer.create(),
): _m0.Writer {
if (message.vscode === true) {
writer.uint32(8).bool(message.vscode)
}
if (message.vscodeInsiders === true) {
writer.uint32(16).bool(message.vscodeInsiders)
}
if (message.webTerminal === true) {
writer.uint32(24).bool(message.webTerminal)
}
if (message.sshHelper === true) {
writer.uint32(32).bool(message.sshHelper)
}
if (message.portForwardingHelper === true) {
writer.uint32(40).bool(message.portForwardingHelper)
}
return writer
},
}
export const App = {
encode(message: App, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer {
if (message.slug !== "") {

View File

@ -16,6 +16,9 @@ test("web terminal", async ({ context, page }) => {
agents: [
{
token,
displayApps: {
webTerminal: true,
},
},
],
},

View File

@ -1351,6 +1351,7 @@ export interface WorkspaceAgent {
readonly shutdown_script_timeout_seconds: number
readonly subsystems: AgentSubsystem[]
readonly health: WorkspaceAgentHealth
readonly display_apps: DisplayApp[]
}
// From codersdk/workspaceagents.go
@ -1590,6 +1591,21 @@ export const BuildReasons: BuildReason[] = [
"initiator",
]
// From codersdk/workspaceagents.go
export type DisplayApp =
| "port_forwarding_helper"
| "ssh_helper"
| "vscode"
| "vscode_insiders"
| "web_terminal"
export const DisplayApps: DisplayApp[] = [
"port_forwarding_helper",
"ssh_helper",
"vscode",
"vscode_insiders",
"web_terminal",
]
// From codersdk/deployment.go
export type Entitlement = "entitled" | "grace_period" | "not_entitled"
export const Entitlements: Entitlement[] = [

View File

@ -219,14 +219,17 @@ export const AgentRow: FC<AgentRowProps> = ({
<div className={styles.agentButtons}>
{shouldDisplayApps && (
<>
{!hideVSCodeDesktopButton && (
<VSCodeDesktopButton
userName={workspace.owner_name}
workspaceName={workspace.name}
agentName={agent.name}
folderPath={agent.expanded_directory}
/>
)}
{(agent.display_apps.includes("vscode") ||
agent.display_apps.includes("vscode_insiders")) &&
!hideVSCodeDesktopButton && (
<VSCodeDesktopButton
userName={workspace.owner_name}
workspaceName={workspace.name}
agentName={agent.name}
folderPath={agent.expanded_directory}
displayApps={agent.display_apps}
/>
)}
{agent.apps.map((app) => (
<AppLink
key={app.slug}
@ -240,20 +243,24 @@ export const AgentRow: FC<AgentRowProps> = ({
{showBuiltinApps && (
<>
<TerminalLink
workspaceName={workspace.name}
agentName={agent.name}
userName={workspace.owner_name}
/>
{!hideSSHButton && (
<SSHButton
{agent.display_apps.includes("web_terminal") && (
<TerminalLink
workspaceName={workspace.name}
agentName={agent.name}
sshPrefix={sshPrefix}
userName={workspace.owner_name}
/>
)}
{!hideSSHButton &&
agent.display_apps.includes("ssh_helper") && (
<SSHButton
workspaceName={workspace.name}
agentName={agent.name}
sshPrefix={sshPrefix}
/>
)}
{proxy.preferredWildcardHostname &&
proxy.preferredWildcardHostname !== "" && (
proxy.preferredWildcardHostname !== "" &&
agent.display_apps.includes("port_forwarding_helper") && (
<PortForwardButton
host={proxy.preferredWildcardHostname}
workspaceName={workspace.name}

View File

@ -19,4 +19,11 @@ Default.args = {
userName: MockWorkspace.owner_name,
workspaceName: MockWorkspace.name,
agentName: MockWorkspaceAgent.name,
displayApps: [
"vscode",
"port_forwarding_helper",
"ssh_helper",
"vscode_insiders",
"web_terminal",
],
}

View File

@ -8,12 +8,14 @@ import ButtonGroup from "@mui/material/ButtonGroup"
import { useLocalStorage } from "hooks"
import Menu from "@mui/material/Menu"
import MenuItem from "@mui/material/MenuItem"
import { DisplayApp } from "api/typesGenerated"
export interface VSCodeDesktopButtonProps {
userName: string
workspaceName: string
agentName?: string
folderPath?: string
displayApps: DisplayApp[]
}
type VSCodeVariant = "vscode" | "vscode-insiders"
@ -40,13 +42,16 @@ export const VSCodeDesktopButton: FC<
setIsVariantMenuOpen(false)
}
return (
const includesVSCodeDesktop = props.displayApps.includes("vscode")
const includesVSCodeInsiders = props.displayApps.includes("vscode_insiders")
return includesVSCodeDesktop && includesVSCodeInsiders ? (
<div>
<ButtonGroup
ref={menuAnchorRef}
variant="outlined"
sx={{
// Workaround to make the border transitions smmothly on button groups
// Workaround to make the border transitions smoothly on button groups
"& > button:hover + button": {
borderLeft: "1px solid #FFF",
},
@ -105,6 +110,10 @@ export const VSCodeDesktopButton: FC<
</MenuItem>
</Menu>
</div>
) : includesVSCodeDesktop ? (
<VSCodeButton {...props} />
) : (
<VSCodeInsidersButton {...props} />
)
}

View File

@ -567,6 +567,13 @@ export const MockWorkspaceAgent: TypesGen.WorkspaceAgent = {
health: {
healthy: true,
},
display_apps: [
"ssh_helper",
"port_forwarding_helper",
"vscode",
"vscode_insiders",
"web_terminal",
],
}
export const MockWorkspaceAgentDisconnected: TypesGen.WorkspaceAgent = {