Skip to content

feat: add coderd_template resource #35

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions docs/resources/template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "coderd_template Resource - coderd"
subcategory: ""
description: |-
A Coder template
---

# coderd_template (Resource)

A Coder template



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `acl` (Attributes) Access control list for the template. (see [below for nested schema](#nestedatt--acl))
- `name` (String) The name of the template.
- `versions` (Attributes List) (see [below for nested schema](#nestedatt--versions))

### Optional

- `allow_user_auto_start` (Boolean)
- `allow_user_auto_stop` (Boolean)
- `description` (String) A description of the template.
- `display_name` (String) The display name of the template. Defaults to the template name.
- `icon` (String) Relative path or external URL that specifes an icon to be displayed in the dashboard.
- `organization_id` (String) The ID of the organization. Defaults to the provider's default organization

### Read-Only

- `id` (String) The ID of the template.

<a id="nestedatt--acl"></a>
### Nested Schema for `acl`

Required:

- `groups` (Attributes Set) (see [below for nested schema](#nestedatt--acl--groups))
- `users` (Attributes Set) (see [below for nested schema](#nestedatt--acl--users))

<a id="nestedatt--acl--groups"></a>
### Nested Schema for `acl.groups`

Required:

- `id` (String)
- `role` (String)


<a id="nestedatt--acl--users"></a>
### Nested Schema for `acl.users`

Required:

- `id` (String)
- `role` (String)



<a id="nestedatt--versions"></a>
### Nested Schema for `versions`

Required:

- `directory` (String) A path to the directory to create the template version from. Changes in the directory contents will trigger the creation of a new template version.

Optional:

- `active` (Boolean) Whether this version is the active version of the template. Only one version can be active at a time.
- `message` (String) A message describing the changes in this version of the template. Messages longer than 72 characters will be truncated.
- `name` (String) The name of the template version. Automatically generated if not provided.
- `provisioner_tags` (Attributes Set) Provisioner tags for the template version. (see [below for nested schema](#nestedatt--versions--provisioner_tags))
- `tf_vars` (Attributes Set) Terraform variables for the template version. (see [below for nested schema](#nestedatt--versions--tf_vars))

Read-Only:

- `directory_hash` (String)
- `id` (String)

<a id="nestedatt--versions--provisioner_tags"></a>
### Nested Schema for `versions.provisioner_tags`

Required:

- `name` (String)
- `value` (String)


<a id="nestedatt--versions--tf_vars"></a>
### Nested Schema for `versions.tf_vars`

Required:

- `name` (String)
- `value` (String)
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ require (
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
github.com/shopspring/decimal v1.3.1 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/spf13/afero v1.11.0 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tinylib/msgp v1.1.8 // indirect
Expand Down
8 changes: 5 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6 h1:KHblWIE/KHOwQ6lEbMZt6YpcGve2FEZ1sDtrW1Am5UI=
cdr.dev/slog v1.6.2-0.20240126064726-20367d4aede6/go.mod h1:NaoTA7KwopCrnaSb0JXTC0PTp/O/Y83Lndnq0OEV3ZQ=
cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y=
cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU=
cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc=
cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
Expand Down Expand Up @@ -81,8 +81,6 @@ github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU=
github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA=
github.com/coder/coder/v2 v2.13.0 h1:MlkRGqQcCAdwIkLc9iV8sQfT4jB3EThHopG0jF3BuFE=
github.com/coder/coder/v2 v2.13.0/go.mod h1:Gxc79InMB6b+sncuDUORtFLWi7aKshvis3QrMUhpq5Q=
github.com/coder/coder/v2 v2.13.1 h1:tCd8ljqIAufbVcBr8ODS1QbsrjJbmOIvgDkvdd/JMXc=
github.com/coder/coder/v2 v2.13.1/go.mod h1:Gxc79InMB6b+sncuDUORtFLWi7aKshvis3QrMUhpq5Q=
github.com/coder/pretty v0.0.0-20230908205945-e89ba86370e0 h1:3A0ES21Ke+FxEM8CXx9n47SZOKOpgSE1bbJzlE4qPVs=
Expand Down Expand Up @@ -134,6 +132,8 @@ github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8=
github.com/go-chi/render v1.0.1/go.mod h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU=
Expand Down Expand Up @@ -390,6 +390,8 @@ github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L
github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo=
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
Expand Down
39 changes: 39 additions & 0 deletions integration/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,45 @@ func TestIntegration(t *testing.T) {
assert.Equal(t, group.QuotaAllowance, 100)
},
},
{
name: "template-test",
preF: func(t testing.TB, c *codersdk.Client) {},
assertF: func(t testing.TB, c *codersdk.Client) {
defaultOrg, err := c.OrganizationByName(ctx, "first-organization")
assert.NoError(t, err)
user, err := c.User(ctx, "ethan")
require.NoError(t, err)

// Check template metadata
templates, err := c.Templates(ctx)
require.NoError(t, err)
require.Len(t, templates, 1)
require.Equal(t, "example-template", templates[0].Name)
require.False(t, templates[0].AllowUserAutostart)
require.False(t, templates[0].AllowUserAutostop)

// Check versions
versions, err := c.TemplateVersionsByTemplate(ctx, codersdk.TemplateVersionsByTemplateRequest{
TemplateID: templates[0].ID,
})
require.NoError(t, err)
require.Len(t, versions, 2)
require.Equal(t, "latest", versions[0].Name)
require.NotEmpty(t, versions[0].ID)
require.Equal(t, templates[0].ID, *versions[0].TemplateID)
require.Equal(t, templates[0].ActiveVersionID, versions[0].ID)

// Check ACL
acl, err := c.TemplateACL(ctx, templates[0].ID)
require.NoError(t, err)
require.Len(t, acl.Groups, 1)
require.Equal(t, codersdk.TemplateRoleUse, acl.Groups[0].Role)
require.Equal(t, defaultOrg.ID, acl.Groups[0].ID)
require.Len(t, acl.Users, 1)
require.Equal(t, codersdk.TemplateRoleAdmin, acl.Users[0].Role)
require.Equal(t, user.ID, acl.Users[0].ID)
},
},
} {
t.Run(tt.name, func(t *testing.T) {
client := StartCoder(ctx, t, tt.name, true)
Expand Down
12 changes: 12 additions & 0 deletions integration/template-test/example-template-2/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
variable "name" {
type = string
}

resource "local_file" "a" {
filename = "${path.module}/a.txt"
content = "hello ${var.name}"
}

output "a" {
value = local_file.a.content
}
12 changes: 12 additions & 0 deletions integration/template-test/example-template/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
variable "name" {
type = string
}

resource "local_file" "a" {
filename = "${path.module}/a.txt"
content = "hello ${var.name}"
}

output "a" {
value = local_file.a.content
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "world"
67 changes: 67 additions & 0 deletions integration/template-test/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
terraform {
required_providers {
coderd = {
source = "coder/coderd"
version = ">=0.0.0"
}
}
}

resource "coderd_user" "ethan" {
username = "ethan"
name = "Ethan Coolguy"
email = "[email protected]"
roles = ["owner", "template-admin"]
login_type = "password"
password = "SomeSecurePassword!"
suspended = false
}


data "coderd_organization" "default" {
is_default = true
}

resource "coderd_template" "sample" {
name = "example-template"
allow_user_auto_stop = false
allow_user_auto_start = false
acl = {
groups = [
{
id = data.coderd_organization.default.id
role = "use"
}
]
users = [
{
id = resource.coderd_user.ethan.id
role = "admin"
}
]
}
versions = [
{
name = "latest"
directory = "./example-template"
active = true
tf_vars = [
{
name = "name"
value = "world"
},
]
},
{
name = "legacy"
directory = "./example-template-2"
active = false
tf_vars = [
{
name = "name"
value = "ethan"
},
]
}
]
}
45 changes: 45 additions & 0 deletions internal/provider/logger.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package provider

import (
"context"

"cdr.dev/slog"
"github.com/hashicorp/terraform-plugin-log/tflog"
)

var _ slog.Sink = &tfLogSink{}

type tfLogSink struct {
tfCtx context.Context
}

func newTFLogSink(tfCtx context.Context) *tfLogSink {
return &tfLogSink{
tfCtx: tfCtx,
}
}

func (s *tfLogSink) LogEntry(ctx context.Context, e slog.SinkEntry) {
var logFn func(ctx context.Context, msg string, additionalFields ...map[string]interface{})
switch e.Level {
case slog.LevelDebug:
logFn = tflog.Debug
case slog.LevelInfo:
logFn = tflog.Info
case slog.LevelWarn:
logFn = tflog.Warn
default:
logFn = tflog.Error
}
logFn(s.tfCtx, e.Message, mapToFields(e.Fields))
}

func (s *tfLogSink) Sync() {}

func mapToFields(m slog.Map) map[string]interface{} {
fields := make(map[string]interface{}, len(m))
for _, v := range m {
fields[v.Name] = v.Value
}
return fields
}
2 changes: 1 addition & 1 deletion internal/provider/organization_data_source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestAccOrganizationDataSource(t *testing.T) {
t.Skip("Acceptance tests are disabled.")
}
ctx := context.Background()
client := integration.StartCoder(ctx, t, "group_acc", true)
client := integration.StartCoder(ctx, t, "org_data_acc", true)
firstUser, err := client.User(ctx, codersdk.Me)
require.NoError(t, err)

Expand Down
1 change: 1 addition & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func (p *CoderdProvider) Resources(ctx context.Context) []func() resource.Resour
return []func() resource.Resource{
NewUserResource,
NewGroupResource,
NewTemplateResource,
}
}

Expand Down
Loading
Loading