mirror of https://github.com/coder/coder.git
788 lines
26 KiB
Go
788 lines
26 KiB
Go
package cli_test
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/coder/coder/v2/cli/clitest"
|
|
"github.com/coder/coder/v2/coderd/coderdtest"
|
|
"github.com/coder/coder/v2/coderd/database"
|
|
"github.com/coder/coder/v2/coderd/rbac"
|
|
"github.com/coder/coder/v2/codersdk"
|
|
"github.com/coder/coder/v2/provisioner/echo"
|
|
"github.com/coder/coder/v2/provisionersdk/proto"
|
|
"github.com/coder/coder/v2/pty/ptytest"
|
|
"github.com/coder/coder/v2/testutil"
|
|
)
|
|
|
|
func TestTemplatePush(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("OK", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
|
|
// Test the cli command.
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
inv, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example")
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
require.NoError(t, <-execDone)
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
require.Equal(t, "example", templateVersions[1].Name)
|
|
})
|
|
|
|
t.Run("Message less than or equal to 72 chars", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
|
|
wantMessage := strings.Repeat("a", 72)
|
|
|
|
inv, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example", "--message", wantMessage, "--yes")
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
|
|
inv = inv.WithContext(ctx)
|
|
w := clitest.StartWithWaiter(t, inv)
|
|
|
|
pty.ExpectNoMatchBefore(ctx, "Template message is longer than 72 characters", "Updated version at")
|
|
|
|
w.RequireSuccess()
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(ctx, codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
require.Equal(t, wantMessage, templateVersions[1].Message)
|
|
})
|
|
|
|
t.Run("Message too long, warn but continue", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
|
defer cancel()
|
|
|
|
for i, tt := range []struct {
|
|
wantMessage string
|
|
wantMatch string
|
|
}{
|
|
{wantMessage: strings.Repeat("a", 73), wantMatch: "Template message is longer than 72 characters"},
|
|
{wantMessage: "This is my title\n\nAnd this is my body.", wantMatch: "Template message contains newlines"},
|
|
} {
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--message", tt.wantMessage,
|
|
"--yes",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
inv = inv.WithContext(ctx)
|
|
w := clitest.StartWithWaiter(t, inv)
|
|
|
|
pty.ExpectMatchContext(ctx, tt.wantMatch)
|
|
|
|
w.RequireSuccess()
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(ctx, codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2+i)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1+i].ID)
|
|
require.Equal(t, tt.wantMessage, templateVersions[1+i].Message)
|
|
}
|
|
})
|
|
|
|
t.Run("NoLockfile", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
|
|
// Test the cli command.
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
require.NoError(t, os.Remove(filepath.Join(source, ".terraform.lock.hcl")))
|
|
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "No .terraform.lock.hcl file found"},
|
|
{match: "Upload", write: "no"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
if m.write != "" {
|
|
pty.WriteLine(m.write)
|
|
}
|
|
}
|
|
|
|
// cmd should error once we say no.
|
|
require.Error(t, <-execDone)
|
|
})
|
|
|
|
t.Run("NoLockfileIgnored", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
|
|
// Test the cli command.
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
require.NoError(t, os.Remove(filepath.Join(source, ".terraform.lock.hcl")))
|
|
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
"--ignore-lockfile",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
{
|
|
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitMedium)
|
|
defer cancel()
|
|
|
|
pty.ExpectNoMatchBefore(ctx, "No .terraform.lock.hcl file found", "Upload")
|
|
pty.WriteLine("no")
|
|
}
|
|
|
|
// cmd should error once we say no.
|
|
require.Error(t, <-execDone)
|
|
})
|
|
|
|
t.Run("PushInactiveTemplateVersion", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
|
|
// Test the cli command.
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--activate=false",
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
w := clitest.StartWithWaiter(t, inv)
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
w.RequireSuccess()
|
|
|
|
// Assert that the template version didn't change.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.Equal(t, template.ActiveVersionID, templateVersions[0].ID)
|
|
require.NotEqual(t, "example", templateVersions[0].Name)
|
|
})
|
|
|
|
t.Run("UseWorkingDir", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if runtime.GOOS == "windows" {
|
|
t.Skip(`On Windows this test flakes with: "The process cannot access the file because it is being used by another process"`)
|
|
}
|
|
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
// Test the cli command.
|
|
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID,
|
|
func(r *codersdk.CreateTemplateRequest) {
|
|
r.Name = filepath.Base(source)
|
|
})
|
|
|
|
// Don't pass the name of the template, it should use the
|
|
// directory of the source.
|
|
inv, root := clitest.New(t, "templates", "push",
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--test.workdir", source,
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
waiter := clitest.StartWithWaiter(t, inv)
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
waiter.RequireSuccess()
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
})
|
|
|
|
t.Run("Stdin", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
|
|
|
|
source, err := echo.Tar(&echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
|
|
|
|
inv, root := clitest.New(
|
|
t, "templates", "push", "--directory", "-",
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
template.Name,
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t)
|
|
inv.Stdin = bytes.NewReader(source)
|
|
inv.Stdout = pty.Output()
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
require.NoError(t, <-execDone)
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
})
|
|
|
|
t.Run("Variables", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
initialTemplateVariables := []*proto.TemplateVariable{
|
|
{
|
|
Name: "first_variable",
|
|
Description: "This is the first variable",
|
|
Type: "string",
|
|
DefaultValue: "abc",
|
|
Required: false,
|
|
Sensitive: true,
|
|
},
|
|
}
|
|
|
|
t.Run("VariableIsRequired", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
|
|
templateVersion := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, templateVersion.ID)
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, templateVersion.ID)
|
|
|
|
// Test the cli command.
|
|
modifiedTemplateVariables := append(initialTemplateVariables,
|
|
&proto.TemplateVariable{
|
|
Name: "second_variable",
|
|
Description: "This is the second variable.",
|
|
Type: "string",
|
|
Required: true,
|
|
},
|
|
)
|
|
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
|
tempDir := t.TempDir()
|
|
removeTmpDirUntilSuccessAfterTest(t, tempDir)
|
|
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
|
|
_, _ = variablesFile.WriteString(`second_variable: foobar`)
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
"--variables-file", variablesFile.Name(),
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t)
|
|
inv.Stdin = pty.Input()
|
|
inv.Stdout = pty.Output()
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
require.NoError(t, <-execDone)
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
require.Equal(t, "example", templateVersions[1].Name)
|
|
|
|
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVariables, 2)
|
|
require.Equal(t, "second_variable", templateVariables[1].Name)
|
|
require.Equal(t, "foobar", templateVariables[1].Value)
|
|
})
|
|
|
|
t.Run("VariableIsRequiredButNotProvided", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
|
|
templateVersion := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, templateVersion.ID)
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, templateVersion.ID)
|
|
|
|
// Test the cli command.
|
|
modifiedTemplateVariables := append(initialTemplateVariables,
|
|
&proto.TemplateVariable{
|
|
Name: "second_variable",
|
|
Description: "This is the second variable.",
|
|
Type: "string",
|
|
Required: true,
|
|
},
|
|
)
|
|
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
|
inv, root := clitest.New(t, "templates", "push", template.Name, "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--name", "example")
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t)
|
|
inv.Stdin = pty.Input()
|
|
inv.Stdout = pty.Output()
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
wantErr := <-execDone
|
|
require.Error(t, wantErr)
|
|
require.Contains(t, wantErr.Error(), "required template variables need values")
|
|
})
|
|
|
|
t.Run("VariableIsOptionalButNotProvided", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
|
|
templateVersion := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, templateVersion.ID)
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, templateVersion.ID)
|
|
|
|
// Test the cli command.
|
|
modifiedTemplateVariables := append(initialTemplateVariables,
|
|
&proto.TemplateVariable{
|
|
Name: "second_variable",
|
|
Description: "This is the second variable",
|
|
Type: "string",
|
|
DefaultValue: "abc",
|
|
Required: true,
|
|
},
|
|
)
|
|
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
|
inv, root := clitest.New(t, "templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t)
|
|
inv.Stdin = pty.Input()
|
|
inv.Stdout = pty.Output()
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
require.NoError(t, <-execDone)
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
require.Equal(t, "example", templateVersions[1].Name)
|
|
|
|
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVariables, 2)
|
|
require.Equal(t, "second_variable", templateVariables[1].Name)
|
|
require.Equal(t, "abc", templateVariables[1].Value)
|
|
require.Equal(t, templateVariables[1].DefaultValue, templateVariables[1].Value)
|
|
})
|
|
|
|
t.Run("WithVariableOption", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
|
|
templateVersion := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, createEchoResponsesWithTemplateVariables(initialTemplateVariables))
|
|
_ = coderdtest.AwaitTemplateVersionJobCompleted(t, client, templateVersion.ID)
|
|
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, templateVersion.ID)
|
|
|
|
// Test the cli command.
|
|
modifiedTemplateVariables := append(initialTemplateVariables,
|
|
&proto.TemplateVariable{
|
|
Name: "second_variable",
|
|
Description: "This is the second variable.",
|
|
Type: "string",
|
|
Required: true,
|
|
},
|
|
)
|
|
source := clitest.CreateTemplateVersionSource(t, createEchoResponsesWithTemplateVariables(modifiedTemplateVariables))
|
|
inv, root := clitest.New(t,
|
|
"templates", "push", template.Name,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
"--name", "example",
|
|
"--variable", "second_variable=foobar",
|
|
)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t)
|
|
inv.Stdin = pty.Input()
|
|
inv.Stdout = pty.Output()
|
|
|
|
execDone := make(chan error)
|
|
go func() {
|
|
execDone <- inv.Run()
|
|
}()
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
pty.WriteLine(m.write)
|
|
}
|
|
|
|
require.NoError(t, <-execDone)
|
|
|
|
// Assert that the template version changed.
|
|
templateVersions, err := client.TemplateVersionsByTemplate(context.Background(), codersdk.TemplateVersionsByTemplateRequest{
|
|
TemplateID: template.ID,
|
|
})
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVersions, 2)
|
|
assert.NotEqual(t, template.ActiveVersionID, templateVersions[1].ID)
|
|
require.Equal(t, "example", templateVersions[1].Name)
|
|
|
|
templateVariables, err := client.TemplateVersionVariables(context.Background(), templateVersions[1].ID)
|
|
require.NoError(t, err)
|
|
assert.Len(t, templateVariables, 2)
|
|
require.Equal(t, "second_variable", templateVariables[1].Name)
|
|
require.Equal(t, "foobar", templateVariables[1].Value)
|
|
})
|
|
|
|
t.Run("CreateTemplate", func(t *testing.T) {
|
|
t.Parallel()
|
|
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
|
owner := coderdtest.CreateFirstUser(t, client)
|
|
templateAdmin, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID, rbac.RoleTemplateAdmin())
|
|
source := clitest.CreateTemplateVersionSource(t, completeWithAgent())
|
|
|
|
const templateName = "my-template"
|
|
args := []string{
|
|
"templates",
|
|
"push",
|
|
templateName,
|
|
"--directory", source,
|
|
"--test.provisioner", string(database.ProvisionerTypeEcho),
|
|
}
|
|
inv, root := clitest.New(t, args...)
|
|
clitest.SetupConfig(t, templateAdmin, root)
|
|
pty := ptytest.New(t).Attach(inv)
|
|
|
|
waiter := clitest.StartWithWaiter(t, inv)
|
|
|
|
matches := []struct {
|
|
match string
|
|
write string
|
|
}{
|
|
{match: "Upload", write: "yes"},
|
|
{match: "template has been created"},
|
|
}
|
|
for _, m := range matches {
|
|
pty.ExpectMatch(m.match)
|
|
if m.write != "" {
|
|
pty.WriteLine(m.write)
|
|
}
|
|
}
|
|
|
|
waiter.RequireSuccess()
|
|
|
|
template, err := client.TemplateByName(context.Background(), owner.OrganizationID, templateName)
|
|
require.NoError(t, err)
|
|
require.Equal(t, templateName, template.Name)
|
|
require.NotEqual(t, uuid.Nil, template.ActiveVersionID)
|
|
})
|
|
})
|
|
}
|
|
|
|
func createEchoResponsesWithTemplateVariables(templateVariables []*proto.TemplateVariable) *echo.Responses {
|
|
return &echo.Responses{
|
|
Parse: []*proto.Response{
|
|
{
|
|
Type: &proto.Response_Parse{
|
|
Parse: &proto.ParseComplete{
|
|
TemplateVariables: templateVariables,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ProvisionPlan: echo.PlanComplete,
|
|
ProvisionApply: echo.ApplyComplete,
|
|
}
|
|
}
|
|
|
|
func completeWithAgent() *echo.Responses {
|
|
return &echo.Responses{
|
|
Parse: echo.ParseComplete,
|
|
ProvisionPlan: []*proto.Response{
|
|
{
|
|
Type: &proto.Response_Plan{
|
|
Plan: &proto.PlanComplete{
|
|
Resources: []*proto.Resource{
|
|
{
|
|
Type: "compute",
|
|
Name: "main",
|
|
Agents: []*proto.Agent{
|
|
{
|
|
Name: "smith",
|
|
OperatingSystem: "linux",
|
|
Architecture: "i386",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
ProvisionApply: []*proto.Response{
|
|
{
|
|
Type: &proto.Response_Apply{
|
|
Apply: &proto.ApplyComplete{
|
|
Resources: []*proto.Resource{
|
|
{
|
|
Type: "compute",
|
|
Name: "main",
|
|
Agents: []*proto.Agent{
|
|
{
|
|
Name: "smith",
|
|
OperatingSystem: "linux",
|
|
Architecture: "i386",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
// Need this for Windows because of a known issue with Go:
|
|
// https://github.com/golang/go/issues/52986
|
|
func removeTmpDirUntilSuccessAfterTest(t *testing.T, tempDir string) {
|
|
t.Helper()
|
|
t.Cleanup(func() {
|
|
err := os.RemoveAll(tempDir)
|
|
for err != nil {
|
|
err = os.RemoveAll(tempDir)
|
|
}
|
|
})
|
|
}
|