Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd933a71

Browse files
authored
add open_in option to coder_app (#321)
* add open_in option to coder_app* work on tests* add missing example* rename test* lint* generate docs
1 parent8349a69 commitd933a71

File tree

6 files changed

+207
-0
lines changed

6 files changed

+207
-0
lines changed

‎docs/resources/app.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ resource "coder_app" "code-server" {
3333
url = "http://localhost:13337"
3434
share = "owner"
3535
subdomain = false
36+
open_in = "window"
3637
healthcheck {
3738
url = "http://localhost:13337/healthz"
3839
interval = 5
@@ -65,6 +66,7 @@ resource "coder_app" "vim" {
6566
-`healthcheck` (Block Set, Max: 1) HTTP health checking to determine the application readiness. (see[below for nested schema](#nestedblock--healthcheck))
6667
-`hidden` (Boolean) Determines if the app is visible in the UI (minimum Coder version: v2.16).
6768
-`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/icon. Use a built-in icon with`"${data.coder_workspace.me.access_url}/icon/<path>"`.
69+
-`open_in` (String) Determines where the app will be opened. Valid values are`"tab"`,`"window"`, and`"slim-window" (default)`.`"tab"` opens in a new tab in the same browser window.`"window"` opens a fresh browser window with navigation options.`"slim-window"` opens a new browser window without navigation controls.
6870
-`order` (Number) The order determines the position of app in the UI presentation. The lowest order is shown first and apps with equal order are sorted by name (ascending order).
6971
-`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).
7072
-`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`.

‎examples/resources/coder_app/resource.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ resource "coder_app" "code-server" {
1818
url="http://localhost:13337"
1919
share="owner"
2020
subdomain=false
21+
open_in="window"
2122
healthcheck {
2223
url="http://localhost:13337/healthz"
2324
interval=5

‎integration/coder-app-open-in/main.tf

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
terraform {
2+
required_providers {
3+
coder={
4+
source="coder/coder"
5+
}
6+
local={
7+
source="hashicorp/local"
8+
}
9+
}
10+
}
11+
12+
data"coder_workspace""me" {}
13+
14+
resource"coder_agent""dev" {
15+
os="linux"
16+
arch="amd64"
17+
dir="/workspace"
18+
}
19+
20+
resource"coder_app""window" {
21+
agent_id=coder_agent.dev.id
22+
slug="window"
23+
share="owner"
24+
open_in="window"
25+
}
26+
27+
resource"coder_app""slim-window" {
28+
agent_id=coder_agent.dev.id
29+
slug="slim-window"
30+
share="owner"
31+
open_in="slim-window"
32+
}
33+
34+
resource"coder_app""defaulted" {
35+
agent_id=coder_agent.dev.id
36+
slug="defaulted"
37+
share="owner"
38+
}
39+
40+
locals {
41+
# NOTE: these must all be strings in the output
42+
output={
43+
"coder_app.window.open_in"=tostring(coder_app.window.open_in)
44+
"coder_app.slim-window.open_in"=tostring(coder_app.slim-window.open_in)
45+
"coder_app.defaulted.open_in"=tostring(coder_app.defaulted.open_in)
46+
}
47+
}
48+
49+
variable"output_path" {
50+
type=string
51+
}
52+
53+
resource"local_file""output" {
54+
filename=var.output_path
55+
content=jsonencode(local.output)
56+
}
57+
58+
output"output" {
59+
value=local.output
60+
sensitive=true
61+
}
62+

‎integration/integration_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ func TestIntegration(t *testing.T) {
143143
"workspace_owner.login_type":`password`,
144144
},
145145
},
146+
{
147+
name:"coder-app-open-in",
148+
minVersion:"v2.19.0",
149+
expectedOutput:map[string]string{
150+
"coder_app.window.open_in":"window",
151+
"coder_app.slim-window.open_in":"slim-window",
152+
"coder_app.defaulted.open_in":"slim-window",
153+
},
154+
},
146155
{
147156
name:"coder-app-hidden",
148157
minVersion:"v0.0.0",

‎provider/app.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,28 @@ func appResource() *schema.Resource {
223223
ForceNew:true,
224224
Optional:true,
225225
},
226+
"open_in": {
227+
Type:schema.TypeString,
228+
Description:"Determines where the app will be opened. Valid values are `\"tab\"`, `\"window\"`, and `\"slim-window\" (default)`. "+
229+
"`\"tab\"` opens in a new tab in the same browser window. `\"window\"` opens a fresh browser window with navigation options. "+
230+
"`\"slim-window\"` opens a new browser window without navigation controls.",
231+
ForceNew:true,
232+
Optional:true,
233+
Default:"slim-window",
234+
ValidateDiagFunc:func(valinterface{},c cty.Path) diag.Diagnostics {
235+
valStr,ok:=val.(string)
236+
if!ok {
237+
returndiag.Errorf("expected string, got %T",val)
238+
}
239+
240+
switchvalStr {
241+
case"tab","window","slim-window":
242+
returnnil
243+
}
244+
245+
returndiag.Errorf(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": %q`,valStr)
246+
},
247+
},
226248
},
227249
}
228250
}

‎provider/app_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ func TestApp(t *testing.T) {
4242
}
4343
order = 4
4444
hidden = false
45+
open_in = "slim-window"
4546
}
4647
`,
4748
Check:func(state*terraform.State)error {
@@ -64,6 +65,7 @@ func TestApp(t *testing.T) {
6465
"healthcheck.0.threshold",
6566
"order",
6667
"hidden",
68+
"open_in",
6769
} {
6870
value:=resource.Primary.Attributes[key]
6971
t.Logf("%q = %q",key,value)
@@ -98,6 +100,7 @@ func TestApp(t *testing.T) {
98100
display_name = "Testing"
99101
url = "https://google.com"
100102
external = true
103+
open_in = "slim-window"
101104
}
102105
`,
103106
external:true,
@@ -116,6 +119,7 @@ func TestApp(t *testing.T) {
116119
url = "https://google.com"
117120
external = true
118121
subdomain = true
122+
open_in = "slim-window"
119123
}
120124
`,
121125
expectError:regexp.MustCompile("conflicts with subdomain"),
@@ -209,6 +213,7 @@ func TestApp(t *testing.T) {
209213
interval = 5
210214
threshold = 6
211215
}
216+
open_in = "slim-window"
212217
}
213218
`,sharingLine)
214219

@@ -241,13 +246,114 @@ func TestApp(t *testing.T) {
241246
}
242247
})
243248

249+
t.Run("OpenIn",func(t*testing.T) {
250+
t.Parallel()
251+
252+
cases:= []struct {
253+
namestring
254+
valuestring
255+
expectValuestring
256+
expectError*regexp.Regexp
257+
}{
258+
{
259+
name:"default",
260+
value:"",// default
261+
expectValue:"slim-window",
262+
},
263+
{
264+
name:"InvalidValue",
265+
value:"nonsense",
266+
expectError:regexp.MustCompile(`invalid "coder_app" open_in value, must be one of "tab", "window", "slim-window": "nonsense"`),
267+
},
268+
{
269+
name:"ExplicitWindow",
270+
value:"window",
271+
expectValue:"window",
272+
},
273+
{
274+
name:"ExplicitSlimWindow",
275+
value:"slim-window",
276+
expectValue:"slim-window",
277+
},
278+
{
279+
name:"ExplicitTab",
280+
value:"tab",
281+
expectValue:"tab",
282+
},
283+
}
284+
285+
for_,c:=rangecases {
286+
c:=c
287+
288+
t.Run(c.name,func(t*testing.T) {
289+
t.Parallel()
290+
291+
config:=`
292+
provider "coder" {
293+
}
294+
resource "coder_agent" "dev" {
295+
os = "linux"
296+
arch = "amd64"
297+
}
298+
resource "coder_app" "code-server" {
299+
agent_id = coder_agent.dev.id
300+
slug = "code-server"
301+
display_name = "code-server"
302+
icon = "builtin:vim"
303+
url = "http://localhost:13337"
304+
healthcheck {
305+
url = "http://localhost:13337/healthz"
306+
interval = 5
307+
threshold = 6
308+
}`
309+
310+
ifc.value!="" {
311+
config+=fmt.Sprintf(`
312+
open_in = %q
313+
`,c.value)
314+
}
315+
316+
config+=`
317+
}
318+
`
319+
320+
checkFn:=func(state*terraform.State)error {
321+
require.Len(t,state.Modules,1)
322+
require.Len(t,state.Modules[0].Resources,2)
323+
resource:=state.Modules[0].Resources["coder_app.code-server"]
324+
require.NotNil(t,resource)
325+
326+
// Read share and ensure it matches the expected
327+
// value.
328+
value:=resource.Primary.Attributes["open_in"]
329+
require.Equal(t,c.expectValue,value)
330+
returnnil
331+
}
332+
ifc.expectError!=nil {
333+
checkFn=nil
334+
}
335+
336+
resource.Test(t, resource.TestCase{
337+
ProviderFactories:coderFactory(),
338+
IsUnitTest:true,
339+
Steps: []resource.TestStep{{
340+
Config:config,
341+
Check:checkFn,
342+
ExpectError:c.expectError,
343+
}},
344+
})
345+
})
346+
}
347+
})
348+
244349
t.Run("Hidden",func(t*testing.T) {
245350
t.Parallel()
246351

247352
cases:= []struct {
248353
namestring
249354
configstring
250355
hiddenbool
356+
openInstring
251357
}{{
252358
name:"Is Hidden",
253359
config:`
@@ -263,9 +369,11 @@ func TestApp(t *testing.T) {
263369
url = "https://google.com"
264370
external = true
265371
hidden = true
372+
open_in = "slim-window"
266373
}
267374
`,
268375
hidden:true,
376+
openIn:"slim-window",
269377
}, {
270378
name:"Is Not Hidden",
271379
config:`
@@ -281,9 +389,11 @@ func TestApp(t *testing.T) {
281389
url = "https://google.com"
282390
external = true
283391
hidden = false
392+
open_in = "window"
284393
}
285394
`,
286395
hidden:false,
396+
openIn:"window",
287397
}}
288398
for_,tc:=rangecases {
289399
tc:=tc
@@ -300,6 +410,7 @@ func TestApp(t *testing.T) {
300410
resource:=state.Modules[0].Resources["coder_app.test"]
301411
require.NotNil(t,resource)
302412
require.Equal(t,strconv.FormatBool(tc.hidden),resource.Primary.Attributes["hidden"])
413+
require.Equal(t,tc.openIn,resource.Primary.Attributes["open_in"])
303414
returnnil
304415
},
305416
ExpectError:nil,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp