From 4de19bfcecc2e905d517e53f91acb43ee9753867 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 14:35:16 +0000 Subject: [PATCH 01/11] feeat: Allow hide resources --- coderd/database/databasefake/databasefake.go | 1 + coderd/database/dump.sql | 3 +- .../000047_workspace_resource_hide.down.sql | 2 + .../000047_workspace_resource_hide.up.sql | 2 + coderd/database/models.go | 1 + coderd/database/queries.sql.go | 16 +- .../database/queries/workspaceresources.sql | 4 +- coderd/provisionerdaemons.go | 1 + coderd/workspacebuilds.go | 1 + codersdk/workspaceresources.go | 1 + provisioner/terraform/resources.go | 1 + provisionersdk/proto/provisioner.pb.go | 216 +++++++++--------- provisionersdk/proto/provisioner.proto | 1 + site/src/api/typesGenerated.ts | 1 + 14 files changed, 140 insertions(+), 111 deletions(-) create mode 100644 coderd/database/migrations/000047_workspace_resource_hide.down.sql create mode 100644 coderd/database/migrations/000047_workspace_resource_hide.up.sql diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index 8ef1be0355e9e..b08e6e7ce85b1 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -1764,6 +1764,7 @@ func (q *fakeQuerier) InsertWorkspaceResource(_ context.Context, arg database.In Transition: arg.Transition, Type: arg.Type, Name: arg.Name, + Hide: arg.Hide, } q.provisionerJobResources = append(q.provisionerJobResources, resource) return resource, nil diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index c6b4d9ca15c7d..fb4696cf2474b 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -366,7 +366,8 @@ CREATE TABLE workspace_resources ( job_id uuid NOT NULL, transition workspace_transition NOT NULL, type character varying(192) NOT NULL, - name character varying(64) NOT NULL + name character varying(64) NOT NULL, + hide boolean NOT NULL ); CREATE TABLE workspaces ( diff --git a/coderd/database/migrations/000047_workspace_resource_hide.down.sql b/coderd/database/migrations/000047_workspace_resource_hide.down.sql new file mode 100644 index 0000000000000..ab83f61ce690e --- /dev/null +++ b/coderd/database/migrations/000047_workspace_resource_hide.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE workspace_resources + DROP COLUMN hide; diff --git a/coderd/database/migrations/000047_workspace_resource_hide.up.sql b/coderd/database/migrations/000047_workspace_resource_hide.up.sql new file mode 100644 index 0000000000000..7a4510d388e4b --- /dev/null +++ b/coderd/database/migrations/000047_workspace_resource_hide.up.sql @@ -0,0 +1,2 @@ +ALTER TABLE workspace_resources + ADD COLUMN hide boolean NOT NULL; diff --git a/coderd/database/models.go b/coderd/database/models.go index f5cf7fab97de2..5fbc3f9081e99 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -586,6 +586,7 @@ type WorkspaceResource struct { Transition WorkspaceTransition `db:"transition" json:"transition"` Type string `db:"type" json:"type"` Name string `db:"name" json:"name"` + Hide bool `db:"hide" json:"hide"` } type WorkspaceResourceMetadatum struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 5c3c7f5a8276e..ec1e4c93c6569 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -4304,7 +4304,7 @@ func (q *sqlQuerier) UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWor const getWorkspaceResourceByID = `-- name: GetWorkspaceResourceByID :one SELECT - id, created_at, job_id, transition, type, name + id, created_at, job_id, transition, type, name, hide FROM workspace_resources WHERE @@ -4321,6 +4321,7 @@ func (q *sqlQuerier) GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) &i.Transition, &i.Type, &i.Name, + &i.Hide, ) return i, err } @@ -4435,7 +4436,7 @@ func (q *sqlQuerier) GetWorkspaceResourceMetadataCreatedAfter(ctx context.Contex const getWorkspaceResourcesByJobID = `-- name: GetWorkspaceResourcesByJobID :many SELECT - id, created_at, job_id, transition, type, name + id, created_at, job_id, transition, type, name, hide FROM workspace_resources WHERE @@ -4458,6 +4459,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui &i.Transition, &i.Type, &i.Name, + &i.Hide, ); err != nil { return nil, err } @@ -4473,7 +4475,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesByJobID(ctx context.Context, jobID uui } const getWorkspaceResourcesCreatedAfter = `-- name: GetWorkspaceResourcesCreatedAfter :many -SELECT id, created_at, job_id, transition, type, name FROM workspace_resources WHERE created_at > $1 +SELECT id, created_at, job_id, transition, type, name, hide FROM workspace_resources WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceResource, error) { @@ -4492,6 +4494,7 @@ func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, crea &i.Transition, &i.Type, &i.Name, + &i.Hide, ); err != nil { return nil, err } @@ -4508,9 +4511,9 @@ func (q *sqlQuerier) GetWorkspaceResourcesCreatedAfter(ctx context.Context, crea const insertWorkspaceResource = `-- name: InsertWorkspaceResource :one INSERT INTO - workspace_resources (id, created_at, job_id, transition, type, name) + workspace_resources (id, created_at, job_id, transition, type, name, hide) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING id, created_at, job_id, transition, type, name + ($1, $2, $3, $4, $5, $6, $7) RETURNING id, created_at, job_id, transition, type, name, hide ` type InsertWorkspaceResourceParams struct { @@ -4520,6 +4523,7 @@ type InsertWorkspaceResourceParams struct { Transition WorkspaceTransition `db:"transition" json:"transition"` Type string `db:"type" json:"type"` Name string `db:"name" json:"name"` + Hide bool `db:"hide" json:"hide"` } func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error) { @@ -4530,6 +4534,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork arg.Transition, arg.Type, arg.Name, + arg.Hide, ) var i WorkspaceResource err := row.Scan( @@ -4539,6 +4544,7 @@ func (q *sqlQuerier) InsertWorkspaceResource(ctx context.Context, arg InsertWork &i.Transition, &i.Type, &i.Name, + &i.Hide, ) return i, err } diff --git a/coderd/database/queries/workspaceresources.sql b/coderd/database/queries/workspaceresources.sql index d317e9db27b30..5603a65ae09c7 100644 --- a/coderd/database/queries/workspaceresources.sql +++ b/coderd/database/queries/workspaceresources.sql @@ -19,9 +19,9 @@ SELECT * FROM workspace_resources WHERE created_at > $1; -- name: InsertWorkspaceResource :one INSERT INTO - workspace_resources (id, created_at, job_id, transition, type, name) + workspace_resources (id, created_at, job_id, transition, type, name, hide) VALUES - ($1, $2, $3, $4, $5, $6) RETURNING *; + ($1, $2, $3, $4, $5, $6, $7) RETURNING *; -- name: GetWorkspaceResourceMetadataByResourceID :many SELECT diff --git a/coderd/provisionerdaemons.go b/coderd/provisionerdaemons.go index 6a109587676dc..df4197a70ae18 100644 --- a/coderd/provisionerdaemons.go +++ b/coderd/provisionerdaemons.go @@ -752,6 +752,7 @@ func insertWorkspaceResource(ctx context.Context, db database.Store, jobID uuid. Transition: transition, Type: protoResource.Type, Name: protoResource.Name, + Hide: protoResource.Hide, }) if err != nil { return xerrors.Errorf("insert provisioner job resource %q: %w", protoResource.Name, err) diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index b98c67195491a..3fadef1552f55 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -698,6 +698,7 @@ func convertWorkspaceResource(resource database.WorkspaceResource, agents []code Transition: codersdk.WorkspaceTransition(resource.Transition), Type: resource.Type, Name: resource.Name, + Hide: resource.Hide, Agents: agents, Metadata: convertedMetadata, } diff --git a/codersdk/workspaceresources.go b/codersdk/workspaceresources.go index 4dcb2828a8182..782e827092ce2 100644 --- a/codersdk/workspaceresources.go +++ b/codersdk/workspaceresources.go @@ -25,6 +25,7 @@ type WorkspaceResource struct { Transition WorkspaceTransition `json:"workspace_transition"` Type string `json:"type"` Name string `json:"name"` + Hide bool `json:"hide"` Agents []WorkspaceAgent `json:"agents,omitempty"` Metadata []WorkspaceResourceMetadata `json:"metadata,omitempty"` } diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index 8e931c752d8b6..c34580da3bbfb 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -36,6 +36,7 @@ type agentAppAttributes struct { // A mapping of attributes on the "coder_metadata" resource. type metadataAttributes struct { ResourceID string `mapstructure:"resource_id"` + Hide bool `mapstructure:"hide"` Items []metadataItem `mapstructure:"item"` } diff --git a/provisionersdk/proto/provisioner.pb.go b/provisionersdk/proto/provisioner.pb.go index 836426f24b3f1..2efdbac5fabb4 100644 --- a/provisionersdk/proto/provisioner.pb.go +++ b/provisionersdk/proto/provisioner.pb.go @@ -934,6 +934,7 @@ type Resource struct { Type string `protobuf:"bytes,2,opt,name=type,proto3" json:"type,omitempty"` Agents []*Agent `protobuf:"bytes,3,rep,name=agents,proto3" json:"agents,omitempty"` Metadata []*Resource_Metadata `protobuf:"bytes,4,rep,name=metadata,proto3" json:"metadata,omitempty"` + Hide bool `protobuf:"varint,5,opt,name=hide,proto3" json:"hide,omitempty"` } func (x *Resource) Reset() { @@ -996,6 +997,13 @@ func (x *Resource) GetMetadata() []*Resource_Metadata { return nil } +func (x *Resource) GetHide() bool { + if x != nil { + return x.Hide + } + return false +} + // Parse consumes source-code from a directory to produce inputs. type Parse struct { state protoimpl.MessageState @@ -1872,7 +1880,7 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69, 0x63, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x85, + 0x52, 0x0c, 0x72, 0x65, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x50, 0x61, 0x74, 0x68, 0x22, 0x99, 0x02, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, @@ -1882,110 +1890,112 @@ var file_provisionersdk_proto_provisioner_proto_rawDesc = []byte{ 0x3a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x69, 0x0a, 0x08, 0x4d, - 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, 0x12, 0x17, 0x0a, - 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, - 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, 0x08, 0x43, 0x6f, 0x6d, - 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, - 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, - 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, - 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, - 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x6c, - 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, - 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xae, 0x07, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x1a, 0xd1, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, - 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x12, 0x53, 0x0a, - 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, 0x72, 0x61, 0x6e, 0x73, - 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x20, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x77, + 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, 0x68, + 0x69, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x68, 0x69, 0x64, 0x65, 0x1a, + 0x69, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x65, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x76, + 0x65, 0x12, 0x17, 0x0a, 0x07, 0x69, 0x73, 0x5f, 0x6e, 0x75, 0x6c, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x08, 0x52, 0x06, 0x69, 0x73, 0x4e, 0x75, 0x6c, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x05, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x1a, 0x27, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x1a, 0x55, 0x0a, + 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61, 0x72, + 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, + 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, 0x65, + 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68, + 0x65, 0x6d, 0x61, 0x73, 0x1a, 0x73, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, + 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, 0x39, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x43, 0x6f, 0x6d, + 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, + 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xae, 0x07, 0x0a, 0x09, 0x50, 0x72, + 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x1a, 0xd1, 0x02, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x75, 0x72, + 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x55, 0x72, + 0x6c, 0x12, 0x53, 0x0a, 0x14, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x74, + 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x57, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, + 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, + 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, + 0x65, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x1a, 0xd9, 0x01, 0x0a, 0x05, + 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, + 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, + 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, + 0x0a, 0x07, 0x64, 0x72, 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x64, 0x72, 0x79, 0x52, 0x75, 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, + 0x6c, 0x1a, 0x80, 0x01, 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, + 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, + 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, + 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x6e, 0x63, + 0x65, 0x6c, 0x48, 0x00, 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x1a, 0x6b, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x73, 0x1a, 0x77, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, + 0x03, 0x6c, 0x6f, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, + 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, + 0x6c, 0x6f, 0x67, 0x12, 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, + 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, + 0x74, 0x65, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, + 0x67, 0x4c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, + 0x00, 0x12, 0x09, 0x0a, 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x49, 0x4e, 0x46, 0x4f, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, + 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, - 0x65, 0x72, 0x12, 0x21, 0x0a, 0x0c, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x69, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, - 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, - 0x63, 0x65, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, 0x65, - 0x72, 0x49, 0x64, 0x12, 0x32, 0x0a, 0x15, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, - 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x13, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4f, 0x77, 0x6e, - 0x65, 0x72, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x1a, 0xd9, 0x01, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x72, - 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, - 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, - 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, - 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, - 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x17, 0x0a, 0x07, 0x64, 0x72, - 0x79, 0x5f, 0x72, 0x75, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x64, 0x72, 0x79, - 0x52, 0x75, 0x6e, 0x1a, 0x08, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x1a, 0x80, 0x01, - 0x0a, 0x07, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x61, - 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, - 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, - 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x48, 0x00, 0x52, 0x05, 0x73, 0x74, 0x61, 0x72, 0x74, 0x12, - 0x37, 0x0a, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x48, 0x00, - 0x52, 0x06, 0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x1a, 0x6b, 0x0a, 0x08, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, - 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x77, 0x0a, - 0x08, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x24, 0x0a, 0x03, 0x6c, 0x6f, 0x67, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, - 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x48, 0x00, 0x52, 0x03, 0x6c, 0x6f, 0x67, 0x12, - 0x3d, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, - 0x74, 0x65, 0x48, 0x00, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x42, 0x06, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x2a, 0x3f, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x4c, 0x65, 0x76, - 0x65, 0x6c, 0x12, 0x09, 0x0a, 0x05, 0x54, 0x52, 0x41, 0x43, 0x45, 0x10, 0x00, 0x12, 0x09, 0x0a, - 0x05, 0x44, 0x45, 0x42, 0x55, 0x47, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, 0x49, 0x4e, 0x46, 0x4f, - 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x41, 0x52, 0x4e, 0x10, 0x03, 0x12, 0x09, 0x0a, 0x05, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x04, 0x2a, 0x37, 0x0a, 0x13, 0x57, 0x6f, 0x72, 0x6b, 0x73, - 0x70, 0x61, 0x63, 0x65, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x09, - 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x54, 0x4f, - 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, 0x4f, 0x59, 0x10, 0x02, - 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, - 0x12, 0x42, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, + 0x6f, 0x6e, 0x12, 0x09, 0x0a, 0x05, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0x00, 0x12, 0x08, 0x0a, + 0x04, 0x53, 0x54, 0x4f, 0x50, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x44, 0x45, 0x53, 0x54, 0x52, + 0x4f, 0x59, 0x10, 0x02, 0x32, 0xa3, 0x01, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, + 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x05, 0x50, 0x61, 0x72, 0x73, 0x65, 0x12, 0x1a, 0x2e, + 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, + 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, - 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, - 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x12, 0x50, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x2d, 0x5a, 0x2b, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, + 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, + 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } var ( diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index ab521256853c0..b95389000259f 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -109,6 +109,7 @@ message Resource { bool is_null = 4; } repeated Metadata metadata = 4; + bool hide = 5; } // Parse consumes source-code from a directory to produce inputs. diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 175cdf63a54d8..78afe1f57be15 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -635,6 +635,7 @@ export interface WorkspaceResource { readonly workspace_transition: WorkspaceTransition readonly type: string readonly name: string + readonly hide: boolean readonly agents?: WorkspaceAgent[] readonly metadata?: WorkspaceResourceMetadata[] } From d41e219cfb3c496f9414b2aa31a9051279102123 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 12:20:10 -0300 Subject: [PATCH 02/11] Update provisionersdk/proto/provisioner.proto Co-authored-by: Dean Sheather --- provisionersdk/proto/provisioner.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/provisionersdk/proto/provisioner.proto b/provisionersdk/proto/provisioner.proto index b95389000259f..3bf760d1dc5d8 100644 --- a/provisionersdk/proto/provisioner.proto +++ b/provisionersdk/proto/provisioner.proto @@ -109,7 +109,7 @@ message Resource { bool is_null = 4; } repeated Metadata metadata = 4; - bool hide = 5; + bool hide = 5; } // Parse consumes source-code from a directory to produce inputs. From f2648e627ff8e921e613cc33c2a433536cd39541 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 15:35:30 +0000 Subject: [PATCH 03/11] Fix entities --- site/src/testHelpers/entities.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index 8818283658a2c..ad877dcbcbd10 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -392,6 +392,7 @@ export const MockWorkspaceResource: TypesGen.WorkspaceResource = { name: "a-workspace-resource", type: "google_compute_disk", workspace_transition: "start", + hide: false, metadata: [ { key: "type", value: "a-workspace-resource", sensitive: false }, { key: "api_key", value: "12345678", sensitive: true }, @@ -406,6 +407,7 @@ export const MockWorkspaceResource2: TypesGen.WorkspaceResource = { name: "another-workspace-resource", type: "google_compute_disk", workspace_transition: "start", + hide: false, metadata: [ { key: "type", value: "google_compute_disk", sensitive: false }, { key: "size", value: "32GB", sensitive: false }, From 34c8fd44a46398d1b86637f98d5e9f1d4a15d9c6 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 16:07:28 +0000 Subject: [PATCH 04/11] Add button to show or hide hidden resrources --- site/src/components/Resources/Resources.tsx | 265 ++++++++++-------- .../Workspace/Workspace.stories.tsx | 6 +- site/src/testHelpers/entities.ts | 15 + site/src/theme/overrides.ts | 3 +- 4 files changed, 173 insertions(+), 116 deletions(-) diff --git a/site/src/components/Resources/Resources.tsx b/site/src/components/Resources/Resources.tsx index 91bd788e09f83..6a93c80e56b4d 100644 --- a/site/src/components/Resources/Resources.tsx +++ b/site/src/components/Resources/Resources.tsx @@ -1,3 +1,4 @@ +import Button from "@material-ui/core/Button" import { makeStyles, Theme } from "@material-ui/core/styles" import Table from "@material-ui/core/Table" import TableBody from "@material-ui/core/TableBody" @@ -7,9 +8,10 @@ import TableHead from "@material-ui/core/TableHead" import TableRow from "@material-ui/core/TableRow" import { Skeleton } from "@material-ui/lab" import useTheme from "@material-ui/styles/useTheme" +import { CloseDropdown, OpenDropdown } from "components/DropdownArrows/DropdownArrows" import { ErrorSummary } from "components/ErrorSummary/ErrorSummary" import { TableCellDataPrimary } from "components/TableCellData/TableCellData" -import { FC } from "react" +import { FC, useState } from "react" import { getDisplayAgentStatus, getDisplayVersionStatus } from "util/workspace" import { BuildInfoResponse, Workspace, WorkspaceResource } from "../../api/typesGenerated" import { AppLink } from "../AppLink/AppLink" @@ -34,7 +36,7 @@ const Language = { } interface ResourcesProps { - resources?: WorkspaceResource[] + resources: WorkspaceResource[] getResourcesError?: Error | unknown workspace: Workspace canUpdateWorkspace: boolean @@ -51,129 +53,152 @@ export const Resources: FC> = ({ const styles = useStyles() const theme: Theme = useTheme() const serverVersion = buildInfo?.version || "" + const [shouldDisplayHideResources, setShouldDisplayHideResources] = useState(false) + const displayResources = shouldDisplayHideResources + ? resources + : resources.filter((resource) => !resource.hide) + const hasHideResources = resources.some((r) => r.hide) return ( -
- {getResourcesError ? ( - - ) : ( - - - - - - - {Language.resourceLabel} - - - - - - {Language.agentLabel} - - - - {canUpdateWorkspace && } - - - - {resources?.map((resource) => { - { - /* We need to initialize the agents to display the resource */ - } - const agents = resource.agents ?? [null] - const resourceName = - - return agents.map((agent, agentIndex) => { + +
+ {getResourcesError ? ( + + ) : ( + +
+ + + + + {Language.resourceLabel} + + + + + + {Language.agentLabel} + + + + {canUpdateWorkspace && } + + + + {displayResources.map((resource) => { { - /* If there is no agent, just display the resource name */ + /* We need to initialize the agents to display the resource */ } - if (!agent) { - return ( - - {resourceName} - - + const agents = resource.agents ?? [null] + const resourceName = + + return agents.map((agent, agentIndex) => { + { + /* If there is no agent, just display the resource name */ + } + if (!agent) { + return ( + + {resourceName} + + + ) + } + + const { displayVersion, outdated } = getDisplayVersionStatus( + agent.version, + serverVersion, ) - } + const agentStatus = getDisplayAgentStatus(theme, agent) + return ( + + {/* We only want to display the name in the first row because we are using rowSpan */} + {/* The rowspan should be the same than the number of agents */} + {agentIndex === 0 && ( + + {resourceName} + + )} - const { displayVersion, outdated } = getDisplayVersionStatus( - agent.version, - serverVersion, - ) - const agentStatus = getDisplayAgentStatus(theme, agent) - return ( - - {/* We only want to display the name in the first row because we are using rowSpan */} - {/* The rowspan should be the same than the number of agents */} - {agentIndex === 0 && ( - - {resourceName} - - )} - - - {agent.name} -
-
- {Language.statusLabel} - - {agentStatus.status} - -
-
- {Language.osLabel} - {agent.operating_system} -
-
- {Language.versionLabel} - {displayVersion} - + + {agent.name} +
+
+ {Language.statusLabel} + + {agentStatus.status} + +
+
+ {Language.osLabel} + + {agent.operating_system} + +
+
+ {Language.versionLabel} + {displayVersion} + +
+
+ +
-
- -
-
- - -
- {canUpdateWorkspace && agent.status === "connected" && ( - <> - - - {agent.apps.map((app) => ( - + +
+ {canUpdateWorkspace && agent.status === "connected" && ( + <> + + - ))} - - )} - {canUpdateWorkspace && agent.status === "connecting" && ( - <> - - - - )} -
-
- - ) - }) - })} - -
-
+ {agent.apps.map((app) => ( + + ))} + + )} + {canUpdateWorkspace && agent.status === "connecting" && ( + <> + + + + )} +
+ + + ) + }) + })} + + + + )} + + + {hasHideResources && ( +
+ +
)} - + ) } @@ -247,4 +272,16 @@ const useStyles = makeStyles((theme) => ({ marginRight: theme.spacing(1), }, }, + + buttonWrapper: { + display: "flex", + alignItems: "center", + justifyContent: "center", + }, + + showMoreButton: { + borderRadius: 9999, + width: "100%", + maxWidth: 260, + }, })) diff --git a/site/src/components/Workspace/Workspace.stories.tsx b/site/src/components/Workspace/Workspace.stories.tsx index 2fd6136e60e27..33f9d1d2c78b9 100644 --- a/site/src/components/Workspace/Workspace.stories.tsx +++ b/site/src/components/Workspace/Workspace.stories.tsx @@ -40,7 +40,11 @@ Started.args = { workspace: Mocks.MockWorkspace, handleStart: action("start"), handleStop: action("stop"), - resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2], + resources: [ + Mocks.MockWorkspaceResource, + Mocks.MockWorkspaceResource2, + Mocks.MockWorkspaceResource3, + ], builds: [Mocks.MockWorkspaceBuild], canUpdateWorkspace: true, workspaceErrors: {}, diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index ad877dcbcbd10..737521376649e 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -414,6 +414,21 @@ export const MockWorkspaceResource2: TypesGen.WorkspaceResource = { ], } +export const MockWorkspaceResource3: TypesGen.WorkspaceResource = { + agents: [MockWorkspaceAgent, MockWorkspaceAgentDisconnected, MockWorkspaceAgentOutdated], + created_at: "", + id: "test-workspace-resource-3", + job_id: "", + name: "another-workspace-resource", + type: "google_compute_disk", + workspace_transition: "start", + hide: true, + metadata: [ + { key: "type", value: "google_compute_disk", sensitive: false }, + { key: "size", value: "32GB", sensitive: false }, + ], +} + export const MockUserAgent: Types.UserAgent = { browser: "Chrome 99.0.4844", device: "Other", diff --git a/site/src/theme/overrides.ts b/site/src/theme/overrides.ts index 8d3ac13f6425b..98dd27091a678 100644 --- a/site/src/theme/overrides.ts +++ b/site/src/theme/overrides.ts @@ -67,8 +67,9 @@ export const getOverrides = ({ palette, breakpoints }: Theme): Overrides => { }, outlined: { border: `1px solid ${palette.divider}`, + "&:hover": { - backgroundColor: palette.background.default, + backgroundColor: palette.action.hover, }, }, }, From a0ad4dd4f3c693c2495d1b60f64cae0349189125 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 16:16:53 +0000 Subject: [PATCH 05/11] Fix test typo --- site/src/components/Resources/Resources.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/components/Resources/Resources.test.tsx b/site/src/components/Resources/Resources.test.tsx index a4c3286993735..36913d98a98e2 100644 --- a/site/src/components/Resources/Resources.test.tsx +++ b/site/src/components/Resources/Resources.test.tsx @@ -12,7 +12,7 @@ describe("ResourceTable", () => { it("hides status text when a workspace is stopped", async () => { // When const props = { - resource: [{ ...MockWorkspaceResource }, { ...MockWorkspaceResource2 }], + resources: [{ ...MockWorkspaceResource }, { ...MockWorkspaceResource2 }], workspace: { ...MockStoppedWorkspace }, canUpdateWorkspace: false, } From 944bbd3b1605362bf1049887023912b1b05bc093 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 16:41:25 +0000 Subject: [PATCH 06/11] Remove unecessary test --- .../components/Resources/Resources.test.tsx | 27 ------------------- 1 file changed, 27 deletions(-) delete mode 100644 site/src/components/Resources/Resources.test.tsx diff --git a/site/src/components/Resources/Resources.test.tsx b/site/src/components/Resources/Resources.test.tsx deleted file mode 100644 index 36913d98a98e2..0000000000000 --- a/site/src/components/Resources/Resources.test.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { screen } from "@testing-library/react" -import { - MockStoppedWorkspace, - MockWorkspaceResource, - MockWorkspaceResource2, -} from "testHelpers/entities" -import { render } from "testHelpers/renderHelpers" -import { DisplayAgentStatusLanguage } from "util/workspace" -import { Resources } from "./Resources" - -describe("ResourceTable", () => { - it("hides status text when a workspace is stopped", async () => { - // When - const props = { - resources: [{ ...MockWorkspaceResource }, { ...MockWorkspaceResource2 }], - workspace: { ...MockStoppedWorkspace }, - canUpdateWorkspace: false, - } - - render() - - const statusText = screen.queryByText(DisplayAgentStatusLanguage.connecting) - - // Then - expect(statusText).toBeNull() - }) -}) From d4918df95cf01001546fd06a91f67cb08962e009 Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 17:12:49 +0000 Subject: [PATCH 07/11] Fix default value --- coderd/database/dump.sql | 2 +- .../database/migrations/000047_workspace_resource_hide.up.sql | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index fb4696cf2474b..cc371f34b1048 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -367,7 +367,7 @@ CREATE TABLE workspace_resources ( transition workspace_transition NOT NULL, type character varying(192) NOT NULL, name character varying(64) NOT NULL, - hide boolean NOT NULL + hide boolean DEFAULT false NOT NULL ); CREATE TABLE workspaces ( diff --git a/coderd/database/migrations/000047_workspace_resource_hide.up.sql b/coderd/database/migrations/000047_workspace_resource_hide.up.sql index 7a4510d388e4b..86d56c47ffcdd 100644 --- a/coderd/database/migrations/000047_workspace_resource_hide.up.sql +++ b/coderd/database/migrations/000047_workspace_resource_hide.up.sql @@ -1,2 +1,2 @@ ALTER TABLE workspace_resources - ADD COLUMN hide boolean NOT NULL; + ADD COLUMN hide boolean DEFAULT false NOT NULL; From 49bd13918a534b37bf63409a1699900cc07b9e15 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 9 Sep 2022 17:21:43 +0000 Subject: [PATCH 08/11] Add test for hide to provisioner --- provisioner/terraform/provision_test.go | 2 +- provisioner/terraform/resources.go | 67 +++++++++++++++---- provisioner/terraform/resources_test.go | 7 +- .../testdata/calling-module/calling-module.tf | 2 +- .../calling-module/calling-module.tfplan.json | 4 +- .../calling-module.tfstate.json | 10 +-- .../chaining-resources/chaining-resources.tf | 2 +- .../chaining-resources.tfplan.json | 4 +- .../chaining-resources.tfstate.json | 10 +-- .../conflicting-resources.tf | 2 +- .../conflicting-resources.tfplan.json | 4 +- .../conflicting-resources.tfstate.json | 10 +-- ...erraform_fake_cancel.sh => fake_cancel.sh} | 0 provisioner/terraform/testdata/generate.sh | 2 +- .../testdata/instance-id/instance-id.tf | 2 +- .../instance-id/instance-id.tfplan.json | 4 +- .../instance-id/instance-id.tfstate.json | 12 ++-- .../multiple-agents/multiple-agents.tf | 2 +- .../multiple-agents.tfplan.json | 4 +- .../multiple-agents.tfstate.json | 16 ++--- .../testdata/multiple-apps/multiple-apps.tf | 2 +- .../multiple-apps/multiple-apps.tfplan.json | 4 +- .../multiple-apps/multiple-apps.tfstate.json | 16 ++--- .../resource-metadata/resource-metadata.tf | 3 +- .../resource-metadata.tfplan.json | 9 ++- .../resource-metadata.tfstate.json | 13 ++-- 26 files changed, 133 insertions(+), 80 deletions(-) rename provisioner/terraform/testdata/{bin/terraform_fake_cancel.sh => fake_cancel.sh} (100%) diff --git a/provisioner/terraform/provision_test.go b/provisioner/terraform/provision_test.go index a9bd00cad9289..a1ab1584e7df6 100644 --- a/provisioner/terraform/provision_test.go +++ b/provisioner/terraform/provision_test.go @@ -68,7 +68,7 @@ func TestProvision_Cancel(t *testing.T) { cwd, err := os.Getwd() require.NoError(t, err) - fakeBin := filepath.Join(cwd, "testdata", "bin", "terraform_fake_cancel.sh") + fakeBin := filepath.Join(cwd, "testdata", "fake_cancel.sh") tests := []struct { name string diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index c34580da3bbfb..aded1a0516b9c 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -138,7 +138,7 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res } var agentResource *graphResource - for _, resource := range findResourcesUpGraph(graph, tfResourceByLabel, agentNode.Name, 0) { + for _, resource := range findResourcesInGraph(graph, tfResourceByLabel, agentNode.Name, 0, true) { if agentResource == nil { // Default to the first resource because we have nothing to compare! agentResource = resource @@ -235,7 +235,8 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res // Associate metadata blocks with resources. resourceMetadata := map[string][]*proto.Resource_Metadata{} - for label, resource := range tfResourceByLabel { + resourceHidden := map[string]bool{} + for _, resource := range tfResourceByLabel { if resource.Type != "coder_metadata" { continue } @@ -245,17 +246,54 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res return nil, xerrors.Errorf("decode metadata attributes: %w", err) } + var targetLabel string + // This occurs in a plan, because there is no resource ID. + // We attempt to find the closest node, just so we can hide it from the UI. if attrs.ResourceID == "" { - // TODO: detect this as an error - // At plan time, change.after_unknown.resource_id should be "true". - // At provision time, values.resource_id should be set. - continue + resourceLabel := convertAddressToLabel(resource.Address) + + var attachedNode *gographviz.Node + for _, node := range graph.Nodes.Lookup { + // The node attributes surround the label with quotes. + if strings.Trim(node.Attrs["label"], `"`) != resourceLabel { + continue + } + attachedNode = node + break + } + if attachedNode == nil { + continue + } + var attachedResource *graphResource + for _, resource := range findResourcesInGraph(graph, tfResourceByLabel, attachedNode.Name, 0, false) { + if attachedResource == nil { + // Default to the first resource because we have nothing to compare! + attachedResource = resource + continue + } + if resource.Depth < attachedResource.Depth { + // There's a closer resource! + attachedResource = resource + continue + } + if resource.Depth == attachedResource.Depth && resource.Label < attachedResource.Label { + attachedResource = resource + continue + } + } + if attachedResource == nil { + continue + } + targetLabel = attachedResource.Label } - targetLabel, ok := resourceLabelByID[attrs.ResourceID] - if !ok { - return nil, xerrors.Errorf("attribute %s.resource_id = %q does not refer to a valid resource", label, attrs.ResourceID) + if targetLabel == "" { + targetLabel = resourceLabelByID[attrs.ResourceID] + } + if targetLabel == "" { + continue } + resourceHidden[targetLabel] = attrs.Hide for _, item := range attrs.Items { resourceMetadata[targetLabel] = append(resourceMetadata[targetLabel], &proto.Resource_Metadata{ @@ -285,6 +323,7 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res Name: resource.Name, Type: resource.Type, Agents: agents, + Hide: resourceHidden[label], Metadata: resourceMetadata[label], }) } @@ -347,12 +386,16 @@ func applyAutomaticInstanceID(resource *tfjson.StateResource, agents []*proto.Ag // findResourcesUpGraph traverses upwards in a graph until a resource is found, // then it stores the depth it was found at, and continues working up the tree. -func findResourcesUpGraph(graph *gographviz.Graph, tfResourceByLabel map[string]*tfjson.StateResource, nodeName string, currentDepth uint) []*graphResource { +func findResourcesInGraph(graph *gographviz.Graph, tfResourceByLabel map[string]*tfjson.StateResource, nodeName string, currentDepth uint, up bool) []*graphResource { graphResources := make([]*graphResource, 0) - for destination := range graph.Edges.DstToSrcs[nodeName] { + mapping := graph.Edges.DstToSrcs + if !up { + mapping = graph.Edges.SrcToDsts + } + for destination := range mapping[nodeName] { destinationNode := graph.Nodes.Lookup[destination] // Work our way up the tree! - graphResources = append(graphResources, findResourcesUpGraph(graph, tfResourceByLabel, destinationNode.Name, currentDepth+1)...) + graphResources = append(graphResources, findResourcesInGraph(graph, tfResourceByLabel, destinationNode.Name, currentDepth+1, up)...) destinationLabel, exists := destinationNode.Attrs["label"] if !exists { diff --git a/provisioner/terraform/resources_test.go b/provisioner/terraform/resources_test.go index 5ad6f49669300..e378462c3cd3b 100644 --- a/provisioner/terraform/resources_test.go +++ b/provisioner/terraform/resources_test.go @@ -120,6 +120,7 @@ func TestConvertResources(t *testing.T) { "resource-metadata": {{ Name: "about", Type: "null_resource", + Hide: true, Metadata: []*proto.Resource_Metadata{{ Key: "hello", Value: "world", @@ -155,11 +156,13 @@ func TestConvertResources(t *testing.T) { require.NoError(t, err) sortResources(resources) - // plan does not contain metadata, so clone expected and remove it var expectedNoMetadata []*proto.Resource for _, resource := range expected { resourceCopy, _ := protobuf.Clone(resource).(*proto.Resource) - resourceCopy.Metadata = nil + // plan cannot know whether values are null or not + for _, metadata := range resourceCopy.Metadata { + metadata.IsNull = false + } expectedNoMetadata = append(expectedNoMetadata, resourceCopy) } diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tf b/provisioner/terraform/testdata/calling-module/calling-module.tf index 382e003b222e8..0da8a94a6ad79 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tf +++ b/provisioner/terraform/testdata/calling-module/calling-module.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json b/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json index d0d511e2a29a6..4fbb241c12479 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json +++ b/provisioner/terraform/testdata/calling-module/calling-module.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -147,7 +147,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "module.module:null": { "name": "null", diff --git a/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json b/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json index b089ad2a761b8..8499a27dfe848 100644 --- a/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json +++ b/provisioner/terraform/testdata/calling-module/calling-module.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "78098841-3d6c-4aa7-9d3c-6e4c9be7e2df", + "id": "ee0b689a-9785-4d72-923f-e2acf88d709b", "init_script": "", "os": "linux", "startup_script": null, - "token": "605d8d2c-a720-4422-9410-62b41e3e6565" + "token": "a295c68a-27af-4dc8-92cd-db154084cf30" }, "sensitive_values": {} } @@ -44,7 +44,7 @@ "outputs": { "script": "" }, - "random": "3340396623875729305" + "random": "410687191584620713" }, "sensitive_values": { "inputs": {}, @@ -59,7 +59,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "831556400374221454", + "id": "7780508472225873711", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf index ab4987321a143..8133e91976bec 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json index cb109c5459af0..feaa74b9ee0ff 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -125,7 +125,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "null": { "name": "null", diff --git a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json index e11e5f8a1c4c6..6109908119a33 100644 --- a/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json +++ b/provisioner/terraform/testdata/chaining-resources/chaining-resources.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "79e7cbba-c238-47f1-aec2-eb816385595d", + "id": "97baf22d-c3fc-4570-a025-58dd5235366f", "init_script": "", "os": "linux", "startup_script": null, - "token": "96cc0f63-c65b-4fea-90bb-073e57ddc766" + "token": "ae325f47-8fe4-436c-9787-7295eef26604" }, "sensitive_values": {} }, @@ -32,7 +32,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "6159719504309004303", + "id": "8957171845319631256", "triggers": null }, "sensitive_values": {}, @@ -49,7 +49,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "5246585857846899839", + "id": "7521770950111838137", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf index 889f63eeb481e..6a5a56a90a780 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json index 286704416f245..a2848e565b8e2 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -125,7 +125,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "null": { "name": "null", diff --git a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json index 9f065432e5a41..fc56ad8dd1a8c 100644 --- a/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json +++ b/provisioner/terraform/testdata/conflicting-resources/conflicting-resources.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "1c27d2eb-c2e3-4391-b3a2-5e3f57ae9ec6", + "id": "75c43b92-2812-4a6b-9a40-16c124c3c2ff", "init_script": "", "os": "linux", "startup_script": null, - "token": "c0dbedc7-fb3d-4b77-a3f8-6c84c688db57" + "token": "bf14e82d-7e8f-49b5-8e2a-fb84da4b6afa" }, "sensitive_values": {} }, @@ -32,7 +32,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "2210256189362430895", + "id": "5082348601033637104", "triggers": null }, "sensitive_values": {}, @@ -48,7 +48,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "7017926349421667565", + "id": "135765900644760615", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/bin/terraform_fake_cancel.sh b/provisioner/terraform/testdata/fake_cancel.sh similarity index 100% rename from provisioner/terraform/testdata/bin/terraform_fake_cancel.sh rename to provisioner/terraform/testdata/fake_cancel.sh diff --git a/provisioner/terraform/testdata/generate.sh b/provisioner/terraform/testdata/generate.sh index 95cf6fde2b19e..41e94f9c207e5 100755 --- a/provisioner/terraform/testdata/generate.sh +++ b/provisioner/terraform/testdata/generate.sh @@ -6,7 +6,7 @@ cd "$(dirname "${BASH_SOURCE[0]}")" for d in */; do pushd "$d" name=$(basename "$(pwd)") - terraform init + terraform init -upgrade terraform plan -out terraform.tfplan terraform show -json ./terraform.tfplan | jq >"$name".tfplan.json terraform graph >"$name".tfplan.dot diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tf b/provisioner/terraform/testdata/instance-id/instance-id.tf index 802f7e0faf02f..c785b61cea5b9 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tf +++ b/provisioner/terraform/testdata/instance-id/instance-id.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json b/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json index 09103f4cbcb50..6a1f48a06fc1e 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json +++ b/provisioner/terraform/testdata/instance-id/instance-id.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -126,7 +126,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "null": { "name": "null", diff --git a/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json b/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json index 738ccafaa83a7..24c7fdcc3ee70 100644 --- a/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json +++ b/provisioner/terraform/testdata/instance-id/instance-id.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "google-instance-identity", "dir": null, "env": null, - "id": "0c214e55-a886-4b2b-a3b5-a3eaf55be2f4", + "id": "9112719f-1e11-41d0-8baf-7f92e94fb510", "init_script": "", "os": "linux", "startup_script": null, - "token": "afeac870-ff84-4bd9-952b-0325f8e4266a" + "token": "8d556c96-9010-4ae9-8993-69c01de97d24" }, "sensitive_values": {} }, @@ -32,8 +32,8 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "0c214e55-a886-4b2b-a3b5-a3eaf55be2f4", - "id": "e48f98eb-6d1a-4fe9-8526-3ad92ac54dc9", + "agent_id": "9112719f-1e11-41d0-8baf-7f92e94fb510", + "id": "35efb5bc-da00-45e8-b38c-df4899417842", "instance_id": "example" }, "sensitive_values": {}, @@ -49,7 +49,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "565648463520883027", + "id": "6105197068461821872", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf index 820708859a0af..2b99c01530b56 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json index 5612095570dce..5b2c6f0788a70 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -182,7 +182,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "null": { "name": "null", diff --git a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json index ed62f4c2b2076..4a55acc1c73f8 100644 --- a/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json +++ b/provisioner/terraform/testdata/multiple-agents/multiple-agents.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "7a5de656-7e69-4cb2-9ae1-8bed34e62f13", + "id": "0a714220-de27-4721-a6ab-d5c21c8e99b8", "init_script": "", "os": "linux", "startup_script": null, - "token": "03d9d621-c589-4b89-8bc1-07acb60c4c4d" + "token": "d241aebd-6d75-4c06-a02e-74b41607345c" }, "sensitive_values": {} }, @@ -36,11 +36,11 @@ "auth": "token", "dir": null, "env": null, - "id": "8dadb875-f4af-4827-b701-5e22815cbd72", + "id": "27567c6b-c52a-4c01-a6ad-368fddb36c9a", "init_script": "", "os": "darwin", "startup_script": null, - "token": "b431714b-b2e9-45d7-969f-bf93f5cc0dab" + "token": "eb5f4e5e-eb57-434c-a444-274b811afa30" }, "sensitive_values": {} }, @@ -56,11 +56,11 @@ "auth": "token", "dir": null, "env": null, - "id": "7947e78a-70b6-4fed-aa0e-5b262cf531dc", + "id": "b689c633-e666-43e1-ac77-9522f187a098", "init_script": "", "os": "windows", "startup_script": null, - "token": "93b837fb-0676-4d52-a343-b6668adeb733" + "token": "90a9c42e-df1f-4656-ac4c-c7f4ab06a269" }, "sensitive_values": {} }, @@ -72,7 +72,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "2338175068284005953", + "id": "7866048965316331550", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf index 569ae3321429c..aec64fda3f288 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.2" + version = "0.4.10" } } } diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json index d688e25c62ec6..6dd8ddca4a8bb 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -176,7 +176,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.2" + "version_constraint": "0.4.10" }, "null": { "name": "null", diff --git a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json index 7db65b609050c..5c4eb5baf442f 100644 --- a/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json +++ b/provisioner/terraform/testdata/multiple-apps/multiple-apps.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.5", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "7ad4fa50-dc01-49dc-ac83-8ad5740aa0cb", + "id": "04d74496-49a6-4757-b1b2-47e21840067e", "init_script": "", "os": "linux", "startup_script": null, - "token": "eafde061-9020-409c-b258-bde0a8d05075" + "token": "1417b29e-da8c-45fb-998d-fbec32069e8d" }, "sensitive_values": {} }, @@ -32,10 +32,10 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "7ad4fa50-dc01-49dc-ac83-8ad5740aa0cb", + "agent_id": "04d74496-49a6-4757-b1b2-47e21840067e", "command": null, "icon": null, - "id": "9cea1631-c146-4996-9e29-7977cfe62a23", + "id": "0a5869ef-00d9-4a37-9f72-e0b2bf0d266b", "name": null, "relative_path": null, "url": null @@ -53,10 +53,10 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "agent_id": "7ad4fa50-dc01-49dc-ac83-8ad5740aa0cb", + "agent_id": "04d74496-49a6-4757-b1b2-47e21840067e", "command": null, "icon": null, - "id": "4d9b0721-3630-4807-b3f6-0114a9ccd938", + "id": "d525e0c1-b494-4911-8b17-8cfb2d248fbf", "name": null, "relative_path": null, "url": null @@ -74,7 +74,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "4241115483797204647", + "id": "5711218402680555438", "triggers": null }, "sensitive_values": {}, diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf index fb5e50719f9f0..4af8b26953b8d 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tf @@ -2,7 +2,7 @@ terraform { required_providers { coder = { source = "coder/coder" - version = "0.4.4" + version = "0.4.10" } } } @@ -16,6 +16,7 @@ resource "null_resource" "about" {} resource "coder_metadata" "about_info" { resource_id = null_resource.about.id + hide = true item { key = "hello" value = "world" diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json index da3c773f66a1e..65052d5074ca2 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfplan.json @@ -1,6 +1,6 @@ { "format_version": "1.1", - "terraform_version": "1.2.6", + "terraform_version": "1.2.8", "planned_values": { "root_module": { "resources": [ @@ -29,6 +29,7 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { + "hide": true, "item": [ { "key": "hello", @@ -117,6 +118,7 @@ ], "before": null, "after": { + "hide": true, "item": [ { "key": "hello", @@ -196,7 +198,7 @@ "coder": { "name": "coder", "full_name": "registry.terraform.io/coder/coder", - "version_constraint": "0.4.4" + "version_constraint": "0.4.10" }, "null": { "name": "null", @@ -228,6 +230,9 @@ "name": "about_info", "provider_config_key": "coder", "expressions": { + "hide": { + "constant_value": true + }, "item": [ { "key": { diff --git a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json index be27e5b562eb1..1a56c51f53d9b 100644 --- a/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json +++ b/provisioner/terraform/testdata/resource-metadata/resource-metadata.tfstate.json @@ -1,6 +1,6 @@ { "format_version": "1.0", - "terraform_version": "1.2.6", + "terraform_version": "1.2.8", "values": { "root_module": { "resources": [ @@ -16,11 +16,11 @@ "auth": "token", "dir": null, "env": null, - "id": "33d1fa51-2987-43da-8f07-53131af520f2", + "id": "bf761056-4c83-4f36-98e9-fb15c4f3818f", "init_script": "", "os": "linux", "startup_script": null, - "token": "5acee40a-6f4f-4e38-92a8-98b057d4945f" + "token": "fcc945d1-ad27-47e5-9c31-aeb4ffd2dd67" }, "sensitive_values": {} }, @@ -32,7 +32,8 @@ "provider_name": "registry.terraform.io/coder/coder", "schema_version": 0, "values": { - "id": "5b828eb0-938f-4fba-8599-701dce975627", + "hide": true, + "id": "6f981e35-73a3-4478-8227-fed4643afd71", "item": [ { "is_null": false, @@ -59,7 +60,7 @@ "value": "squirrel" } ], - "resource_id": "6511007151682544728" + "resource_id": "3184975245680216434" }, "sensitive_values": { "item": [ @@ -81,7 +82,7 @@ "provider_name": "registry.terraform.io/hashicorp/null", "schema_version": 0, "values": { - "id": "6511007151682544728", + "id": "3184975245680216434", "triggers": null }, "sensitive_values": {} From c9bb3db87327582629040191c7346ebf04e51794 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 9 Sep 2022 17:47:12 +0000 Subject: [PATCH 09/11] Fix linting error --- provisioner/terraform/resources.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index aded1a0516b9c..adcd3d77b912d 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -384,8 +384,9 @@ func applyAutomaticInstanceID(resource *tfjson.StateResource, agents []*proto.Ag } } -// findResourcesUpGraph traverses upwards in a graph until a resource is found, +// findResourcesInGraph traverses directionally in a graph until a resource is found, // then it stores the depth it was found at, and continues working up the tree. +// nolint:revive func findResourcesInGraph(graph *gographviz.Graph, tfResourceByLabel map[string]*tfjson.StateResource, nodeName string, currentDepth uint, up bool) []*graphResource { graphResources := make([]*graphResource, 0) mapping := graph.Edges.DstToSrcs From 6f58f0084e6a16ac6226009acbc1e1bf49a0c53f Mon Sep 17 00:00:00 2001 From: Bruno Quaresma Date: Fri, 9 Sep 2022 19:09:42 +0000 Subject: [PATCH 10/11] Improve button verbiage --- site/src/components/Resources/Resources.tsx | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/site/src/components/Resources/Resources.tsx b/site/src/components/Resources/Resources.tsx index 6a93c80e56b4d..21a9459cc764f 100644 --- a/site/src/components/Resources/Resources.tsx +++ b/site/src/components/Resources/Resources.tsx @@ -193,8 +193,15 @@ export const Resources: FC> = ({ size="small" onClick={() => setShouldDisplayHideResources((v) => !v)} > - Show hidden resources{" "} - {shouldDisplayHideResources ? : } + {shouldDisplayHideResources ? ( + <> + Hide resources + + ) : ( + <> + Show hidden resources + + )} )} From a25bbb7b3d03470f1bf142d22833d47aa1ce19e8 Mon Sep 17 00:00:00 2001 From: Kyle Carberry Date: Fri, 9 Sep 2022 19:17:08 +0000 Subject: [PATCH 11/11] Fix linting error --- provisioner/terraform/resources.go | 1 + 1 file changed, 1 insertion(+) diff --git a/provisioner/terraform/resources.go b/provisioner/terraform/resources.go index adcd3d77b912d..d6c68b0fdefa7 100644 --- a/provisioner/terraform/resources.go +++ b/provisioner/terraform/resources.go @@ -49,6 +49,7 @@ type metadataItem struct { // ConvertResources consumes Terraform state and a GraphViz representation produced by // `terraform graph` to produce resources consumable by Coder. +// nolint:gocyclo func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Resource, error) { parsedGraph, err := gographviz.ParseString(rawGraph) if err != nil {