feat: add new required slug property to coder_app, use in URLs (#4573)

This commit is contained in:
Dean Sheather
2022-10-28 17:41:31 +00:00
committed by GitHub
parent 90f77a3415
commit 10df2fd4fb
75 changed files with 852 additions and 460 deletions
+15
View File
@@ -0,0 +1,15 @@
package provisioner
import "regexp"
var (
// AppSlugRegex is the regex used to validate the slug of a coder_app
// resource. It must be a valid hostname and cannot contain two consecutive
// hyphens or start/end with a hyphen.
//
// This regex is duplicated in the terraform provider code, so make sure to
// update it there as well.
//
// There are test cases for this regex in appslug_test.go.
AppSlugRegex = regexp.MustCompile(`^[a-z0-9](-?[a-z0-9])*$`)
)
+64
View File
@@ -0,0 +1,64 @@
package provisioner_test
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/coder/coder/provisioner"
)
func TestValidAppSlugRegex(t *testing.T) {
t.Parallel()
t.Run("Valid", func(t *testing.T) {
t.Parallel()
validStrings := []string{
"a",
"1",
"a1",
"1a",
"1a1",
"1-1",
"a-a",
"ab-cd",
"ab-cd-ef",
"abc-123",
"a-123",
"abc-1",
"ab-c",
"a-bc",
}
for _, s := range validStrings {
require.True(t, provisioner.AppSlugRegex.MatchString(s), s)
}
})
t.Run("Invalid", func(t *testing.T) {
t.Parallel()
invalidStrings := []string{
"",
"-",
"-abc",
"abc-",
"ab--cd",
"a--bc",
"ab--c",
"_",
"ab_cd",
"_abc",
"abc_",
" ",
"abc ",
" abc",
"ab cd",
}
for _, s := range invalidStrings {
require.False(t, provisioner.AppSlugRegex.MatchString(s), s)
}
})
}
+33 -5
View File
@@ -8,6 +8,7 @@ import (
"github.com/mitchellh/mapstructure"
"golang.org/x/xerrors"
"github.com/coder/coder/provisioner"
"github.com/coder/coder/provisionersdk/proto"
)
@@ -25,7 +26,12 @@ type agentAttributes struct {
// A mapping of attributes on the "coder_app" resource.
type agentAppAttributes struct {
AgentID string `mapstructure:"agent_id"`
AgentID string `mapstructure:"agent_id"`
// Slug is required in terraform, but to avoid breaking existing users we
// will default to the resource name if it is not specified.
Slug string `mapstructure:"slug"`
DisplayName string `mapstructure:"display_name"`
// Name is deprecated in favor of DisplayName.
Name string `mapstructure:"name"`
Icon string `mapstructure:"icon"`
URL string `mapstructure:"url"`
@@ -214,19 +220,40 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res
}
// Associate Apps with agents.
appSlugs := make(map[string]struct{})
for _, resource := range tfResourceByLabel {
if resource.Type != "coder_app" {
continue
}
var attrs agentAppAttributes
err = mapstructure.Decode(resource.AttributeValues, &attrs)
if err != nil {
return nil, xerrors.Errorf("decode app attributes: %w", err)
}
if attrs.Name == "" {
// Default to the resource name if none is set!
attrs.Name = resource.Name
// Default to the resource name if none is set!
if attrs.Slug == "" {
attrs.Slug = resource.Name
}
if attrs.DisplayName == "" {
if attrs.Name != "" {
// Name is deprecated but still accepted.
attrs.DisplayName = attrs.Name
} else {
attrs.DisplayName = attrs.Slug
}
}
if !provisioner.AppSlugRegex.MatchString(attrs.Slug) {
return nil, xerrors.Errorf("invalid app slug %q, please update your coder/coder provider to the latest version and specify the slug property on each coder_app", attrs.Slug)
}
if _, exists := appSlugs[attrs.Slug]; exists {
return nil, xerrors.Errorf("duplicate app slug, they must be unique per template: %q", attrs.Slug)
}
appSlugs[attrs.Slug] = struct{}{}
var healthcheck *proto.Healthcheck
if len(attrs.Healthcheck) != 0 {
healthcheck = &proto.Healthcheck{
@@ -253,7 +280,8 @@ func ConvertResources(module *tfjson.StateModule, rawGraph string) ([]*proto.Res
continue
}
agent.Apps = append(agent.Apps, &proto.App{
Name: attrs.Name,
Slug: attrs.Slug,
DisplayName: attrs.DisplayName,
Command: attrs.Command,
Url: attrs.URL,
Icon: attrs.Icon,
+76 -12
View File
@@ -110,13 +110,15 @@ func TestConvertResources(t *testing.T) {
Architecture: "amd64",
Apps: []*proto.App{
{
Name: "app1",
Slug: "app1",
DisplayName: "app1",
// Subdomain defaults to false if unspecified.
Subdomain: false,
},
{
Name: "app2",
Subdomain: true,
Slug: "app2",
DisplayName: "app2",
Subdomain: true,
Healthcheck: &proto.Healthcheck{
Url: "http://localhost:13337/healthz",
Interval: 5,
@@ -124,8 +126,9 @@ func TestConvertResources(t *testing.T) {
},
},
{
Name: "app3",
Subdomain: false,
Slug: "app3",
DisplayName: "app3",
Subdomain: false,
},
},
Auth: &proto.Agent_Token{},
@@ -182,12 +185,23 @@ func TestConvertResources(t *testing.T) {
expectedNoMetadata = append(expectedNoMetadata, resourceCopy)
}
resourcesWant, err := json.Marshal(expectedNoMetadata)
// Convert expectedNoMetadata and resources into a
// []map[string]interface{} so they can be compared easily.
data, err := json.Marshal(expectedNoMetadata)
require.NoError(t, err)
resourcesGot, err := json.Marshal(resources)
var expectedNoMetadataMap []map[string]interface{}
err = json.Unmarshal(data, &expectedNoMetadataMap)
require.NoError(t, err)
require.Equal(t, string(resourcesWant), string(resourcesGot))
data, err = json.Marshal(resources)
require.NoError(t, err)
var resourcesMap []map[string]interface{}
err = json.Unmarshal(data, &resourcesMap)
require.NoError(t, err)
require.Equal(t, expectedNoMetadataMap, resourcesMap)
})
t.Run("Provision", func(t *testing.T) {
t.Parallel()
tfStateRaw, err := os.ReadFile(filepath.Join(dir, folderName+".tfstate.json"))
@@ -212,17 +226,67 @@ func TestConvertResources(t *testing.T) {
}
}
}
resourcesWant, err := json.Marshal(expected)
// Convert expectedNoMetadata and resources into a
// []map[string]interface{} so they can be compared easily.
data, err := json.Marshal(expected)
require.NoError(t, err)
resourcesGot, err := json.Marshal(resources)
var expectedMap []map[string]interface{}
err = json.Unmarshal(data, &expectedMap)
require.NoError(t, err)
require.Equal(t, string(resourcesWant), string(resourcesGot))
data, err = json.Marshal(resources)
require.NoError(t, err)
var resourcesMap []map[string]interface{}
err = json.Unmarshal(data, &resourcesMap)
require.NoError(t, err)
require.Equal(t, expectedMap, resourcesMap)
})
})
}
}
func TestAppSlugValidation(t *testing.T) {
t.Parallel()
// nolint:dogsled
_, filename, _, _ := runtime.Caller(0)
// Load the multiple-apps state file and edit it.
dir := filepath.Join(filepath.Dir(filename), "testdata", "multiple-apps")
tfPlanRaw, err := os.ReadFile(filepath.Join(dir, "multiple-apps.tfplan.json"))
require.NoError(t, err)
var tfPlan tfjson.Plan
err = json.Unmarshal(tfPlanRaw, &tfPlan)
require.NoError(t, err)
tfPlanGraph, err := os.ReadFile(filepath.Join(dir, "multiple-apps.tfplan.dot"))
require.NoError(t, err)
// Change all slugs to be invalid.
for _, resource := range tfPlan.PlannedValues.RootModule.Resources {
if resource.Type == "coder_app" {
resource.AttributeValues["slug"] = "$$$ invalid slug $$$"
}
}
resources, err := terraform.ConvertResources(tfPlan.PlannedValues.RootModule, string(tfPlanGraph))
require.Nil(t, resources)
require.Error(t, err)
require.ErrorContains(t, err, "invalid app slug")
// Change all slugs to be identical and valid.
for _, resource := range tfPlan.PlannedValues.RootModule.Resources {
if resource.Type == "coder_app" {
resource.AttributeValues["slug"] = "valid"
}
}
resources, err = terraform.ConvertResources(tfPlan.PlannedValues.RootModule, string(tfPlanGraph))
require.Nil(t, resources)
require.Error(t, err)
require.ErrorContains(t, err, "duplicate app slug")
}
func TestInstanceIDAssociation(t *testing.T) {
t.Parallel()
type tc struct {
@@ -304,7 +368,7 @@ func sortResources(resources []*proto.Resource) {
for _, resource := range resources {
for _, agent := range resource.Agents {
sort.Slice(agent.Apps, func(i, j int) bool {
return agent.Apps[i].Name < agent.Apps[j].Name
return agent.Apps[i].Slug < agent.Apps[j].Slug
})
}
sort.Slice(resource.Agents, func(i, j int) bool {
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
+23 -8
View File
@@ -66,7 +66,9 @@
"name": "main",
"provider_name": "registry.terraform.io/coder/coder",
"change": {
"actions": ["create"],
"actions": [
"create"
],
"before": null,
"after": {
"arch": "amd64",
@@ -95,7 +97,9 @@
"name": "script",
"provider_name": "registry.terraform.io/hashicorp/null",
"change": {
"actions": ["read"],
"actions": [
"read"
],
"before": null,
"after": {
"inputs": {}
@@ -125,7 +129,9 @@
"name": "example",
"provider_name": "registry.terraform.io/hashicorp/null",
"change": {
"actions": ["create"],
"actions": [
"create"
],
"before": null,
"after": {
"triggers": null
@@ -143,7 +149,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"module.module:null": {
"name": "null",
@@ -175,7 +181,10 @@
"source": "./module",
"expressions": {
"script": {
"references": ["coder_agent.main.init_script", "coder_agent.main"]
"references": [
"coder_agent.main.init_script",
"coder_agent.main"
]
}
},
"module": {
@@ -187,7 +196,9 @@
"name": "example",
"provider_config_key": "module.module:null",
"schema_version": 0,
"depends_on": ["data.null_data_source.script"]
"depends_on": [
"data.null_data_source.script"
]
},
{
"address": "data.null_data_source.script",
@@ -197,7 +208,9 @@
"provider_config_key": "module.module:null",
"expressions": {
"inputs": {
"references": ["var.script"]
"references": [
"var.script"
]
}
},
"schema_version": 0
@@ -214,7 +227,9 @@
"relevant_attributes": [
{
"resource": "coder_agent.main",
"attribute": ["init_script"]
"attribute": [
"init_script"
]
}
]
}
+4 -4
View File
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "b92bd0ce-d854-47af-a2f6-4941cd5dbd27",
"id": "8a08d6a8-2ae8-4af3-b385-9d7c9230c3d3",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "3f1b6b3f-7ea9-4944-bef4-8be9b78db8ae"
"token": "e5397170-34e8-4f59-9b3d-85d11203aba1"
},
"sensitive_values": {}
}
@@ -44,7 +44,7 @@
"outputs": {
"script": ""
},
"random": "5257014674084238393"
"random": "4606778210381604065"
},
"sensitive_values": {
"inputs": {},
@@ -59,7 +59,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "6805057619323391144",
"id": "8484494817832091886",
"triggers": null
},
"sensitive_values": {},
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
@@ -121,7 +121,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "d8de89cb-bb6b-4f4f-80f8-e5d39e8c5f62",
"id": "8c46ed09-5988-47fe-8f1b-2afe4ec0b35a",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "4e877d5c-95c4-4365-b9a1-856348b54f43"
"token": "af26634c-4fa8-4b60-aff4-736d43457b35"
},
"sensitive_values": {}
},
@@ -32,7 +32,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "2870641260310442024",
"id": "1333327345487383126",
"triggers": null
},
"sensitive_values": {},
@@ -46,7 +46,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "7093709823890756895",
"id": "1306294717300675697",
"triggers": null
},
"sensitive_values": {},
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
@@ -121,7 +121,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "5c00c97c-7291-47b7-96cf-3ac7d7588a99",
"id": "3621f0c7-090a-4610-8fd0-bdcf835225bd",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "a1939d12-8b8a-414b-b745-3fac020e51c0"
"token": "4cb0ef71-0161-4a1a-b8f1-b9d81f53d658"
},
"sensitive_values": {}
},
@@ -32,7 +32,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "8930370582092686733",
"id": "3108014752132131382",
"triggers": null
},
"sensitive_values": {},
@@ -46,7 +46,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "8209925920170986769",
"id": "8356243415524842498",
"triggers": null
},
"sensitive_values": {},
+1 -1
View File
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
+1 -1
View File
@@ -122,7 +122,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
+5 -5
View File
@@ -16,11 +16,11 @@
"auth": "google-instance-identity",
"dir": null,
"env": null,
"id": "248ed639-3dbe-479e-909a-37d5d226529f",
"id": "1156666a-c202-4c54-9831-6b62dbf665fe",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "8bee2595-095f-4965-ade2-deef475023d6"
"token": "80a893a4-fcb1-4a3a-824d-74cf5317d307"
},
"sensitive_values": {}
},
@@ -32,8 +32,8 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "248ed639-3dbe-479e-909a-37d5d226529f",
"id": "edbfac7a-a88d-433a-ab7c-be3816656477",
"agent_id": "1156666a-c202-4c54-9831-6b62dbf665fe",
"id": "ec6451f5-fea2-4d6f-aedc-822b93723abd",
"instance_id": "example"
},
"sensitive_values": {},
@@ -47,7 +47,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "5674804341417746589",
"id": "5076117657273396114",
"triggers": null
},
"sensitive_values": {},
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
@@ -180,7 +180,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "882ce97a-3c12-410f-8916-e3bc03862162",
"id": "dc6b52bf-7bcb-4657-9c11-2859d8721ba9",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "b24ba29b-8cb3-42da-91c5-599c7be310f7"
"token": "85317d35-1e92-4565-850e-8ee17bf86992"
},
"sensitive_values": {}
},
@@ -36,11 +36,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "8a26cec7-3189-4eaf-99a1-1dce00b756dc",
"id": "a709bb80-b4df-4d4a-9cc3-4bedd009b44f",
"init_script": "",
"os": "darwin",
"startup_script": null,
"token": "6a155e3b-3279-40cb-9c16-4b827b561bc1"
"token": "a4b37df4-dbdd-494b-9434-92abaa88c23b"
},
"sensitive_values": {}
},
@@ -56,11 +56,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "57486477-64a5-4fea-8223-dbf3c259d710",
"id": "e429fb2c-1d4a-4c7c-9747-f495e5611c9e",
"init_script": "",
"os": "windows",
"startup_script": null,
"token": "0fa9933e-802a-4d6a-b273-43c05993e52a"
"token": "27009ab7-ec2e-476c-9193-177eeea0766c"
},
"sensitive_values": {}
},
@@ -72,7 +72,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "8587500025119121667",
"id": "4682926564646626748",
"triggers": null
},
"sensitive_values": {},
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
@@ -15,6 +15,7 @@ resource "coder_agent" "dev1" {
# app1 is for testing subdomain default.
resource "coder_app" "app1" {
agent_id = coder_agent.dev1.id
slug = "app1"
# subdomain should default to false.
# subdomain = false
}
@@ -22,6 +23,7 @@ resource "coder_app" "app1" {
# app2 tests that subdomaincan be true, and that healthchecks work.
resource "coder_app" "app2" {
agent_id = coder_agent.dev1.id
slug = "app2"
subdomain = true
healthcheck {
url = "http://localhost:13337/healthz"
@@ -33,6 +35,7 @@ resource "coder_app" "app2" {
# app3 tests that subdomain can explicitly be false.
resource "coder_app" "app3" {
agent_id = coder_agent.dev1.id
slug = "app3"
subdomain = false
}
+28 -1
View File
@@ -30,10 +30,13 @@
"schema_version": 0,
"values": {
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
@@ -50,6 +53,7 @@
"schema_version": 0,
"values": {
"command": null,
"display_name": null,
"healthcheck": [
{
"interval": 5,
@@ -60,6 +64,8 @@
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": true,
"url": null
},
@@ -76,10 +82,13 @@
"schema_version": 0,
"values": {
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app3",
"subdomain": false,
"url": null
},
@@ -142,10 +151,13 @@
"before": null,
"after": {
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
@@ -171,6 +183,7 @@
"before": null,
"after": {
"command": null,
"display_name": null,
"healthcheck": [
{
"interval": 5,
@@ -181,6 +194,8 @@
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": true,
"url": null
},
@@ -206,10 +221,13 @@
"before": null,
"after": {
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app3",
"subdomain": false,
"url": null
},
@@ -249,7 +267,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
@@ -283,6 +301,9 @@
"expressions": {
"agent_id": {
"references": ["coder_agent.dev1.id", "coder_agent.dev1"]
},
"slug": {
"constant_value": "app1"
}
},
"schema_version": 0
@@ -310,6 +331,9 @@
}
}
],
"slug": {
"constant_value": "app2"
},
"subdomain": {
"constant_value": true
}
@@ -326,6 +350,9 @@
"agent_id": {
"references": ["coder_agent.dev1.id", "coder_agent.dev1"]
},
"slug": {
"constant_value": "app3"
},
"subdomain": {
"constant_value": false
}
+18 -9
View File
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "ecf210c8-aaa7-4a14-9b44-2a5f805f0126",
"id": "4fa379bd-8aa9-48f2-9868-2da104013c3c",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "7e748146-cea2-45cb-927d-b4a90b0021b3"
"token": "4eb813cb-8f29-454c-91d9-b430d76d7fcd"
},
"sensitive_values": {}
},
@@ -32,13 +32,16 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "ecf210c8-aaa7-4a14-9b44-2a5f805f0126",
"agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c",
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"id": "95667002-bd60-4d2c-9313-0666f66c44ff",
"id": "f303f406-b9ea-4253-935e-f80f7be54a97",
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app1",
"subdomain": null,
"url": null
},
@@ -55,8 +58,9 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "ecf210c8-aaa7-4a14-9b44-2a5f805f0126",
"agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c",
"command": null,
"display_name": null,
"healthcheck": [
{
"interval": 5,
@@ -65,9 +69,11 @@
}
],
"icon": null,
"id": "817c6904-69e1-485f-a057-4ddac83a9c5a",
"id": "7086ae57-501d-4b39-bfaf-d30b83f753d4",
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app2",
"subdomain": true,
"url": null
},
@@ -84,13 +90,16 @@
"provider_name": "registry.terraform.io/coder/coder",
"schema_version": 0,
"values": {
"agent_id": "ecf210c8-aaa7-4a14-9b44-2a5f805f0126",
"agent_id": "4fa379bd-8aa9-48f2-9868-2da104013c3c",
"command": null,
"display_name": null,
"healthcheck": [],
"icon": null,
"id": "c4a502b3-cc82-4fdf-952b-4b429e711798",
"id": "e4b1f16b-2b8d-4278-abec-1f876f8a6aba",
"name": null,
"relative_path": null,
"share": "owner",
"slug": "app3",
"subdomain": false,
"url": null
},
@@ -107,7 +116,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "1281108380136021489",
"id": "7676198272426781226",
"triggers": null
},
"sensitive_values": {},
@@ -2,7 +2,7 @@ terraform {
required_providers {
coder = {
source = "coder/coder"
version = "0.5.3"
version = "0.6.0"
}
}
}
@@ -186,7 +186,7 @@
"coder": {
"name": "coder",
"full_name": "registry.terraform.io/coder/coder",
"version_constraint": "0.5.0"
"version_constraint": "0.6.0"
},
"null": {
"name": "null",
@@ -16,11 +16,11 @@
"auth": "token",
"dir": null,
"env": null,
"id": "0bfa269a-e373-4fbc-929a-07b8ed0f3477",
"id": "a7e62a9d-ef94-4abc-8bd5-e0555eae4aaf",
"init_script": "",
"os": "linux",
"startup_script": null,
"token": "4bc54f84-7d97-492a-ad98-40ae7dfbb300"
"token": "812935fe-858a-4ff5-b890-6c8eea6a3764"
},
"sensitive_values": {}
},
@@ -34,7 +34,7 @@
"values": {
"hide": true,
"icon": "/icon/server.svg",
"id": "2ee6d253-dec1-4336-95ba-bd5e93cf4c84",
"id": "5e954683-7a6d-47f4-bc82-5831c0ea2120",
"item": [
{
"is_null": false,
@@ -61,7 +61,7 @@
"value": "squirrel"
}
],
"resource_id": "3043919679469754967"
"resource_id": "288893601116381968"
},
"sensitive_values": {
"item": [{}, {}, {}, {}]
@@ -76,7 +76,7 @@
"provider_name": "registry.terraform.io/hashicorp/null",
"schema_version": 0,
"values": {
"id": "3043919679469754967",
"id": "288893601116381968",
"triggers": null
},
"sensitive_values": {}