Skip to content

Commit f8a0356

Browse files
committed
chore(enterprise/coderd): RED: add TestWorkspaceTagsTerraform
1 parent 0ebaeb2 commit f8a0356

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

enterprise/coderd/workspaces_test.go

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package coderd_test
22

33
import (
4+
"bytes"
45
"context"
56
"database/sql"
7+
"fmt"
68
"net/http"
79
"sync/atomic"
810
"testing"
@@ -1420,6 +1422,157 @@ func TestTemplateDoesNotAllowUserAutostop(t *testing.T) {
14201422
})
14211423
}
14221424

1425+
// TestWorkspaceTagsTerraform tests that a workspace can be created with tags.
1426+
// This is an end-to-end-style test, meaning that we actually run the
1427+
// real Terraform provisioner and validate that the workspace is created
1428+
// successfully. The workspace itself does not specify any resources, and
1429+
// this is fine.
1430+
func TestWorkspaceTagsTerraform(t *testing.T) {
1431+
t.Parallel()
1432+
1433+
mainTfTemplate := `
1434+
terraform {
1435+
required_providers {
1436+
coder = {
1437+
source = "coder/coder"
1438+
}
1439+
}
1440+
}
1441+
provider "coder" {}
1442+
data "coder_workspace" "me" {}
1443+
data "coder_workspace_owner" "me" {}
1444+
%s
1445+
`
1446+
1447+
for _, tc := range []struct {
1448+
name string
1449+
// tags to apply to the external provisioner
1450+
provisionerTags map[string]string
1451+
// tags to apply to the create template version request
1452+
createTemplateVersionRequestTags map[string]string
1453+
// the coder_workspace_tags bit of main.tf.
1454+
// you can add more stuff here if you need
1455+
tfWorkspaceTags string
1456+
}{
1457+
{
1458+
name: "no tags",
1459+
tfWorkspaceTags: ``,
1460+
},
1461+
{
1462+
name: "empty tags",
1463+
tfWorkspaceTags: `
1464+
data "coder_workspace_tags" "tags" {
1465+
tags = {}
1466+
}
1467+
`,
1468+
},
1469+
{
1470+
name: "static tag",
1471+
provisionerTags: map[string]string{"foo": "bar"},
1472+
tfWorkspaceTags: `
1473+
data "coder_workspace_tags" "tags" {
1474+
tags = {
1475+
"foo" = "bar"
1476+
}
1477+
}`,
1478+
},
1479+
{
1480+
name: "tag variable",
1481+
provisionerTags: map[string]string{"foo": "bar"},
1482+
tfWorkspaceTags: `
1483+
variable "foo" {
1484+
default = "bar"
1485+
}
1486+
data "coder_workspace_tags" "tags" {
1487+
tags = {
1488+
"foo" = var.foo
1489+
}
1490+
}`,
1491+
},
1492+
{
1493+
name: "tag param",
1494+
provisionerTags: map[string]string{"foo": "bar"},
1495+
tfWorkspaceTags: `
1496+
data "coder_parameter" "foo" {
1497+
name = "foo"
1498+
type = "string"
1499+
default = "bar"
1500+
}
1501+
data "coder_workspace_tags" "tags" {
1502+
tags = {
1503+
"foo" = data.coder_parameter.foo.value
1504+
}
1505+
}`,
1506+
},
1507+
{
1508+
name: "tag param with default from var",
1509+
provisionerTags: map[string]string{"foo": "bar"},
1510+
tfWorkspaceTags: `
1511+
variable "foo" {
1512+
type = "string"
1513+
default = "bar"
1514+
}
1515+
data "coder_parameter" "foo" {
1516+
name = "foo"
1517+
type = "string"
1518+
default = var.foo
1519+
}
1520+
data "coder_workspace_tags" "tags" {
1521+
tags = {
1522+
"foo" = data.coder_parameter.foo.value
1523+
}
1524+
}`,
1525+
},
1526+
} {
1527+
tc := tc
1528+
t.Run(tc.name, func(t *testing.T) {
1529+
t.Parallel()
1530+
ctx := testutil.Context(t, testutil.WaitShort)
1531+
1532+
client, owner := coderdenttest.New(t, &coderdenttest.Options{
1533+
Options: &coderdtest.Options{
1534+
// We intentionally do not run a built-in provisioner daemon here.
1535+
IncludeProvisionerDaemon: false,
1536+
},
1537+
LicenseOptions: &coderdenttest.LicenseOptions{
1538+
Features: license.Features{
1539+
codersdk.FeatureExternalProvisionerDaemons: 1,
1540+
},
1541+
},
1542+
})
1543+
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
1544+
member, memberUser := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
1545+
1546+
_ = coderdenttest.NewExternalProvisionerDaemonTerraform(t, client, owner.OrganizationID, tc.provisionerTags)
1547+
1548+
// Creating a template as a template admin must succeed
1549+
templateFiles := map[string]string{"main.tf": fmt.Sprintf(mainTfTemplate, tc.tfWorkspaceTags)}
1550+
tarBytes := testutil.CreateTar(t, templateFiles)
1551+
fi, err := templateAdmin.Upload(ctx, "application/x-tar", bytes.NewReader(tarBytes))
1552+
require.NoError(t, err, "failed to upload file")
1553+
tv, err := templateAdmin.CreateTemplateVersion(ctx, owner.OrganizationID, codersdk.CreateTemplateVersionRequest{
1554+
Name: testutil.GetRandomName(t),
1555+
FileID: fi.ID,
1556+
StorageMethod: codersdk.ProvisionerStorageMethodFile,
1557+
Provisioner: codersdk.ProvisionerTypeTerraform,
1558+
ProvisionerTags: tc.createTemplateVersionRequestTags,
1559+
})
1560+
require.NoError(t, err, "failed to create template version")
1561+
coderdtest.AwaitTemplateVersionJobCompleted(t, templateAdmin, tv.ID)
1562+
require.NoError(t, err, "failed to create template version")
1563+
tpl := coderdtest.CreateTemplate(t, templateAdmin, owner.OrganizationID, tv.ID)
1564+
1565+
// Creating a workspace as a non-privileged user must succeed
1566+
ws, err := member.CreateUserWorkspace(ctx, memberUser.Username, codersdk.CreateWorkspaceRequest{
1567+
TemplateID: tpl.ID,
1568+
Name: coderdtest.RandomUsername(t),
1569+
})
1570+
require.NoError(t, err, "failed to create workspace")
1571+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, member, ws.LatestBuild.ID)
1572+
})
1573+
}
1574+
}
1575+
14231576
// Blocked by autostart requirements
14241577
func TestExecutorAutostartBlocked(t *testing.T) {
14251578
t.Parallel()

0 commit comments

Comments
 (0)