Skip to content

Commit c474eba

Browse files
authored
feat: add slug to app, rename name to display_name (#68)
1 parent bcd1524 commit c474eba

File tree

4 files changed

+95
-41
lines changed

4 files changed

+95
-41
lines changed

Diff for: docs/resources/app.md

+20-15
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,13 @@ EOF
2626
}
2727
2828
resource "coder_app" "code-server" {
29-
agent_id = coder_agent.dev.id
30-
name = "VS Code"
31-
icon = data.coder_workspace.me.access_url + "/icons/vscode.svg"
32-
url = "http://localhost:13337"
33-
share = "owner"
34-
subdomain = false
29+
agent_id = coder_agent.dev.id
30+
slug = "code-server"
31+
display_name = "VS Code"
32+
icon = data.coder_workspace.me.access_url + "/icons/vscode.svg"
33+
url = "http://localhost:13337"
34+
share = "owner"
35+
subdomain = false
3536
healthcheck {
3637
url = "http://localhost:13337/healthz"
3738
interval = 5
@@ -40,17 +41,19 @@ resource "coder_app" "code-server" {
4041
}
4142
4243
resource "coder_app" "vim" {
43-
agent_id = coder_agent.dev.id
44-
name = "Vim"
45-
icon = "${data.coder_workspace.me.access_url}/icon/vim.svg"
46-
command = "vim"
44+
agent_id = coder_agent.dev.id
45+
slug = "vim"
46+
display_name = "Vim"
47+
icon = "${data.coder_workspace.me.access_url}/icon/vim.svg"
48+
command = "vim"
4749
}
4850
4951
resource "coder_app" "intellij" {
50-
agent_id = coder_agent.dev.id
51-
icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg"
52-
name = "JetBrains IntelliJ"
53-
command = "projector run"
52+
agent_id = coder_agent.dev.id
53+
icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg"
54+
slug = "intellij"
55+
display_name = "JetBrains IntelliJ"
56+
command = "projector run"
5457
}
5558
```
5659

@@ -60,13 +63,15 @@ resource "coder_app" "intellij" {
6063
### Required
6164

6265
- `agent_id` (String) The "id" property of a "coder_agent" resource to associate with.
66+
- `slug` (String) A hostname-friendly name for the app. This is used in URLs to access the app. May contain alphanumerics and hyphens. Cannot start/end with a hyphen or contain two consecutive hyphens.
6367

6468
### Optional
6569

6670
- `command` (String) A command to run in a terminal opening this app. In the web, this will open in a new tab. In the CLI, this will SSH and execute the command. Either "command" or "url" may be specified, but not both.
71+
- `display_name` (String) A display name to identify the app. Defaults to the slug.
6772
- `healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see [below for nested schema](#nestedblock--healthcheck))
6873
- `icon` (String) A URL to an icon that will display in the dashboard. View built-in icons here: https://github.com/coder/coder/tree/main/site/static/icons. Use a built-in icon with `data.coder_workspace.me.access_url + "/icons/<path>"`.
69-
- `name` (String) A display name to identify the app.
74+
- `name` (String, Deprecated) A display name to identify the app.
7075
- `relative_path` (Boolean, Deprecated) Specifies whether the URL will be accessed via a relative path or wildcard. Use if wildcard routing is unavailable. Defaults to true.
7176
- `share` (String) Determines the "level" which the application is shared at. Valid levels are "owner" (default), "authenticated" and "public". Level "owner" disables sharing on the app, so only the workspace owner can access it. Level "authenticated" shares the app with all authenticated users. Level "public" shares it with any user, including unauthenticated users. Permitted application sharing levels can be configured site-wide via a flag on `coder server` (Enterprise only).
7277
- `subdomain` (Boolean) Determines whether the app will be accessed via it's own subdomain or whether it will be accessed via a path on Coder. If wildcards have not been setup by the administrator then apps with "subdomain" set to true will not be accessible. Defaults to false.

Diff for: examples/resources/coder_app/resource.tf

+17-14
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ EOF
1111
}
1212

1313
resource "coder_app" "code-server" {
14-
agent_id = coder_agent.dev.id
15-
name = "VS Code"
16-
icon = data.coder_workspace.me.access_url + "/icons/vscode.svg"
17-
url = "http://localhost:13337"
18-
share = "owner"
19-
subdomain = false
14+
agent_id = coder_agent.dev.id
15+
slug = "code-server"
16+
display_name = "VS Code"
17+
icon = data.coder_workspace.me.access_url + "/icons/vscode.svg"
18+
url = "http://localhost:13337"
19+
share = "owner"
20+
subdomain = false
2021
healthcheck {
2122
url = "http://localhost:13337/healthz"
2223
interval = 5
@@ -25,15 +26,17 @@ resource "coder_app" "code-server" {
2526
}
2627

2728
resource "coder_app" "vim" {
28-
agent_id = coder_agent.dev.id
29-
name = "Vim"
30-
icon = "${data.coder_workspace.me.access_url}/icon/vim.svg"
31-
command = "vim"
29+
agent_id = coder_agent.dev.id
30+
slug = "vim"
31+
display_name = "Vim"
32+
icon = "${data.coder_workspace.me.access_url}/icon/vim.svg"
33+
command = "vim"
3234
}
3335

3436
resource "coder_app" "intellij" {
35-
agent_id = coder_agent.dev.id
36-
icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg"
37-
name = "JetBrains IntelliJ"
38-
command = "projector run"
37+
agent_id = coder_agent.dev.id
38+
icon = "${data.coder_workspace.me.access_url}/icon/intellij.svg"
39+
slug = "intellij"
40+
display_name = "JetBrains IntelliJ"
41+
command = "projector run"
3942
}

Diff for: provider/app.go

+52-9
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@ package provider
33
import (
44
"context"
55
"net/url"
6+
"regexp"
67

78
"github.com/google/uuid"
89
"github.com/hashicorp/go-cty/cty"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
)
1213

14+
var (
15+
// appSlugRegex is the regex used to validate the slug of a coder_app
16+
// resource. It must be a valid hostname and cannot contain two consecutive
17+
// hyphens or start/end with a hyphen.
18+
//
19+
// This regex is duplicated in the Coder source code, so make sure to update
20+
// it there as well.
21+
//
22+
// There are test cases for this regex in the Coder product.
23+
appSlugRegex = regexp.MustCompile(`^[a-z0-9](-?[a-z0-9])*$`)
24+
)
25+
1326
func appResource() *schema.Resource {
1427
return &schema.Resource{
1528
Description: "Use this resource to define shortcuts to access applications in a workspace.",
@@ -54,19 +67,40 @@ func appResource() *schema.Resource {
5467
return nil, nil
5568
},
5669
},
57-
"name": {
70+
"slug": {
71+
Type: schema.TypeString,
72+
Description: "A hostname-friendly name for the app. This is " +
73+
"used in URLs to access the app. May contain " +
74+
"alphanumerics and hyphens. Cannot start/end with a " +
75+
"hyphen or contain two consecutive hyphens.",
76+
ForceNew: true,
77+
Required: true,
78+
ValidateDiagFunc: func(val interface{}, c cty.Path) diag.Diagnostics {
79+
valStr, ok := val.(string)
80+
if !ok {
81+
return diag.Errorf("expected string, got %T", val)
82+
}
83+
84+
if !appSlugRegex.MatchString(valStr) {
85+
return diag.Errorf("invalid coder_app slug, must be a valid hostname (%q, cannot contain two consecutive hyphens or start/end with a hyphen): %q", appSlugRegex.String(), valStr)
86+
}
87+
88+
return nil
89+
},
90+
},
91+
"display_name": {
5892
Type: schema.TypeString,
59-
Description: "A display name to identify the app.",
93+
Description: "A display name to identify the app. Defaults to the slug.",
6094
ForceNew: true,
6195
Optional: true,
6296
},
63-
"relative_path": {
64-
Type: schema.TypeBool,
65-
Deprecated: "`relative_path` on apps is deprecated, use `subdomain` instead.",
66-
Description: "Specifies whether the URL will be accessed via a relative " +
67-
"path or wildcard. Use if wildcard routing is unavailable. Defaults to true.",
68-
ForceNew: true,
69-
Optional: true,
97+
"name": {
98+
Type: schema.TypeString,
99+
Description: "A display name to identify the app.",
100+
Deprecated: "`name` on apps is deprecated, use `display_name` instead",
101+
ForceNew: true,
102+
Optional: true,
103+
ConflictsWith: []string{"display_name"},
70104
},
71105
"subdomain": {
72106
Type: schema.TypeBool,
@@ -77,6 +111,15 @@ func appResource() *schema.Resource {
77111
ForceNew: true,
78112
Optional: true,
79113
},
114+
"relative_path": {
115+
Type: schema.TypeBool,
116+
Deprecated: "`relative_path` on apps is deprecated, use `subdomain` instead.",
117+
Description: "Specifies whether the URL will be accessed via a relative " +
118+
"path or wildcard. Use if wildcard routing is unavailable. Defaults to true.",
119+
ForceNew: true,
120+
Optional: true,
121+
ConflictsWith: []string{"subdomain"},
122+
},
80123
"share": {
81124
Type: schema.TypeString,
82125
Description: `Determines the "level" which the application ` +

Diff for: provider/app_test.go

+6-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ func TestApp(t *testing.T) {
3333
}
3434
resource "coder_app" "code-server" {
3535
agent_id = coder_agent.dev.id
36-
name = "code-server"
36+
slug = "code-server"
37+
display_name = "code-server"
3738
icon = "builtin:vim"
3839
subdomain = false
3940
url = "http://localhost:13337"
@@ -51,7 +52,8 @@ func TestApp(t *testing.T) {
5152
require.NotNil(t, resource)
5253
for _, key := range []string{
5354
"agent_id",
54-
"name",
55+
"slug",
56+
"display_name",
5557
"icon",
5658
"subdomain",
5759
// Should be set by default even though it isn't
@@ -128,7 +130,8 @@ func TestApp(t *testing.T) {
128130
}
129131
resource "coder_app" "code-server" {
130132
agent_id = coder_agent.dev.id
131-
name = "code-server"
133+
slug = "code-server"
134+
display_name = "code-server"
132135
icon = "builtin:vim"
133136
url = "http://localhost:13337"
134137
%s

0 commit comments

Comments
 (0)