mirror of https://github.com/coder/coder.git
chore: Rename Projects to Templates (#880)
Customer feedback indicated projects was a confusing name.
After querying the team internally, it seemed unanimous
that it is indeed a confusing name.
Here's for a lil less confusion @ashmeer7 🥂
This commit is contained in:
parent
584c8b4fc3
commit
02ad3f14f5
|
@ -36,9 +36,9 @@ func SetupConfig(t *testing.T, client *codersdk.Client, root config.Root) {
|
|||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// CreateProjectVersionSource writes the echo provisioner responses into a
|
||||
// CreateTemplateVersionSource writes the echo provisioner responses into a
|
||||
// new temporary testing directory.
|
||||
func CreateProjectVersionSource(t *testing.T, responses *echo.Responses) string {
|
||||
func CreateTemplateVersionSource(t *testing.T, responses *echo.Responses) string {
|
||||
directory := t.TempDir()
|
||||
data, err := echo.Tar(responses)
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -17,7 +17,7 @@ func TestMain(m *testing.M) {
|
|||
|
||||
func TestCli(t *testing.T) {
|
||||
t.Parallel()
|
||||
clitest.CreateProjectVersionSource(t, nil)
|
||||
clitest.CreateTemplateVersionSource(t, nil)
|
||||
client := coderdtest.New(t, nil)
|
||||
cmd, config := clitest.New(t)
|
||||
clitest.SetupConfig(t, client, config)
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func ParameterSchema(cmd *cobra.Command, parameterSchema codersdk.ProjectVersionParameterSchema) (string, error) {
|
||||
func ParameterSchema(cmd *cobra.Command, parameterSchema codersdk.TemplateVersionParameterSchema) (string, error) {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), Styles.Bold.Render("var."+parameterSchema.Name))
|
||||
if parameterSchema.Description != "" {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), " "+strings.TrimSpace(strings.Join(strings.Split(parameterSchema.Description, "\n"), "\n "))+"\n")
|
||||
|
|
|
@ -19,10 +19,10 @@ func TestConfigSSH(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
tempFile, err := os.CreateTemp(t.TempDir(), "")
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -150,7 +150,7 @@ func login() *cobra.Command {
|
|||
cliui.Styles.Paragraph.Render(fmt.Sprintf("Welcome to Coder, %s! You're authenticated.", cliui.Styles.Keyword.Render(username)))+"\n")
|
||||
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(),
|
||||
cliui.Styles.Paragraph.Render("Get started by creating a project: "+cliui.Styles.Code.Render("coder projects create"))+"\n")
|
||||
cliui.Styles.Paragraph.Render("Get started by creating a template: "+cliui.Styles.Code.Render("coder templates create"))+"\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -39,12 +39,12 @@ func parseScopeAndID(ctx context.Context, client *codersdk.Client, organization
|
|||
}
|
||||
scopeID = org.ID
|
||||
}
|
||||
case codersdk.ParameterProject:
|
||||
project, err := client.ProjectByName(ctx, organization.ID, name)
|
||||
case codersdk.ParameterTemplate:
|
||||
template, err := client.TemplateByName(ctx, organization.ID, name)
|
||||
if err != nil {
|
||||
return scope, uuid.Nil, err
|
||||
}
|
||||
scopeID = project.ID
|
||||
scopeID = template.ID
|
||||
case codersdk.ParameterUser:
|
||||
uid, _ := uuid.Parse(name)
|
||||
user, err := client.User(ctx, uid)
|
||||
|
@ -67,8 +67,8 @@ func parseParameterScope(scope string) (codersdk.ParameterScope, error) {
|
|||
switch scope {
|
||||
case string(codersdk.ParameterOrganization):
|
||||
return codersdk.ParameterOrganization, nil
|
||||
case string(codersdk.ParameterProject):
|
||||
return codersdk.ParameterProject, nil
|
||||
case string(codersdk.ParameterTemplate):
|
||||
return codersdk.ParameterTemplate, nil
|
||||
case string(codersdk.ParameterUser):
|
||||
return codersdk.ParameterUser, nil
|
||||
case string(codersdk.ParameterWorkspace):
|
||||
|
|
|
@ -43,9 +43,9 @@ func Root() *cobra.Command {
|
|||
Example: cliui.Styles.Paragraph.Render(`Start Coder in "dev" mode. This dev-mode requires no further setup, and your local `+cliui.Styles.Code.Render("coder")+` CLI will be authenticated to talk to it. This makes it easy to experiment with Coder.`) + `
|
||||
|
||||
` + cliui.Styles.Code.Render("$ coder start --dev") + `
|
||||
` + cliui.Styles.Paragraph.Render("Get started by creating a project from an example.") + `
|
||||
` + cliui.Styles.Paragraph.Render("Get started by creating a template from an example.") + `
|
||||
|
||||
` + cliui.Styles.Code.Render("$ coder projects init"),
|
||||
` + cliui.Styles.Code.Render("$ coder templates init"),
|
||||
}
|
||||
// Customizes the color of headings to make subcommands
|
||||
// more visually appealing.
|
||||
|
@ -65,7 +65,7 @@ func Root() *cobra.Command {
|
|||
start(),
|
||||
login(),
|
||||
parameters(),
|
||||
projects(),
|
||||
templates(),
|
||||
users(),
|
||||
workspaces(),
|
||||
ssh(),
|
||||
|
|
|
@ -31,7 +31,7 @@ func TestSSH(t *testing.T) {
|
|||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
agentToken := uuid.NewString()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
|
@ -51,9 +51,9 @@ func TestSSH(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
go func() {
|
||||
// Run this async so the SSH command has to wait for
|
||||
// the build and agent to connect!
|
||||
|
@ -89,7 +89,7 @@ func TestSSH(t *testing.T) {
|
|||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
agentToken := uuid.NewString()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
|
@ -109,9 +109,9 @@ func TestSSH(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
go func() {
|
||||
// Run this async so the SSH command has to wait for
|
||||
// the build and agent to connect!
|
||||
|
|
|
@ -217,7 +217,7 @@ func start() *cobra.Command {
|
|||
cliui.Styles.Field.Render("dev")+` mode. All data is in-memory! Do not use in production. Press `+cliui.Styles.Field.Render("ctrl+c")+` to clean up provisioned infrastructure.`))+
|
||||
`
|
||||
`+
|
||||
cliui.Styles.Paragraph.Render(cliui.Styles.Wrap.Render(cliui.Styles.Prompt.String()+`Run `+cliui.Styles.Code.Render("coder projects init")+" in a new terminal to get started.\n"))+`
|
||||
cliui.Styles.Paragraph.Render(cliui.Styles.Wrap.Render(cliui.Styles.Prompt.String()+`Run `+cliui.Styles.Code.Render("coder templates init")+" in a new terminal to get started.\n"))+`
|
||||
`)
|
||||
} else {
|
||||
// This is helpful for tests, but can be silently ignored.
|
||||
|
|
|
@ -187,10 +187,10 @@ func TestStart(t *testing.T) {
|
|||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
|
||||
// Create a workspace so the cleanup occurs!
|
||||
version := coderdtest.CreateProjectVersion(t, client, orgs[0].ID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, orgs[0].ID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, orgs[0].ID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, orgs[0].ID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
"github.com/coder/coder/provisionersdk"
|
||||
)
|
||||
|
||||
func projectCreate() *cobra.Command {
|
||||
func templateCreate() *cobra.Command {
|
||||
var (
|
||||
yes bool
|
||||
directory string
|
||||
|
@ -28,7 +28,7 @@ func projectCreate() *cobra.Command {
|
|||
)
|
||||
cmd := &cobra.Command{
|
||||
Use: "create [name]",
|
||||
Short: "Create a project from the current directory",
|
||||
Short: "Create a template from the current directory",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := createClient(cmd)
|
||||
if err != nil {
|
||||
|
@ -39,15 +39,15 @@ func projectCreate() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
var projectName string
|
||||
var templateName string
|
||||
if len(args) == 0 {
|
||||
projectName = filepath.Base(directory)
|
||||
templateName = filepath.Base(directory)
|
||||
} else {
|
||||
projectName = args[0]
|
||||
templateName = args[0]
|
||||
}
|
||||
_, err = client.ProjectByName(cmd.Context(), organization.ID, projectName)
|
||||
_, err = client.TemplateByName(cmd.Context(), organization.ID, templateName)
|
||||
if err == nil {
|
||||
return xerrors.Errorf("A project already exists named %q!", projectName)
|
||||
return xerrors.Errorf("A template already exists named %q!", templateName)
|
||||
}
|
||||
|
||||
spin := spinner.New(spinner.CharSets[5], 100*time.Millisecond)
|
||||
|
@ -69,14 +69,14 @@ func projectCreate() *cobra.Command {
|
|||
spin = spinner.New(spinner.CharSets[5], 100*time.Millisecond)
|
||||
spin.Writer = cmd.OutOrStdout()
|
||||
spin.Suffix = cliui.Styles.Keyword.Render("Something")
|
||||
job, parameters, err := createValidProjectVersion(cmd, client, organization, database.ProvisionerType(provisioner), resp.Hash)
|
||||
job, parameters, err := createValidTemplateVersion(cmd, client, organization, database.ProvisionerType(provisioner), resp.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !yes {
|
||||
_, err = cliui.Prompt(cmd, cliui.PromptOptions{
|
||||
Text: "Create project?",
|
||||
Text: "Create template?",
|
||||
IsConfirm: true,
|
||||
Default: "yes",
|
||||
})
|
||||
|
@ -88,8 +88,8 @@ func projectCreate() *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
_, err = client.CreateProject(cmd.Context(), organization.ID, codersdk.CreateProjectRequest{
|
||||
Name: projectName,
|
||||
_, err = client.CreateTemplate(cmd.Context(), organization.ID, codersdk.CreateTemplateRequest{
|
||||
Name: templateName,
|
||||
VersionID: job.ID,
|
||||
ParameterValues: parameters,
|
||||
})
|
||||
|
@ -97,7 +97,7 @@ func projectCreate() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "The %s project has been created!\n", projectName)
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "The %s template has been created!\n", templateName)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
@ -113,9 +113,9 @@ func projectCreate() *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, organization codersdk.Organization, provisioner database.ProvisionerType, hash string, parameters ...codersdk.CreateParameterRequest) (*codersdk.ProjectVersion, []codersdk.CreateParameterRequest, error) {
|
||||
func createValidTemplateVersion(cmd *cobra.Command, client *codersdk.Client, organization codersdk.Organization, provisioner database.ProvisionerType, hash string, parameters ...codersdk.CreateParameterRequest) (*codersdk.TemplateVersion, []codersdk.CreateParameterRequest, error) {
|
||||
before := time.Now()
|
||||
version, err := client.CreateProjectVersion(cmd.Context(), organization.ID, codersdk.CreateProjectVersionRequest{
|
||||
version, err := client.CreateTemplateVersion(cmd.Context(), organization.ID, codersdk.CreateTemplateVersionRequest{
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: hash,
|
||||
Provisioner: provisioner,
|
||||
|
@ -127,14 +127,14 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
|
|||
|
||||
err = cliui.ProvisionerJob(cmd.Context(), cmd.OutOrStdout(), cliui.ProvisionerJobOptions{
|
||||
Fetch: func() (codersdk.ProvisionerJob, error) {
|
||||
version, err := client.ProjectVersion(cmd.Context(), version.ID)
|
||||
version, err := client.TemplateVersion(cmd.Context(), version.ID)
|
||||
return version.Job, err
|
||||
},
|
||||
Cancel: func() error {
|
||||
return client.CancelProjectVersion(cmd.Context(), version.ID)
|
||||
return client.CancelTemplateVersion(cmd.Context(), version.ID)
|
||||
},
|
||||
Logs: func() (<-chan codersdk.ProvisionerJobLog, error) {
|
||||
return client.ProjectVersionLogsAfter(cmd.Context(), version.ID, before)
|
||||
return client.TemplateVersionLogsAfter(cmd.Context(), version.ID, before)
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -142,28 +142,28 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
|
|||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
version, err = client.ProjectVersion(cmd.Context(), version.ID)
|
||||
version, err = client.TemplateVersion(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
parameterSchemas, err := client.ProjectVersionSchema(cmd.Context(), version.ID)
|
||||
parameterSchemas, err := client.TemplateVersionSchema(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
parameterValues, err := client.ProjectVersionParameters(cmd.Context(), version.ID)
|
||||
parameterValues, err := client.TemplateVersionParameters(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if provisionerd.IsMissingParameterError(version.Job.Error) {
|
||||
valuesBySchemaID := map[string]codersdk.ProjectVersionParameter{}
|
||||
valuesBySchemaID := map[string]codersdk.TemplateVersionParameter{}
|
||||
for _, parameterValue := range parameterValues {
|
||||
valuesBySchemaID[parameterValue.SchemaID.String()] = parameterValue
|
||||
}
|
||||
sort.Slice(parameterSchemas, func(i, j int) bool {
|
||||
return parameterSchemas[i].Name < parameterSchemas[j].Name
|
||||
})
|
||||
missingSchemas := make([]codersdk.ProjectVersionParameterSchema, 0)
|
||||
missingSchemas := make([]codersdk.TemplateVersionParameterSchema, 0)
|
||||
for _, parameterSchema := range parameterSchemas {
|
||||
_, ok := valuesBySchemaID[parameterSchema.ID.String()]
|
||||
if ok {
|
||||
|
@ -171,7 +171,7 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
|
|||
}
|
||||
missingSchemas = append(missingSchemas, parameterSchema)
|
||||
}
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("This project has required variables! They are scoped to the project, and not viewable after being set.")+"\r\n")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("This template has required variables! They are scoped to the template, and not viewable after being set.")+"\r\n")
|
||||
for _, parameterSchema := range missingSchemas {
|
||||
value, err := cliui.ParameterSchema(cmd, parameterSchema)
|
||||
if err != nil {
|
||||
|
@ -185,18 +185,18 @@ func createValidProjectVersion(cmd *cobra.Command, client *codersdk.Client, orga
|
|||
})
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout())
|
||||
}
|
||||
return createValidProjectVersion(cmd, client, organization, provisioner, hash, parameters...)
|
||||
return createValidTemplateVersion(cmd, client, organization, provisioner, hash, parameters...)
|
||||
}
|
||||
|
||||
if version.Job.Status != codersdk.ProvisionerJobSucceeded {
|
||||
return nil, nil, xerrors.New(version.Job.Error)
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), cliui.Styles.Checkmark.String()+" Successfully imported project source!\n")
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), cliui.Styles.Checkmark.String()+" Successfully imported template source!\n")
|
||||
|
||||
resources, err := client.ProjectVersionResources(cmd.Context(), version.ID)
|
||||
resources, err := client.TemplateVersionResources(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return &version, parameters, displayProjectVersionInfo(cmd, resources)
|
||||
return &version, parameters, displayTemplateVersionInfo(cmd, resources)
|
||||
}
|
|
@ -12,17 +12,17 @@ import (
|
|||
"github.com/coder/coder/pty/ptytest"
|
||||
)
|
||||
|
||||
func TestProjectCreate(t *testing.T) {
|
||||
func TestTemplateCreate(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.CreateFirstUser(t, client)
|
||||
source := clitest.CreateProjectVersionSource(t, &echo.Responses{
|
||||
source := clitest.CreateTemplateVersionSource(t, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: echo.ProvisionComplete,
|
||||
})
|
||||
cmd, root := clitest.New(t, "projects", "create", "my-project", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
|
||||
cmd, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--provisioner", string(database.ProvisionerTypeEcho))
|
||||
clitest.SetupConfig(t, client, root)
|
||||
_ = coderdtest.NewProvisionerDaemon(t, client)
|
||||
doneChan := make(chan struct{})
|
||||
|
@ -35,7 +35,7 @@ func TestProjectCreate(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
}()
|
||||
matches := []string{
|
||||
"Create project?", "yes",
|
||||
"Create template?", "yes",
|
||||
}
|
||||
for i := 0; i < len(matches); i += 2 {
|
||||
match := matches[i]
|
|
@ -2,7 +2,7 @@ package cli
|
|||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func projectEdit() *cobra.Command {
|
||||
func templateEdit() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "edit",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
@ -12,10 +12,10 @@ import (
|
|||
"github.com/coder/coder/provisionersdk"
|
||||
)
|
||||
|
||||
func projectInit() *cobra.Command {
|
||||
func templateInit() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "init [directory]",
|
||||
Short: "Get started with a templated project.",
|
||||
Short: "Get started with a templated template.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
exampleList, err := examples.List()
|
||||
if err != nil {
|
||||
|
@ -28,7 +28,7 @@ func projectInit() *cobra.Command {
|
|||
exampleByName[example.Name] = example
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Projects contain Infrastructure as Code that works with Coder to provision development workspaces. Get started by selecting an example:\n"))
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Templates contain Infrastructure as Code that works with Coder to provision development workspaces. Get started by selecting an example:\n"))
|
||||
option, err := cliui.Select(cmd, cliui.SelectOptions{
|
||||
Options: exampleNames,
|
||||
})
|
||||
|
@ -66,7 +66,7 @@ func projectInit() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Inside that directory, get started by running:")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("coder projects create"))+"\n")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render(cliui.Styles.Code.Render("coder templates create"))+"\n")
|
||||
return nil
|
||||
},
|
||||
}
|
|
@ -10,12 +10,12 @@ import (
|
|||
"github.com/coder/coder/pty/ptytest"
|
||||
)
|
||||
|
||||
func TestProjectInit(t *testing.T) {
|
||||
func TestTemplateInit(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Extract", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
tempDir := t.TempDir()
|
||||
cmd, _ := clitest.New(t, "projects", "init", tempDir)
|
||||
cmd, _ := clitest.New(t, "templates", "init", tempDir)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
cmd.SetIn(pty.Input())
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func projectList() *cobra.Command {
|
||||
func templateList() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "list",
|
||||
Aliases: []string{"ls"},
|
||||
|
@ -23,18 +23,18 @@ func projectList() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
projects, err := client.ProjectsByOrganization(cmd.Context(), organization.ID)
|
||||
templates, err := client.TemplatesByOrganization(cmd.Context(), organization.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(projects) == 0 {
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s No projects found in %s! Create one:\n\n", caret, color.HiWhiteString(organization.Name))
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), color.HiMagentaString(" $ coder projects create <directory>\n"))
|
||||
if len(templates) == 0 {
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s No templates found in %s! Create one:\n\n", caret, color.HiWhiteString(organization.Name))
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), color.HiMagentaString(" $ coder templates create <directory>\n"))
|
||||
return nil
|
||||
}
|
||||
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s Projects found in %s %s\n\n",
|
||||
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "%s Templates found in %s %s\n\n",
|
||||
caret,
|
||||
color.HiWhiteString(organization.Name),
|
||||
color.HiBlackString("[%dms]",
|
||||
|
@ -42,20 +42,20 @@ func projectList() *cobra.Command {
|
|||
|
||||
writer := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 4, ' ', 0)
|
||||
_, _ = fmt.Fprintf(writer, "%s\t%s\t%s\t%s\n",
|
||||
color.HiBlackString("Project"),
|
||||
color.HiBlackString("Template"),
|
||||
color.HiBlackString("Source"),
|
||||
color.HiBlackString("Last Updated"),
|
||||
color.HiBlackString("Used By"))
|
||||
for _, project := range projects {
|
||||
for _, template := range templates {
|
||||
suffix := ""
|
||||
if project.WorkspaceOwnerCount != 1 {
|
||||
if template.WorkspaceOwnerCount != 1 {
|
||||
suffix = "s"
|
||||
}
|
||||
_, _ = fmt.Fprintf(writer, "%s\t%s\t%s\t%s\n",
|
||||
color.New(color.FgHiCyan).Sprint(project.Name),
|
||||
color.New(color.FgHiCyan).Sprint(template.Name),
|
||||
color.WhiteString("Archive"),
|
||||
color.WhiteString(project.UpdatedAt.Format("January 2, 2006")),
|
||||
color.New(color.FgHiWhite).Sprintf("%d developer%s", project.WorkspaceOwnerCount, suffix))
|
||||
color.WhiteString(template.UpdatedAt.Format("January 2, 2006")),
|
||||
color.New(color.FgHiWhite).Sprintf("%d developer%s", template.WorkspaceOwnerCount, suffix))
|
||||
}
|
||||
return writer.Flush()
|
||||
},
|
|
@ -4,11 +4,11 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
func projectPlan() *cobra.Command {
|
||||
func templatePlan() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "plan <directory>",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Short: "Plan a project update from the current directory",
|
||||
Short: "Plan a template update from the current directory",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
|
@ -12,37 +12,37 @@ import (
|
|||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func projects() *cobra.Command {
|
||||
func templates() *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "projects",
|
||||
Aliases: []string{"project"},
|
||||
Use: "templates",
|
||||
Aliases: []string{"template"},
|
||||
Example: `
|
||||
- Create a project for developers to create workspaces
|
||||
- Create a template for developers to create workspaces
|
||||
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder projects create") + `
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder templates create") + `
|
||||
|
||||
- Make changes to your project, and plan the changes
|
||||
- Make changes to your template, and plan the changes
|
||||
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder projects plan <name>") + `
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder templates plan <name>") + `
|
||||
|
||||
- Update the project. Your developers can update their workspaces
|
||||
- Update the template. Your developers can update their workspaces
|
||||
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder projects update <name>"),
|
||||
` + color.New(color.FgHiMagenta).Sprint("$ coder templates update <name>"),
|
||||
}
|
||||
cmd.AddCommand(
|
||||
projectCreate(),
|
||||
projectEdit(),
|
||||
projectInit(),
|
||||
projectList(),
|
||||
projectPlan(),
|
||||
projectUpdate(),
|
||||
projectVersions(),
|
||||
templateCreate(),
|
||||
templateEdit(),
|
||||
templateInit(),
|
||||
templateList(),
|
||||
templatePlan(),
|
||||
templateUpdate(),
|
||||
templateVersions(),
|
||||
)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func displayProjectVersionInfo(cmd *cobra.Command, resources []codersdk.WorkspaceResource) error {
|
||||
func displayTemplateVersionInfo(cmd *cobra.Command, resources []codersdk.WorkspaceResource) error {
|
||||
sort.Slice(resources, func(i, j int) bool {
|
||||
return fmt.Sprintf("%s.%s", resources[i].Type, resources[i].Name) < fmt.Sprintf("%s.%s", resources[j].Type, resources[j].Name)
|
||||
})
|
|
@ -14,11 +14,11 @@ import (
|
|||
"github.com/coder/coder/provisionersdk"
|
||||
)
|
||||
|
||||
func projectUpdate() *cobra.Command {
|
||||
func templateUpdate() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "update <project> [directory]",
|
||||
Use: "update <template> [directory]",
|
||||
Args: cobra.MinimumNArgs(1),
|
||||
Short: "Update the source-code of a project from a directory.",
|
||||
Short: "Update the source-code of a template from a directory.",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := createClient(cmd)
|
||||
if err != nil {
|
||||
|
@ -28,7 +28,7 @@ func projectUpdate() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project, err := client.ProjectByName(cmd.Context(), organization.ID, args[0])
|
||||
template, err := client.TemplateByName(cmd.Context(), organization.ID, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -53,8 +53,8 @@ func projectUpdate() *cobra.Command {
|
|||
}
|
||||
|
||||
before := time.Now()
|
||||
projectVersion, err := client.CreateProjectVersion(cmd.Context(), organization.ID, codersdk.CreateProjectVersionRequest{
|
||||
ProjectID: project.ID,
|
||||
templateVersion, err := client.CreateTemplateVersion(cmd.Context(), organization.ID, codersdk.CreateTemplateVersionRequest{
|
||||
TemplateID: template.ID,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: resp.Hash,
|
||||
Provisioner: database.ProvisionerTypeTerraform,
|
||||
|
@ -62,7 +62,7 @@ func projectUpdate() *cobra.Command {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logs, err := client.ProjectVersionLogsAfter(cmd.Context(), projectVersion.ID, before)
|
||||
logs, err := client.TemplateVersionLogsAfter(cmd.Context(), templateVersion.ID, before)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -73,17 +73,17 @@ func projectUpdate() *cobra.Command {
|
|||
}
|
||||
_, _ = fmt.Printf("terraform (%s): %s\n", log.Level, log.Output)
|
||||
}
|
||||
projectVersion, err = client.ProjectVersion(cmd.Context(), projectVersion.ID)
|
||||
templateVersion, err = client.TemplateVersion(cmd.Context(), templateVersion.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if projectVersion.Job.Status != codersdk.ProvisionerJobSucceeded {
|
||||
if templateVersion.Job.Status != codersdk.ProvisionerJobSucceeded {
|
||||
return xerrors.New("job failed")
|
||||
}
|
||||
|
||||
err = client.UpdateActiveProjectVersion(cmd.Context(), project.ID, codersdk.UpdateActiveProjectVersion{
|
||||
ID: projectVersion.ID,
|
||||
err = client.UpdateActiveTemplateVersion(cmd.Context(), template.ID, codersdk.UpdateActiveTemplateVersion{
|
||||
ID: templateVersion.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
|
@ -2,7 +2,7 @@ package cli
|
|||
|
||||
import "github.com/spf13/cobra"
|
||||
|
||||
func projectVersions() *cobra.Command {
|
||||
func templateVersions() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "versions",
|
||||
Aliases: []string{"version"},
|
||||
|
@ -12,4 +12,4 @@ func projectVersions() *cobra.Command {
|
|||
}
|
||||
}
|
||||
|
||||
// coder project versions
|
||||
// coder template versions
|
|
@ -24,7 +24,7 @@ func TestWorkspaceAgent(t *testing.T) {
|
|||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -42,9 +42,9 @@ func TestWorkspaceAgent(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
cmd, _ := clitest.New(t, "workspaces", "agent", "--auth", "aws-instance-identity", "--url", client.URL.String())
|
||||
|
@ -78,7 +78,7 @@ func TestWorkspaceAgent(t *testing.T) {
|
|||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -96,9 +96,9 @@ func TestWorkspaceAgent(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
cmd, _ := clitest.New(t, "workspaces", "agent", "--auth", "google-instance-identity", "--url", client.URL.String())
|
||||
|
|
|
@ -18,12 +18,12 @@ import (
|
|||
|
||||
func workspaceCreate() *cobra.Command {
|
||||
var (
|
||||
projectName string
|
||||
templateName string
|
||||
)
|
||||
cmd := &cobra.Command{
|
||||
Use: "create <name>",
|
||||
Args: cobra.ExactArgs(1),
|
||||
Short: "Create a workspace from a project",
|
||||
Short: "Create a workspace from a template",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
client, err := createClient(cmd)
|
||||
if err != nil {
|
||||
|
@ -34,36 +34,36 @@ func workspaceCreate() *cobra.Command {
|
|||
return err
|
||||
}
|
||||
|
||||
var project codersdk.Project
|
||||
if projectName == "" {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Select a project:"))
|
||||
var template codersdk.Template
|
||||
if templateName == "" {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Wrap.Render("Select a template:"))
|
||||
|
||||
projectNames := []string{}
|
||||
projectByName := map[string]codersdk.Project{}
|
||||
projects, err := client.ProjectsByOrganization(cmd.Context(), organization.ID)
|
||||
templateNames := []string{}
|
||||
templateByName := map[string]codersdk.Template{}
|
||||
templates, err := client.TemplatesByOrganization(cmd.Context(), organization.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, project := range projects {
|
||||
projectNames = append(projectNames, project.Name)
|
||||
projectByName[project.Name] = project
|
||||
for _, template := range templates {
|
||||
templateNames = append(templateNames, template.Name)
|
||||
templateByName[template.Name] = template
|
||||
}
|
||||
sort.Slice(projectNames, func(i, j int) bool {
|
||||
return projectByName[projectNames[i]].WorkspaceOwnerCount > projectByName[projectNames[j]].WorkspaceOwnerCount
|
||||
sort.Slice(templateNames, func(i, j int) bool {
|
||||
return templateByName[templateNames[i]].WorkspaceOwnerCount > templateByName[templateNames[j]].WorkspaceOwnerCount
|
||||
})
|
||||
// Move the cursor up a single line for nicer display!
|
||||
option, err := cliui.Select(cmd, cliui.SelectOptions{
|
||||
Options: projectNames,
|
||||
Options: templateNames,
|
||||
HideSearch: true,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
project = projectByName[option]
|
||||
template = templateByName[option]
|
||||
} else {
|
||||
project, err = client.ProjectByName(cmd.Context(), organization.ID, projectName)
|
||||
template, err = client.TemplateByName(cmd.Context(), organization.ID, templateName)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get project by name: %w", err)
|
||||
return xerrors.Errorf("get template by name: %w", err)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -71,7 +71,7 @@ func workspaceCreate() *cobra.Command {
|
|||
}
|
||||
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout())
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Creating with the "+cliui.Styles.Field.Render(project.Name)+" project...")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Prompt.String()+"Creating with the "+cliui.Styles.Field.Render(template.Name)+" template...")
|
||||
|
||||
workspaceName := args[0]
|
||||
_, err = client.WorkspaceByName(cmd.Context(), codersdk.Me, workspaceName)
|
||||
|
@ -79,11 +79,11 @@ func workspaceCreate() *cobra.Command {
|
|||
return xerrors.Errorf("A workspace already exists named %q!", workspaceName)
|
||||
}
|
||||
|
||||
projectVersion, err := client.ProjectVersion(cmd.Context(), project.ActiveVersionID)
|
||||
templateVersion, err := client.TemplateVersion(cmd.Context(), template.ActiveVersionID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
parameterSchemas, err := client.ProjectVersionSchema(cmd.Context(), projectVersion.ID)
|
||||
parameterSchemas, err := client.TemplateVersionSchema(cmd.Context(), templateVersion.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ func workspaceCreate() *cobra.Command {
|
|||
continue
|
||||
}
|
||||
if !printed {
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("This project has customizable parameters! These can be changed after create, but may have unintended side effects (like data loss).")+"\r\n")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.Paragraph.Render("This template has customizable parameters! These can be changed after create, but may have unintended side effects (like data loss).")+"\r\n")
|
||||
printed = true
|
||||
}
|
||||
|
||||
|
@ -115,11 +115,11 @@ func workspaceCreate() *cobra.Command {
|
|||
_, _ = fmt.Fprintln(cmd.OutOrStdout(), cliui.Styles.FocusedPrompt.String()+"Previewing resources...")
|
||||
_, _ = fmt.Fprintln(cmd.OutOrStdout())
|
||||
}
|
||||
resources, err := client.ProjectVersionResources(cmd.Context(), projectVersion.ID)
|
||||
resources, err := client.TemplateVersionResources(cmd.Context(), templateVersion.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = displayProjectVersionInfo(cmd, resources)
|
||||
err = displayTemplateVersionInfo(cmd, resources)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ func workspaceCreate() *cobra.Command {
|
|||
|
||||
before := time.Now()
|
||||
workspace, err := client.CreateWorkspace(cmd.Context(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: project.ID,
|
||||
TemplateID: template.ID,
|
||||
Name: workspaceName,
|
||||
ParameterValues: parameters,
|
||||
})
|
||||
|
@ -167,7 +167,7 @@ func workspaceCreate() *cobra.Command {
|
|||
return err
|
||||
},
|
||||
}
|
||||
cmd.Flags().StringVarP(&projectName, "project", "p", "", "Specify a project name.")
|
||||
cmd.Flags().StringVarP(&templateName, "template", "p", "", "Specify a template name.")
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -17,10 +17,10 @@ func TestWorkspaceCreate(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "my-workspace", "--project", project.Name)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
cmd, root := clitest.New(t, "workspaces", "create", "my-workspace", "--template", template.Name)
|
||||
clitest.SetupConfig(t, client, root)
|
||||
doneChan := make(chan struct{})
|
||||
pty := ptytest.New(t)
|
||||
|
|
|
@ -42,14 +42,14 @@ func workspaceList() *cobra.Command {
|
|||
writer := tabwriter.NewWriter(cmd.OutOrStdout(), 0, 0, 4, ' ', 0)
|
||||
_, _ = fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%s\n",
|
||||
color.HiBlackString("Workspace"),
|
||||
color.HiBlackString("Project"),
|
||||
color.HiBlackString("Template"),
|
||||
color.HiBlackString("Status"),
|
||||
color.HiBlackString("Last Built"),
|
||||
color.HiBlackString("Outdated"))
|
||||
for _, workspace := range workspaces {
|
||||
_, _ = fmt.Fprintf(writer, "%s\t%s\t%s\t%s\t%+v\n",
|
||||
color.New(color.FgHiCyan).Sprint(workspace.Name),
|
||||
color.WhiteString(workspace.ProjectName),
|
||||
color.WhiteString(workspace.TemplateName),
|
||||
color.WhiteString(string(workspace.LatestBuild.Transition)),
|
||||
color.WhiteString(workspace.LatestBuild.Job.CompletedAt.Format("January 2, 2006")),
|
||||
workspace.Outdated)
|
||||
|
|
|
@ -25,14 +25,14 @@ func workspaceUpdate() *cobra.Command {
|
|||
_, _ = fmt.Printf("Workspace isn't outdated!\n")
|
||||
return nil
|
||||
}
|
||||
project, err := client.Project(cmd.Context(), workspace.ProjectID)
|
||||
template, err := client.Template(cmd.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
before := time.Now()
|
||||
build, err := client.CreateWorkspaceBuild(cmd.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
ProjectVersionID: project.ActiveVersionID,
|
||||
Transition: workspace.LatestBuild.Transition,
|
||||
TemplateVersionID: template.ActiveVersionID,
|
||||
Transition: workspace.LatestBuild.Transition,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -130,7 +130,7 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
}
|
||||
|
||||
before := time.Now()
|
||||
version, err := client.CreateProjectVersion(cmd.Context(), created.OrganizationID, codersdk.CreateProjectVersionRequest{
|
||||
version, err := client.CreateTemplateVersion(cmd.Context(), created.OrganizationID, codersdk.CreateTemplateVersionRequest{
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: resp.Hash,
|
||||
Provisioner: database.ProvisionerTypeTerraform,
|
||||
|
@ -139,7 +139,7 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
logs, err := client.ProjectVersionLogsAfter(cmd.Context(), version.ID, before)
|
||||
logs, err := client.TemplateVersionLogsAfter(cmd.Context(), version.ID, before)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
}
|
||||
_, _ = fmt.Printf("terraform (%s): %s\n", log.Level, log.Output)
|
||||
}
|
||||
version, err = client.ProjectVersion(cmd.Context(), version.ID)
|
||||
version, err = client.TemplateVersion(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -158,12 +158,12 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
return xerrors.Errorf("Job wasn't successful, it was %q. Check the logs!", version.Job.Status)
|
||||
}
|
||||
|
||||
_, err = client.ProjectVersionResources(cmd.Context(), version.ID)
|
||||
_, err = client.TemplateVersionResources(cmd.Context(), version.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
project, err := client.CreateProject(cmd.Context(), created.OrganizationID, codersdk.CreateProjectRequest{
|
||||
template, err := client.CreateTemplate(cmd.Context(), created.OrganizationID, codersdk.CreateTemplateRequest{
|
||||
Name: "test",
|
||||
VersionID: version.ID,
|
||||
})
|
||||
|
@ -172,8 +172,8 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
}
|
||||
|
||||
workspace, err := client.CreateWorkspace(cmd.Context(), created.UserID, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: project.ID,
|
||||
Name: "example",
|
||||
TemplateID: template.ID,
|
||||
Name: "example",
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -205,8 +205,8 @@ func parse(cmd *cobra.Command, parameters []codersdk.CreateParameterRequest) err
|
|||
}
|
||||
|
||||
build, err := client.CreateWorkspaceBuild(cmd.Context(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
ProjectVersionID: version.ID,
|
||||
Transition: database.WorkspaceTransitionDelete,
|
||||
TemplateVersionID: version.ID,
|
||||
Transition: database.WorkspaceTransitionDelete,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -76,11 +76,11 @@ func New(options *Options) (http.Handler, func()) {
|
|||
)
|
||||
r.Get("/", api.organization)
|
||||
r.Get("/provisionerdaemons", api.provisionerDaemonsByOrganization)
|
||||
r.Post("/projectversions", api.postProjectVersionsByOrganization)
|
||||
r.Route("/projects", func(r chi.Router) {
|
||||
r.Post("/", api.postProjectsByOrganization)
|
||||
r.Get("/", api.projectsByOrganization)
|
||||
r.Get("/{projectname}", api.projectByOrganizationAndName)
|
||||
r.Post("/templateversions", api.postTemplateVersionsByOrganization)
|
||||
r.Route("/templates", func(r chi.Router) {
|
||||
r.Post("/", api.postTemplatesByOrganization)
|
||||
r.Get("/", api.templatesByOrganization)
|
||||
r.Get("/{templatename}", api.templateByOrganizationAndName)
|
||||
})
|
||||
})
|
||||
r.Route("/parameters/{scope}/{id}", func(r chi.Router) {
|
||||
|
@ -91,33 +91,33 @@ func New(options *Options) (http.Handler, func()) {
|
|||
r.Delete("/", api.deleteParameter)
|
||||
})
|
||||
})
|
||||
r.Route("/projects/{project}", func(r chi.Router) {
|
||||
r.Route("/templates/{template}", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.ExtractAPIKey(options.Database, nil),
|
||||
httpmw.ExtractProjectParam(options.Database),
|
||||
httpmw.ExtractTemplateParam(options.Database),
|
||||
httpmw.ExtractOrganizationParam(options.Database),
|
||||
)
|
||||
r.Get("/", api.project)
|
||||
r.Delete("/", api.deleteProject)
|
||||
r.Get("/", api.template)
|
||||
r.Delete("/", api.deleteTemplate)
|
||||
r.Route("/versions", func(r chi.Router) {
|
||||
r.Get("/", api.projectVersionsByProject)
|
||||
r.Patch("/", api.patchActiveProjectVersion)
|
||||
r.Get("/{projectversionname}", api.projectVersionByName)
|
||||
r.Get("/", api.templateVersionsByTemplate)
|
||||
r.Patch("/", api.patchActiveTemplateVersion)
|
||||
r.Get("/{templateversionname}", api.templateVersionByName)
|
||||
})
|
||||
})
|
||||
r.Route("/projectversions/{projectversion}", func(r chi.Router) {
|
||||
r.Route("/templateversions/{templateversion}", func(r chi.Router) {
|
||||
r.Use(
|
||||
httpmw.ExtractAPIKey(options.Database, nil),
|
||||
httpmw.ExtractProjectVersionParam(options.Database),
|
||||
httpmw.ExtractTemplateVersionParam(options.Database),
|
||||
httpmw.ExtractOrganizationParam(options.Database),
|
||||
)
|
||||
|
||||
r.Get("/", api.projectVersion)
|
||||
r.Patch("/cancel", api.patchCancelProjectVersion)
|
||||
r.Get("/schema", api.projectVersionSchema)
|
||||
r.Get("/parameters", api.projectVersionParameters)
|
||||
r.Get("/resources", api.projectVersionResources)
|
||||
r.Get("/logs", api.projectVersionLogs)
|
||||
r.Get("/", api.templateVersion)
|
||||
r.Patch("/cancel", api.patchCancelTemplateVersion)
|
||||
r.Get("/schema", api.templateVersionSchema)
|
||||
r.Get("/parameters", api.templateVersionParameters)
|
||||
r.Get("/resources", api.templateVersionResources)
|
||||
r.Get("/logs", api.templateVersionLogs)
|
||||
})
|
||||
r.Route("/provisionerdaemons", func(r chi.Router) {
|
||||
r.Route("/me", func(r chi.Router) {
|
||||
|
|
|
@ -203,44 +203,44 @@ func CreateAnotherUser(t *testing.T, client *codersdk.Client, organizationID uui
|
|||
return other
|
||||
}
|
||||
|
||||
// CreateProjectVersion creates a project import provisioner job
|
||||
// CreateTemplateVersion creates a template import provisioner job
|
||||
// with the responses provided. It uses the "echo" provisioner for compatibility
|
||||
// with testing.
|
||||
func CreateProjectVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses) codersdk.ProjectVersion {
|
||||
func CreateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID uuid.UUID, res *echo.Responses) codersdk.TemplateVersion {
|
||||
data, err := echo.Tar(res)
|
||||
require.NoError(t, err)
|
||||
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, data)
|
||||
require.NoError(t, err)
|
||||
projectVersion, err := client.CreateProjectVersion(context.Background(), organizationID, codersdk.CreateProjectVersionRequest{
|
||||
templateVersion, err := client.CreateTemplateVersion(context.Background(), organizationID, codersdk.CreateTemplateVersionRequest{
|
||||
StorageSource: file.Hash,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return projectVersion
|
||||
return templateVersion
|
||||
}
|
||||
|
||||
// CreateProject creates a project with the "echo" provisioner for
|
||||
// CreateTemplate creates a template with the "echo" provisioner for
|
||||
// compatibility with testing. The name assigned is randomly generated.
|
||||
func CreateProject(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID) codersdk.Project {
|
||||
project, err := client.CreateProject(context.Background(), organization, codersdk.CreateProjectRequest{
|
||||
func CreateTemplate(t *testing.T, client *codersdk.Client, organization uuid.UUID, version uuid.UUID) codersdk.Template {
|
||||
template, err := client.CreateTemplate(context.Background(), organization, codersdk.CreateTemplateRequest{
|
||||
Name: randomUsername(),
|
||||
VersionID: version,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return project
|
||||
return template
|
||||
}
|
||||
|
||||
// AwaitProjectImportJob awaits for an import job to reach completed status.
|
||||
func AwaitProjectVersionJob(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.ProjectVersion {
|
||||
var projectVersion codersdk.ProjectVersion
|
||||
// AwaitTemplateImportJob awaits for an import job to reach completed status.
|
||||
func AwaitTemplateVersionJob(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
|
||||
var templateVersion codersdk.TemplateVersion
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
projectVersion, err = client.ProjectVersion(context.Background(), version)
|
||||
templateVersion, err = client.TemplateVersion(context.Background(), version)
|
||||
require.NoError(t, err)
|
||||
return projectVersion.Job.CompletedAt != nil
|
||||
return templateVersion.Job.CompletedAt != nil
|
||||
}, 5*time.Second, 25*time.Millisecond)
|
||||
return projectVersion
|
||||
return templateVersion
|
||||
}
|
||||
|
||||
// AwaitWorkspaceBuildJob waits for a workspace provision job to reach completed status.
|
||||
|
@ -275,12 +275,12 @@ func AwaitWorkspaceAgents(t *testing.T, client *codersdk.Client, build uuid.UUID
|
|||
return resources
|
||||
}
|
||||
|
||||
// CreateWorkspace creates a workspace for the user and project provided.
|
||||
// CreateWorkspace creates a workspace for the user and template provided.
|
||||
// A random name is generated for it.
|
||||
func CreateWorkspace(t *testing.T, client *codersdk.Client, user uuid.UUID, projectID uuid.UUID) codersdk.Workspace {
|
||||
func CreateWorkspace(t *testing.T, client *codersdk.Client, user uuid.UUID, templateID uuid.UUID) codersdk.Workspace {
|
||||
workspace, err := client.CreateWorkspace(context.Background(), user, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: projectID,
|
||||
Name: randomUsername(),
|
||||
TemplateID: templateID,
|
||||
Name: randomUsername(),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
return workspace
|
||||
|
|
|
@ -18,10 +18,10 @@ func TestNew(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
closer := coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
coderdtest.AwaitWorkspaceAgents(t, client, workspace.LatestBuild.ID)
|
||||
_, _ = coderdtest.NewGoogleInstanceIdentity(t, "example", false)
|
||||
|
|
|
@ -22,8 +22,8 @@ func New() database.Store {
|
|||
files: make([]database.File, 0),
|
||||
parameterValue: make([]database.ParameterValue, 0),
|
||||
parameterSchema: make([]database.ParameterSchema, 0),
|
||||
project: make([]database.Project, 0),
|
||||
projectVersion: make([]database.ProjectVersion, 0),
|
||||
template: make([]database.Template, 0),
|
||||
templateVersion: make([]database.TemplateVersion, 0),
|
||||
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
|
||||
provisionerJobs: make([]database.ProvisionerJob, 0),
|
||||
provisionerJobLog: make([]database.ProvisionerJobLog, 0),
|
||||
|
@ -49,8 +49,8 @@ type fakeQuerier struct {
|
|||
files []database.File
|
||||
parameterValue []database.ParameterValue
|
||||
parameterSchema []database.ParameterSchema
|
||||
project []database.Project
|
||||
projectVersion []database.ProjectVersion
|
||||
template []database.Template
|
||||
templateVersion []database.TemplateVersion
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
provisionerJobAgent []database.WorkspaceAgent
|
||||
|
@ -164,13 +164,13 @@ func (q *fakeQuerier) GetUserCount(_ context.Context) (int64, error) {
|
|||
return int64(len(q.users)), nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetWorkspacesByProjectID(_ context.Context, arg database.GetWorkspacesByProjectIDParams) ([]database.Workspace, error) {
|
||||
func (q *fakeQuerier) GetWorkspacesByTemplateID(_ context.Context, arg database.GetWorkspacesByTemplateIDParams) ([]database.Workspace, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
workspaces := make([]database.Workspace, 0)
|
||||
for _, workspace := range q.workspace {
|
||||
if workspace.ProjectID.String() != arg.ProjectID.String() {
|
||||
if workspace.TemplateID.String() != arg.TemplateID.String() {
|
||||
continue
|
||||
}
|
||||
if workspace.Deleted != arg.Deleted {
|
||||
|
@ -215,38 +215,38 @@ func (q *fakeQuerier) GetWorkspaceByUserIDAndName(_ context.Context, arg databas
|
|||
return database.Workspace{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetWorkspaceOwnerCountsByProjectIDs(_ context.Context, projectIDs []uuid.UUID) ([]database.GetWorkspaceOwnerCountsByProjectIDsRow, error) {
|
||||
func (q *fakeQuerier) GetWorkspaceOwnerCountsByTemplateIDs(_ context.Context, templateIDs []uuid.UUID) ([]database.GetWorkspaceOwnerCountsByTemplateIDsRow, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
counts := map[uuid.UUID]map[uuid.UUID]struct{}{}
|
||||
for _, projectID := range projectIDs {
|
||||
for _, templateID := range templateIDs {
|
||||
found := false
|
||||
for _, workspace := range q.workspace {
|
||||
if workspace.ProjectID != projectID {
|
||||
if workspace.TemplateID != templateID {
|
||||
continue
|
||||
}
|
||||
if workspace.Deleted {
|
||||
continue
|
||||
}
|
||||
countByOwnerID, ok := counts[projectID]
|
||||
countByOwnerID, ok := counts[templateID]
|
||||
if !ok {
|
||||
countByOwnerID = map[uuid.UUID]struct{}{}
|
||||
}
|
||||
countByOwnerID[workspace.OwnerID] = struct{}{}
|
||||
counts[projectID] = countByOwnerID
|
||||
counts[templateID] = countByOwnerID
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
counts[projectID] = map[uuid.UUID]struct{}{}
|
||||
counts[templateID] = map[uuid.UUID]struct{}{}
|
||||
}
|
||||
}
|
||||
res := make([]database.GetWorkspaceOwnerCountsByProjectIDsRow, 0)
|
||||
res := make([]database.GetWorkspaceOwnerCountsByTemplateIDsRow, 0)
|
||||
for key, value := range counts {
|
||||
res = append(res, database.GetWorkspaceOwnerCountsByProjectIDsRow{
|
||||
ProjectID: key,
|
||||
Count: int64(len(value)),
|
||||
res = append(res, database.GetWorkspaceOwnerCountsByTemplateIDsRow{
|
||||
TemplateID: key,
|
||||
Count: int64(len(value)),
|
||||
})
|
||||
}
|
||||
if len(res) == 0 {
|
||||
|
@ -431,47 +431,47 @@ func (q *fakeQuerier) GetParameterValuesByScope(_ context.Context, arg database.
|
|||
return parameterValues, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectByID(_ context.Context, id uuid.UUID) (database.Project, error) {
|
||||
func (q *fakeQuerier) GetTemplateByID(_ context.Context, id uuid.UUID) (database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, project := range q.project {
|
||||
if project.ID.String() == id.String() {
|
||||
return project, nil
|
||||
for _, template := range q.template {
|
||||
if template.ID.String() == id.String() {
|
||||
return template, nil
|
||||
}
|
||||
}
|
||||
return database.Project{}, sql.ErrNoRows
|
||||
return database.Template{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectByOrganizationAndName(_ context.Context, arg database.GetProjectByOrganizationAndNameParams) (database.Project, error) {
|
||||
func (q *fakeQuerier) GetTemplateByOrganizationAndName(_ context.Context, arg database.GetTemplateByOrganizationAndNameParams) (database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, project := range q.project {
|
||||
if project.OrganizationID != arg.OrganizationID {
|
||||
for _, template := range q.template {
|
||||
if template.OrganizationID != arg.OrganizationID {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(project.Name, arg.Name) {
|
||||
if !strings.EqualFold(template.Name, arg.Name) {
|
||||
continue
|
||||
}
|
||||
if project.Deleted != arg.Deleted {
|
||||
if template.Deleted != arg.Deleted {
|
||||
continue
|
||||
}
|
||||
return project, nil
|
||||
return template, nil
|
||||
}
|
||||
return database.Project{}, sql.ErrNoRows
|
||||
return database.Template{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectVersionsByProjectID(_ context.Context, projectID uuid.UUID) ([]database.ProjectVersion, error) {
|
||||
func (q *fakeQuerier) GetTemplateVersionsByTemplateID(_ context.Context, templateID uuid.UUID) ([]database.TemplateVersion, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
version := make([]database.ProjectVersion, 0)
|
||||
for _, projectVersion := range q.projectVersion {
|
||||
if projectVersion.ProjectID.UUID.String() != projectID.String() {
|
||||
version := make([]database.TemplateVersion, 0)
|
||||
for _, templateVersion := range q.templateVersion {
|
||||
if templateVersion.TemplateID.UUID.String() != templateID.String() {
|
||||
continue
|
||||
}
|
||||
version = append(version, projectVersion)
|
||||
version = append(version, templateVersion)
|
||||
}
|
||||
if len(version) == 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
|
@ -479,46 +479,46 @@ func (q *fakeQuerier) GetProjectVersionsByProjectID(_ context.Context, projectID
|
|||
return version, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectVersionByProjectIDAndName(_ context.Context, arg database.GetProjectVersionByProjectIDAndNameParams) (database.ProjectVersion, error) {
|
||||
func (q *fakeQuerier) GetTemplateVersionByTemplateIDAndName(_ context.Context, arg database.GetTemplateVersionByTemplateIDAndNameParams) (database.TemplateVersion, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, projectVersion := range q.projectVersion {
|
||||
if projectVersion.ProjectID != arg.ProjectID {
|
||||
for _, templateVersion := range q.templateVersion {
|
||||
if templateVersion.TemplateID != arg.TemplateID {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(projectVersion.Name, arg.Name) {
|
||||
if !strings.EqualFold(templateVersion.Name, arg.Name) {
|
||||
continue
|
||||
}
|
||||
return projectVersion, nil
|
||||
return templateVersion, nil
|
||||
}
|
||||
return database.ProjectVersion{}, sql.ErrNoRows
|
||||
return database.TemplateVersion{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectVersionByID(_ context.Context, projectVersionID uuid.UUID) (database.ProjectVersion, error) {
|
||||
func (q *fakeQuerier) GetTemplateVersionByID(_ context.Context, templateVersionID uuid.UUID) (database.TemplateVersion, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, projectVersion := range q.projectVersion {
|
||||
if projectVersion.ID.String() != projectVersionID.String() {
|
||||
for _, templateVersion := range q.templateVersion {
|
||||
if templateVersion.ID.String() != templateVersionID.String() {
|
||||
continue
|
||||
}
|
||||
return projectVersion, nil
|
||||
return templateVersion, nil
|
||||
}
|
||||
return database.ProjectVersion{}, sql.ErrNoRows
|
||||
return database.TemplateVersion{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectVersionByJobID(_ context.Context, jobID uuid.UUID) (database.ProjectVersion, error) {
|
||||
func (q *fakeQuerier) GetTemplateVersionByJobID(_ context.Context, jobID uuid.UUID) (database.TemplateVersion, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, projectVersion := range q.projectVersion {
|
||||
if projectVersion.JobID.String() != jobID.String() {
|
||||
for _, templateVersion := range q.templateVersion {
|
||||
if templateVersion.JobID.String() != jobID.String() {
|
||||
continue
|
||||
}
|
||||
return projectVersion, nil
|
||||
return templateVersion, nil
|
||||
}
|
||||
return database.ProjectVersion{}, sql.ErrNoRows
|
||||
return database.TemplateVersion{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.UUID) ([]database.ParameterSchema, error) {
|
||||
|
@ -557,43 +557,43 @@ func (q *fakeQuerier) GetParameterValueByScopeAndName(_ context.Context, arg dat
|
|||
return database.ParameterValue{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectsByOrganization(_ context.Context, arg database.GetProjectsByOrganizationParams) ([]database.Project, error) {
|
||||
func (q *fakeQuerier) GetTemplatesByOrganization(_ context.Context, arg database.GetTemplatesByOrganizationParams) ([]database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
projects := make([]database.Project, 0)
|
||||
for _, project := range q.project {
|
||||
if project.Deleted != arg.Deleted {
|
||||
templates := make([]database.Template, 0)
|
||||
for _, template := range q.template {
|
||||
if template.Deleted != arg.Deleted {
|
||||
continue
|
||||
}
|
||||
if project.OrganizationID != arg.OrganizationID {
|
||||
if template.OrganizationID != arg.OrganizationID {
|
||||
continue
|
||||
}
|
||||
projects = append(projects, project)
|
||||
templates = append(templates, template)
|
||||
}
|
||||
if len(projects) == 0 {
|
||||
if len(templates) == 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return projects, nil
|
||||
return templates, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetProjectsByIDs(_ context.Context, ids []uuid.UUID) ([]database.Project, error) {
|
||||
func (q *fakeQuerier) GetTemplatesByIDs(_ context.Context, ids []uuid.UUID) ([]database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
projects := make([]database.Project, 0)
|
||||
for _, project := range q.project {
|
||||
templates := make([]database.Template, 0)
|
||||
for _, template := range q.template {
|
||||
for _, id := range ids {
|
||||
if project.ID.String() != id.String() {
|
||||
if template.ID.String() != id.String() {
|
||||
continue
|
||||
}
|
||||
projects = append(projects, project)
|
||||
templates = append(templates, template)
|
||||
}
|
||||
}
|
||||
if len(projects) == 0 {
|
||||
if len(templates) == 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return projects, nil
|
||||
return templates, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetOrganizationMemberByUserID(_ context.Context, arg database.GetOrganizationMemberByUserIDParams) (database.OrganizationMember, error) {
|
||||
|
@ -850,12 +850,12 @@ func (q *fakeQuerier) InsertParameterValue(_ context.Context, arg database.Inser
|
|||
return parameterValue, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertProject(_ context.Context, arg database.InsertProjectParams) (database.Project, error) {
|
||||
func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTemplateParams) (database.Template, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
project := database.Project{
|
||||
template := database.Template{
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
|
@ -864,18 +864,18 @@ func (q *fakeQuerier) InsertProject(_ context.Context, arg database.InsertProjec
|
|||
Provisioner: arg.Provisioner,
|
||||
ActiveVersionID: arg.ActiveVersionID,
|
||||
}
|
||||
q.project = append(q.project, project)
|
||||
return project, nil
|
||||
q.template = append(q.template, template)
|
||||
return template, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertProjectVersion(_ context.Context, arg database.InsertProjectVersionParams) (database.ProjectVersion, error) {
|
||||
func (q *fakeQuerier) InsertTemplateVersion(_ context.Context, arg database.InsertTemplateVersionParams) (database.TemplateVersion, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
version := database.ProjectVersion{
|
||||
version := database.TemplateVersion{
|
||||
ID: arg.ID,
|
||||
ProjectID: arg.ProjectID,
|
||||
TemplateID: arg.TemplateID,
|
||||
OrganizationID: arg.OrganizationID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
|
@ -883,7 +883,7 @@ func (q *fakeQuerier) InsertProjectVersion(_ context.Context, arg database.Inser
|
|||
Description: arg.Description,
|
||||
JobID: arg.JobID,
|
||||
}
|
||||
q.projectVersion = append(q.projectVersion, version)
|
||||
q.templateVersion = append(q.templateVersion, version)
|
||||
return version, nil
|
||||
}
|
||||
|
||||
|
@ -1033,12 +1033,12 @@ func (q *fakeQuerier) InsertWorkspace(_ context.Context, arg database.InsertWork
|
|||
|
||||
//nolint:gosimple
|
||||
workspace := database.Workspace{
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
OwnerID: arg.OwnerID,
|
||||
ProjectID: arg.ProjectID,
|
||||
Name: arg.Name,
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
OwnerID: arg.OwnerID,
|
||||
TemplateID: arg.TemplateID,
|
||||
Name: arg.Name,
|
||||
}
|
||||
q.workspace = append(q.workspace, workspace)
|
||||
return workspace, nil
|
||||
|
@ -1049,17 +1049,17 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
|
|||
defer q.mutex.Unlock()
|
||||
|
||||
workspaceBuild := database.WorkspaceBuild{
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
WorkspaceID: arg.WorkspaceID,
|
||||
Name: arg.Name,
|
||||
ProjectVersionID: arg.ProjectVersionID,
|
||||
BeforeID: arg.BeforeID,
|
||||
Transition: arg.Transition,
|
||||
InitiatorID: arg.InitiatorID,
|
||||
JobID: arg.JobID,
|
||||
ProvisionerState: arg.ProvisionerState,
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
WorkspaceID: arg.WorkspaceID,
|
||||
Name: arg.Name,
|
||||
TemplateVersionID: arg.TemplateVersionID,
|
||||
BeforeID: arg.BeforeID,
|
||||
Transition: arg.Transition,
|
||||
InitiatorID: arg.InitiatorID,
|
||||
JobID: arg.JobID,
|
||||
ProvisionerState: arg.ProvisionerState,
|
||||
}
|
||||
q.workspaceBuild = append(q.workspaceBuild, workspaceBuild)
|
||||
return workspaceBuild, nil
|
||||
|
@ -1084,47 +1084,47 @@ func (q *fakeQuerier) UpdateAPIKeyByID(_ context.Context, arg database.UpdateAPI
|
|||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateProjectActiveVersionByID(_ context.Context, arg database.UpdateProjectActiveVersionByIDParams) error {
|
||||
func (q *fakeQuerier) UpdateTemplateActiveVersionByID(_ context.Context, arg database.UpdateTemplateActiveVersionByIDParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, project := range q.project {
|
||||
if project.ID.String() != arg.ID.String() {
|
||||
for index, template := range q.template {
|
||||
if template.ID.String() != arg.ID.String() {
|
||||
continue
|
||||
}
|
||||
project.ActiveVersionID = arg.ActiveVersionID
|
||||
q.project[index] = project
|
||||
template.ActiveVersionID = arg.ActiveVersionID
|
||||
q.template[index] = template
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateProjectDeletedByID(_ context.Context, arg database.UpdateProjectDeletedByIDParams) error {
|
||||
func (q *fakeQuerier) UpdateTemplateDeletedByID(_ context.Context, arg database.UpdateTemplateDeletedByIDParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, project := range q.project {
|
||||
if project.ID.String() != arg.ID.String() {
|
||||
for index, template := range q.template {
|
||||
if template.ID.String() != arg.ID.String() {
|
||||
continue
|
||||
}
|
||||
project.Deleted = arg.Deleted
|
||||
q.project[index] = project
|
||||
template.Deleted = arg.Deleted
|
||||
q.template[index] = template
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) UpdateProjectVersionByID(_ context.Context, arg database.UpdateProjectVersionByIDParams) error {
|
||||
func (q *fakeQuerier) UpdateTemplateVersionByID(_ context.Context, arg database.UpdateTemplateVersionByIDParams) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, projectVersion := range q.projectVersion {
|
||||
if projectVersion.ID.String() != arg.ID.String() {
|
||||
for index, templateVersion := range q.templateVersion {
|
||||
if templateVersion.ID.String() != arg.ID.String() {
|
||||
continue
|
||||
}
|
||||
projectVersion.ProjectID = arg.ProjectID
|
||||
projectVersion.UpdatedAt = arg.UpdatedAt
|
||||
q.projectVersion[index] = projectVersion
|
||||
templateVersion.TemplateID = arg.TemplateID
|
||||
templateVersion.UpdatedAt = arg.UpdatedAt
|
||||
q.templateVersion[index] = templateVersion
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
|
|
|
@ -27,7 +27,7 @@ CREATE TYPE parameter_destination_scheme AS ENUM (
|
|||
|
||||
CREATE TYPE parameter_scope AS ENUM (
|
||||
'organization',
|
||||
'project',
|
||||
'template',
|
||||
'import_job',
|
||||
'user',
|
||||
'workspace'
|
||||
|
@ -44,7 +44,7 @@ CREATE TYPE parameter_type_system AS ENUM (
|
|||
);
|
||||
|
||||
CREATE TYPE provisioner_job_type AS ENUM (
|
||||
'project_version_import',
|
||||
'template_version_import',
|
||||
'workspace_build'
|
||||
);
|
||||
|
||||
|
@ -160,28 +160,6 @@ CREATE TABLE parameter_values (
|
|||
destination_scheme parameter_destination_scheme NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE project_versions (
|
||||
id uuid NOT NULL,
|
||||
project_id uuid,
|
||||
organization_id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
description character varying(1048576) NOT NULL,
|
||||
job_id uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE projects (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
organization_id uuid NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
provisioner provisioner_type NOT NULL,
|
||||
active_version_id uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE provisioner_daemons (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
|
@ -219,6 +197,28 @@ CREATE TABLE provisioner_jobs (
|
|||
worker_id uuid
|
||||
);
|
||||
|
||||
CREATE TABLE template_versions (
|
||||
id uuid NOT NULL,
|
||||
template_id uuid,
|
||||
organization_id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
description character varying(1048576) NOT NULL,
|
||||
job_id uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE templates (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
organization_id uuid NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
provisioner provisioner_type NOT NULL,
|
||||
active_version_id uuid NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id uuid NOT NULL,
|
||||
email text NOT NULL,
|
||||
|
@ -252,7 +252,7 @@ CREATE TABLE workspace_builds (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
workspace_id uuid NOT NULL,
|
||||
project_version_id uuid NOT NULL,
|
||||
template_version_id uuid NOT NULL,
|
||||
name character varying(64) NOT NULL,
|
||||
before_id uuid,
|
||||
after_id uuid,
|
||||
|
@ -278,7 +278,7 @@ CREATE TABLE workspaces (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
owner_id uuid NOT NULL,
|
||||
project_id uuid NOT NULL,
|
||||
template_id uuid NOT NULL,
|
||||
deleted boolean DEFAULT false NOT NULL,
|
||||
name character varying(64) NOT NULL
|
||||
);
|
||||
|
@ -315,18 +315,6 @@ ALTER TABLE ONLY parameter_values
|
|||
ALTER TABLE ONLY parameter_values
|
||||
ADD CONSTRAINT parameter_values_scope_id_name_key UNIQUE (scope_id, name);
|
||||
|
||||
ALTER TABLE ONLY project_versions
|
||||
ADD CONSTRAINT project_versions_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY project_versions
|
||||
ADD CONSTRAINT project_versions_project_id_name_key UNIQUE (project_id, name);
|
||||
|
||||
ALTER TABLE ONLY projects
|
||||
ADD CONSTRAINT projects_organization_id_name_key UNIQUE (organization_id, name);
|
||||
|
||||
ALTER TABLE ONLY projects
|
||||
ADD CONSTRAINT projects_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY provisioner_daemons
|
||||
ADD CONSTRAINT provisioner_daemons_name_key UNIQUE (name);
|
||||
|
||||
|
@ -339,6 +327,18 @@ ALTER TABLE ONLY provisioner_job_logs
|
|||
ALTER TABLE ONLY provisioner_jobs
|
||||
ADD CONSTRAINT provisioner_jobs_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY template_versions
|
||||
ADD CONSTRAINT template_versions_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY template_versions
|
||||
ADD CONSTRAINT template_versions_template_id_name_key UNIQUE (template_id, name);
|
||||
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_organization_id_name_key UNIQUE (organization_id, name);
|
||||
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE ONLY users
|
||||
ADD CONSTRAINT users_pkey PRIMARY KEY (id);
|
||||
|
||||
|
@ -373,7 +373,7 @@ CREATE UNIQUE INDEX idx_organization_name ON organizations USING btree (name);
|
|||
|
||||
CREATE UNIQUE INDEX idx_organization_name_lower ON organizations USING btree (lower(name));
|
||||
|
||||
CREATE UNIQUE INDEX idx_projects_name_lower ON projects USING btree (lower((name)::text));
|
||||
CREATE UNIQUE INDEX idx_templates_name_lower ON templates USING btree (lower((name)::text));
|
||||
|
||||
CREATE UNIQUE INDEX idx_users_email ON users USING btree (email);
|
||||
|
||||
|
@ -381,7 +381,7 @@ CREATE UNIQUE INDEX idx_users_username ON users USING btree (username);
|
|||
|
||||
CREATE UNIQUE INDEX idx_workspaces_name_lower ON workspaces USING btree (lower((name)::text));
|
||||
|
||||
CREATE UNIQUE INDEX projects_organization_id_name_idx ON projects USING btree (organization_id, name) WHERE (deleted = false);
|
||||
CREATE UNIQUE INDEX templates_organization_id_name_idx ON templates USING btree (organization_id, name) WHERE (deleted = false);
|
||||
|
||||
CREATE UNIQUE INDEX users_username_lower_idx ON users USING btree (lower(username));
|
||||
|
||||
|
@ -402,21 +402,21 @@ ALTER TABLE ONLY organization_members
|
|||
ALTER TABLE ONLY parameter_schemas
|
||||
ADD CONSTRAINT parameter_schemas_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY project_versions
|
||||
ADD CONSTRAINT project_versions_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY project_versions
|
||||
ADD CONSTRAINT project_versions_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY projects
|
||||
ADD CONSTRAINT projects_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY provisioner_job_logs
|
||||
ADD CONSTRAINT provisioner_job_logs_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY provisioner_jobs
|
||||
ADD CONSTRAINT provisioner_jobs_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY template_versions
|
||||
ADD CONSTRAINT template_versions_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY template_versions
|
||||
ADD CONSTRAINT template_versions_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY templates
|
||||
ADD CONSTRAINT templates_organization_id_fkey FOREIGN KEY (organization_id) REFERENCES organizations(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_agents
|
||||
ADD CONSTRAINT workspace_agents_resource_id_fkey FOREIGN KEY (resource_id) REFERENCES workspace_resources(id) ON DELETE CASCADE;
|
||||
|
||||
|
@ -424,7 +424,7 @@ ALTER TABLE ONLY workspace_builds
|
|||
ADD CONSTRAINT workspace_builds_job_id_fkey FOREIGN KEY (job_id) REFERENCES provisioner_jobs(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_builds
|
||||
ADD CONSTRAINT workspace_builds_project_version_id_fkey FOREIGN KEY (project_version_id) REFERENCES project_versions(id) ON DELETE CASCADE;
|
||||
ADD CONSTRAINT workspace_builds_template_version_id_fkey FOREIGN KEY (template_version_id) REFERENCES template_versions(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY workspace_builds
|
||||
ADD CONSTRAINT workspace_builds_workspace_id_fkey FOREIGN KEY (workspace_id) REFERENCES workspaces(id) ON DELETE CASCADE;
|
||||
|
@ -436,5 +436,5 @@ ALTER TABLE ONLY workspaces
|
|||
ADD CONSTRAINT workspaces_owner_id_fkey FOREIGN KEY (owner_id) REFERENCES users(id) ON DELETE RESTRICT;
|
||||
|
||||
ALTER TABLE ONLY workspaces
|
||||
ADD CONSTRAINT workspaces_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE RESTRICT;
|
||||
ADD CONSTRAINT workspaces_template_id_fkey FOREIGN KEY (template_id) REFERENCES templates(id) ON DELETE RESTRICT;
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
DROP TABLE project_versions;
|
||||
|
||||
DROP TABLE projects;
|
||||
DROP TYPE provisioner_type;
|
||||
|
||||
DROP TABLE files;
|
|
@ -0,0 +1,6 @@
|
|||
DROP TABLE template_versions;
|
||||
|
||||
DROP TABLE templates;
|
||||
DROP TYPE provisioner_type;
|
||||
|
||||
DROP TABLE files;
|
|
@ -1,4 +1,4 @@
|
|||
-- Store arbitrary data like project source code or avatars.
|
||||
-- Store arbitrary data like template source code or avatars.
|
||||
CREATE TABLE files (
|
||||
hash varchar(64) NOT NULL,
|
||||
created_at timestamptz NOT NULL,
|
||||
|
@ -11,37 +11,37 @@ CREATE TABLE files (
|
|||
|
||||
CREATE TYPE provisioner_type AS ENUM ('echo', 'terraform');
|
||||
|
||||
-- Project defines infrastructure that your software project
|
||||
-- Template defines infrastructure that your software template
|
||||
-- requires for development.
|
||||
CREATE TABLE projects (
|
||||
CREATE TABLE templates (
|
||||
id uuid NOT NULL,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL,
|
||||
-- Projects must be scoped to an organization.
|
||||
-- Templates must be scoped to an organization.
|
||||
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
|
||||
deleted boolean NOT NULL DEFAULT FALSE,
|
||||
name varchar(64) NOT NULL,
|
||||
provisioner provisioner_type NOT NULL,
|
||||
-- Target's a Project Version to use for Workspaces.
|
||||
-- Target's a Template Version to use for Workspaces.
|
||||
-- If a Workspace doesn't match this version, it will be prompted to rebuild.
|
||||
active_version_id uuid NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
-- Disallow projects to have the same name under
|
||||
-- Disallow templates to have the same name under
|
||||
-- the same organization.
|
||||
UNIQUE(organization_id, name)
|
||||
);
|
||||
|
||||
-- Enforces no active projects have the same name.
|
||||
CREATE UNIQUE INDEX ON projects (organization_id, name) WHERE deleted = FALSE;
|
||||
CREATE UNIQUE INDEX idx_projects_name_lower ON projects USING btree (lower(name));
|
||||
-- Enforces no active templates have the same name.
|
||||
CREATE UNIQUE INDEX ON templates (organization_id, name) WHERE deleted = FALSE;
|
||||
CREATE UNIQUE INDEX idx_templates_name_lower ON templates USING btree (lower(name));
|
||||
|
||||
-- Project Versions store historical project data. When a Project Version is imported,
|
||||
-- an "import" job is queued to parse parameters. A Project Version
|
||||
-- Template Versions store historical template data. When a Template Version is imported,
|
||||
-- an "import" job is queued to parse parameters. A Template Version
|
||||
-- can only be used if the import job succeeds.
|
||||
CREATE TABLE project_versions (
|
||||
CREATE TABLE template_versions (
|
||||
id uuid NOT NULL,
|
||||
-- This should be indexed. It is intentionally nullable.
|
||||
project_id uuid REFERENCES projects (id) ON DELETE CASCADE,
|
||||
template_id uuid REFERENCES templates (id) ON DELETE CASCADE,
|
||||
organization_id uuid NOT NULL REFERENCES organizations (id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL,
|
||||
|
@ -51,10 +51,10 @@ CREATE TABLE project_versions (
|
|||
-- Extracted from a README.md on import.
|
||||
-- Maximum of 1MB.
|
||||
description varchar(1048576) NOT NULL,
|
||||
-- The job ID for building the project version.
|
||||
-- The job ID for building the template version.
|
||||
job_id uuid NOT NULL,
|
||||
PRIMARY KEY (id),
|
||||
-- Disallow projects to have the same build name
|
||||
-- Disallow templates to have the same build name
|
||||
-- multiple times.
|
||||
UNIQUE(project_id, name)
|
||||
UNIQUE(template_id, name)
|
||||
);
|
|
@ -5,7 +5,7 @@ CREATE TABLE workspaces (
|
|||
-- Use ON DELETE RESTRICT so that we can cleanup external workspace
|
||||
-- resources first.
|
||||
owner_id uuid NOT NULL REFERENCES users (id) ON DELETE RESTRICT,
|
||||
project_id uuid NOT NULL REFERENCES projects (id) ON DELETE RESTRICT,
|
||||
template_id uuid NOT NULL REFERENCES templates (id) ON DELETE RESTRICT,
|
||||
deleted boolean NOT NULL DEFAULT FALSE,
|
||||
name varchar(64) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
|
|
|
@ -11,7 +11,7 @@ CREATE TABLE IF NOT EXISTS provisioner_daemons (
|
|||
);
|
||||
|
||||
CREATE TYPE provisioner_job_type AS ENUM (
|
||||
'project_version_import',
|
||||
'template_version_import',
|
||||
'workspace_build'
|
||||
);
|
||||
|
||||
|
@ -92,7 +92,7 @@ CREATE TABLE workspace_agents (
|
|||
|
||||
CREATE TYPE parameter_scope AS ENUM (
|
||||
'organization',
|
||||
'project',
|
||||
'template',
|
||||
'import_job',
|
||||
'user',
|
||||
'workspace'
|
||||
|
@ -107,7 +107,7 @@ CREATE TYPE parameter_source_scheme AS ENUM('none', 'data');
|
|||
-- Supported schemes for a parameter destination.
|
||||
CREATE TYPE parameter_destination_scheme AS ENUM('none', 'environment_variable', 'provisioner_variable');
|
||||
|
||||
-- Stores project version parameters parsed on import.
|
||||
-- Stores template version parameters parsed on import.
|
||||
-- No secrets are stored here.
|
||||
--
|
||||
-- All parameter validation occurs server-side to process
|
||||
|
@ -162,7 +162,7 @@ CREATE TABLE workspace_builds (
|
|||
created_at timestamptz NOT NULL,
|
||||
updated_at timestamptz NOT NULL,
|
||||
workspace_id uuid NOT NULL REFERENCES workspaces (id) ON DELETE CASCADE,
|
||||
project_version_id uuid NOT NULL REFERENCES project_versions (id) ON DELETE CASCADE,
|
||||
template_version_id uuid NOT NULL REFERENCES template_versions (id) ON DELETE CASCADE,
|
||||
name varchar(64) NOT NULL,
|
||||
before_id uuid,
|
||||
after_id uuid,
|
||||
|
|
|
@ -97,7 +97,7 @@ type ParameterScope string
|
|||
|
||||
const (
|
||||
ParameterScopeOrganization ParameterScope = "organization"
|
||||
ParameterScopeProject ParameterScope = "project"
|
||||
ParameterScopeTemplate ParameterScope = "template"
|
||||
ParameterScopeImportJob ParameterScope = "import_job"
|
||||
ParameterScopeUser ParameterScope = "user"
|
||||
ParameterScopeWorkspace ParameterScope = "workspace"
|
||||
|
@ -156,8 +156,8 @@ func (e *ParameterTypeSystem) Scan(src interface{}) error {
|
|||
type ProvisionerJobType string
|
||||
|
||||
const (
|
||||
ProvisionerJobTypeProjectVersionImport ProvisionerJobType = "project_version_import"
|
||||
ProvisionerJobTypeWorkspaceBuild ProvisionerJobType = "workspace_build"
|
||||
ProvisionerJobTypeTemplateVersionImport ProvisionerJobType = "template_version_import"
|
||||
ProvisionerJobTypeWorkspaceBuild ProvisionerJobType = "workspace_build"
|
||||
)
|
||||
|
||||
func (e *ProvisionerJobType) Scan(src interface{}) error {
|
||||
|
@ -316,28 +316,6 @@ type ParameterValue struct {
|
|||
DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
|
||||
}
|
||||
|
||||
type Project struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
|
||||
ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
|
||||
}
|
||||
|
||||
type ProjectVersion struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
ProjectID uuid.NullUUID `db:"project_id" json:"project_id"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
}
|
||||
|
||||
type ProvisionerDaemon struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
|
@ -375,6 +353,28 @@ type ProvisionerJobLog struct {
|
|||
Output string `db:"output" json:"output"`
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Provisioner ProvisionerType `db:"provisioner" json:"provisioner"`
|
||||
ActiveVersionID uuid.UUID `db:"active_version_id" json:"active_version_id"`
|
||||
}
|
||||
|
||||
type TemplateVersion struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
TemplateID uuid.NullUUID `db:"template_id" json:"template_id"`
|
||||
OrganizationID uuid.UUID `db:"organization_id" json:"organization_id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
Email string `db:"email" json:"email"`
|
||||
|
@ -388,13 +388,13 @@ type User struct {
|
|||
}
|
||||
|
||||
type Workspace struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
ProjectID uuid.UUID `db:"project_id" json:"project_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Name string `db:"name" json:"name"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
|
||||
TemplateID uuid.UUID `db:"template_id" json:"template_id"`
|
||||
Deleted bool `db:"deleted" json:"deleted"`
|
||||
Name string `db:"name" json:"name"`
|
||||
}
|
||||
|
||||
type WorkspaceAgent struct {
|
||||
|
@ -414,18 +414,18 @@ type WorkspaceAgent struct {
|
|||
}
|
||||
|
||||
type WorkspaceBuild struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
ProjectVersionID uuid.UUID `db:"project_version_id" json:"project_version_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
BeforeID uuid.NullUUID `db:"before_id" json:"before_id"`
|
||||
AfterID uuid.NullUUID `db:"after_id" json:"after_id"`
|
||||
Transition WorkspaceTransition `db:"transition" json:"transition"`
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
WorkspaceID uuid.UUID `db:"workspace_id" json:"workspace_id"`
|
||||
TemplateVersionID uuid.UUID `db:"template_version_id" json:"template_version_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
BeforeID uuid.NullUUID `db:"before_id" json:"before_id"`
|
||||
AfterID uuid.NullUUID `db:"after_id" json:"after_id"`
|
||||
Transition WorkspaceTransition `db:"transition" json:"transition"`
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
}
|
||||
|
||||
type WorkspaceResource struct {
|
||||
|
|
|
@ -22,19 +22,19 @@ type querier interface {
|
|||
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
|
||||
GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error)
|
||||
GetParameterValuesByScope(ctx context.Context, arg GetParameterValuesByScopeParams) ([]ParameterValue, error)
|
||||
GetProjectByID(ctx context.Context, id uuid.UUID) (Project, error)
|
||||
GetProjectByOrganizationAndName(ctx context.Context, arg GetProjectByOrganizationAndNameParams) (Project, error)
|
||||
GetProjectVersionByID(ctx context.Context, id uuid.UUID) (ProjectVersion, error)
|
||||
GetProjectVersionByJobID(ctx context.Context, jobID uuid.UUID) (ProjectVersion, error)
|
||||
GetProjectVersionByProjectIDAndName(ctx context.Context, arg GetProjectVersionByProjectIDAndNameParams) (ProjectVersion, error)
|
||||
GetProjectVersionsByProjectID(ctx context.Context, dollar_1 uuid.UUID) ([]ProjectVersion, error)
|
||||
GetProjectsByIDs(ctx context.Context, ids []uuid.UUID) ([]Project, error)
|
||||
GetProjectsByOrganization(ctx context.Context, arg GetProjectsByOrganizationParams) ([]Project, error)
|
||||
GetProvisionerDaemonByID(ctx context.Context, id uuid.UUID) (ProvisionerDaemon, error)
|
||||
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error)
|
||||
GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error)
|
||||
GetProvisionerJobsByIDs(ctx context.Context, ids []uuid.UUID) ([]ProvisionerJob, error)
|
||||
GetProvisionerLogsByIDBetween(ctx context.Context, arg GetProvisionerLogsByIDBetweenParams) ([]ProvisionerJobLog, error)
|
||||
GetTemplateByID(ctx context.Context, id uuid.UUID) (Template, error)
|
||||
GetTemplateByOrganizationAndName(ctx context.Context, arg GetTemplateByOrganizationAndNameParams) (Template, error)
|
||||
GetTemplateVersionByID(ctx context.Context, id uuid.UUID) (TemplateVersion, error)
|
||||
GetTemplateVersionByJobID(ctx context.Context, jobID uuid.UUID) (TemplateVersion, error)
|
||||
GetTemplateVersionByTemplateIDAndName(ctx context.Context, arg GetTemplateVersionByTemplateIDAndNameParams) (TemplateVersion, error)
|
||||
GetTemplateVersionsByTemplateID(ctx context.Context, dollar_1 uuid.UUID) ([]TemplateVersion, error)
|
||||
GetTemplatesByIDs(ctx context.Context, ids []uuid.UUID) ([]Template, error)
|
||||
GetTemplatesByOrganization(ctx context.Context, arg GetTemplatesByOrganizationParams) ([]Template, error)
|
||||
GetUserByEmailOrUsername(ctx context.Context, arg GetUserByEmailOrUsernameParams) (User, error)
|
||||
GetUserByID(ctx context.Context, id uuid.UUID) (User, error)
|
||||
GetUserCount(ctx context.Context) (int64, error)
|
||||
|
@ -49,10 +49,10 @@ type querier interface {
|
|||
GetWorkspaceBuildsByWorkspaceIDsWithoutAfter(ctx context.Context, ids []uuid.UUID) ([]WorkspaceBuild, error)
|
||||
GetWorkspaceByID(ctx context.Context, id uuid.UUID) (Workspace, error)
|
||||
GetWorkspaceByUserIDAndName(ctx context.Context, arg GetWorkspaceByUserIDAndNameParams) (Workspace, error)
|
||||
GetWorkspaceOwnerCountsByProjectIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByProjectIDsRow, error)
|
||||
GetWorkspaceOwnerCountsByTemplateIDs(ctx context.Context, ids []uuid.UUID) ([]GetWorkspaceOwnerCountsByTemplateIDsRow, error)
|
||||
GetWorkspaceResourceByID(ctx context.Context, id uuid.UUID) (WorkspaceResource, error)
|
||||
GetWorkspaceResourcesByJobID(ctx context.Context, jobID uuid.UUID) ([]WorkspaceResource, error)
|
||||
GetWorkspacesByProjectID(ctx context.Context, arg GetWorkspacesByProjectIDParams) ([]Workspace, error)
|
||||
GetWorkspacesByTemplateID(ctx context.Context, arg GetWorkspacesByTemplateIDParams) ([]Workspace, error)
|
||||
GetWorkspacesByUserID(ctx context.Context, arg GetWorkspacesByUserIDParams) ([]Workspace, error)
|
||||
InsertAPIKey(ctx context.Context, arg InsertAPIKeyParams) (APIKey, error)
|
||||
InsertFile(ctx context.Context, arg InsertFileParams) (File, error)
|
||||
|
@ -61,11 +61,11 @@ type querier interface {
|
|||
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
|
||||
InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error)
|
||||
InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error)
|
||||
InsertProject(ctx context.Context, arg InsertProjectParams) (Project, error)
|
||||
InsertProjectVersion(ctx context.Context, arg InsertProjectVersionParams) (ProjectVersion, error)
|
||||
InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error)
|
||||
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
|
||||
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
|
||||
InsertTemplate(ctx context.Context, arg InsertTemplateParams) (Template, error)
|
||||
InsertTemplateVersion(ctx context.Context, arg InsertTemplateVersionParams) (TemplateVersion, error)
|
||||
InsertUser(ctx context.Context, arg InsertUserParams) (User, error)
|
||||
InsertWorkspace(ctx context.Context, arg InsertWorkspaceParams) (Workspace, error)
|
||||
InsertWorkspaceAgent(ctx context.Context, arg InsertWorkspaceAgentParams) (WorkspaceAgent, error)
|
||||
|
@ -73,13 +73,13 @@ type querier interface {
|
|||
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
|
||||
UpdateAPIKeyByID(ctx context.Context, arg UpdateAPIKeyByIDParams) error
|
||||
UpdateGitSSHKey(ctx context.Context, arg UpdateGitSSHKeyParams) error
|
||||
UpdateProjectActiveVersionByID(ctx context.Context, arg UpdateProjectActiveVersionByIDParams) error
|
||||
UpdateProjectDeletedByID(ctx context.Context, arg UpdateProjectDeletedByIDParams) error
|
||||
UpdateProjectVersionByID(ctx context.Context, arg UpdateProjectVersionByIDParams) error
|
||||
UpdateProvisionerDaemonByID(ctx context.Context, arg UpdateProvisionerDaemonByIDParams) error
|
||||
UpdateProvisionerJobByID(ctx context.Context, arg UpdateProvisionerJobByIDParams) error
|
||||
UpdateProvisionerJobWithCancelByID(ctx context.Context, arg UpdateProvisionerJobWithCancelByIDParams) error
|
||||
UpdateProvisionerJobWithCompleteByID(ctx context.Context, arg UpdateProvisionerJobWithCompleteByIDParams) error
|
||||
UpdateTemplateActiveVersionByID(ctx context.Context, arg UpdateTemplateActiveVersionByIDParams) error
|
||||
UpdateTemplateDeletedByID(ctx context.Context, arg UpdateTemplateDeletedByIDParams) error
|
||||
UpdateTemplateVersionByID(ctx context.Context, arg UpdateTemplateVersionByIDParams) error
|
||||
UpdateWorkspaceAgentConnectionByID(ctx context.Context, arg UpdateWorkspaceAgentConnectionByIDParams) error
|
||||
UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWorkspaceBuildByIDParams) error
|
||||
UpdateWorkspaceDeletedByID(ctx context.Context, arg UpdateWorkspaceDeletedByIDParams) error
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,56 +0,0 @@
|
|||
-- name: GetProjectVersionsByProjectID :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
project_versions
|
||||
WHERE
|
||||
project_id = $1 :: uuid;
|
||||
|
||||
-- name: GetProjectVersionByJobID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
project_versions
|
||||
WHERE
|
||||
job_id = $1;
|
||||
|
||||
-- name: GetProjectVersionByProjectIDAndName :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
project_versions
|
||||
WHERE
|
||||
project_id = $1
|
||||
AND "name" = $2;
|
||||
|
||||
-- name: GetProjectVersionByID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
project_versions
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: InsertProjectVersion :one
|
||||
INSERT INTO
|
||||
project_versions (
|
||||
id,
|
||||
project_id,
|
||||
organization_id,
|
||||
created_at,
|
||||
updated_at,
|
||||
"name",
|
||||
description,
|
||||
job_id
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *;
|
||||
|
||||
-- name: UpdateProjectVersionByID :exec
|
||||
UPDATE
|
||||
project_versions
|
||||
SET
|
||||
project_id = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1;
|
|
@ -1,26 +1,26 @@
|
|||
-- name: GetProjectByID :one
|
||||
-- name: GetTemplateByID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
projects
|
||||
templates
|
||||
WHERE
|
||||
id = $1
|
||||
LIMIT
|
||||
1;
|
||||
|
||||
-- name: GetProjectsByIDs :many
|
||||
-- name: GetTemplatesByIDs :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
projects
|
||||
templates
|
||||
WHERE
|
||||
id = ANY(@ids :: uuid [ ]);
|
||||
|
||||
-- name: GetProjectByOrganizationAndName :one
|
||||
-- name: GetTemplateByOrganizationAndName :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
projects
|
||||
templates
|
||||
WHERE
|
||||
organization_id = @organization_id
|
||||
AND deleted = @deleted
|
||||
|
@ -28,18 +28,18 @@ WHERE
|
|||
LIMIT
|
||||
1;
|
||||
|
||||
-- name: GetProjectsByOrganization :many
|
||||
-- name: GetTemplatesByOrganization :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
projects
|
||||
templates
|
||||
WHERE
|
||||
organization_id = $1
|
||||
AND deleted = $2;
|
||||
|
||||
-- name: InsertProject :one
|
||||
-- name: InsertTemplate :one
|
||||
INSERT INTO
|
||||
projects (
|
||||
templates (
|
||||
id,
|
||||
created_at,
|
||||
updated_at,
|
||||
|
@ -51,17 +51,17 @@ INSERT INTO
|
|||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7) RETURNING *;
|
||||
|
||||
-- name: UpdateProjectActiveVersionByID :exec
|
||||
-- name: UpdateTemplateActiveVersionByID :exec
|
||||
UPDATE
|
||||
projects
|
||||
templates
|
||||
SET
|
||||
active_version_id = $2
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: UpdateProjectDeletedByID :exec
|
||||
-- name: UpdateTemplateDeletedByID :exec
|
||||
UPDATE
|
||||
projects
|
||||
templates
|
||||
SET
|
||||
deleted = $2
|
||||
WHERE
|
|
@ -0,0 +1,56 @@
|
|||
-- name: GetTemplateVersionsByTemplateID :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
template_id = $1 :: uuid;
|
||||
|
||||
-- name: GetTemplateVersionByJobID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
job_id = $1;
|
||||
|
||||
-- name: GetTemplateVersionByTemplateIDAndName :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
template_id = $1
|
||||
AND "name" = $2;
|
||||
|
||||
-- name: GetTemplateVersionByID :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
template_versions
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: InsertTemplateVersion :one
|
||||
INSERT INTO
|
||||
template_versions (
|
||||
id,
|
||||
template_id,
|
||||
organization_id,
|
||||
created_at,
|
||||
updated_at,
|
||||
"name",
|
||||
description,
|
||||
job_id
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8) RETURNING *;
|
||||
|
||||
-- name: UpdateTemplateVersionByID :exec
|
||||
UPDATE
|
||||
template_versions
|
||||
SET
|
||||
template_id = $2,
|
||||
updated_at = $3
|
||||
WHERE
|
||||
id = $1;
|
|
@ -62,7 +62,7 @@ INSERT INTO
|
|||
created_at,
|
||||
updated_at,
|
||||
workspace_id,
|
||||
project_version_id,
|
||||
template_version_id,
|
||||
before_id,
|
||||
"name",
|
||||
transition,
|
||||
|
|
|
@ -8,13 +8,13 @@ WHERE
|
|||
LIMIT
|
||||
1;
|
||||
|
||||
-- name: GetWorkspacesByProjectID :many
|
||||
-- name: GetWorkspacesByTemplateID :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
project_id = $1
|
||||
template_id = $1
|
||||
AND deleted = $2;
|
||||
|
||||
-- name: GetWorkspacesByUserID :many
|
||||
|
@ -36,16 +36,16 @@ WHERE
|
|||
AND deleted = @deleted
|
||||
AND LOWER("name") = LOWER(@name);
|
||||
|
||||
-- name: GetWorkspaceOwnerCountsByProjectIDs :many
|
||||
-- name: GetWorkspaceOwnerCountsByTemplateIDs :many
|
||||
SELECT
|
||||
project_id,
|
||||
template_id,
|
||||
COUNT(DISTINCT owner_id)
|
||||
FROM
|
||||
workspaces
|
||||
WHERE
|
||||
project_id = ANY(@ids :: uuid [ ])
|
||||
template_id = ANY(@ids :: uuid [ ])
|
||||
GROUP BY
|
||||
project_id,
|
||||
template_id,
|
||||
owner_id;
|
||||
|
||||
-- name: InsertWorkspace :one
|
||||
|
@ -55,7 +55,7 @@ INSERT INTO
|
|||
created_at,
|
||||
updated_at,
|
||||
owner_id,
|
||||
project_id,
|
||||
template_id,
|
||||
name
|
||||
)
|
||||
VALUES
|
||||
|
|
|
@ -86,7 +86,7 @@ func TestAgentGitSSHKey(t *testing.T) {
|
|||
user := coderdtest.CreateFirstUser(t, client)
|
||||
daemonCloser := coderdtest.NewProvisionerDaemon(t, client)
|
||||
authToken := uuid.NewString()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
|
@ -106,8 +106,8 @@ func TestAgentGitSSHKey(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
daemonCloser.Close()
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
package httpmw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
type projectParamContextKey struct{}
|
||||
|
||||
// ProjectParam returns the project from the ExtractProjectParam handler.
|
||||
func ProjectParam(r *http.Request) database.Project {
|
||||
project, ok := r.Context().Value(projectParamContextKey{}).(database.Project)
|
||||
if !ok {
|
||||
panic("developer error: project param middleware not provided")
|
||||
}
|
||||
return project
|
||||
}
|
||||
|
||||
// ExtractProjectParam grabs a project from the "project" URL parameter.
|
||||
func ExtractProjectParam(db database.Store) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
projectID, parsed := parseUUID(rw, r, "project")
|
||||
if !parsed {
|
||||
return
|
||||
}
|
||||
project, err := db.GetProjectByID(r.Context(), projectID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("project %q does not exist", projectID),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), projectParamContextKey{}, project)
|
||||
chi.RouteContext(ctx).URLParams.Add("organization", project.OrganizationID.String())
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
package httpmw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
type projectVersionParamContextKey struct{}
|
||||
|
||||
// ProjectVersionParam returns the project version from the ExtractProjectVersionParam handler.
|
||||
func ProjectVersionParam(r *http.Request) database.ProjectVersion {
|
||||
projectVersion, ok := r.Context().Value(projectVersionParamContextKey{}).(database.ProjectVersion)
|
||||
if !ok {
|
||||
panic("developer error: project version param middleware not provided")
|
||||
}
|
||||
return projectVersion
|
||||
}
|
||||
|
||||
// ExtractProjectVersionParam grabs project version from the "projectversion" URL parameter.
|
||||
func ExtractProjectVersionParam(db database.Store) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersionID, parsed := parseUUID(rw, r, "projectversion")
|
||||
if !parsed {
|
||||
return
|
||||
}
|
||||
projectVersion, err := db.GetProjectVersionByID(r.Context(), projectVersionID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("project version %q does not exist", projectVersionID),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), projectVersionParamContextKey{}, projectVersion)
|
||||
chi.RouteContext(ctx).URLParams.Add("organization", projectVersion.OrganizationID.String())
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package httpmw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
type templateParamContextKey struct{}
|
||||
|
||||
// TemplateParam returns the template from the ExtractTemplateParam handler.
|
||||
func TemplateParam(r *http.Request) database.Template {
|
||||
template, ok := r.Context().Value(templateParamContextKey{}).(database.Template)
|
||||
if !ok {
|
||||
panic("developer error: template param middleware not provided")
|
||||
}
|
||||
return template
|
||||
}
|
||||
|
||||
// ExtractTemplateParam grabs a template from the "template" URL parameter.
|
||||
func ExtractTemplateParam(db database.Store) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
templateID, parsed := parseUUID(rw, r, "template")
|
||||
if !parsed {
|
||||
return
|
||||
}
|
||||
template, err := db.GetTemplateByID(r.Context(), templateID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("template %q does not exist", templateID),
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), templateParamContextKey{}, template)
|
||||
chi.RouteContext(ctx).URLParams.Add("organization", template.OrganizationID.String())
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -19,7 +19,7 @@ import (
|
|||
"github.com/coder/coder/cryptorand"
|
||||
)
|
||||
|
||||
func TestProjectParam(t *testing.T) {
|
||||
func TestTemplateParam(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
setupAuthentication := func(db database.Store) (*http.Request, database.Organization) {
|
||||
|
@ -84,7 +84,7 @@ func TestProjectParam(t *testing.T) {
|
|||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(httpmw.ExtractProjectParam(db))
|
||||
rtr.Use(httpmw.ExtractTemplateParam(db))
|
||||
rtr.Get("/", nil)
|
||||
r, _ := setupAuthentication(db)
|
||||
rw := httptest.NewRecorder()
|
||||
|
@ -99,11 +99,11 @@ func TestProjectParam(t *testing.T) {
|
|||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(httpmw.ExtractProjectParam(db))
|
||||
rtr.Use(httpmw.ExtractTemplateParam(db))
|
||||
rtr.Get("/", nil)
|
||||
|
||||
r, _ := setupAuthentication(db)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("project", uuid.NewString())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("template", uuid.NewString())
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
||||
|
@ -116,11 +116,11 @@ func TestProjectParam(t *testing.T) {
|
|||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(httpmw.ExtractProjectParam(db))
|
||||
rtr.Use(httpmw.ExtractTemplateParam(db))
|
||||
rtr.Get("/", nil)
|
||||
|
||||
r, _ := setupAuthentication(db)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("project", "not-a-uuid")
|
||||
chi.RouteContext(r.Context()).URLParams.Add("template", "not-a-uuid")
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
||||
|
@ -129,28 +129,28 @@ func TestProjectParam(t *testing.T) {
|
|||
require.Equal(t, http.StatusBadRequest, res.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("Project", func(t *testing.T) {
|
||||
t.Run("Template", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(
|
||||
httpmw.ExtractAPIKey(db, nil),
|
||||
httpmw.ExtractProjectParam(db),
|
||||
httpmw.ExtractTemplateParam(db),
|
||||
httpmw.ExtractOrganizationParam(db),
|
||||
)
|
||||
rtr.Get("/", func(rw http.ResponseWriter, r *http.Request) {
|
||||
_ = httpmw.ProjectParam(r)
|
||||
_ = httpmw.TemplateParam(r)
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
r, org := setupAuthentication(db)
|
||||
project, err := db.InsertProject(context.Background(), database.InsertProjectParams{
|
||||
template, err := db.InsertTemplate(context.Background(), database.InsertTemplateParams{
|
||||
ID: uuid.New(),
|
||||
OrganizationID: org.ID,
|
||||
Name: "moo",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("project", project.ID.String())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("template", template.ID.String())
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package httpmw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
type templateVersionParamContextKey struct{}
|
||||
|
||||
// TemplateVersionParam returns the template version from the ExtractTemplateVersionParam handler.
|
||||
func TemplateVersionParam(r *http.Request) database.TemplateVersion {
|
||||
templateVersion, ok := r.Context().Value(templateVersionParamContextKey{}).(database.TemplateVersion)
|
||||
if !ok {
|
||||
panic("developer error: template version param middleware not provided")
|
||||
}
|
||||
return templateVersion
|
||||
}
|
||||
|
||||
// ExtractTemplateVersionParam grabs template version from the "templateversion" URL parameter.
|
||||
func ExtractTemplateVersionParam(db database.Store) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersionID, parsed := parseUUID(rw, r, "templateversion")
|
||||
if !parsed {
|
||||
return
|
||||
}
|
||||
templateVersion, err := db.GetTemplateVersionByID(r.Context(), templateVersionID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("template version %q does not exist", templateVersionID),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get template version: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := context.WithValue(r.Context(), templateVersionParamContextKey{}, templateVersion)
|
||||
chi.RouteContext(ctx).URLParams.Add("organization", templateVersion.OrganizationID.String())
|
||||
next.ServeHTTP(rw, r.WithContext(ctx))
|
||||
})
|
||||
}
|
||||
}
|
|
@ -19,10 +19,10 @@ import (
|
|||
"github.com/coder/coder/cryptorand"
|
||||
)
|
||||
|
||||
func TestProjectVersionParam(t *testing.T) {
|
||||
func TestTemplateVersionParam(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
setupAuthentication := func(db database.Store) (*http.Request, database.Project) {
|
||||
setupAuthentication := func(db database.Store) (*http.Request, database.Template) {
|
||||
var (
|
||||
id, secret = randomAPIKeyParts()
|
||||
hashed = sha256.Sum256([]byte(secret))
|
||||
|
@ -75,7 +75,7 @@ func TestProjectVersionParam(t *testing.T) {
|
|||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
project, err := db.InsertProject(context.Background(), database.InsertProjectParams{
|
||||
template, err := db.InsertTemplate(context.Background(), database.InsertTemplateParams{
|
||||
ID: uuid.New(),
|
||||
OrganizationID: organization.ID,
|
||||
Name: "moo",
|
||||
|
@ -84,16 +84,16 @@ func TestProjectVersionParam(t *testing.T) {
|
|||
|
||||
ctx := chi.NewRouteContext()
|
||||
ctx.URLParams.Add("organization", organization.Name)
|
||||
ctx.URLParams.Add("project", project.Name)
|
||||
ctx.URLParams.Add("template", template.Name)
|
||||
r = r.WithContext(context.WithValue(r.Context(), chi.RouteCtxKey, ctx))
|
||||
return r, project
|
||||
return r, template
|
||||
}
|
||||
|
||||
t.Run("None", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(httpmw.ExtractProjectVersionParam(db))
|
||||
rtr.Use(httpmw.ExtractTemplateVersionParam(db))
|
||||
rtr.Get("/", nil)
|
||||
r, _ := setupAuthentication(db)
|
||||
rw := httptest.NewRecorder()
|
||||
|
@ -108,11 +108,11 @@ func TestProjectVersionParam(t *testing.T) {
|
|||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(httpmw.ExtractProjectVersionParam(db))
|
||||
rtr.Use(httpmw.ExtractTemplateVersionParam(db))
|
||||
rtr.Get("/", nil)
|
||||
|
||||
r, _ := setupAuthentication(db)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("projectversion", uuid.NewString())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("templateversion", uuid.NewString())
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
||||
|
@ -121,28 +121,28 @@ func TestProjectVersionParam(t *testing.T) {
|
|||
require.Equal(t, http.StatusNotFound, res.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("ProjectVersion", func(t *testing.T) {
|
||||
t.Run("TemplateVersion", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
rtr := chi.NewRouter()
|
||||
rtr.Use(
|
||||
httpmw.ExtractAPIKey(db, nil),
|
||||
httpmw.ExtractProjectVersionParam(db),
|
||||
httpmw.ExtractTemplateVersionParam(db),
|
||||
httpmw.ExtractOrganizationParam(db),
|
||||
)
|
||||
rtr.Get("/", func(rw http.ResponseWriter, r *http.Request) {
|
||||
_ = httpmw.ProjectVersionParam(r)
|
||||
_ = httpmw.TemplateVersionParam(r)
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
r, project := setupAuthentication(db)
|
||||
projectVersion, err := db.InsertProjectVersion(context.Background(), database.InsertProjectVersionParams{
|
||||
r, template := setupAuthentication(db)
|
||||
templateVersion, err := db.InsertTemplateVersion(context.Background(), database.InsertTemplateVersionParams{
|
||||
ID: uuid.New(),
|
||||
OrganizationID: project.OrganizationID,
|
||||
OrganizationID: template.OrganizationID,
|
||||
Name: "moo",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("projectversion", projectVersion.ID.String())
|
||||
chi.RouteContext(r.Context()).URLParams.Add("templateversion", templateVersion.ID.String())
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
|
@ -58,10 +58,10 @@ func TestWorkspaceBuildParam(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
workspace, err := db.InsertWorkspace(context.Background(), database.InsertWorkspaceParams{
|
||||
ID: uuid.New(),
|
||||
ProjectID: uuid.New(),
|
||||
OwnerID: user.ID,
|
||||
Name: "potato",
|
||||
ID: uuid.New(),
|
||||
TemplateID: uuid.New(),
|
||||
OwnerID: user.ID,
|
||||
Name: "potato",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
|
||||
type workspaceResourceParamContextKey struct{}
|
||||
|
||||
// ProvisionerJobParam returns the project from the ExtractProjectParam handler.
|
||||
// ProvisionerJobParam returns the template from the ExtractTemplateParam handler.
|
||||
func WorkspaceResourceParam(r *http.Request) database.WorkspaceResource {
|
||||
resource, ok := r.Context().Value(workspaceResourceParamContextKey{}).(database.WorkspaceResource)
|
||||
if !ok {
|
||||
|
|
|
@ -88,7 +88,7 @@ func TestWorkspaceResourceParam(t *testing.T) {
|
|||
rw.WriteHeader(http.StatusOK)
|
||||
})
|
||||
|
||||
r, job := setup(db, database.ProvisionerJobTypeProjectVersionImport)
|
||||
r, job := setup(db, database.ProvisionerJobTypeTemplateVersionImport)
|
||||
chi.RouteContext(r.Context()).URLParams.Add("workspaceresource", job.ID.String())
|
||||
rw := httptest.NewRecorder()
|
||||
rtr.ServeHTTP(rw, r)
|
||||
|
|
|
@ -42,25 +42,25 @@ func (api *api) provisionerDaemonsByOrganization(rw http.ResponseWriter, r *http
|
|||
render.JSON(rw, r, daemons)
|
||||
}
|
||||
|
||||
// Creates a new version of a project. An import job is queued to parse the storage method provided.
|
||||
func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
// Creates a new version of a template. An import job is queued to parse the storage method provided.
|
||||
func (api *api) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
apiKey := httpmw.APIKey(r)
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
var req codersdk.CreateProjectVersionRequest
|
||||
var req codersdk.CreateTemplateVersionRequest
|
||||
if !httpapi.Read(rw, r, &req) {
|
||||
return
|
||||
}
|
||||
if req.ProjectID != uuid.Nil {
|
||||
_, err := api.Database.GetProjectByID(r.Context(), req.ProjectID)
|
||||
if req.TemplateID != uuid.Nil {
|
||||
_, err := api.Database.GetTemplateByID(r.Context(), req.TemplateID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: "project does not exist",
|
||||
Message: "template does not exist",
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *htt
|
|||
return
|
||||
}
|
||||
|
||||
var projectVersion database.ProjectVersion
|
||||
var templateVersion database.TemplateVersion
|
||||
var provisionerJob database.ProvisionerJob
|
||||
err = api.Database.InTx(func(db database.Store) error {
|
||||
jobID := uuid.New()
|
||||
|
@ -110,24 +110,24 @@ func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *htt
|
|||
Provisioner: req.Provisioner,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: file.Hash,
|
||||
Type: database.ProvisionerJobTypeProjectVersionImport,
|
||||
Type: database.ProvisionerJobTypeTemplateVersionImport,
|
||||
Input: []byte{'{', '}'},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert provisioner job: %w", err)
|
||||
}
|
||||
|
||||
var projectID uuid.NullUUID
|
||||
if req.ProjectID != uuid.Nil {
|
||||
projectID = uuid.NullUUID{
|
||||
UUID: req.ProjectID,
|
||||
var templateID uuid.NullUUID
|
||||
if req.TemplateID != uuid.Nil {
|
||||
templateID = uuid.NullUUID{
|
||||
UUID: req.TemplateID,
|
||||
Valid: true,
|
||||
}
|
||||
}
|
||||
|
||||
projectVersion, err = api.Database.InsertProjectVersion(r.Context(), database.InsertProjectVersionParams{
|
||||
templateVersion, err = api.Database.InsertTemplateVersion(r.Context(), database.InsertTemplateVersionParams{
|
||||
ID: uuid.New(),
|
||||
ProjectID: projectID,
|
||||
TemplateID: templateID,
|
||||
OrganizationID: organization.ID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
|
@ -136,7 +136,7 @@ func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *htt
|
|||
JobID: provisionerJob.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert project version: %w", err)
|
||||
return xerrors.Errorf("insert template version: %w", err)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
@ -148,23 +148,23 @@ func (api *api) postProjectVersionsByOrganization(rw http.ResponseWriter, r *htt
|
|||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, convertProjectVersion(projectVersion, convertProvisionerJob(provisionerJob)))
|
||||
render.JSON(rw, r, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob)))
|
||||
}
|
||||
|
||||
// Create a new project in an organization.
|
||||
func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
var createProject codersdk.CreateProjectRequest
|
||||
if !httpapi.Read(rw, r, &createProject) {
|
||||
// Create a new template in an organization.
|
||||
func (api *api) postTemplatesByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
var createTemplate codersdk.CreateTemplateRequest
|
||||
if !httpapi.Read(rw, r, &createTemplate) {
|
||||
return
|
||||
}
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
_, err := api.Database.GetProjectByOrganizationAndName(r.Context(), database.GetProjectByOrganizationAndNameParams{
|
||||
_, err := api.Database.GetTemplateByOrganizationAndName(r.Context(), database.GetTemplateByOrganizationAndNameParams{
|
||||
OrganizationID: organization.ID,
|
||||
Name: createProject.Name,
|
||||
Name: createTemplate.Name,
|
||||
})
|
||||
if err == nil {
|
||||
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
|
||||
Message: fmt.Sprintf("project %q already exists", createProject.Name),
|
||||
Message: fmt.Sprintf("template %q already exists", createTemplate.Name),
|
||||
Errors: []httpapi.Error{{
|
||||
Field: "name",
|
||||
Code: "exists",
|
||||
|
@ -174,23 +174,23 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project by name: %s", err),
|
||||
Message: fmt.Sprintf("get template by name: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectVersion, err := api.Database.GetProjectVersionByID(r.Context(), createProject.VersionID)
|
||||
templateVersion, err := api.Database.GetTemplateVersionByID(r.Context(), createTemplate.VersionID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: "project version does not exist",
|
||||
Message: "template version does not exist",
|
||||
})
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version by id: %s", err),
|
||||
Message: fmt.Sprintf("get template version by id: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
importJob, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
importJob, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get import job by id: %s", err),
|
||||
|
@ -198,41 +198,41 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
|
|||
return
|
||||
}
|
||||
|
||||
var project codersdk.Project
|
||||
var template codersdk.Template
|
||||
err = api.Database.InTx(func(db database.Store) error {
|
||||
now := database.Now()
|
||||
dbProject, err := db.InsertProject(r.Context(), database.InsertProjectParams{
|
||||
dbTemplate, err := db.InsertTemplate(r.Context(), database.InsertTemplateParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
OrganizationID: organization.ID,
|
||||
Name: createProject.Name,
|
||||
Name: createTemplate.Name,
|
||||
Provisioner: importJob.Provisioner,
|
||||
ActiveVersionID: projectVersion.ID,
|
||||
ActiveVersionID: templateVersion.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert project: %s", err)
|
||||
return xerrors.Errorf("insert template: %s", err)
|
||||
}
|
||||
|
||||
err = db.UpdateProjectVersionByID(r.Context(), database.UpdateProjectVersionByIDParams{
|
||||
ID: projectVersion.ID,
|
||||
ProjectID: uuid.NullUUID{
|
||||
UUID: dbProject.ID,
|
||||
err = db.UpdateTemplateVersionByID(r.Context(), database.UpdateTemplateVersionByIDParams{
|
||||
ID: templateVersion.ID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: dbTemplate.ID,
|
||||
Valid: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert project version: %s", err)
|
||||
return xerrors.Errorf("insert template version: %s", err)
|
||||
}
|
||||
|
||||
for _, parameterValue := range createProject.ParameterValues {
|
||||
for _, parameterValue := range createTemplate.ParameterValues {
|
||||
_, err = db.InsertParameterValue(r.Context(), database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Scope: database.ParameterScopeProject,
|
||||
ScopeID: dbProject.ID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
ScopeID: dbTemplate.ID,
|
||||
SourceScheme: parameterValue.SourceScheme,
|
||||
SourceValue: parameterValue.SourceValue,
|
||||
DestinationScheme: parameterValue.DestinationScheme,
|
||||
|
@ -242,7 +242,7 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
}
|
||||
|
||||
project = convertProject(dbProject, 0)
|
||||
template = convertTemplate(dbTemplate, 0)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -253,12 +253,12 @@ func (api *api) postProjectsByOrganization(rw http.ResponseWriter, r *http.Reque
|
|||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, project)
|
||||
render.JSON(rw, r, template)
|
||||
}
|
||||
|
||||
func (api *api) projectsByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
func (api *api) templatesByOrganization(rw http.ResponseWriter, r *http.Request) {
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
projects, err := api.Database.GetProjectsByOrganization(r.Context(), database.GetProjectsByOrganizationParams{
|
||||
templates, err := api.Database.GetTemplatesByOrganization(r.Context(), database.GetTemplatesByOrganizationParams{
|
||||
OrganizationID: organization.ID,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
@ -266,15 +266,15 @@ func (api *api) projectsByOrganization(rw http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get projects: %s", err.Error()),
|
||||
Message: fmt.Sprintf("get templates: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectIDs := make([]uuid.UUID, 0, len(projects))
|
||||
for _, project := range projects {
|
||||
projectIDs = append(projectIDs, project.ID)
|
||||
templateIDs := make([]uuid.UUID, 0, len(templates))
|
||||
for _, template := range templates {
|
||||
templateIDs = append(templateIDs, template.ID)
|
||||
}
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByProjectIDs(r.Context(), projectIDs)
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByTemplateIDs(r.Context(), templateIDs)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
|
@ -285,31 +285,31 @@ func (api *api) projectsByOrganization(rw http.ResponseWriter, r *http.Request)
|
|||
return
|
||||
}
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertProjects(projects, workspaceCounts))
|
||||
render.JSON(rw, r, convertTemplates(templates, workspaceCounts))
|
||||
}
|
||||
|
||||
func (api *api) projectByOrganizationAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
func (api *api) templateByOrganizationAndName(rw http.ResponseWriter, r *http.Request) {
|
||||
organization := httpmw.OrganizationParam(r)
|
||||
projectName := chi.URLParam(r, "projectname")
|
||||
project, err := api.Database.GetProjectByOrganizationAndName(r.Context(), database.GetProjectByOrganizationAndNameParams{
|
||||
templateName := chi.URLParam(r, "templatename")
|
||||
template, err := api.Database.GetTemplateByOrganizationAndName(r.Context(), database.GetTemplateByOrganizationAndNameParams{
|
||||
OrganizationID: organization.ID,
|
||||
Name: projectName,
|
||||
Name: templateName,
|
||||
})
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("no project found by name %q in the %q organization", projectName, organization.Name),
|
||||
Message: fmt.Sprintf("no template found by name %q in the %q organization", templateName, organization.Name),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project by organization and name: %s", err),
|
||||
Message: fmt.Sprintf("get template by organization and name: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByProjectIDs(r.Context(), []uuid.UUID{project.ID})
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByTemplateIDs(r.Context(), []uuid.UUID{template.ID})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ func (api *api) projectByOrganizationAndName(rw http.ResponseWriter, r *http.Req
|
|||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertProject(project, count))
|
||||
render.JSON(rw, r, convertTemplate(template, count))
|
||||
}
|
||||
|
||||
// convertOrganization consumes the database representation and outputs an API friendly representation.
|
||||
|
|
|
@ -32,15 +32,15 @@ func TestProvisionerDaemonsByOrganization(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestPostProjectVersionsByOrganization(t *testing.T) {
|
||||
func TestPostTemplateVersionsByOrganization(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("InvalidProject", func(t *testing.T) {
|
||||
t.Run("InvalidTemplate", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
projectID := uuid.New()
|
||||
_, err := client.CreateProjectVersion(context.Background(), user.OrganizationID, codersdk.CreateProjectVersionRequest{
|
||||
ProjectID: projectID,
|
||||
templateID := uuid.New()
|
||||
_, err := client.CreateTemplateVersion(context.Background(), user.OrganizationID, codersdk.CreateTemplateVersionRequest{
|
||||
TemplateID: templateID,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: "hash",
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
|
@ -54,7 +54,7 @@ func TestPostProjectVersionsByOrganization(t *testing.T) {
|
|||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
_, err := client.CreateProjectVersion(context.Background(), user.OrganizationID, codersdk.CreateProjectVersionRequest{
|
||||
_, err := client.CreateTemplateVersion(context.Background(), user.OrganizationID, codersdk.CreateTemplateVersionRequest{
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: "hash",
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
|
@ -76,7 +76,7 @@ func TestPostProjectVersionsByOrganization(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
file, err := client.Upload(context.Background(), codersdk.ContentTypeTar, data)
|
||||
require.NoError(t, err)
|
||||
_, err = client.CreateProjectVersion(context.Background(), user.OrganizationID, codersdk.CreateProjectVersionRequest{
|
||||
_, err = client.CreateTemplateVersion(context.Background(), user.OrganizationID, codersdk.CreateTemplateVersionRequest{
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
StorageSource: file.Hash,
|
||||
Provisioner: database.ProvisionerTypeEcho,
|
||||
|
@ -91,24 +91,24 @@ func TestPostProjectVersionsByOrganization(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestPostProjectsByOrganization(t *testing.T) {
|
||||
func TestPostTemplatesByOrganization(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
_ = coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
})
|
||||
|
||||
t.Run("AlreadyExists", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.CreateProject(context.Background(), user.OrganizationID, codersdk.CreateProjectRequest{
|
||||
Name: project.Name,
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.CreateTemplate(context.Background(), user.OrganizationID, codersdk.CreateTemplateRequest{
|
||||
Name: template.Name,
|
||||
VersionID: version.ID,
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -120,7 +120,7 @@ func TestPostProjectsByOrganization(t *testing.T) {
|
|||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
_, err := client.CreateProject(context.Background(), user.OrganizationID, codersdk.CreateProjectRequest{
|
||||
_, err := client.CreateTemplate(context.Background(), user.OrganizationID, codersdk.CreateTemplateRequest{
|
||||
Name: "test",
|
||||
VersionID: uuid.New(),
|
||||
})
|
||||
|
@ -130,48 +130,48 @@ func TestPostProjectsByOrganization(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestProjectsByOrganization(t *testing.T) {
|
||||
func TestTemplatesByOrganization(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListEmpty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
projects, err := client.ProjectsByOrganization(context.Background(), user.OrganizationID)
|
||||
templates, err := client.TemplatesByOrganization(context.Background(), user.OrganizationID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, projects)
|
||||
require.Len(t, projects, 0)
|
||||
require.NotNil(t, templates)
|
||||
require.Len(t, templates, 0)
|
||||
})
|
||||
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
projects, err := client.ProjectsByOrganization(context.Background(), user.OrganizationID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
templates, err := client.TemplatesByOrganization(context.Background(), user.OrganizationID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, projects, 1)
|
||||
require.Len(t, templates, 1)
|
||||
})
|
||||
t.Run("ListMultiple", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
projects, err := client.ProjectsByOrganization(context.Background(), user.OrganizationID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
templates, err := client.TemplatesByOrganization(context.Background(), user.OrganizationID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, projects, 2)
|
||||
require.Len(t, templates, 2)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectByOrganizationAndName(t *testing.T) {
|
||||
func TestTemplateByOrganizationAndName(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
_, err := client.ProjectByName(context.Background(), user.OrganizationID, "something")
|
||||
_, err := client.TemplateByName(context.Background(), user.OrganizationID, "something")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
|
@ -181,9 +181,9 @@ func TestProjectByOrganizationAndName(t *testing.T) {
|
|||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.ProjectByName(context.Background(), user.OrganizationID, project.Name)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.TemplateByName(context.Background(), user.OrganizationID, template.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
|
||||
// ComputeScope targets identifiers to pull parameters from.
|
||||
type ComputeScope struct {
|
||||
ProjectImportJobID uuid.UUID
|
||||
OrganizationID uuid.UUID
|
||||
UserID uuid.UUID
|
||||
ProjectID uuid.NullUUID
|
||||
WorkspaceID uuid.NullUUID
|
||||
TemplateImportJobID uuid.UUID
|
||||
OrganizationID uuid.UUID
|
||||
UserID uuid.UUID
|
||||
TemplateID uuid.NullUUID
|
||||
WorkspaceID uuid.NullUUID
|
||||
}
|
||||
|
||||
type ComputeOptions struct {
|
||||
|
@ -48,12 +48,12 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
|
|||
}
|
||||
|
||||
// All parameters for the import job ID!
|
||||
parameterSchemas, err := db.GetParameterSchemasByJobID(ctx, scope.ProjectImportJobID)
|
||||
parameterSchemas, err := db.GetParameterSchemasByJobID(ctx, scope.TemplateImportJobID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get project parameters: %w", err)
|
||||
return nil, xerrors.Errorf("get template parameters: %w", err)
|
||||
}
|
||||
for _, parameterSchema := range parameterSchemas {
|
||||
compute.parameterSchemasByName[parameterSchema.Name] = parameterSchema
|
||||
|
@ -71,13 +71,13 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
|
|||
// Job parameters come second!
|
||||
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
ScopeID: scope.ProjectImportJobID,
|
||||
ScopeID: scope.TemplateImportJobID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Default project parameter values come second!
|
||||
// Default template parameter values come second!
|
||||
for _, parameterSchema := range parameterSchemas {
|
||||
if parameterSchema.DefaultSourceScheme == database.ParameterSourceSchemeNone {
|
||||
continue
|
||||
|
@ -101,21 +101,21 @@ func Compute(ctx context.Context, db database.Store, scope ComputeScope, options
|
|||
DestinationScheme: parameterSchema.DefaultDestinationScheme,
|
||||
SourceValue: parameterSchema.DefaultSourceValue,
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
ScopeID: scope.ProjectImportJobID,
|
||||
ScopeID: scope.TemplateImportJobID,
|
||||
}, true)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert default value: %w", err)
|
||||
}
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported source scheme for project version parameter %q: %q", parameterSchema.Name, string(parameterSchema.DefaultSourceScheme))
|
||||
return nil, xerrors.Errorf("unsupported source scheme for template version parameter %q: %q", parameterSchema.Name, string(parameterSchema.DefaultSourceScheme))
|
||||
}
|
||||
}
|
||||
|
||||
if scope.ProjectID.Valid {
|
||||
// Project parameters come third!
|
||||
if scope.TemplateID.Valid {
|
||||
// Template parameters come third!
|
||||
err = compute.injectScope(ctx, database.GetParameterValuesByScopeParams{
|
||||
Scope: database.ParameterScopeProject,
|
||||
ScopeID: scope.ProjectID.UUID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
ScopeID: scope.TemplateID.UUID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -178,14 +178,14 @@ func (c *compute) injectScope(ctx context.Context, scopeParams database.GetParam
|
|||
func (c *compute) injectSingle(scopedParameter database.ParameterValue, defaultValue bool) error {
|
||||
parameterSchema, hasParameterSchema := c.parameterSchemasByName[scopedParameter.Name]
|
||||
if !hasParameterSchema {
|
||||
// Don't inject parameters that aren't defined by the project.
|
||||
// Don't inject parameters that aren't defined by the template.
|
||||
return nil
|
||||
}
|
||||
|
||||
_, hasParameterValue := c.computedParameterByName[scopedParameter.Name]
|
||||
if hasParameterValue {
|
||||
if !parameterSchema.AllowOverrideSource &&
|
||||
// Users and workspaces cannot override anything on a project!
|
||||
// Users and workspaces cannot override anything on a template!
|
||||
(scopedParameter.Scope == database.ParameterScopeUser ||
|
||||
scopedParameter.Scope == database.ParameterScopeWorkspace) {
|
||||
return nil
|
||||
|
|
|
@ -17,9 +17,9 @@ func TestCompute(t *testing.T) {
|
|||
t.Parallel()
|
||||
generateScope := func() parameter.ComputeScope {
|
||||
return parameter.ComputeScope{
|
||||
ProjectImportJobID: uuid.New(),
|
||||
OrganizationID: uuid.New(),
|
||||
ProjectID: uuid.NullUUID{
|
||||
TemplateImportJobID: uuid.New(),
|
||||
OrganizationID: uuid.New(),
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: uuid.New(),
|
||||
Valid: true,
|
||||
},
|
||||
|
@ -34,7 +34,7 @@ func TestCompute(t *testing.T) {
|
|||
AllowOverrideSource bool
|
||||
AllowOverrideDestination bool
|
||||
DefaultDestinationScheme database.ParameterDestinationScheme
|
||||
ProjectImportJobID uuid.UUID
|
||||
TemplateImportJobID uuid.UUID
|
||||
}
|
||||
generateParameter := func(t *testing.T, db database.Store, opts parameterOptions) database.ParameterSchema {
|
||||
if opts.DefaultDestinationScheme == "" {
|
||||
|
@ -47,7 +47,7 @@ func TestCompute(t *testing.T) {
|
|||
param, err := db.InsertParameterSchema(context.Background(), database.InsertParameterSchemaParams{
|
||||
ID: uuid.New(),
|
||||
Name: name,
|
||||
JobID: opts.ProjectImportJobID,
|
||||
JobID: opts.TemplateImportJobID,
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeData,
|
||||
DefaultSourceValue: sourceValue,
|
||||
AllowOverrideSource: opts.AllowOverrideSource,
|
||||
|
@ -64,7 +64,7 @@ func TestCompute(t *testing.T) {
|
|||
scope := generateScope()
|
||||
_, err := db.InsertParameterSchema(context.Background(), database.InsertParameterSchemaParams{
|
||||
ID: uuid.New(),
|
||||
JobID: scope.ProjectImportJobID,
|
||||
JobID: scope.TemplateImportJobID,
|
||||
Name: "hey",
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
})
|
||||
|
@ -74,12 +74,12 @@ func TestCompute(t *testing.T) {
|
|||
require.Len(t, computed, 0)
|
||||
})
|
||||
|
||||
t.Run("UseDefaultProjectValue", func(t *testing.T) {
|
||||
t.Run("UseDefaultTemplateValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
|
@ -88,7 +88,7 @@ func TestCompute(t *testing.T) {
|
|||
computedValue := computed[0]
|
||||
require.True(t, computedValue.DefaultSourceValue)
|
||||
require.Equal(t, database.ParameterScopeImportJob, computedValue.Scope)
|
||||
require.Equal(t, scope.ProjectImportJobID, computedValue.ScopeID)
|
||||
require.Equal(t, scope.TemplateImportJobID, computedValue.ScopeID)
|
||||
require.Equal(t, computedValue.SourceValue, parameterSchema.DefaultSourceValue)
|
||||
})
|
||||
|
||||
|
@ -97,7 +97,7 @@ func TestCompute(t *testing.T) {
|
|||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
_, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
|
@ -114,7 +114,7 @@ func TestCompute(t *testing.T) {
|
|||
ID: uuid.New(),
|
||||
Name: parameterSchema.Name,
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
ScopeID: scope.ProjectImportJobID,
|
||||
ScopeID: scope.TemplateImportJobID,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: "secondnop",
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
|
@ -128,18 +128,18 @@ func TestCompute(t *testing.T) {
|
|||
require.Equal(t, value.SourceValue, computed[0].SourceValue)
|
||||
})
|
||||
|
||||
t.Run("ProjectOverridesProjectDefault", func(t *testing.T) {
|
||||
t.Run("TemplateOverridesTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
value, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterSchema.Name,
|
||||
Scope: database.ParameterScopeProject,
|
||||
ScopeID: scope.ProjectID.UUID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
ScopeID: scope.TemplateID.UUID,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: "nop",
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
|
@ -153,12 +153,12 @@ func TestCompute(t *testing.T) {
|
|||
require.Equal(t, value.SourceValue, computed[0].SourceValue)
|
||||
})
|
||||
|
||||
t.Run("WorkspaceCannotOverwriteProjectDefault", func(t *testing.T) {
|
||||
t.Run("WorkspaceCannotOverwriteTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
|
||||
_, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
|
||||
|
@ -178,13 +178,13 @@ func TestCompute(t *testing.T) {
|
|||
require.Equal(t, true, computed[0].DefaultSourceValue)
|
||||
})
|
||||
|
||||
t.Run("WorkspaceOverwriteProjectDefault", func(t *testing.T) {
|
||||
t.Run("WorkspaceOverwriteTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
AllowOverrideSource: true,
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
_, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
|
@ -208,7 +208,7 @@ func TestCompute(t *testing.T) {
|
|||
db := databasefake.New()
|
||||
scope := generateScope()
|
||||
_ = generateParameter(t, db, parameterOptions{
|
||||
ProjectImportJobID: scope.ProjectImportJobID,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, ¶meter.ComputeOptions{
|
||||
|
|
|
@ -143,8 +143,8 @@ func readScopeAndID(rw http.ResponseWriter, r *http.Request) (database.Parameter
|
|||
switch chi.URLParam(r, "scope") {
|
||||
case string(codersdk.ParameterOrganization):
|
||||
scope = database.ParameterScopeOrganization
|
||||
case string(codersdk.ParameterProject):
|
||||
scope = database.ParameterScopeProject
|
||||
case string(codersdk.ParameterTemplate):
|
||||
scope = database.ParameterScopeTemplate
|
||||
case string(codersdk.ParameterUser):
|
||||
scope = database.ParameterScopeUser
|
||||
case string(codersdk.ParameterWorkspace):
|
||||
|
|
|
@ -1,225 +0,0 @@
|
|||
package coderd
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/coderd/httpmw"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// Returns a single project.
|
||||
func (api *api) project(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByProjectIDs(r.Context(), []uuid.UUID{project.ID})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get workspace counts: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
count := uint32(0)
|
||||
if len(workspaceCounts) > 0 {
|
||||
count = uint32(workspaceCounts[0].Count)
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertProject(project, count))
|
||||
}
|
||||
|
||||
func (api *api) deleteProject(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
|
||||
workspaces, err := api.Database.GetWorkspacesByProjectID(r.Context(), database.GetWorkspacesByProjectIDParams{
|
||||
ProjectID: project.ID,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get workspaces by project id: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if len(workspaces) > 0 {
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: "All workspaces must be deleted before a project can be removed.",
|
||||
})
|
||||
return
|
||||
}
|
||||
err = api.Database.UpdateProjectDeletedByID(r.Context(), database.UpdateProjectDeletedByIDParams{
|
||||
ID: project.ID,
|
||||
Deleted: true,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("update project deleted by id: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
||||
Message: "Project has been deleted!",
|
||||
})
|
||||
}
|
||||
|
||||
func (api *api) projectVersionsByProject(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
|
||||
versions, err := api.Database.GetProjectVersionsByProjectID(r.Context(), project.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
jobIDs := make([]uuid.UUID, 0, len(versions))
|
||||
for _, version := range versions {
|
||||
jobIDs = append(jobIDs, version.JobID)
|
||||
}
|
||||
jobs, err := api.Database.GetProvisionerJobsByIDs(r.Context(), jobIDs)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get jobs: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
jobByID := map[string]database.ProvisionerJob{}
|
||||
for _, job := range jobs {
|
||||
jobByID[job.ID.String()] = job
|
||||
}
|
||||
|
||||
apiVersion := make([]codersdk.ProjectVersion, 0)
|
||||
for _, version := range versions {
|
||||
job, exists := jobByID[version.JobID.String()]
|
||||
if !exists {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("job %q doesn't exist for version %q", version.JobID, version.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
apiVersion = append(apiVersion, convertProjectVersion(version, convertProvisionerJob(job)))
|
||||
}
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, apiVersion)
|
||||
}
|
||||
|
||||
func (api *api) projectVersionByName(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
projectVersionName := chi.URLParam(r, "projectversionname")
|
||||
projectVersion, err := api.Database.GetProjectVersionByProjectIDAndName(r.Context(), database.GetProjectVersionByProjectIDAndNameParams{
|
||||
ProjectID: uuid.NullUUID{
|
||||
UUID: project.ID,
|
||||
Valid: true,
|
||||
},
|
||||
Name: projectVersionName,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("no project version found by name %q", projectVersionName),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version by name: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertProjectVersion(projectVersion, convertProvisionerJob(job)))
|
||||
}
|
||||
|
||||
func (api *api) patchActiveProjectVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
var req codersdk.UpdateActiveProjectVersion
|
||||
if !httpapi.Read(rw, r, &req) {
|
||||
return
|
||||
}
|
||||
project := httpmw.ProjectParam(r)
|
||||
version, err := api.Database.GetProjectVersionByID(r.Context(), req.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: "project version not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if version.ProjectID.UUID.String() != project.ID.String() {
|
||||
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
|
||||
Message: "The provided project version doesn't belong to the specified project.",
|
||||
})
|
||||
return
|
||||
}
|
||||
err = api.Database.UpdateProjectActiveVersionByID(r.Context(), database.UpdateProjectActiveVersionByIDParams{
|
||||
ID: project.ID,
|
||||
ActiveVersionID: req.ID,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("update active project version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
||||
Message: "Updated the active project version!",
|
||||
})
|
||||
}
|
||||
|
||||
func convertProjects(projects []database.Project, workspaceCounts []database.GetWorkspaceOwnerCountsByProjectIDsRow) []codersdk.Project {
|
||||
apiProjects := make([]codersdk.Project, 0, len(projects))
|
||||
for _, project := range projects {
|
||||
found := false
|
||||
for _, workspaceCount := range workspaceCounts {
|
||||
if workspaceCount.ProjectID.String() != project.ID.String() {
|
||||
continue
|
||||
}
|
||||
apiProjects = append(apiProjects, convertProject(project, uint32(workspaceCount.Count)))
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
apiProjects = append(apiProjects, convertProject(project, uint32(0)))
|
||||
}
|
||||
}
|
||||
return apiProjects
|
||||
}
|
||||
|
||||
func convertProject(project database.Project, workspaceOwnerCount uint32) codersdk.Project {
|
||||
return codersdk.Project{
|
||||
ID: project.ID,
|
||||
CreatedAt: project.CreatedAt,
|
||||
UpdatedAt: project.UpdatedAt,
|
||||
OrganizationID: project.OrganizationID,
|
||||
Name: project.Name,
|
||||
Provisioner: project.Provisioner,
|
||||
ActiveVersionID: project.ActiveVersionID,
|
||||
WorkspaceOwnerCount: workspaceOwnerCount,
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
package coderd_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func TestProject(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.Project(context.Background(), project.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteProject(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("NoWorkspaces", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
err := client.DeleteProject(context.Background(), project.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Workspaces", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
err := client.DeleteProject(context.Background(), project.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionsByProject(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
versions, err := client.ProjectVersionsByProject(context.Background(), project.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, versions, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionByName(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.ProjectVersionByName(context.Background(), project.ID, "nothing")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("Found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.ProjectVersionByName(context.Background(), project.ID, version.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchActiveProjectVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
err := client.UpdateActiveProjectVersion(context.Background(), project.ID, codersdk.UpdateActiveProjectVersion{
|
||||
ID: uuid.New(),
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("DoesNotBelong", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
version = coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
err := client.UpdateActiveProjectVersion(context.Background(), project.ID, codersdk.UpdateActiveProjectVersion{
|
||||
ID: version.ID,
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("Found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
err := client.UpdateActiveProjectVersion(context.Background(), project.ID, codersdk.UpdateActiveProjectVersion{
|
||||
ID: version.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
|
@ -177,13 +177,13 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
|
|||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("get workspace: %s", err))
|
||||
}
|
||||
projectVersion, err := server.Database.GetProjectVersionByID(ctx, workspaceBuild.ProjectVersionID)
|
||||
templateVersion, err := server.Database.GetTemplateVersionByID(ctx, workspaceBuild.TemplateVersionID)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("get project version: %s", err))
|
||||
return nil, failJob(fmt.Sprintf("get template version: %s", err))
|
||||
}
|
||||
project, err := server.Database.GetProjectByID(ctx, projectVersion.ProjectID.UUID)
|
||||
template, err := server.Database.GetTemplateByID(ctx, templateVersion.TemplateID.UUID)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("get project: %s", err))
|
||||
return nil, failJob(fmt.Sprintf("get template: %s", err))
|
||||
}
|
||||
owner, err := server.Database.GetUserByID(ctx, workspace.OwnerID)
|
||||
if err != nil {
|
||||
|
@ -192,10 +192,10 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
|
|||
|
||||
// Compute parameters for the workspace to consume.
|
||||
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
|
||||
ProjectImportJobID: projectVersion.JobID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
ProjectID: uuid.NullUUID{
|
||||
UUID: project.ID,
|
||||
TemplateImportJobID: templateVersion.JobID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
UserID: user.ID,
|
||||
|
@ -235,9 +235,9 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
|
|||
},
|
||||
},
|
||||
}
|
||||
case database.ProvisionerJobTypeProjectVersionImport:
|
||||
protoJob.Type = &proto.AcquiredJob_ProjectImport_{
|
||||
ProjectImport: &proto.AcquiredJob_ProjectImport{
|
||||
case database.ProvisionerJobTypeTemplateVersionImport:
|
||||
protoJob.Type = &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
Metadata: &sdkproto.Provision_Metadata{
|
||||
CoderUrl: server.AccessURL.String(),
|
||||
},
|
||||
|
@ -250,7 +250,7 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
|
|||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("get file by hash: %s", err))
|
||||
}
|
||||
protoJob.ProjectSourceArchive = file.Data
|
||||
protoJob.TemplateSourceArchive = file.Data
|
||||
default:
|
||||
return nil, failJob(fmt.Sprintf("unsupported storage method: %s", job.StorageMethod))
|
||||
}
|
||||
|
@ -366,20 +366,20 @@ func (server *provisionerdServer) UpdateJob(ctx context.Context, request *proto.
|
|||
}
|
||||
}
|
||||
|
||||
var projectID uuid.NullUUID
|
||||
if job.Type == database.ProvisionerJobTypeProjectVersionImport {
|
||||
projectVersion, err := server.Database.GetProjectVersionByJobID(ctx, job.ID)
|
||||
var templateID uuid.NullUUID
|
||||
if job.Type == database.ProvisionerJobTypeTemplateVersionImport {
|
||||
templateVersion, err := server.Database.GetTemplateVersionByJobID(ctx, job.ID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get project version by job id: %w", err)
|
||||
return nil, xerrors.Errorf("get template version by job id: %w", err)
|
||||
}
|
||||
projectID = projectVersion.ProjectID
|
||||
templateID = templateVersion.TemplateID
|
||||
}
|
||||
|
||||
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
|
||||
ProjectImportJobID: job.ID,
|
||||
ProjectID: projectID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
UserID: job.InitiatorID,
|
||||
TemplateImportJobID: job.ID,
|
||||
TemplateID: templateID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
UserID: job.InitiatorID,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("compute parameters: %w", err)
|
||||
|
@ -450,7 +450,7 @@ func (server *provisionerdServer) FailJob(ctx context.Context, failJob *proto.Fa
|
|||
if err != nil {
|
||||
return nil, xerrors.Errorf("update workspace build state: %w", err)
|
||||
}
|
||||
case *proto.FailedJob_ProjectImport_:
|
||||
case *proto.FailedJob_TemplateImport_:
|
||||
}
|
||||
return &proto.Empty{}, nil
|
||||
}
|
||||
|
@ -470,17 +470,17 @@ func (server *provisionerdServer) CompleteJob(ctx context.Context, completed *pr
|
|||
}
|
||||
|
||||
switch jobType := completed.Type.(type) {
|
||||
case *proto.CompletedJob_ProjectImport_:
|
||||
case *proto.CompletedJob_TemplateImport_:
|
||||
for transition, resources := range map[database.WorkspaceTransition][]*sdkproto.Resource{
|
||||
database.WorkspaceTransitionStart: jobType.ProjectImport.StartResources,
|
||||
database.WorkspaceTransitionStop: jobType.ProjectImport.StopResources,
|
||||
database.WorkspaceTransitionStart: jobType.TemplateImport.StartResources,
|
||||
database.WorkspaceTransitionStop: jobType.TemplateImport.StopResources,
|
||||
} {
|
||||
addresses, err := provisionersdk.ResourceAddresses(resources)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("compute resource addresses: %w", err)
|
||||
}
|
||||
for index, resource := range resources {
|
||||
server.Logger.Info(ctx, "inserting project import job resource",
|
||||
server.Logger.Info(ctx, "inserting template import job resource",
|
||||
slog.F("job_id", job.ID.String()),
|
||||
slog.F("resource_name", resource.Name),
|
||||
slog.F("resource_type", resource.Type),
|
||||
|
|
|
@ -21,7 +21,7 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -36,9 +36,9 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
before := time.Now().UTC()
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
|
@ -59,7 +59,7 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -74,9 +74,9 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
before := database.Now()
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancelFunc)
|
||||
|
@ -95,7 +95,7 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -110,9 +110,9 @@ func TestProvisionerJobLogs(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
logs, err := client.WorkspaceBuildLogsBefore(context.Background(), workspace.LatestBuild.ID, time.Now())
|
||||
require.NoError(t, err)
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
package coderd
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/coderd/httpmw"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// Returns a single template.
|
||||
func (api *api) template(rw http.ResponseWriter, r *http.Request) {
|
||||
template := httpmw.TemplateParam(r)
|
||||
workspaceCounts, err := api.Database.GetWorkspaceOwnerCountsByTemplateIDs(r.Context(), []uuid.UUID{template.ID})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get workspace counts: %s", err.Error()),
|
||||
})
|
||||
return
|
||||
}
|
||||
count := uint32(0)
|
||||
if len(workspaceCounts) > 0 {
|
||||
count = uint32(workspaceCounts[0].Count)
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertTemplate(template, count))
|
||||
}
|
||||
|
||||
func (api *api) deleteTemplate(rw http.ResponseWriter, r *http.Request) {
|
||||
template := httpmw.TemplateParam(r)
|
||||
|
||||
workspaces, err := api.Database.GetWorkspacesByTemplateID(r.Context(), database.GetWorkspacesByTemplateIDParams{
|
||||
TemplateID: template.ID,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get workspaces by template id: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if len(workspaces) > 0 {
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: "All workspaces must be deleted before a template can be removed.",
|
||||
})
|
||||
return
|
||||
}
|
||||
err = api.Database.UpdateTemplateDeletedByID(r.Context(), database.UpdateTemplateDeletedByIDParams{
|
||||
ID: template.ID,
|
||||
Deleted: true,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("update template deleted by id: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
||||
Message: "Template has been deleted!",
|
||||
})
|
||||
}
|
||||
|
||||
func (api *api) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) {
|
||||
template := httpmw.TemplateParam(r)
|
||||
|
||||
versions, err := api.Database.GetTemplateVersionsByTemplateID(r.Context(), template.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get template version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
jobIDs := make([]uuid.UUID, 0, len(versions))
|
||||
for _, version := range versions {
|
||||
jobIDs = append(jobIDs, version.JobID)
|
||||
}
|
||||
jobs, err := api.Database.GetProvisionerJobsByIDs(r.Context(), jobIDs)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get jobs: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
jobByID := map[string]database.ProvisionerJob{}
|
||||
for _, job := range jobs {
|
||||
jobByID[job.ID.String()] = job
|
||||
}
|
||||
|
||||
apiVersion := make([]codersdk.TemplateVersion, 0)
|
||||
for _, version := range versions {
|
||||
job, exists := jobByID[version.JobID.String()]
|
||||
if !exists {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("job %q doesn't exist for version %q", version.JobID, version.ID),
|
||||
})
|
||||
return
|
||||
}
|
||||
apiVersion = append(apiVersion, convertTemplateVersion(version, convertProvisionerJob(job)))
|
||||
}
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, apiVersion)
|
||||
}
|
||||
|
||||
func (api *api) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
|
||||
template := httpmw.TemplateParam(r)
|
||||
templateVersionName := chi.URLParam(r, "templateversionname")
|
||||
templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(r.Context(), database.GetTemplateVersionByTemplateIDAndNameParams{
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
Name: templateVersionName,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: fmt.Sprintf("no template version found by name %q", templateVersionName),
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get template version by name: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertTemplateVersion(templateVersion, convertProvisionerJob(job)))
|
||||
}
|
||||
|
||||
func (api *api) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
var req codersdk.UpdateActiveTemplateVersion
|
||||
if !httpapi.Read(rw, r, &req) {
|
||||
return
|
||||
}
|
||||
template := httpmw.TemplateParam(r)
|
||||
version, err := api.Database.GetTemplateVersionByID(r.Context(), req.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
||||
Message: "template version not found",
|
||||
})
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get template version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
if version.TemplateID.UUID.String() != template.ID.String() {
|
||||
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
|
||||
Message: "The provided template version doesn't belong to the specified template.",
|
||||
})
|
||||
return
|
||||
}
|
||||
err = api.Database.UpdateTemplateActiveVersionByID(r.Context(), database.UpdateTemplateActiveVersionByIDParams{
|
||||
ID: template.ID,
|
||||
ActiveVersionID: req.ID,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("update active template version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
||||
Message: "Updated the active template version!",
|
||||
})
|
||||
}
|
||||
|
||||
func convertTemplates(templates []database.Template, workspaceCounts []database.GetWorkspaceOwnerCountsByTemplateIDsRow) []codersdk.Template {
|
||||
apiTemplates := make([]codersdk.Template, 0, len(templates))
|
||||
for _, template := range templates {
|
||||
found := false
|
||||
for _, workspaceCount := range workspaceCounts {
|
||||
if workspaceCount.TemplateID.String() != template.ID.String() {
|
||||
continue
|
||||
}
|
||||
apiTemplates = append(apiTemplates, convertTemplate(template, uint32(workspaceCount.Count)))
|
||||
found = true
|
||||
break
|
||||
}
|
||||
if !found {
|
||||
apiTemplates = append(apiTemplates, convertTemplate(template, uint32(0)))
|
||||
}
|
||||
}
|
||||
return apiTemplates
|
||||
}
|
||||
|
||||
func convertTemplate(template database.Template, workspaceOwnerCount uint32) codersdk.Template {
|
||||
return codersdk.Template{
|
||||
ID: template.ID,
|
||||
CreatedAt: template.CreatedAt,
|
||||
UpdatedAt: template.UpdatedAt,
|
||||
OrganizationID: template.OrganizationID,
|
||||
Name: template.Name,
|
||||
Provisioner: template.Provisioner,
|
||||
ActiveVersionID: template.ActiveVersionID,
|
||||
WorkspaceOwnerCount: workspaceOwnerCount,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package coderd_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func TestTemplate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.Template(context.Background(), template.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteTemplate(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("NoWorkspaces", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
err := client.DeleteTemplate(context.Background(), template.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Workspaces", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
err := client.DeleteTemplate(context.Background(), template.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionsByTemplate(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
versions, err := client.TemplateVersionsByTemplate(context.Background(), template.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, versions, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionByName(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.TemplateVersionByName(context.Background(), template.ID, "nothing")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("Found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_, err := client.TemplateVersionByName(context.Background(), template.ID, version.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchActiveTemplateVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotFound", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
err := client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
|
||||
ID: uuid.New(),
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("DoesNotBelong", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
err := client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
|
||||
ID: version.ID,
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusUnauthorized, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("Found", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
err := client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
|
||||
ID: version.ID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
|
@ -15,9 +15,9 @@ import (
|
|||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func (api *api) projectVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
func (api *api) templateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -25,12 +25,12 @@ func (api *api) projectVersion(rw http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertProjectVersion(projectVersion, convertProvisionerJob(job)))
|
||||
render.JSON(rw, r, convertTemplateVersion(templateVersion, convertProvisionerJob(job)))
|
||||
}
|
||||
|
||||
func (api *api) patchCancelProjectVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
func (api *api) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -67,9 +67,9 @@ func (api *api) patchCancelProjectVersion(rw http.ResponseWriter, r *http.Reques
|
|||
})
|
||||
}
|
||||
|
||||
func (api *api) projectVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
func (api *api) templateVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -78,7 +78,7 @@ func (api *api) projectVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
if !job.CompletedAt.Valid {
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: "Project version job hasn't completed!",
|
||||
Message: "Template version job hasn't completed!",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -99,10 +99,10 @@ func (api *api) projectVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
|||
render.JSON(rw, r, schemas)
|
||||
}
|
||||
|
||||
func (api *api) projectVersionParameters(rw http.ResponseWriter, r *http.Request) {
|
||||
func (api *api) templateVersionParameters(rw http.ResponseWriter, r *http.Request) {
|
||||
apiKey := httpmw.APIKey(r)
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -116,9 +116,9 @@ func (api *api) projectVersionParameters(rw http.ResponseWriter, r *http.Request
|
|||
return
|
||||
}
|
||||
values, err := parameter.Compute(r.Context(), api.Database, parameter.ComputeScope{
|
||||
ProjectImportJobID: job.ID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
UserID: apiKey.UserID,
|
||||
TemplateImportJobID: job.ID,
|
||||
OrganizationID: job.OrganizationID,
|
||||
UserID: apiKey.UserID,
|
||||
}, ¶meter.ComputeOptions{
|
||||
// We *never* want to send the client secret parameter values.
|
||||
HideRedisplayValues: true,
|
||||
|
@ -136,9 +136,9 @@ func (api *api) projectVersionParameters(rw http.ResponseWriter, r *http.Request
|
|||
render.JSON(rw, r, values)
|
||||
}
|
||||
|
||||
func (api *api) projectVersionResources(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
func (api *api) templateVersionResources(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -148,9 +148,9 @@ func (api *api) projectVersionResources(rw http.ResponseWriter, r *http.Request)
|
|||
api.provisionerJobResources(rw, r, job)
|
||||
}
|
||||
|
||||
func (api *api) projectVersionLogs(rw http.ResponseWriter, r *http.Request) {
|
||||
projectVersion := httpmw.ProjectVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
func (api *api) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
job, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
|
@ -160,13 +160,13 @@ func (api *api) projectVersionLogs(rw http.ResponseWriter, r *http.Request) {
|
|||
api.provisionerJobLogs(rw, r, job)
|
||||
}
|
||||
|
||||
func convertProjectVersion(version database.ProjectVersion, job codersdk.ProvisionerJob) codersdk.ProjectVersion {
|
||||
return codersdk.ProjectVersion{
|
||||
ID: version.ID,
|
||||
ProjectID: &version.ProjectID.UUID,
|
||||
CreatedAt: version.CreatedAt,
|
||||
UpdatedAt: version.UpdatedAt,
|
||||
Name: version.Name,
|
||||
Job: job,
|
||||
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob) codersdk.TemplateVersion {
|
||||
return codersdk.TemplateVersion{
|
||||
ID: version.ID,
|
||||
TemplateID: &version.TemplateID.UUID,
|
||||
CreatedAt: version.CreatedAt,
|
||||
UpdatedAt: version.UpdatedAt,
|
||||
Name: version.Name,
|
||||
Job: job,
|
||||
}
|
||||
}
|
|
@ -15,28 +15,28 @@ import (
|
|||
"github.com/coder/coder/provisionersdk/proto"
|
||||
)
|
||||
|
||||
func TestProjectVersion(t *testing.T) {
|
||||
func TestTemplateVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Get", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.ProjectVersion(context.Background(), version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.TemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestPatchCancelProjectVersion(t *testing.T) {
|
||||
func TestPatchCancelTemplateVersion(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("AlreadyCompleted", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
err := client.CancelProjectVersion(context.Background(), version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
err := client.CancelTemplateVersion(context.Background(), version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
|
@ -46,7 +46,7 @@ func TestPatchCancelProjectVersion(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -56,14 +56,14 @@ func TestPatchCancelProjectVersion(t *testing.T) {
|
|||
})
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
version, err = client.ProjectVersion(context.Background(), version.ID)
|
||||
version, err = client.TemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
t.Logf("Status: %s", version.Job.Status)
|
||||
return version.Job.Status == codersdk.ProvisionerJobRunning
|
||||
}, 5*time.Second, 25*time.Millisecond)
|
||||
err := client.CancelProjectVersion(context.Background(), version.ID)
|
||||
err := client.CancelTemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
err = client.CancelProjectVersion(context.Background(), version.ID)
|
||||
err = client.CancelTemplateVersion(context.Background(), version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
|
@ -73,7 +73,7 @@ func TestPatchCancelProjectVersion(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -83,30 +83,30 @@ func TestPatchCancelProjectVersion(t *testing.T) {
|
|||
})
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
version, err = client.ProjectVersion(context.Background(), version.ID)
|
||||
version, err = client.TemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
t.Logf("Status: %s", version.Job.Status)
|
||||
return version.Job.Status == codersdk.ProvisionerJobRunning
|
||||
}, 5*time.Second, 25*time.Millisecond)
|
||||
err := client.CancelProjectVersion(context.Background(), version.ID)
|
||||
err := client.CancelTemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
version, err = client.ProjectVersion(context.Background(), version.ID)
|
||||
version, err = client.TemplateVersion(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
return version.Job.Status == codersdk.ProvisionerJobCanceled
|
||||
}, 5*time.Second, 25*time.Millisecond)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionSchema(t *testing.T) {
|
||||
func TestTemplateVersionSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListRunning", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.ProjectVersionSchema(context.Background(), version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.TemplateVersionSchema(context.Background(), version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
|
@ -116,7 +116,7 @@ func TestProjectVersionSchema(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
|
@ -131,22 +131,22 @@ func TestProjectVersionSchema(t *testing.T) {
|
|||
}},
|
||||
Provision: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
schemas, err := client.ProjectVersionSchema(context.Background(), version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
schemas, err := client.TemplateVersionSchema(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, schemas)
|
||||
require.Len(t, schemas, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionParameters(t *testing.T) {
|
||||
func TestTemplateVersionParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListRunning", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.ProjectVersionParameters(context.Background(), version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.TemplateVersionParameters(context.Background(), version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
|
@ -156,7 +156,7 @@ func TestProjectVersionParameters(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
|
@ -176,8 +176,8 @@ func TestProjectVersionParameters(t *testing.T) {
|
|||
}},
|
||||
Provision: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
params, err := client.ProjectVersionParameters(context.Background(), version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
params, err := client.TemplateVersionParameters(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, params)
|
||||
require.Len(t, params, 1)
|
||||
|
@ -185,14 +185,14 @@ func TestProjectVersionParameters(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionResources(t *testing.T) {
|
||||
func TestTemplateVersionResources(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListRunning", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.ProjectVersionResources(context.Background(), version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_, err := client.TemplateVersionResources(context.Background(), version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusPreconditionFailed, apiErr.StatusCode())
|
||||
|
@ -202,7 +202,7 @@ func TestProjectVersionResources(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -222,8 +222,8 @@ func TestProjectVersionResources(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
resources, err := client.ProjectVersionResources(context.Background(), version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
resources, err := client.TemplateVersionResources(context.Background(), version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resources)
|
||||
require.Len(t, resources, 4)
|
||||
|
@ -233,13 +233,13 @@ func TestProjectVersionResources(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestProjectVersionLogs(t *testing.T) {
|
||||
func TestTemplateVersionLogs(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
before := time.Now()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
|
@ -271,7 +271,7 @@ func TestProjectVersionLogs(t *testing.T) {
|
|||
})
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancelFunc)
|
||||
logs, err := client.ProjectVersionLogsAfter(ctx, version.ID, before)
|
||||
logs, err := client.TemplateVersionLogsAfter(ctx, version.ID, before)
|
||||
require.NoError(t, err)
|
||||
for {
|
||||
_, ok := <-logs
|
|
@ -23,7 +23,7 @@ const (
|
|||
|
||||
// Compare checks the equality of passwords from a hashed pbkdf2 string.
|
||||
// This uses pbkdf2 to ensure FIPS 140-2 compliance. See:
|
||||
// https://csrc.nist.gov/csrc/media/projects/cryptographic-module-validation-program/documents/security-policies/140sp2261.pdf
|
||||
// https://csrc.nist.gov/csrc/media/templates/cryptographic-module-validation-program/documents/security-policies/140sp2261.pdf
|
||||
func Compare(hashed string, password string) (bool, error) {
|
||||
if len(hashed) < hashLength {
|
||||
return false, xerrors.Errorf("hash too short: %d", len(hashed))
|
||||
|
|
104
coderd/users.go
104
coderd/users.go
|
@ -529,12 +529,12 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
apiKey := httpmw.APIKey(r)
|
||||
project, err := api.Database.GetProjectByID(r.Context(), createWorkspace.ProjectID)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), createWorkspace.TemplateID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: fmt.Sprintf("project %q doesn't exist", createWorkspace.ProjectID.String()),
|
||||
Message: fmt.Sprintf("template %q doesn't exist", createWorkspace.TemplateID.String()),
|
||||
Errors: []httpapi.Error{{
|
||||
Field: "project_id",
|
||||
Field: "template_id",
|
||||
Code: "not_found",
|
||||
}},
|
||||
})
|
||||
|
@ -542,17 +542,17 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
_, err = api.Database.GetOrganizationMemberByUserID(r.Context(), database.GetOrganizationMemberByUserIDParams{
|
||||
OrganizationID: project.OrganizationID,
|
||||
OrganizationID: template.OrganizationID,
|
||||
UserID: apiKey.UserID,
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusUnauthorized, httpapi.Response{
|
||||
Message: "you aren't allowed to access projects in that organization",
|
||||
Message: "you aren't allowed to access templates in that organization",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -569,16 +569,16 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
if err == nil {
|
||||
// If the workspace already exists, don't allow creation.
|
||||
project, err := api.Database.GetProjectByID(r.Context(), workspace.ProjectID)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("find project for conflicting workspace name %q: %s", createWorkspace.Name, err),
|
||||
Message: fmt.Sprintf("find template for conflicting workspace name %q: %s", createWorkspace.Name, err),
|
||||
})
|
||||
return
|
||||
}
|
||||
// The project is fetched for clarity to the user on where the conflicting name may be.
|
||||
// The template is fetched for clarity to the user on where the conflicting name may be.
|
||||
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
|
||||
Message: fmt.Sprintf("workspace %q already exists in the %q project", createWorkspace.Name, project.Name),
|
||||
Message: fmt.Sprintf("workspace %q already exists in the %q template", createWorkspace.Name, template.Name),
|
||||
Errors: []httpapi.Error{{
|
||||
Field: "name",
|
||||
Code: "exists",
|
||||
|
@ -593,35 +593,35 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
projectVersion, err := api.Database.GetProjectVersionByID(r.Context(), project.ActiveVersionID)
|
||||
templateVersion, err := api.Database.GetTemplateVersionByID(r.Context(), template.ActiveVersionID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version: %s", err),
|
||||
Message: fmt.Sprintf("get template version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectVersionJob, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
templateVersionJob, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version job: %s", err),
|
||||
Message: fmt.Sprintf("get template version job: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectVersionJobStatus := convertProvisionerJob(projectVersionJob).Status
|
||||
switch projectVersionJobStatus {
|
||||
templateVersionJobStatus := convertProvisionerJob(templateVersionJob).Status
|
||||
switch templateVersionJobStatus {
|
||||
case codersdk.ProvisionerJobPending, codersdk.ProvisionerJobRunning:
|
||||
httpapi.Write(rw, http.StatusNotAcceptable, httpapi.Response{
|
||||
Message: fmt.Sprintf("The provided project version is %s. Wait for it to complete importing!", projectVersionJobStatus),
|
||||
Message: fmt.Sprintf("The provided template version is %s. Wait for it to complete importing!", templateVersionJobStatus),
|
||||
})
|
||||
return
|
||||
case codersdk.ProvisionerJobFailed:
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: fmt.Sprintf("The provided project version %q has failed to import. You cannot create workspaces using it!", projectVersion.Name),
|
||||
Message: fmt.Sprintf("The provided template version %q has failed to import. You cannot create workspaces using it!", templateVersion.Name),
|
||||
})
|
||||
return
|
||||
case codersdk.ProvisionerJobCanceled:
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: "The provided project version was canceled during import. You cannot create workspaces using it!",
|
||||
Message: "The provided template version was canceled during import. You cannot create workspaces using it!",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -632,12 +632,12 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
workspaceBuildID := uuid.New()
|
||||
// Workspaces are created without any versions.
|
||||
workspace, err = db.InsertWorkspace(r.Context(), database.InsertWorkspaceParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
OwnerID: apiKey.UserID,
|
||||
ProjectID: project.ID,
|
||||
Name: createWorkspace.Name,
|
||||
ID: uuid.New(),
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
OwnerID: apiKey.UserID,
|
||||
TemplateID: template.ID,
|
||||
Name: createWorkspace.Name,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert workspace: %w", err)
|
||||
|
@ -670,26 +670,26 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
InitiatorID: apiKey.UserID,
|
||||
OrganizationID: project.OrganizationID,
|
||||
Provisioner: project.Provisioner,
|
||||
OrganizationID: template.OrganizationID,
|
||||
Provisioner: template.Provisioner,
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
StorageMethod: projectVersionJob.StorageMethod,
|
||||
StorageSource: projectVersionJob.StorageSource,
|
||||
StorageMethod: templateVersionJob.StorageMethod,
|
||||
StorageSource: templateVersionJob.StorageSource,
|
||||
Input: input,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert provisioner job: %w", err)
|
||||
}
|
||||
workspaceBuild, err = db.InsertWorkspaceBuild(r.Context(), database.InsertWorkspaceBuildParams{
|
||||
ID: workspaceBuildID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
WorkspaceID: workspace.ID,
|
||||
ProjectVersionID: projectVersion.ID,
|
||||
Name: namesgenerator.GetRandomName(1),
|
||||
InitiatorID: apiKey.UserID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
JobID: provisionerJob.ID,
|
||||
ID: workspaceBuildID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
WorkspaceID: workspace.ID,
|
||||
TemplateVersionID: templateVersion.ID,
|
||||
Name: namesgenerator.GetRandomName(1),
|
||||
InitiatorID: apiKey.UserID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
JobID: provisionerJob.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert workspace build: %w", err)
|
||||
|
@ -705,7 +705,7 @@ func (api *api) postWorkspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, convertWorkspace(workspace,
|
||||
convertWorkspaceBuild(workspaceBuild, convertProvisionerJob(projectVersionJob)), project))
|
||||
convertWorkspaceBuild(workspaceBuild, convertProvisionerJob(templateVersionJob)), template))
|
||||
}
|
||||
|
||||
func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
||||
|
@ -723,10 +723,10 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
workspaceIDs := make([]uuid.UUID, 0, len(workspaces))
|
||||
projectIDs := make([]uuid.UUID, 0, len(workspaces))
|
||||
templateIDs := make([]uuid.UUID, 0, len(workspaces))
|
||||
for _, workspace := range workspaces {
|
||||
workspaceIDs = append(workspaceIDs, workspace.ID)
|
||||
projectIDs = append(projectIDs, workspace.ProjectID)
|
||||
templateIDs = append(templateIDs, workspace.TemplateID)
|
||||
}
|
||||
workspaceBuilds, err := api.Database.GetWorkspaceBuildsByWorkspaceIDsWithoutAfter(r.Context(), workspaceIDs)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
|
@ -738,13 +738,13 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
return
|
||||
}
|
||||
projects, err := api.Database.GetProjectsByIDs(r.Context(), projectIDs)
|
||||
templates, err := api.Database.GetTemplatesByIDs(r.Context(), templateIDs)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get projects: %s", err),
|
||||
Message: fmt.Sprintf("get templates: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -767,9 +767,9 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
for _, workspaceBuild := range workspaceBuilds {
|
||||
buildByWorkspaceID[workspaceBuild.WorkspaceID] = workspaceBuild
|
||||
}
|
||||
projectByID := map[uuid.UUID]database.Project{}
|
||||
for _, project := range projects {
|
||||
projectByID[project.ID] = project
|
||||
templateByID := map[uuid.UUID]database.Template{}
|
||||
for _, template := range templates {
|
||||
templateByID[template.ID] = template
|
||||
}
|
||||
jobByID := map[uuid.UUID]database.ProvisionerJob{}
|
||||
for _, job := range jobs {
|
||||
|
@ -784,10 +784,10 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
return
|
||||
}
|
||||
project, exists := projectByID[workspace.ProjectID]
|
||||
template, exists := templateByID[workspace.TemplateID]
|
||||
if !exists {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("project not found for workspace %q", workspace.Name),
|
||||
Message: fmt.Sprintf("template not found for workspace %q", workspace.Name),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -799,7 +799,7 @@ func (api *api) workspacesByUser(rw http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
apiWorkspaces = append(apiWorkspaces,
|
||||
convertWorkspace(workspace, convertWorkspaceBuild(build, convertProvisionerJob(job)), project))
|
||||
convertWorkspace(workspace, convertWorkspaceBuild(build, convertProvisionerJob(job)), template))
|
||||
}
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, apiWorkspaces)
|
||||
|
@ -838,17 +838,17 @@ func (api *api) workspaceByUserAndName(rw http.ResponseWriter, r *http.Request)
|
|||
})
|
||||
return
|
||||
}
|
||||
project, err := api.Database.GetProjectByID(r.Context(), workspace.ProjectID)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, convertWorkspace(workspace,
|
||||
convertWorkspaceBuild(build, convertProvisionerJob(job)), project))
|
||||
convertWorkspaceBuild(build, convertProvisionerJob(job)), template))
|
||||
}
|
||||
|
||||
// Generates a new ID and secret for an API key.
|
||||
|
|
|
@ -310,13 +310,13 @@ func TestPostAPIKey(t *testing.T) {
|
|||
|
||||
func TestPostWorkspacesByUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("InvalidProject", func(t *testing.T) {
|
||||
t.Run("InvalidTemplate", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
_ = coderdtest.CreateFirstUser(t, client)
|
||||
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: uuid.New(),
|
||||
Name: "workspace",
|
||||
TemplateID: uuid.New(),
|
||||
Name: "workspace",
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -324,7 +324,7 @@ func TestPostWorkspacesByUser(t *testing.T) {
|
|||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("NoProjectAccess", func(t *testing.T) {
|
||||
t.Run("NoTemplateAccess", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
first := coderdtest.CreateFirstUser(t, client)
|
||||
|
@ -334,12 +334,12 @@ func TestPostWorkspacesByUser(t *testing.T) {
|
|||
Name: "another",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
version := coderdtest.CreateProjectVersion(t, other, org.ID, nil)
|
||||
project := coderdtest.CreateProject(t, other, org.ID, version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, other, org.ID, nil)
|
||||
template := coderdtest.CreateTemplate(t, other, org.ID, version.ID)
|
||||
|
||||
_, err = client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: project.ID,
|
||||
Name: "workspace",
|
||||
TemplateID: template.ID,
|
||||
Name: "workspace",
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -352,13 +352,13 @@ func TestPostWorkspacesByUser(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: project.ID,
|
||||
Name: workspace.Name,
|
||||
TemplateID: template.ID,
|
||||
Name: workspace.Name,
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -371,10 +371,10 @@ func TestPostWorkspacesByUser(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -392,10 +392,10 @@ func TestWorkspacesByUser(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
_ = coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
workspaces, err := client.WorkspacesByUser(context.Background(), codersdk.Me)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, workspaces, 1)
|
||||
|
@ -418,10 +418,10 @@ func TestWorkspaceByUserAndName(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.WorkspaceByName(context.Background(), codersdk.Me, workspace.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
|
|
@ -92,17 +92,17 @@ func (api *api) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) {
|
|||
func convertWorkspaceBuild(workspaceBuild database.WorkspaceBuild, job codersdk.ProvisionerJob) codersdk.WorkspaceBuild {
|
||||
//nolint:unconvert
|
||||
return codersdk.WorkspaceBuild{
|
||||
ID: workspaceBuild.ID,
|
||||
CreatedAt: workspaceBuild.CreatedAt,
|
||||
UpdatedAt: workspaceBuild.UpdatedAt,
|
||||
WorkspaceID: workspaceBuild.WorkspaceID,
|
||||
ProjectVersionID: workspaceBuild.ProjectVersionID,
|
||||
BeforeID: workspaceBuild.BeforeID.UUID,
|
||||
AfterID: workspaceBuild.AfterID.UUID,
|
||||
Name: workspaceBuild.Name,
|
||||
Transition: workspaceBuild.Transition,
|
||||
InitiatorID: workspaceBuild.InitiatorID,
|
||||
Job: job,
|
||||
ID: workspaceBuild.ID,
|
||||
CreatedAt: workspaceBuild.CreatedAt,
|
||||
UpdatedAt: workspaceBuild.UpdatedAt,
|
||||
WorkspaceID: workspaceBuild.WorkspaceID,
|
||||
TemplateVersionID: workspaceBuild.TemplateVersionID,
|
||||
BeforeID: workspaceBuild.BeforeID.UUID,
|
||||
AfterID: workspaceBuild.AfterID.UUID,
|
||||
Name: workspaceBuild.Name,
|
||||
Transition: workspaceBuild.Transition,
|
||||
InitiatorID: workspaceBuild.InitiatorID,
|
||||
Job: job,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,10 +19,10 @@ func TestWorkspaceBuild(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.WorkspaceBuild(context.Background(), workspace.LatestBuild.ID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@ -32,7 +32,7 @@ func TestPatchCancelWorkspaceBuild(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -41,9 +41,9 @@ func TestPatchCancelWorkspaceBuild(t *testing.T) {
|
|||
}},
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
var build codersdk.WorkspaceBuild
|
||||
require.Eventually(t, func() bool {
|
||||
var err error
|
||||
|
@ -68,11 +68,11 @@ func TestWorkspaceBuildResources(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
closeDaemon := coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
closeDaemon.Close()
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
|
@ -83,7 +83,7 @@ func TestWorkspaceBuildResources(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -103,9 +103,9 @@ func TestWorkspaceBuildResources(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
resources, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
|
||||
require.NoError(t, err)
|
||||
|
@ -123,7 +123,7 @@ func TestWorkspaceBuildLogs(t *testing.T) {
|
|||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
before := time.Now()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Log{
|
||||
|
@ -150,9 +150,9 @@ func TestWorkspaceBuildLogs(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
t.Cleanup(cancelFunc)
|
||||
logs, err := client.WorkspaceBuildLogsAfter(ctx, workspace.LatestBuild.ID, before)
|
||||
|
|
|
@ -24,7 +24,7 @@ func TestPostWorkspaceAuthAWSInstanceIdentity(t *testing.T) {
|
|||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -42,9 +42,9 @@ func TestPostWorkspaceAuthAWSInstanceIdentity(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
client.HTTPClient = metadataClient
|
||||
|
@ -90,7 +90,7 @@ func TestPostWorkspaceAuthGoogleInstanceIdentity(t *testing.T) {
|
|||
})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -108,9 +108,9 @@ func TestPostWorkspaceAuthGoogleInstanceIdentity(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
|
||||
_, err := client.AuthWorkspaceGoogleInstanceIdentity(context.Background(), "", metadata)
|
||||
|
|
|
@ -25,7 +25,7 @@ func TestWorkspaceResource(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
|
@ -42,9 +42,9 @@ func TestWorkspaceResource(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
resources, err := client.WorkspaceResourcesByBuild(context.Background(), workspace.LatestBuild.ID)
|
||||
require.NoError(t, err)
|
||||
|
@ -59,7 +59,7 @@ func TestWorkspaceAgentListen(t *testing.T) {
|
|||
user := coderdtest.CreateFirstUser(t, client)
|
||||
daemonCloser := coderdtest.NewProvisionerDaemon(t, client)
|
||||
authToken := uuid.NewString()
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionDryRun: echo.ProvisionComplete,
|
||||
Provision: []*proto.Provision_Response{{
|
||||
|
@ -79,9 +79,9 @@ func TestWorkspaceAgentListen(t *testing.T) {
|
|||
},
|
||||
}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
daemonCloser.Close()
|
||||
|
||||
|
|
|
@ -37,14 +37,14 @@ func (api *api) workspace(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
return
|
||||
}
|
||||
project, err := api.Database.GetProjectByID(r.Context(), workspace.ProjectID)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), workspace.TemplateID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
render.JSON(rw, r, convertWorkspace(workspace, convertWorkspaceBuild(build, convertProvisionerJob(job)), project))
|
||||
render.JSON(rw, r, convertWorkspace(workspace, convertWorkspaceBuild(build, convertProvisionerJob(job)), template))
|
||||
}
|
||||
|
||||
func (api *api) workspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
|
@ -102,7 +102,7 @@ func (api *api) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
|||
if !httpapi.Read(rw, r, &createBuild) {
|
||||
return
|
||||
}
|
||||
if createBuild.ProjectVersionID == uuid.Nil {
|
||||
if createBuild.TemplateVersionID == uuid.Nil {
|
||||
latestBuild, err := api.Database.GetWorkspaceBuildByWorkspaceIDWithoutAfter(r.Context(), workspace.ID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
|
@ -110,14 +110,14 @@ func (api *api) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
|||
})
|
||||
return
|
||||
}
|
||||
createBuild.ProjectVersionID = latestBuild.ProjectVersionID
|
||||
createBuild.TemplateVersionID = latestBuild.TemplateVersionID
|
||||
}
|
||||
projectVersion, err := api.Database.GetProjectVersionByID(r.Context(), createBuild.ProjectVersionID)
|
||||
templateVersion, err := api.Database.GetTemplateVersionByID(r.Context(), createBuild.TemplateVersionID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
||||
Message: "project version not found",
|
||||
Message: "template version not found",
|
||||
Errors: []httpapi.Error{{
|
||||
Field: "project_version_id",
|
||||
Field: "template_version_id",
|
||||
Code: "exists",
|
||||
}},
|
||||
})
|
||||
|
@ -125,40 +125,40 @@ func (api *api) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
|||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project version: %s", err),
|
||||
Message: fmt.Sprintf("get template version: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectVersionJob, err := api.Database.GetProvisionerJobByID(r.Context(), projectVersion.JobID)
|
||||
templateVersionJob, err := api.Database.GetProvisionerJobByID(r.Context(), templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get provisioner job: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
projectVersionJobStatus := convertProvisionerJob(projectVersionJob).Status
|
||||
switch projectVersionJobStatus {
|
||||
templateVersionJobStatus := convertProvisionerJob(templateVersionJob).Status
|
||||
switch templateVersionJobStatus {
|
||||
case codersdk.ProvisionerJobPending, codersdk.ProvisionerJobRunning:
|
||||
httpapi.Write(rw, http.StatusNotAcceptable, httpapi.Response{
|
||||
Message: fmt.Sprintf("The provided project version is %s. Wait for it to complete importing!", projectVersionJobStatus),
|
||||
Message: fmt.Sprintf("The provided template version is %s. Wait for it to complete importing!", templateVersionJobStatus),
|
||||
})
|
||||
return
|
||||
case codersdk.ProvisionerJobFailed:
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: fmt.Sprintf("The provided project version %q has failed to import: %q. You cannot build workspaces with it!", projectVersion.Name, projectVersionJob.Error.String),
|
||||
Message: fmt.Sprintf("The provided template version %q has failed to import: %q. You cannot build workspaces with it!", templateVersion.Name, templateVersionJob.Error.String),
|
||||
})
|
||||
return
|
||||
case codersdk.ProvisionerJobCanceled:
|
||||
httpapi.Write(rw, http.StatusPreconditionFailed, httpapi.Response{
|
||||
Message: "The provided project version was canceled during import. You cannot builds workspaces with it!",
|
||||
Message: "The provided template version was canceled during import. You cannot builds workspaces with it!",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
project, err := api.Database.GetProjectByID(r.Context(), projectVersion.ProjectID.UUID)
|
||||
template, err := api.Database.GetTemplateByID(r.Context(), templateVersion.TemplateID.UUID)
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get project: %s", err),
|
||||
Message: fmt.Sprintf("get template: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
@ -203,28 +203,28 @@ func (api *api) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
|||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
InitiatorID: apiKey.UserID,
|
||||
OrganizationID: project.OrganizationID,
|
||||
Provisioner: project.Provisioner,
|
||||
OrganizationID: template.OrganizationID,
|
||||
Provisioner: template.Provisioner,
|
||||
Type: database.ProvisionerJobTypeWorkspaceBuild,
|
||||
StorageMethod: projectVersionJob.StorageMethod,
|
||||
StorageSource: projectVersionJob.StorageSource,
|
||||
StorageMethod: templateVersionJob.StorageMethod,
|
||||
StorageSource: templateVersionJob.StorageSource,
|
||||
Input: input,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert provisioner job: %w", err)
|
||||
}
|
||||
workspaceBuild, err = db.InsertWorkspaceBuild(r.Context(), database.InsertWorkspaceBuildParams{
|
||||
ID: workspaceBuildID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
WorkspaceID: workspace.ID,
|
||||
ProjectVersionID: projectVersion.ID,
|
||||
BeforeID: priorHistoryID,
|
||||
Name: namesgenerator.GetRandomName(1),
|
||||
ProvisionerState: priorHistory.ProvisionerState,
|
||||
InitiatorID: apiKey.UserID,
|
||||
Transition: createBuild.Transition,
|
||||
JobID: provisionerJob.ID,
|
||||
ID: workspaceBuildID,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
WorkspaceID: workspace.ID,
|
||||
TemplateVersionID: templateVersion.ID,
|
||||
BeforeID: priorHistoryID,
|
||||
Name: namesgenerator.GetRandomName(1),
|
||||
ProvisionerState: priorHistory.ProvisionerState,
|
||||
InitiatorID: apiKey.UserID,
|
||||
Transition: createBuild.Transition,
|
||||
JobID: provisionerJob.ID,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert workspace build: %w", err)
|
||||
|
@ -290,16 +290,16 @@ func (api *api) workspaceBuildByName(rw http.ResponseWriter, r *http.Request) {
|
|||
render.JSON(rw, r, convertWorkspaceBuild(workspaceBuild, convertProvisionerJob(job)))
|
||||
}
|
||||
|
||||
func convertWorkspace(workspace database.Workspace, workspaceBuild codersdk.WorkspaceBuild, project database.Project) codersdk.Workspace {
|
||||
func convertWorkspace(workspace database.Workspace, workspaceBuild codersdk.WorkspaceBuild, template database.Template) codersdk.Workspace {
|
||||
return codersdk.Workspace{
|
||||
ID: workspace.ID,
|
||||
CreatedAt: workspace.CreatedAt,
|
||||
UpdatedAt: workspace.UpdatedAt,
|
||||
OwnerID: workspace.OwnerID,
|
||||
ProjectID: workspace.ProjectID,
|
||||
LatestBuild: workspaceBuild,
|
||||
ProjectName: project.Name,
|
||||
Outdated: workspaceBuild.ProjectVersionID.String() != project.ActiveVersionID.String(),
|
||||
Name: workspace.Name,
|
||||
ID: workspace.ID,
|
||||
CreatedAt: workspace.CreatedAt,
|
||||
UpdatedAt: workspace.UpdatedAt,
|
||||
OwnerID: workspace.OwnerID,
|
||||
TemplateID: workspace.TemplateID,
|
||||
LatestBuild: workspaceBuild,
|
||||
TemplateName: template.Name,
|
||||
Outdated: workspaceBuild.TemplateVersionID.String() != template.ActiveVersionID.String(),
|
||||
Name: workspace.Name,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,10 +20,10 @@ func TestWorkspace(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.Workspace(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ func TestWorkspaceBuilds(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.WorkspaceBuilds(context.Background(), workspace.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
@ -46,18 +46,18 @@ func TestWorkspaceBuilds(t *testing.T) {
|
|||
|
||||
func TestPostWorkspaceBuild(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NoProjectVersion", func(t *testing.T) {
|
||||
t.Run("NoTemplateVersion", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
ProjectVersionID: uuid.New(),
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
TemplateVersionID: uuid.New(),
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -65,19 +65,19 @@ func TestPostWorkspaceBuild(t *testing.T) {
|
|||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("ProjectVersionFailedImport", func(t *testing.T) {
|
||||
t.Run("TemplateVersionFailedImport", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Provision: []*proto.Provision_Response{{}},
|
||||
})
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
_, err := client.CreateWorkspace(context.Background(), codersdk.Me, codersdk.CreateWorkspaceRequest{
|
||||
ProjectID: project.ID,
|
||||
Name: "workspace",
|
||||
TemplateID: template.ID,
|
||||
Name: "workspace",
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
|
@ -89,15 +89,15 @@ func TestPostWorkspaceBuild(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
closeDaemon := coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
// Close here so workspace build doesn't process!
|
||||
closeDaemon.Close()
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
ProjectVersionID: project.ActiveVersionID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
TemplateVersionID: template.ActiveVersionID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
})
|
||||
require.Error(t, err)
|
||||
var apiErr *codersdk.Error
|
||||
|
@ -110,14 +110,14 @@ func TestPostWorkspaceBuild(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
ProjectVersionID: project.ActiveVersionID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
TemplateVersionID: template.ActiveVersionID,
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, workspace.LatestBuild.ID.String(), build.BeforeID.String())
|
||||
|
@ -132,10 +132,10 @@ func TestPostWorkspaceBuild(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
Transition: database.WorkspaceTransitionDelete,
|
||||
|
@ -157,10 +157,10 @@ func TestWorkspaceBuildByName(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
_, err := client.WorkspaceBuildByName(context.Background(), workspace.ID, "something")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
|
@ -172,10 +172,10 @@ func TestWorkspaceBuildByName(t *testing.T) {
|
|||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
coderdtest.NewProvisionerDaemon(t, client)
|
||||
version := coderdtest.CreateProjectVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitProjectVersionJob(t, client, version.ID)
|
||||
project := coderdtest.CreateProject(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace := coderdtest.CreateWorkspace(t, client, codersdk.Me, template.ID)
|
||||
build, err := client.WorkspaceBuild(context.Background(), workspace.LatestBuild.ID)
|
||||
require.NoError(t, err)
|
||||
_, err = client.WorkspaceBuildByName(context.Background(), workspace.ID, build.Name)
|
||||
|
|
|
@ -21,10 +21,10 @@ type Organization struct {
|
|||
UpdatedAt time.Time `json:"updated_at" validate:"required"`
|
||||
}
|
||||
|
||||
// CreateProjectVersionRequest enables callers to create a new Project Version.
|
||||
type CreateProjectVersionRequest struct {
|
||||
// ProjectID optionally associates a version with a project.
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
// CreateTemplateVersionRequest enables callers to create a new Template Version.
|
||||
type CreateTemplateVersionRequest struct {
|
||||
// TemplateID optionally associates a version with a template.
|
||||
TemplateID uuid.UUID `json:"template_id"`
|
||||
|
||||
StorageMethod database.ProvisionerStorageMethod `json:"storage_method" validate:"oneof=file,required"`
|
||||
StorageSource string `json:"storage_source" validate:"required"`
|
||||
|
@ -34,17 +34,17 @@ type CreateProjectVersionRequest struct {
|
|||
ParameterValues []CreateParameterRequest `json:"parameter_values"`
|
||||
}
|
||||
|
||||
// CreateProjectRequest provides options when creating a project.
|
||||
type CreateProjectRequest struct {
|
||||
// CreateTemplateRequest provides options when creating a template.
|
||||
type CreateTemplateRequest struct {
|
||||
Name string `json:"name" validate:"username,required"`
|
||||
|
||||
// VersionID is an in-progress or completed job to use as
|
||||
// an initial version of the project.
|
||||
// an initial version of the template.
|
||||
//
|
||||
// This is required on creation to enable a user-flow of validating a
|
||||
// project works. There is no reason the data-model cannot support
|
||||
// empty projects, but it doesn't make sense for users.
|
||||
VersionID uuid.UUID `json:"project_version_id" validate:"required"`
|
||||
// template works. There is no reason the data-model cannot support
|
||||
// empty templates, but it doesn't make sense for users.
|
||||
VersionID uuid.UUID `json:"template_version_id" validate:"required"`
|
||||
ParameterValues []CreateParameterRequest `json:"parameter_values"`
|
||||
}
|
||||
|
||||
|
@ -82,49 +82,49 @@ func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organizat
|
|||
return daemons, json.NewDecoder(res.Body).Decode(&daemons)
|
||||
}
|
||||
|
||||
// CreateProjectVersion processes source-code and optionally associates the version with a project.
|
||||
// Executing without a project is useful for validating source-code.
|
||||
func (c *Client) CreateProjectVersion(ctx context.Context, organizationID uuid.UUID, req CreateProjectVersionRequest) (ProjectVersion, error) {
|
||||
// CreateTemplateVersion processes source-code and optionally associates the version with a template.
|
||||
// Executing without a template is useful for validating source-code.
|
||||
func (c *Client) CreateTemplateVersion(ctx context.Context, organizationID uuid.UUID, req CreateTemplateVersionRequest) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodPost,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/projectversions", organizationID.String()),
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templateversions", organizationID.String()),
|
||||
req,
|
||||
)
|
||||
if err != nil {
|
||||
return ProjectVersion{}, xerrors.Errorf("execute request: %w", err)
|
||||
return TemplateVersion{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return ProjectVersion{}, readBodyAsError(res)
|
||||
return TemplateVersion{}, readBodyAsError(res)
|
||||
}
|
||||
|
||||
var projectVersion ProjectVersion
|
||||
return projectVersion, json.NewDecoder(res.Body).Decode(&projectVersion)
|
||||
var templateVersion TemplateVersion
|
||||
return templateVersion, json.NewDecoder(res.Body).Decode(&templateVersion)
|
||||
}
|
||||
|
||||
// CreateProject creates a new project inside an organization.
|
||||
func (c *Client) CreateProject(ctx context.Context, organizationID uuid.UUID, request CreateProjectRequest) (Project, error) {
|
||||
// CreateTemplate creates a new template inside an organization.
|
||||
func (c *Client) CreateTemplate(ctx context.Context, organizationID uuid.UUID, request CreateTemplateRequest) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodPost,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/projects", organizationID.String()),
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates", organizationID.String()),
|
||||
request,
|
||||
)
|
||||
if err != nil {
|
||||
return Project{}, xerrors.Errorf("execute request: %w", err)
|
||||
return Template{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusCreated {
|
||||
return Project{}, readBodyAsError(res)
|
||||
return Template{}, readBodyAsError(res)
|
||||
}
|
||||
|
||||
var project Project
|
||||
return project, json.NewDecoder(res.Body).Decode(&project)
|
||||
var template Template
|
||||
return template, json.NewDecoder(res.Body).Decode(&template)
|
||||
}
|
||||
|
||||
// ProjectsByOrganization lists all projects inside of an organization.
|
||||
func (c *Client) ProjectsByOrganization(ctx context.Context, organizationID uuid.UUID) ([]Project, error) {
|
||||
// TemplatesByOrganization lists all templates inside of an organization.
|
||||
func (c *Client) TemplatesByOrganization(ctx context.Context, organizationID uuid.UUID) ([]Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/projects", organizationID.String()),
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates", organizationID.String()),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -136,25 +136,25 @@ func (c *Client) ProjectsByOrganization(ctx context.Context, organizationID uuid
|
|||
return nil, readBodyAsError(res)
|
||||
}
|
||||
|
||||
var projects []Project
|
||||
return projects, json.NewDecoder(res.Body).Decode(&projects)
|
||||
var templates []Template
|
||||
return templates, json.NewDecoder(res.Body).Decode(&templates)
|
||||
}
|
||||
|
||||
// ProjectByName finds a project inside the organization provided with a case-insensitive name.
|
||||
func (c *Client) ProjectByName(ctx context.Context, organizationID uuid.UUID, name string) (Project, error) {
|
||||
// TemplateByName finds a template inside the organization provided with a case-insensitive name.
|
||||
func (c *Client) TemplateByName(ctx context.Context, organizationID uuid.UUID, name string) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet,
|
||||
fmt.Sprintf("/api/v2/organizations/%s/projects/%s", organizationID.String(), name),
|
||||
fmt.Sprintf("/api/v2/organizations/%s/templates/%s", organizationID.String(), name),
|
||||
nil,
|
||||
)
|
||||
if err != nil {
|
||||
return Project{}, xerrors.Errorf("execute request: %w", err)
|
||||
return Template{}, xerrors.Errorf("execute request: %w", err)
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return Project{}, readBodyAsError(res)
|
||||
return Template{}, readBodyAsError(res)
|
||||
}
|
||||
|
||||
var project Project
|
||||
return project, json.NewDecoder(res.Body).Decode(&project)
|
||||
var template Template
|
||||
return template, json.NewDecoder(res.Body).Decode(&template)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ type ParameterScope string
|
|||
|
||||
const (
|
||||
ParameterOrganization ParameterScope = "organization"
|
||||
ParameterProject ParameterScope = "project"
|
||||
ParameterTemplate ParameterScope = "template"
|
||||
ParameterUser ParameterScope = "user"
|
||||
ParameterWorkspace ParameterScope = "workspace"
|
||||
)
|
||||
|
|
|
@ -1,109 +0,0 @@
|
|||
package codersdk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
)
|
||||
|
||||
// ProjectVersion represents a single version of a project.
|
||||
type ProjectVersion struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
ProjectID *uuid.UUID `json:"project_id,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Job ProvisionerJob `json:"job"`
|
||||
}
|
||||
|
||||
// ProjectVersionParameterSchema represents a parameter parsed from project version source.
|
||||
type ProjectVersionParameterSchema database.ParameterSchema
|
||||
|
||||
// ProjectVersionParameter represents a computed parameter value.
|
||||
type ProjectVersionParameter parameter.ComputedValue
|
||||
|
||||
// ProjectVersion returns a project version by ID.
|
||||
func (c *Client) ProjectVersion(ctx context.Context, id uuid.UUID) (ProjectVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projectversions/%s", id), nil)
|
||||
if err != nil {
|
||||
return ProjectVersion{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return ProjectVersion{}, readBodyAsError(res)
|
||||
}
|
||||
var version ProjectVersion
|
||||
return version, json.NewDecoder(res.Body).Decode(&version)
|
||||
}
|
||||
|
||||
// CancelProjectVersion marks a project version job as canceled.
|
||||
func (c *Client) CancelProjectVersion(ctx context.Context, version uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/projectversions/%s/cancel", version), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return readBodyAsError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ProjectVersionSchema returns schemas for a project version by ID.
|
||||
func (c *Client) ProjectVersionSchema(ctx context.Context, version uuid.UUID) ([]ProjectVersionParameterSchema, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projectversions/%s/schema", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var params []ProjectVersionParameterSchema
|
||||
return params, json.NewDecoder(res.Body).Decode(¶ms)
|
||||
}
|
||||
|
||||
// ProjectVersionParameters returns computed parameters for a project version.
|
||||
func (c *Client) ProjectVersionParameters(ctx context.Context, version uuid.UUID) ([]ProjectVersionParameter, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projectversions/%s/parameters", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var params []ProjectVersionParameter
|
||||
return params, json.NewDecoder(res.Body).Decode(¶ms)
|
||||
}
|
||||
|
||||
// ProjectVersionResources returns resources a project version declares.
|
||||
func (c *Client) ProjectVersionResources(ctx context.Context, version uuid.UUID) ([]WorkspaceResource, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projectversions/%s/resources", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var resources []WorkspaceResource
|
||||
return resources, json.NewDecoder(res.Body).Decode(&resources)
|
||||
}
|
||||
|
||||
// ProjectVersionLogsBefore returns logs that occurred before a specific time.
|
||||
func (c *Client) ProjectVersionLogsBefore(ctx context.Context, version uuid.UUID, before time.Time) ([]ProvisionerJobLog, error) {
|
||||
return c.provisionerJobLogsBefore(ctx, fmt.Sprintf("/api/v2/projectversions/%s/logs", version), before)
|
||||
}
|
||||
|
||||
// ProjectVersionLogsAfter streams logs for a project version that occurred after a specific time.
|
||||
func (c *Client) ProjectVersionLogsAfter(ctx context.Context, version uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) {
|
||||
return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/projectversions/%s/logs", version), after)
|
||||
}
|
|
@ -12,9 +12,9 @@ import (
|
|||
"github.com/coder/coder/coderd/database"
|
||||
)
|
||||
|
||||
// Project is the JSON representation of a Coder project. This type matches the
|
||||
// Template is the JSON representation of a Coder template. This type matches the
|
||||
// database object for now, but is abstracted for ease of change later on.
|
||||
type Project struct {
|
||||
type Template struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
@ -25,26 +25,26 @@ type Project struct {
|
|||
WorkspaceOwnerCount uint32 `json:"workspace_owner_count"`
|
||||
}
|
||||
|
||||
type UpdateActiveProjectVersion struct {
|
||||
type UpdateActiveTemplateVersion struct {
|
||||
ID uuid.UUID `json:"id" validate:"required"`
|
||||
}
|
||||
|
||||
// Project returns a single project.
|
||||
func (c *Client) Project(ctx context.Context, project uuid.UUID) (Project, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projects/%s", project), nil)
|
||||
// Template returns a single template.
|
||||
func (c *Client) Template(ctx context.Context, template uuid.UUID) (Template, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
if err != nil {
|
||||
return Project{}, nil
|
||||
return Template{}, nil
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return Project{}, readBodyAsError(res)
|
||||
return Template{}, readBodyAsError(res)
|
||||
}
|
||||
var resp Project
|
||||
var resp Template
|
||||
return resp, json.NewDecoder(res.Body).Decode(&resp)
|
||||
}
|
||||
|
||||
func (c *Client) DeleteProject(ctx context.Context, project uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/projects/%s", project), nil)
|
||||
func (c *Client) DeleteTemplate(ctx context.Context, template uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodDelete, fmt.Sprintf("/api/v2/templates/%s", template), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -55,10 +55,10 @@ func (c *Client) DeleteProject(ctx context.Context, project uuid.UUID) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// UpdateActiveProjectVersion updates the active project version to the ID provided.
|
||||
// The project version must be attached to the project.
|
||||
func (c *Client) UpdateActiveProjectVersion(ctx context.Context, project uuid.UUID, req UpdateActiveProjectVersion) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/projects/%s/versions", project), req)
|
||||
// UpdateActiveTemplateVersion updates the active template version to the ID provided.
|
||||
// The template version must be attached to the template.
|
||||
func (c *Client) UpdateActiveTemplateVersion(ctx context.Context, template uuid.UUID, req UpdateActiveTemplateVersion) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templates/%s/versions", template), req)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -69,9 +69,9 @@ func (c *Client) UpdateActiveProjectVersion(ctx context.Context, project uuid.UU
|
|||
return nil
|
||||
}
|
||||
|
||||
// ProjectVersionsByProject lists versions associated with a project.
|
||||
func (c *Client) ProjectVersionsByProject(ctx context.Context, project uuid.UUID) ([]ProjectVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projects/%s/versions", project), nil)
|
||||
// TemplateVersionsByTemplate lists versions associated with a template.
|
||||
func (c *Client) TemplateVersionsByTemplate(ctx context.Context, template uuid.UUID) ([]TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions", template), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -79,21 +79,21 @@ func (c *Client) ProjectVersionsByProject(ctx context.Context, project uuid.UUID
|
|||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var projectVersion []ProjectVersion
|
||||
return projectVersion, json.NewDecoder(res.Body).Decode(&projectVersion)
|
||||
var templateVersion []TemplateVersion
|
||||
return templateVersion, json.NewDecoder(res.Body).Decode(&templateVersion)
|
||||
}
|
||||
|
||||
// ProjectVersionByName returns a project version by it's friendly name.
|
||||
// This is used for path-based routing. Like: /projects/example/versions/helloworld
|
||||
func (c *Client) ProjectVersionByName(ctx context.Context, project uuid.UUID, name string) (ProjectVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/projects/%s/versions/%s", project, name), nil)
|
||||
// TemplateVersionByName returns a template version by it's friendly name.
|
||||
// This is used for path-based routing. Like: /templates/example/versions/helloworld
|
||||
func (c *Client) TemplateVersionByName(ctx context.Context, template uuid.UUID, name string) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templates/%s/versions/%s", template, name), nil)
|
||||
if err != nil {
|
||||
return ProjectVersion{}, err
|
||||
return TemplateVersion{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return ProjectVersion{}, readBodyAsError(res)
|
||||
return TemplateVersion{}, readBodyAsError(res)
|
||||
}
|
||||
var projectVersion ProjectVersion
|
||||
return projectVersion, json.NewDecoder(res.Body).Decode(&projectVersion)
|
||||
var templateVersion TemplateVersion
|
||||
return templateVersion, json.NewDecoder(res.Body).Decode(&templateVersion)
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package codersdk
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
)
|
||||
|
||||
// TemplateVersion represents a single version of a template.
|
||||
type TemplateVersion struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
TemplateID *uuid.UUID `json:"template_id,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Name string `json:"name"`
|
||||
Job ProvisionerJob `json:"job"`
|
||||
}
|
||||
|
||||
// TemplateVersionParameterSchema represents a parameter parsed from template version source.
|
||||
type TemplateVersionParameterSchema database.ParameterSchema
|
||||
|
||||
// TemplateVersionParameter represents a computed parameter value.
|
||||
type TemplateVersionParameter parameter.ComputedValue
|
||||
|
||||
// TemplateVersion returns a template version by ID.
|
||||
func (c *Client) TemplateVersion(ctx context.Context, id uuid.UUID) (TemplateVersion, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s", id), nil)
|
||||
if err != nil {
|
||||
return TemplateVersion{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return TemplateVersion{}, readBodyAsError(res)
|
||||
}
|
||||
var version TemplateVersion
|
||||
return version, json.NewDecoder(res.Body).Decode(&version)
|
||||
}
|
||||
|
||||
// CancelTemplateVersion marks a template version job as canceled.
|
||||
func (c *Client) CancelTemplateVersion(ctx context.Context, version uuid.UUID) error {
|
||||
res, err := c.request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/templateversions/%s/cancel", version), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return readBodyAsError(res)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TemplateVersionSchema returns schemas for a template version by ID.
|
||||
func (c *Client) TemplateVersionSchema(ctx context.Context, version uuid.UUID) ([]TemplateVersionParameterSchema, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/schema", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var params []TemplateVersionParameterSchema
|
||||
return params, json.NewDecoder(res.Body).Decode(¶ms)
|
||||
}
|
||||
|
||||
// TemplateVersionParameters returns computed parameters for a template version.
|
||||
func (c *Client) TemplateVersionParameters(ctx context.Context, version uuid.UUID) ([]TemplateVersionParameter, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/parameters", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var params []TemplateVersionParameter
|
||||
return params, json.NewDecoder(res.Body).Decode(¶ms)
|
||||
}
|
||||
|
||||
// TemplateVersionResources returns resources a template version declares.
|
||||
func (c *Client) TemplateVersionResources(ctx context.Context, version uuid.UUID) ([]WorkspaceResource, error) {
|
||||
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/templateversions/%s/resources", version), nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return nil, readBodyAsError(res)
|
||||
}
|
||||
var resources []WorkspaceResource
|
||||
return resources, json.NewDecoder(res.Body).Decode(&resources)
|
||||
}
|
||||
|
||||
// TemplateVersionLogsBefore returns logs that occurred before a specific time.
|
||||
func (c *Client) TemplateVersionLogsBefore(ctx context.Context, version uuid.UUID, before time.Time) ([]ProvisionerJobLog, error) {
|
||||
return c.provisionerJobLogsBefore(ctx, fmt.Sprintf("/api/v2/templateversions/%s/logs", version), before)
|
||||
}
|
||||
|
||||
// TemplateVersionLogsAfter streams logs for a template version that occurred after a specific time.
|
||||
func (c *Client) TemplateVersionLogsAfter(ctx context.Context, version uuid.UUID, after time.Time) (<-chan ProvisionerJobLog, error) {
|
||||
return c.provisionerJobLogsAfter(ctx, fmt.Sprintf("/api/v2/templateversions/%s/logs", version), after)
|
||||
}
|
|
@ -63,8 +63,8 @@ type CreateOrganizationRequest struct {
|
|||
|
||||
// CreateWorkspaceRequest provides options for creating a new workspace.
|
||||
type CreateWorkspaceRequest struct {
|
||||
ProjectID uuid.UUID `json:"project_id" validate:"required"`
|
||||
Name string `json:"name" validate:"username,required"`
|
||||
TemplateID uuid.UUID `json:"template_id" validate:"required"`
|
||||
Name string `json:"name" validate:"username,required"`
|
||||
// ParameterValues allows for additional parameters to be provided
|
||||
// during the initial provision.
|
||||
ParameterValues []CreateParameterRequest `json:"parameter_values"`
|
||||
|
@ -219,7 +219,7 @@ func (c *Client) CreateOrganization(ctx context.Context, userID uuid.UUID, req C
|
|||
return org, json.NewDecoder(res.Body).Decode(&org)
|
||||
}
|
||||
|
||||
// CreateWorkspace creates a new workspace for the project specified.
|
||||
// CreateWorkspace creates a new workspace for the template specified.
|
||||
func (c *Client) CreateWorkspace(ctx context.Context, userID uuid.UUID, request CreateWorkspaceRequest) (Workspace, error) {
|
||||
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/users/%s/workspaces", uuidOrMe(userID)), request)
|
||||
if err != nil {
|
||||
|
|
|
@ -15,17 +15,17 @@ import (
|
|||
// WorkspaceBuild is an at-point representation of a workspace state.
|
||||
// Iterate on before/after to determine a chronological history.
|
||||
type WorkspaceBuild struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
WorkspaceID uuid.UUID `json:"workspace_id"`
|
||||
ProjectVersionID uuid.UUID `json:"project_version_id"`
|
||||
BeforeID uuid.UUID `json:"before_id"`
|
||||
AfterID uuid.UUID `json:"after_id"`
|
||||
Name string `json:"name"`
|
||||
Transition database.WorkspaceTransition `json:"transition"`
|
||||
InitiatorID uuid.UUID `json:"initiator_id"`
|
||||
Job ProvisionerJob `json:"job"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
WorkspaceID uuid.UUID `json:"workspace_id"`
|
||||
TemplateVersionID uuid.UUID `json:"template_version_id"`
|
||||
BeforeID uuid.UUID `json:"before_id"`
|
||||
AfterID uuid.UUID `json:"after_id"`
|
||||
Name string `json:"name"`
|
||||
Transition database.WorkspaceTransition `json:"transition"`
|
||||
InitiatorID uuid.UUID `json:"initiator_id"`
|
||||
Job ProvisionerJob `json:"job"`
|
||||
}
|
||||
|
||||
// WorkspaceBuild returns a single workspace build for a workspace.
|
||||
|
|
|
@ -12,25 +12,25 @@ import (
|
|||
"github.com/coder/coder/coderd/database"
|
||||
)
|
||||
|
||||
// Workspace is a per-user deployment of a project. It tracks
|
||||
// project versions, and can be updated.
|
||||
// Workspace is a per-user deployment of a template. It tracks
|
||||
// template versions, and can be updated.
|
||||
type Workspace struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
OwnerID uuid.UUID `json:"owner_id"`
|
||||
ProjectID uuid.UUID `json:"project_id"`
|
||||
ProjectName string `json:"project_name"`
|
||||
LatestBuild WorkspaceBuild `json:"latest_build"`
|
||||
Outdated bool `json:"outdated"`
|
||||
Name string `json:"name"`
|
||||
ID uuid.UUID `json:"id"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
OwnerID uuid.UUID `json:"owner_id"`
|
||||
TemplateID uuid.UUID `json:"template_id"`
|
||||
TemplateName string `json:"template_name"`
|
||||
LatestBuild WorkspaceBuild `json:"latest_build"`
|
||||
Outdated bool `json:"outdated"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// CreateWorkspaceBuildRequest provides options to update the latest workspace build.
|
||||
type CreateWorkspaceBuildRequest struct {
|
||||
ProjectVersionID uuid.UUID `json:"project_version_id"`
|
||||
Transition database.WorkspaceTransition `json:"transition" validate:"oneof=create start stop delete,required"`
|
||||
DryRun bool `json:"dry_run"`
|
||||
TemplateVersionID uuid.UUID `json:"template_version_id"`
|
||||
Transition database.WorkspaceTransition `json:"transition" validate:"oneof=create start stop delete,required"`
|
||||
DryRun bool `json:"dry_run"`
|
||||
}
|
||||
|
||||
// Workspace returns a single workspace.
|
||||
|
|
|
@ -113,14 +113,14 @@ type AcquiredJob struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
Provisioner string `protobuf:"bytes,3,opt,name=provisioner,proto3" json:"provisioner,omitempty"`
|
||||
UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
|
||||
ProjectSourceArchive []byte `protobuf:"bytes,5,opt,name=project_source_archive,json=projectSourceArchive,proto3" json:"project_source_archive,omitempty"`
|
||||
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
CreatedAt int64 `protobuf:"varint,2,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"`
|
||||
Provisioner string `protobuf:"bytes,3,opt,name=provisioner,proto3" json:"provisioner,omitempty"`
|
||||
UserName string `protobuf:"bytes,4,opt,name=user_name,json=userName,proto3" json:"user_name,omitempty"`
|
||||
TemplateSourceArchive []byte `protobuf:"bytes,5,opt,name=template_source_archive,json=templateSourceArchive,proto3" json:"template_source_archive,omitempty"`
|
||||
// Types that are assignable to Type:
|
||||
// *AcquiredJob_WorkspaceBuild_
|
||||
// *AcquiredJob_ProjectImport_
|
||||
// *AcquiredJob_TemplateImport_
|
||||
Type isAcquiredJob_Type `protobuf_oneof:"type"`
|
||||
}
|
||||
|
||||
|
@ -184,9 +184,9 @@ func (x *AcquiredJob) GetUserName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *AcquiredJob) GetProjectSourceArchive() []byte {
|
||||
func (x *AcquiredJob) GetTemplateSourceArchive() []byte {
|
||||
if x != nil {
|
||||
return x.ProjectSourceArchive
|
||||
return x.TemplateSourceArchive
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -205,9 +205,9 @@ func (x *AcquiredJob) GetWorkspaceBuild() *AcquiredJob_WorkspaceBuild {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *AcquiredJob) GetProjectImport() *AcquiredJob_ProjectImport {
|
||||
if x, ok := x.GetType().(*AcquiredJob_ProjectImport_); ok {
|
||||
return x.ProjectImport
|
||||
func (x *AcquiredJob) GetTemplateImport() *AcquiredJob_TemplateImport {
|
||||
if x, ok := x.GetType().(*AcquiredJob_TemplateImport_); ok {
|
||||
return x.TemplateImport
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -220,13 +220,13 @@ type AcquiredJob_WorkspaceBuild_ struct {
|
|||
WorkspaceBuild *AcquiredJob_WorkspaceBuild `protobuf:"bytes,6,opt,name=workspace_build,json=workspaceBuild,proto3,oneof"`
|
||||
}
|
||||
|
||||
type AcquiredJob_ProjectImport_ struct {
|
||||
ProjectImport *AcquiredJob_ProjectImport `protobuf:"bytes,7,opt,name=project_import,json=projectImport,proto3,oneof"`
|
||||
type AcquiredJob_TemplateImport_ struct {
|
||||
TemplateImport *AcquiredJob_TemplateImport `protobuf:"bytes,7,opt,name=template_import,json=templateImport,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*AcquiredJob_WorkspaceBuild_) isAcquiredJob_Type() {}
|
||||
|
||||
func (*AcquiredJob_ProjectImport_) isAcquiredJob_Type() {}
|
||||
func (*AcquiredJob_TemplateImport_) isAcquiredJob_Type() {}
|
||||
|
||||
type FailedJob struct {
|
||||
state protoimpl.MessageState
|
||||
|
@ -237,7 +237,7 @@ type FailedJob struct {
|
|||
Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"`
|
||||
// Types that are assignable to Type:
|
||||
// *FailedJob_WorkspaceBuild_
|
||||
// *FailedJob_ProjectImport_
|
||||
// *FailedJob_TemplateImport_
|
||||
Type isFailedJob_Type `protobuf_oneof:"type"`
|
||||
}
|
||||
|
||||
|
@ -301,9 +301,9 @@ func (x *FailedJob) GetWorkspaceBuild() *FailedJob_WorkspaceBuild {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *FailedJob) GetProjectImport() *FailedJob_ProjectImport {
|
||||
if x, ok := x.GetType().(*FailedJob_ProjectImport_); ok {
|
||||
return x.ProjectImport
|
||||
func (x *FailedJob) GetTemplateImport() *FailedJob_TemplateImport {
|
||||
if x, ok := x.GetType().(*FailedJob_TemplateImport_); ok {
|
||||
return x.TemplateImport
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -316,13 +316,13 @@ type FailedJob_WorkspaceBuild_ struct {
|
|||
WorkspaceBuild *FailedJob_WorkspaceBuild `protobuf:"bytes,3,opt,name=workspace_build,json=workspaceBuild,proto3,oneof"`
|
||||
}
|
||||
|
||||
type FailedJob_ProjectImport_ struct {
|
||||
ProjectImport *FailedJob_ProjectImport `protobuf:"bytes,4,opt,name=project_import,json=projectImport,proto3,oneof"`
|
||||
type FailedJob_TemplateImport_ struct {
|
||||
TemplateImport *FailedJob_TemplateImport `protobuf:"bytes,4,opt,name=template_import,json=templateImport,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*FailedJob_WorkspaceBuild_) isFailedJob_Type() {}
|
||||
|
||||
func (*FailedJob_ProjectImport_) isFailedJob_Type() {}
|
||||
func (*FailedJob_TemplateImport_) isFailedJob_Type() {}
|
||||
|
||||
// CompletedJob is sent when the provisioner daemon completes a job.
|
||||
type CompletedJob struct {
|
||||
|
@ -333,7 +333,7 @@ type CompletedJob struct {
|
|||
JobId string `protobuf:"bytes,1,opt,name=job_id,json=jobId,proto3" json:"job_id,omitempty"`
|
||||
// Types that are assignable to Type:
|
||||
// *CompletedJob_WorkspaceBuild_
|
||||
// *CompletedJob_ProjectImport_
|
||||
// *CompletedJob_TemplateImport_
|
||||
Type isCompletedJob_Type `protobuf_oneof:"type"`
|
||||
}
|
||||
|
||||
|
@ -390,9 +390,9 @@ func (x *CompletedJob) GetWorkspaceBuild() *CompletedJob_WorkspaceBuild {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *CompletedJob) GetProjectImport() *CompletedJob_ProjectImport {
|
||||
if x, ok := x.GetType().(*CompletedJob_ProjectImport_); ok {
|
||||
return x.ProjectImport
|
||||
func (x *CompletedJob) GetTemplateImport() *CompletedJob_TemplateImport {
|
||||
if x, ok := x.GetType().(*CompletedJob_TemplateImport_); ok {
|
||||
return x.TemplateImport
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -405,13 +405,13 @@ type CompletedJob_WorkspaceBuild_ struct {
|
|||
WorkspaceBuild *CompletedJob_WorkspaceBuild `protobuf:"bytes,2,opt,name=workspace_build,json=workspaceBuild,proto3,oneof"`
|
||||
}
|
||||
|
||||
type CompletedJob_ProjectImport_ struct {
|
||||
ProjectImport *CompletedJob_ProjectImport `protobuf:"bytes,3,opt,name=project_import,json=projectImport,proto3,oneof"`
|
||||
type CompletedJob_TemplateImport_ struct {
|
||||
TemplateImport *CompletedJob_TemplateImport `protobuf:"bytes,3,opt,name=template_import,json=templateImport,proto3,oneof"`
|
||||
}
|
||||
|
||||
func (*CompletedJob_WorkspaceBuild_) isCompletedJob_Type() {}
|
||||
|
||||
func (*CompletedJob_ProjectImport_) isCompletedJob_Type() {}
|
||||
func (*CompletedJob_TemplateImport_) isCompletedJob_Type() {}
|
||||
|
||||
// Log represents output from a job.
|
||||
type Log struct {
|
||||
|
@ -693,7 +693,7 @@ func (x *AcquiredJob_WorkspaceBuild) GetState() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
type AcquiredJob_ProjectImport struct {
|
||||
type AcquiredJob_TemplateImport struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
@ -701,8 +701,8 @@ type AcquiredJob_ProjectImport struct {
|
|||
Metadata *proto.Provision_Metadata `protobuf:"bytes,1,opt,name=metadata,proto3" json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AcquiredJob_ProjectImport) Reset() {
|
||||
*x = AcquiredJob_ProjectImport{}
|
||||
func (x *AcquiredJob_TemplateImport) Reset() {
|
||||
*x = AcquiredJob_TemplateImport{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -710,13 +710,13 @@ func (x *AcquiredJob_ProjectImport) Reset() {
|
|||
}
|
||||
}
|
||||
|
||||
func (x *AcquiredJob_ProjectImport) String() string {
|
||||
func (x *AcquiredJob_TemplateImport) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*AcquiredJob_ProjectImport) ProtoMessage() {}
|
||||
func (*AcquiredJob_TemplateImport) ProtoMessage() {}
|
||||
|
||||
func (x *AcquiredJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
||||
func (x *AcquiredJob_TemplateImport) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -728,12 +728,12 @@ func (x *AcquiredJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use AcquiredJob_ProjectImport.ProtoReflect.Descriptor instead.
|
||||
func (*AcquiredJob_ProjectImport) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use AcquiredJob_TemplateImport.ProtoReflect.Descriptor instead.
|
||||
func (*AcquiredJob_TemplateImport) Descriptor() ([]byte, []int) {
|
||||
return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{1, 1}
|
||||
}
|
||||
|
||||
func (x *AcquiredJob_ProjectImport) GetMetadata() *proto.Provision_Metadata {
|
||||
func (x *AcquiredJob_TemplateImport) GetMetadata() *proto.Provision_Metadata {
|
||||
if x != nil {
|
||||
return x.Metadata
|
||||
}
|
||||
|
@ -787,14 +787,14 @@ func (x *FailedJob_WorkspaceBuild) GetState() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
type FailedJob_ProjectImport struct {
|
||||
type FailedJob_TemplateImport struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *FailedJob_ProjectImport) Reset() {
|
||||
*x = FailedJob_ProjectImport{}
|
||||
func (x *FailedJob_TemplateImport) Reset() {
|
||||
*x = FailedJob_TemplateImport{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -802,13 +802,13 @@ func (x *FailedJob_ProjectImport) Reset() {
|
|||
}
|
||||
}
|
||||
|
||||
func (x *FailedJob_ProjectImport) String() string {
|
||||
func (x *FailedJob_TemplateImport) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*FailedJob_ProjectImport) ProtoMessage() {}
|
||||
func (*FailedJob_TemplateImport) ProtoMessage() {}
|
||||
|
||||
func (x *FailedJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
||||
func (x *FailedJob_TemplateImport) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -820,8 +820,8 @@ func (x *FailedJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use FailedJob_ProjectImport.ProtoReflect.Descriptor instead.
|
||||
func (*FailedJob_ProjectImport) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use FailedJob_TemplateImport.ProtoReflect.Descriptor instead.
|
||||
func (*FailedJob_TemplateImport) Descriptor() ([]byte, []int) {
|
||||
return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{2, 1}
|
||||
}
|
||||
|
||||
|
@ -880,7 +880,7 @@ func (x *CompletedJob_WorkspaceBuild) GetResources() []*proto.Resource {
|
|||
return nil
|
||||
}
|
||||
|
||||
type CompletedJob_ProjectImport struct {
|
||||
type CompletedJob_TemplateImport struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
@ -889,8 +889,8 @@ type CompletedJob_ProjectImport struct {
|
|||
StopResources []*proto.Resource `protobuf:"bytes,2,rep,name=stop_resources,json=stopResources,proto3" json:"stop_resources,omitempty"`
|
||||
}
|
||||
|
||||
func (x *CompletedJob_ProjectImport) Reset() {
|
||||
*x = CompletedJob_ProjectImport{}
|
||||
func (x *CompletedJob_TemplateImport) Reset() {
|
||||
*x = CompletedJob_TemplateImport{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -898,13 +898,13 @@ func (x *CompletedJob_ProjectImport) Reset() {
|
|||
}
|
||||
}
|
||||
|
||||
func (x *CompletedJob_ProjectImport) String() string {
|
||||
func (x *CompletedJob_TemplateImport) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*CompletedJob_ProjectImport) ProtoMessage() {}
|
||||
func (*CompletedJob_TemplateImport) ProtoMessage() {}
|
||||
|
||||
func (x *CompletedJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
||||
func (x *CompletedJob_TemplateImport) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_provisionerd_proto_provisionerd_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
|
@ -916,19 +916,19 @@ func (x *CompletedJob_ProjectImport) ProtoReflect() protoreflect.Message {
|
|||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use CompletedJob_ProjectImport.ProtoReflect.Descriptor instead.
|
||||
func (*CompletedJob_ProjectImport) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use CompletedJob_TemplateImport.ProtoReflect.Descriptor instead.
|
||||
func (*CompletedJob_TemplateImport) Descriptor() ([]byte, []int) {
|
||||
return file_provisionerd_proto_provisionerd_proto_rawDescGZIP(), []int{3, 1}
|
||||
}
|
||||
|
||||
func (x *CompletedJob_ProjectImport) GetStartResources() []*proto.Resource {
|
||||
func (x *CompletedJob_TemplateImport) GetStartResources() []*proto.Resource {
|
||||
if x != nil {
|
||||
return x.StartResources
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (x *CompletedJob_ProjectImport) GetStopResources() []*proto.Resource {
|
||||
func (x *CompletedJob_TemplateImport) GetStopResources() []*proto.Resource {
|
||||
if x != nil {
|
||||
return x.StopResources
|
||||
}
|
||||
|
@ -944,7 +944,7 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
|
|||
0x6f, 0x6e, 0x65, 0x72, 0x64, 0x1a, 0x26, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x65, 0x72, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x07, 0x0a,
|
||||
0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xb8, 0x05, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69,
|
||||
0x05, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0xbe, 0x05, 0x0a, 0x0b, 0x41, 0x63, 0x71, 0x75, 0x69,
|
||||
0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x1d, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
|
@ -952,142 +952,143 @@ var file_provisionerd_proto_provisionerd_proto_rawDesc = []byte{
|
|||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x12, 0x1b,
|
||||
0x0a, 0x09, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x34, 0x0a, 0x16, 0x70,
|
||||
0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61, 0x72,
|
||||
0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x14, 0x70, 0x72, 0x6f,
|
||||
0x6a, 0x65, 0x63, 0x74, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68, 0x69, 0x76,
|
||||
0x65, 0x12, 0x53, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62,
|
||||
0x75, 0x69, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72,
|
||||
0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42,
|
||||
0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x50, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x27,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63,
|
||||
0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63,
|
||||
0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x80, 0x02, 0x0a, 0x0e, 0x57, 0x6f, 0x72,
|
||||
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x2c, 0x0a, 0x12, 0x77,
|
||||
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61,
|
||||
0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72,
|
||||
0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65,
|
||||
0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
|
||||
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
|
||||
0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x4c, 0x0a, 0x0d, 0x50,
|
||||
0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3b, 0x0a, 0x08,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x52,
|
||||
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70,
|
||||
0x65, 0x22, 0x9c, 0x02, 0x0a, 0x09, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12,
|
||||
0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0f,
|
||||
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18,
|
||||
0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57,
|
||||
0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52,
|
||||
0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12,
|
||||
0x4e, 0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62,
|
||||
0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00,
|
||||
0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a,
|
||||
0x26, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c,
|
||||
0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c,
|
||||
0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x1a, 0x0f, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65,
|
||||
0x22, 0xc3, 0x03, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f,
|
||||
0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x36, 0x0a, 0x17, 0x74,
|
||||
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x61,
|
||||
0x72, 0x63, 0x68, 0x69, 0x76, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x15, 0x74, 0x65,
|
||||
0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x41, 0x72, 0x63, 0x68,
|
||||
0x69, 0x76, 0x65, 0x12, 0x53, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71, 0x75,
|
||||
0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x53, 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70,
|
||||
0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
|
||||
0x2e, 0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d,
|
||||
0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74,
|
||||
0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x80, 0x02,
|
||||
0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64,
|
||||
0x12, 0x2c, 0x0a, 0x12, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x62, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x77, 0x6f,
|
||||
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x49, 0x64, 0x12, 0x25,
|
||||
0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74,
|
||||
0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32,
|
||||
0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x12, 0x3b, 0x0a,
|
||||
0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32,
|
||||
0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x1a, 0x4d, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x12, 0x3b, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e,
|
||||
0x65, 0x72, 0x2e, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x42,
|
||||
0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xa0, 0x02, 0x0a, 0x09, 0x46, 0x61, 0x69, 0x6c,
|
||||
0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05,
|
||||
0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72,
|
||||
0x6f, 0x72, 0x12, 0x51, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
|
||||
0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65,
|
||||
0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x51, 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74,
|
||||
0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x46, 0x61,
|
||||
0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65,
|
||||
0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0e, 0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61,
|
||||
0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x26, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74,
|
||||
0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65,
|
||||
0x1a, 0x10, 0x0a, 0x0e, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x42, 0x06, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xc7, 0x03, 0x0a, 0x0c, 0x43,
|
||||
0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x15, 0x0a, 0x06, 0x6a,
|
||||
0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f, 0x62,
|
||||
0x49, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f,
|
||||
0x62, 0x75, 0x69, 0x6c, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c,
|
||||
0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63,
|
||||
0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70,
|
||||
0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x54, 0x0a, 0x0f, 0x74, 0x65, 0x6d, 0x70,
|
||||
0x6c, 0x61, 0x74, 0x65, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x29, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x57, 0x6f,
|
||||
0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x48, 0x00, 0x52, 0x0e,
|
||||
0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x12, 0x51,
|
||||
0x0a, 0x0e, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x6d, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a,
|
||||
0x6f, 0x62, 0x2e, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x48, 0x00, 0x52, 0x0d, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x1a, 0x5b, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75,
|
||||
0x69, 0x6c, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x8d,
|
||||
0x01, 0x0a, 0x0d, 0x50, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74,
|
||||
0x12, 0x3e, 0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x2e, 0x54, 0x65,
|
||||
0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x48, 0x00, 0x52, 0x0e,
|
||||
0x74, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x1a, 0x5b,
|
||||
0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x42, 0x75, 0x69, 0x6c, 0x64,
|
||||
0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x33, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x52, 0x0e, 0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
|
||||
0x12, 0x3c, 0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63,
|
||||
0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
|
||||
0x0d, 0x73, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, 0x06,
|
||||
0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f,
|
||||
0x0a, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f,
|
||||
0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12,
|
||||
0x2b, 0x0a, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67,
|
||||
0x4c, 0x65, 0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03,
|
||||
0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73,
|
||||
0x74, 0x61, 0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67,
|
||||
0x65, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x10, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15,
|
||||
0x0a, 0x06, 0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x6a, 0x6f, 0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
|
||||
0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x49, 0x0a, 0x11,
|
||||
0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61,
|
||||
0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53,
|
||||
0x63, 0x68, 0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72,
|
||||
0x53, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x22, 0x77, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74,
|
||||
0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08,
|
||||
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08,
|
||||
0x63, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61,
|
||||
0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72,
|
||||
0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52,
|
||||
0x0f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73,
|
||||
0x2a, 0x34, 0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a,
|
||||
0x12, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45,
|
||||
0x4d, 0x4f, 0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49,
|
||||
0x4f, 0x4e, 0x45, 0x52, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a,
|
||||
0x41, 0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a,
|
||||
0x19, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41,
|
||||
0x63, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70,
|
||||
0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c,
|
||||
0x4a, 0x6f, 0x62, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65,
|
||||
0x72, 0x64, 0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x12, 0x3e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62,
|
||||
0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e,
|
||||
0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74,
|
||||
0x79, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
|
||||
0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76,
|
||||
0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x52, 0x09, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x1a, 0x8e, 0x01, 0x0a, 0x0e,
|
||||
0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x49, 0x6d, 0x70, 0x6f, 0x72, 0x74, 0x12, 0x3e,
|
||||
0x0a, 0x0f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
|
||||
0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0e,
|
||||
0x73, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x3c,
|
||||
0x0a, 0x0e, 0x73, 0x74, 0x6f, 0x70, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x0d, 0x73,
|
||||
0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x42, 0x06, 0x0a, 0x04,
|
||||
0x74, 0x79, 0x70, 0x65, 0x22, 0xb0, 0x01, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x2f, 0x0a, 0x06,
|
||||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x17, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x4c, 0x6f, 0x67, 0x53,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x06, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x2b, 0x0a,
|
||||
0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x4c, 0x6f, 0x67, 0x4c, 0x65,
|
||||
0x76, 0x65, 0x6c, 0x52, 0x05, 0x6c, 0x65, 0x76, 0x65, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09,
|
||||
0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61,
|
||||
0x67, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x22, 0x9b, 0x01, 0x0a, 0x10, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x15, 0x0a, 0x06,
|
||||
0x6a, 0x6f, 0x62, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6a, 0x6f,
|
||||
0x62, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x11, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
|
||||
0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x61,
|
||||
0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x5f, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x73, 0x18,
|
||||
0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63, 0x68,
|
||||
0x65, 0x6d, 0x61, 0x52, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x53, 0x63,
|
||||
0x68, 0x65, 0x6d, 0x61, 0x73, 0x22, 0x77, 0x0a, 0x11, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a,
|
||||
0x6f, 0x62, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x63, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x6c, 0x65, 0x64, 0x12, 0x46, 0x0a, 0x10, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65,
|
||||
0x74, 0x65, 0x72, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x1b, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x2e, 0x50,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0f, 0x70,
|
||||
0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x73, 0x2a, 0x34,
|
||||
0x0a, 0x09, 0x4c, 0x6f, 0x67, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x16, 0x0a, 0x12, 0x50,
|
||||
0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x45, 0x52, 0x5f, 0x44, 0x41, 0x45, 0x4d, 0x4f,
|
||||
0x4e, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x50, 0x52, 0x4f, 0x56, 0x49, 0x53, 0x49, 0x4f, 0x4e,
|
||||
0x45, 0x52, 0x10, 0x01, 0x32, 0x98, 0x02, 0x0a, 0x11, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x3c, 0x0a, 0x0a, 0x41, 0x63,
|
||||
0x71, 0x75, 0x69, 0x72, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x13, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x19, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x41, 0x63, 0x71,
|
||||
0x75, 0x69, 0x72, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x12, 0x4c, 0x0a, 0x09, 0x55, 0x70, 0x64, 0x61,
|
||||
0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x65, 0x72, 0x64, 0x2e, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x37, 0x0a, 0x07, 0x46, 0x61, 0x69, 0x6c, 0x4a, 0x6f,
|
||||
0x62, 0x12, 0x17, 0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64,
|
||||
0x2e, 0x46, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12,
|
||||
0x3e, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x4a, 0x6f, 0x62, 0x12, 0x1a,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x43, 0x6f,
|
||||
0x6d, 0x70, 0x6c, 0x65, 0x74, 0x65, 0x64, 0x4a, 0x6f, 0x62, 0x1a, 0x13, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42,
|
||||
0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f,
|
||||
0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x65, 0x72, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -1114,11 +1115,11 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{
|
|||
(*UpdateJobRequest)(nil), // 6: provisionerd.UpdateJobRequest
|
||||
(*UpdateJobResponse)(nil), // 7: provisionerd.UpdateJobResponse
|
||||
(*AcquiredJob_WorkspaceBuild)(nil), // 8: provisionerd.AcquiredJob.WorkspaceBuild
|
||||
(*AcquiredJob_ProjectImport)(nil), // 9: provisionerd.AcquiredJob.ProjectImport
|
||||
(*AcquiredJob_TemplateImport)(nil), // 9: provisionerd.AcquiredJob.TemplateImport
|
||||
(*FailedJob_WorkspaceBuild)(nil), // 10: provisionerd.FailedJob.WorkspaceBuild
|
||||
(*FailedJob_ProjectImport)(nil), // 11: provisionerd.FailedJob.ProjectImport
|
||||
(*FailedJob_TemplateImport)(nil), // 11: provisionerd.FailedJob.TemplateImport
|
||||
(*CompletedJob_WorkspaceBuild)(nil), // 12: provisionerd.CompletedJob.WorkspaceBuild
|
||||
(*CompletedJob_ProjectImport)(nil), // 13: provisionerd.CompletedJob.ProjectImport
|
||||
(*CompletedJob_TemplateImport)(nil), // 13: provisionerd.CompletedJob.TemplateImport
|
||||
(proto.LogLevel)(0), // 14: provisioner.LogLevel
|
||||
(*proto.ParameterSchema)(nil), // 15: provisioner.ParameterSchema
|
||||
(*proto.ParameterValue)(nil), // 16: provisioner.ParameterValue
|
||||
|
@ -1127,11 +1128,11 @@ var file_provisionerd_proto_provisionerd_proto_goTypes = []interface{}{
|
|||
}
|
||||
var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
|
||||
8, // 0: provisionerd.AcquiredJob.workspace_build:type_name -> provisionerd.AcquiredJob.WorkspaceBuild
|
||||
9, // 1: provisionerd.AcquiredJob.project_import:type_name -> provisionerd.AcquiredJob.ProjectImport
|
||||
9, // 1: provisionerd.AcquiredJob.template_import:type_name -> provisionerd.AcquiredJob.TemplateImport
|
||||
10, // 2: provisionerd.FailedJob.workspace_build:type_name -> provisionerd.FailedJob.WorkspaceBuild
|
||||
11, // 3: provisionerd.FailedJob.project_import:type_name -> provisionerd.FailedJob.ProjectImport
|
||||
11, // 3: provisionerd.FailedJob.template_import:type_name -> provisionerd.FailedJob.TemplateImport
|
||||
12, // 4: provisionerd.CompletedJob.workspace_build:type_name -> provisionerd.CompletedJob.WorkspaceBuild
|
||||
13, // 5: provisionerd.CompletedJob.project_import:type_name -> provisionerd.CompletedJob.ProjectImport
|
||||
13, // 5: provisionerd.CompletedJob.template_import:type_name -> provisionerd.CompletedJob.TemplateImport
|
||||
0, // 6: provisionerd.Log.source:type_name -> provisionerd.LogSource
|
||||
14, // 7: provisionerd.Log.level:type_name -> provisioner.LogLevel
|
||||
5, // 8: provisionerd.UpdateJobRequest.logs:type_name -> provisionerd.Log
|
||||
|
@ -1139,10 +1140,10 @@ var file_provisionerd_proto_provisionerd_proto_depIdxs = []int32{
|
|||
16, // 10: provisionerd.UpdateJobResponse.parameter_values:type_name -> provisioner.ParameterValue
|
||||
16, // 11: provisionerd.AcquiredJob.WorkspaceBuild.parameter_values:type_name -> provisioner.ParameterValue
|
||||
17, // 12: provisionerd.AcquiredJob.WorkspaceBuild.metadata:type_name -> provisioner.Provision.Metadata
|
||||
17, // 13: provisionerd.AcquiredJob.ProjectImport.metadata:type_name -> provisioner.Provision.Metadata
|
||||
17, // 13: provisionerd.AcquiredJob.TemplateImport.metadata:type_name -> provisioner.Provision.Metadata
|
||||
18, // 14: provisionerd.CompletedJob.WorkspaceBuild.resources:type_name -> provisioner.Resource
|
||||
18, // 15: provisionerd.CompletedJob.ProjectImport.start_resources:type_name -> provisioner.Resource
|
||||
18, // 16: provisionerd.CompletedJob.ProjectImport.stop_resources:type_name -> provisioner.Resource
|
||||
18, // 15: provisionerd.CompletedJob.TemplateImport.start_resources:type_name -> provisioner.Resource
|
||||
18, // 16: provisionerd.CompletedJob.TemplateImport.stop_resources:type_name -> provisioner.Resource
|
||||
1, // 17: provisionerd.ProvisionerDaemon.AcquireJob:input_type -> provisionerd.Empty
|
||||
6, // 18: provisionerd.ProvisionerDaemon.UpdateJob:input_type -> provisionerd.UpdateJobRequest
|
||||
3, // 19: provisionerd.ProvisionerDaemon.FailJob:input_type -> provisionerd.FailedJob
|
||||
|
@ -1261,7 +1262,7 @@ func file_provisionerd_proto_provisionerd_proto_init() {
|
|||
}
|
||||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*AcquiredJob_ProjectImport); i {
|
||||
switch v := v.(*AcquiredJob_TemplateImport); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1285,7 +1286,7 @@ func file_provisionerd_proto_provisionerd_proto_init() {
|
|||
}
|
||||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*FailedJob_ProjectImport); i {
|
||||
switch v := v.(*FailedJob_TemplateImport); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1309,7 +1310,7 @@ func file_provisionerd_proto_provisionerd_proto_init() {
|
|||
}
|
||||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*CompletedJob_ProjectImport); i {
|
||||
switch v := v.(*CompletedJob_TemplateImport); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
@ -1323,15 +1324,15 @@ func file_provisionerd_proto_provisionerd_proto_init() {
|
|||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[1].OneofWrappers = []interface{}{
|
||||
(*AcquiredJob_WorkspaceBuild_)(nil),
|
||||
(*AcquiredJob_ProjectImport_)(nil),
|
||||
(*AcquiredJob_TemplateImport_)(nil),
|
||||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[2].OneofWrappers = []interface{}{
|
||||
(*FailedJob_WorkspaceBuild_)(nil),
|
||||
(*FailedJob_ProjectImport_)(nil),
|
||||
(*FailedJob_TemplateImport_)(nil),
|
||||
}
|
||||
file_provisionerd_proto_provisionerd_proto_msgTypes[3].OneofWrappers = []interface{}{
|
||||
(*CompletedJob_WorkspaceBuild_)(nil),
|
||||
(*CompletedJob_ProjectImport_)(nil),
|
||||
(*CompletedJob_TemplateImport_)(nil),
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
|
|
|
@ -18,17 +18,17 @@ message AcquiredJob {
|
|||
provisioner.Provision.Metadata metadata = 4;
|
||||
bytes state = 5;
|
||||
}
|
||||
message ProjectImport {
|
||||
message TemplateImport {
|
||||
provisioner.Provision.Metadata metadata = 1;
|
||||
}
|
||||
string job_id = 1;
|
||||
int64 created_at = 2;
|
||||
string provisioner = 3;
|
||||
string user_name = 4;
|
||||
bytes project_source_archive = 5;
|
||||
bytes template_source_archive = 5;
|
||||
oneof type {
|
||||
WorkspaceBuild workspace_build = 6;
|
||||
ProjectImport project_import = 7;
|
||||
TemplateImport template_import = 7;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,13 +36,13 @@ message FailedJob {
|
|||
message WorkspaceBuild {
|
||||
bytes state = 1;
|
||||
}
|
||||
message ProjectImport{
|
||||
message TemplateImport{
|
||||
}
|
||||
string job_id = 1;
|
||||
string error = 2;
|
||||
oneof type {
|
||||
WorkspaceBuild workspace_build = 3;
|
||||
ProjectImport project_import = 4;
|
||||
TemplateImport template_import = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,14 +52,14 @@ message CompletedJob {
|
|||
bytes state = 1;
|
||||
repeated provisioner.Resource resources = 2;
|
||||
}
|
||||
message ProjectImport {
|
||||
message TemplateImport {
|
||||
repeated provisioner.Resource start_resources = 1;
|
||||
repeated provisioner.Resource stop_resources = 2;
|
||||
}
|
||||
string job_id = 1;
|
||||
oneof type {
|
||||
WorkspaceBuild workspace_build = 2;
|
||||
ProjectImport project_import = 3;
|
||||
TemplateImport template_import = 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -312,15 +312,15 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
return
|
||||
}
|
||||
|
||||
p.opts.Logger.Info(ctx, "unpacking project source archive", slog.F("size_bytes", len(job.ProjectSourceArchive)))
|
||||
reader := tar.NewReader(bytes.NewBuffer(job.ProjectSourceArchive))
|
||||
p.opts.Logger.Info(ctx, "unpacking template source archive", slog.F("size_bytes", len(job.TemplateSourceArchive)))
|
||||
reader := tar.NewReader(bytes.NewBuffer(job.TemplateSourceArchive))
|
||||
for {
|
||||
header, err := reader.Next()
|
||||
if errors.Is(err, io.EOF) {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
p.failActiveJobf("read project source archive: %s", err)
|
||||
p.failActiveJobf("read template source archive: %s", err)
|
||||
return
|
||||
}
|
||||
// #nosec
|
||||
|
@ -371,10 +371,10 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
}
|
||||
|
||||
switch jobType := job.Type.(type) {
|
||||
case *proto.AcquiredJob_ProjectImport_:
|
||||
p.opts.Logger.Debug(context.Background(), "acquired job is project import")
|
||||
case *proto.AcquiredJob_TemplateImport_:
|
||||
p.opts.Logger.Debug(context.Background(), "acquired job is template import")
|
||||
|
||||
p.runProjectImport(ctx, shutdown, provisioner, job)
|
||||
p.runTemplateImport(ctx, shutdown, provisioner, job)
|
||||
case *proto.AcquiredJob_WorkspaceBuild_:
|
||||
p.opts.Logger.Debug(context.Background(), "acquired job is workspace provision",
|
||||
slog.F("workspace_name", jobType.WorkspaceBuild.WorkspaceName),
|
||||
|
@ -409,7 +409,7 @@ func (p *Server) runJob(ctx context.Context, job *proto.AcquiredJob) {
|
|||
}
|
||||
}
|
||||
|
||||
func (p *Server) runProjectImport(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) {
|
||||
func (p *Server) runTemplateImport(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) {
|
||||
_, err := p.client.UpdateJob(ctx, &proto.UpdateJobRequest{
|
||||
JobId: job.GetJobId(),
|
||||
Logs: []*proto.Log{{
|
||||
|
@ -424,7 +424,7 @@ func (p *Server) runProjectImport(ctx, shutdown context.Context, provisioner sdk
|
|||
return
|
||||
}
|
||||
|
||||
parameterSchemas, err := p.runProjectImportParse(ctx, provisioner, job)
|
||||
parameterSchemas, err := p.runTemplateImportParse(ctx, provisioner, job)
|
||||
if err != nil {
|
||||
p.failActiveJobf("run parse: %s", err)
|
||||
return
|
||||
|
@ -464,12 +464,12 @@ func (p *Server) runProjectImport(ctx, shutdown context.Context, provisioner sdk
|
|||
p.failActiveJobf("write log: %s", err)
|
||||
return
|
||||
}
|
||||
startResources, err := p.runProjectImportProvision(ctx, shutdown, provisioner, job, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
|
||||
CoderUrl: job.GetProjectImport().Metadata.CoderUrl,
|
||||
startResources, err := p.runTemplateImportProvision(ctx, shutdown, provisioner, job, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
|
||||
CoderUrl: job.GetTemplateImport().Metadata.CoderUrl,
|
||||
WorkspaceTransition: sdkproto.WorkspaceTransition_START,
|
||||
})
|
||||
if err != nil {
|
||||
p.failActiveJobf("project import provision for start: %s", err)
|
||||
p.failActiveJobf("template import provision for start: %s", err)
|
||||
return
|
||||
}
|
||||
_, err = p.client.UpdateJob(ctx, &proto.UpdateJobRequest{
|
||||
|
@ -485,19 +485,19 @@ func (p *Server) runProjectImport(ctx, shutdown context.Context, provisioner sdk
|
|||
p.failActiveJobf("write log: %s", err)
|
||||
return
|
||||
}
|
||||
stopResources, err := p.runProjectImportProvision(ctx, shutdown, provisioner, job, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
|
||||
CoderUrl: job.GetProjectImport().Metadata.CoderUrl,
|
||||
stopResources, err := p.runTemplateImportProvision(ctx, shutdown, provisioner, job, updateResponse.ParameterValues, &sdkproto.Provision_Metadata{
|
||||
CoderUrl: job.GetTemplateImport().Metadata.CoderUrl,
|
||||
WorkspaceTransition: sdkproto.WorkspaceTransition_STOP,
|
||||
})
|
||||
if err != nil {
|
||||
p.failActiveJobf("project import provision for start: %s", err)
|
||||
p.failActiveJobf("template import provision for start: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
_, err = p.client.CompleteJob(ctx, &proto.CompletedJob{
|
||||
JobId: job.JobId,
|
||||
Type: &proto.CompletedJob_ProjectImport_{
|
||||
ProjectImport: &proto.CompletedJob_ProjectImport{
|
||||
Type: &proto.CompletedJob_TemplateImport_{
|
||||
TemplateImport: &proto.CompletedJob_TemplateImport{
|
||||
StartResources: startResources,
|
||||
StopResources: stopResources,
|
||||
},
|
||||
|
@ -510,7 +510,7 @@ func (p *Server) runProjectImport(ctx, shutdown context.Context, provisioner sdk
|
|||
}
|
||||
|
||||
// Parses parameter schemas from source.
|
||||
func (p *Server) runProjectImportParse(ctx context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) ([]*sdkproto.ParameterSchema, error) {
|
||||
func (p *Server) runTemplateImportParse(ctx context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob) ([]*sdkproto.ParameterSchema, error) {
|
||||
stream, err := provisioner.Parse(ctx, &sdkproto.Parse_Request{
|
||||
Directory: p.opts.WorkDirectory,
|
||||
})
|
||||
|
@ -554,10 +554,10 @@ func (p *Server) runProjectImportParse(ctx context.Context, provisioner sdkproto
|
|||
}
|
||||
}
|
||||
|
||||
// Performs a dry-run provision when importing a project.
|
||||
// Performs a dry-run provision when importing a template.
|
||||
// This is used to detect resources that would be provisioned
|
||||
// for a workspace in various states.
|
||||
func (p *Server) runProjectImportProvision(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob, values []*sdkproto.ParameterValue, metadata *sdkproto.Provision_Metadata) ([]*sdkproto.Resource, error) {
|
||||
func (p *Server) runTemplateImportProvision(ctx, shutdown context.Context, provisioner sdkproto.DRPCProvisionerClient, job *proto.AcquiredJob, values []*sdkproto.ParameterValue, metadata *sdkproto.Provision_Metadata) ([]*sdkproto.Resource, error) {
|
||||
stream, err := provisioner.Provision(ctx)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("provision: %w", err)
|
||||
|
@ -596,7 +596,7 @@ func (p *Server) runProjectImportProvision(ctx, shutdown context.Context, provis
|
|||
}
|
||||
switch msgType := msg.Type.(type) {
|
||||
case *sdkproto.Provision_Response_Log:
|
||||
p.opts.Logger.Debug(context.Background(), "project import provision job logged",
|
||||
p.opts.Logger.Debug(context.Background(), "template import provision job logged",
|
||||
slog.F("level", msgType.Log.Level),
|
||||
slog.F("output", msgType.Log.Output),
|
||||
)
|
||||
|
|
|
@ -92,11 +92,11 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_ProjectImport_{
|
||||
ProjectImport: &proto.AcquiredJob_ProjectImport{
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
Metadata: &sdkproto.Provision_Metadata{},
|
||||
},
|
||||
},
|
||||
|
@ -133,11 +133,11 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"../../../etc/passwd": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_ProjectImport_{
|
||||
ProjectImport: &proto.AcquiredJob_ProjectImport{
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
Metadata: &sdkproto.Provision_Metadata{},
|
||||
},
|
||||
},
|
||||
|
@ -165,11 +165,11 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_ProjectImport_{
|
||||
ProjectImport: &proto.AcquiredJob_ProjectImport{
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
Metadata: &sdkproto.Provision_Metadata{},
|
||||
},
|
||||
},
|
||||
|
@ -199,7 +199,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
require.NoError(t, closer.Close())
|
||||
})
|
||||
|
||||
t.Run("ProjectImport", func(t *testing.T) {
|
||||
t.Run("TemplateImport", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
didComplete atomic.Bool
|
||||
|
@ -219,11 +219,11 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_ProjectImport_{
|
||||
ProjectImport: &proto.AcquiredJob_ProjectImport{
|
||||
Type: &proto.AcquiredJob_TemplateImport_{
|
||||
TemplateImport: &proto.AcquiredJob_TemplateImport{
|
||||
Metadata: &sdkproto.Provision_Metadata{},
|
||||
},
|
||||
},
|
||||
|
@ -319,7 +319,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
|
@ -387,7 +387,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
|
@ -431,7 +431,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
|
@ -500,7 +500,7 @@ func TestProvisionerd(t *testing.T) {
|
|||
return &proto.AcquiredJob{
|
||||
JobId: "test",
|
||||
Provisioner: "someprovisioner",
|
||||
ProjectSourceArchive: createTar(t, map[string]string{
|
||||
TemplateSourceArchive: createTar(t, map[string]string{
|
||||
"test.txt": "content",
|
||||
}),
|
||||
Type: &proto.AcquiredJob_WorkspaceBuild_{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { Page } from "@playwright/test"
|
||||
import { BasePom } from "./BasePom"
|
||||
|
||||
export class ProjectsPage extends BasePom {
|
||||
export class TemplatesPage extends BasePom {
|
||||
constructor(baseURL: string | undefined, page: Page) {
|
||||
super(baseURL, "/projects", page)
|
||||
super(baseURL, "/templates", page)
|
||||
}
|
||||
}
|
|
@ -1,2 +1,2 @@
|
|||
export * from "./ProjectsPage"
|
||||
export * from "./SignInPage"
|
||||
export * from "./TemplatesPage"
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
import { test } from "@playwright/test"
|
||||
import { email, password } from "../constants"
|
||||
import { ProjectsPage, SignInPage } from "../pom"
|
||||
import { SignInPage, TemplatesPage } from "../pom"
|
||||
import { waitForClientSideNavigation } from "./../util"
|
||||
|
||||
test("Login takes user to /projects", async ({ baseURL, page }) => {
|
||||
test("Login takes user to /templates", async ({ baseURL, page }) => {
|
||||
await page.goto(baseURL + "/", { waitUntil: "networkidle" })
|
||||
|
||||
// Log-in with the default credentials we set up in the development server
|
||||
const signInPage = new SignInPage(baseURL, page)
|
||||
await signInPage.submitBuiltInAuthentication(email, password)
|
||||
|
||||
const projectsPage = new ProjectsPage(baseURL, page)
|
||||
await waitForClientSideNavigation(page, { to: projectsPage.url })
|
||||
const templatesPage = new TemplatesPage(baseURL, page)
|
||||
await waitForClientSideNavigation(page, { to: templatesPage.url })
|
||||
|
||||
await page.waitForSelector("text=Projects")
|
||||
await page.waitForSelector("text=Templates")
|
||||
})
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
"build:analyze": "NODE_ENV=production webpack --profile --progress --json --config=webpack.prod.ts > out/stats.json && webpack-bundle-analyzer out/stats.json out",
|
||||
"dev": "webpack-dev-server --config=webpack.dev.ts",
|
||||
"format:check": "prettier --check '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'",
|
||||
"format:write": "prettier --write '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}' && sql-formatter -l postgresql ./database/query.sql -o ./database/query.sql",
|
||||
"format:write": "prettier --write '**/*.{css,html,js,json,jsx,md,ts,tsx,yaml,yml}'",
|
||||
"lint": "jest --selectProjects lint",
|
||||
"lint:fix": "FIX=true yarn lint",
|
||||
"playwright:install": "playwright install",
|
||||
|
|
|
@ -6,9 +6,9 @@ import { NotFoundPage } from "./pages/404"
|
|||
import { CliAuthenticationPage } from "./pages/cli-auth"
|
||||
import { HealthzPage } from "./pages/healthz"
|
||||
import { SignInPage } from "./pages/login"
|
||||
import { ProjectsPage } from "./pages/projects"
|
||||
import { ProjectPage } from "./pages/projects/[organization]/[project]"
|
||||
import { CreateWorkspacePage } from "./pages/projects/[organization]/[project]/create"
|
||||
import { TemplatesPage } from "./pages/templates"
|
||||
import { TemplatePage } from "./pages/templates/[organization]/[template]"
|
||||
import { CreateWorkspacePage } from "./pages/templates/[organization]/[template]/create"
|
||||
import { WorkspacePage } from "./pages/workspaces/[workspace]"
|
||||
|
||||
export const AppRouter: React.FC = () => (
|
||||
|
@ -27,21 +27,21 @@ export const AppRouter: React.FC = () => (
|
|||
<Route path="healthz" element={<HealthzPage />} />
|
||||
<Route path="cli-auth" element={<CliAuthenticationPage />} />
|
||||
|
||||
<Route path="projects">
|
||||
<Route path="templates">
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<AuthAndNav>
|
||||
<ProjectsPage />
|
||||
<TemplatesPage />
|
||||
</AuthAndNav>
|
||||
}
|
||||
/>
|
||||
<Route path=":organization/:project">
|
||||
<Route path=":organization/:template">
|
||||
<Route
|
||||
index
|
||||
element={
|
||||
<AuthAndNav>
|
||||
<ProjectPage />
|
||||
<TemplatePage />
|
||||
</AuthAndNav>
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -32,11 +32,11 @@ export namespace Workspace {
|
|||
throw new Error(body.message)
|
||||
}
|
||||
|
||||
// Let SWR know that both the /api/v2/workspaces/* and /api/v2/projects/*
|
||||
// Let SWR know that both the /api/v2/workspaces/* and /api/v2/templates/*
|
||||
// endpoints will need to fetch new data.
|
||||
const mutateWorkspacesPromise = mutate("/api/v2/workspaces")
|
||||
const mutateProjectsPromise = mutate("/api/v2/projects")
|
||||
await Promise.all([mutateWorkspacesPromise, mutateProjectsPromise])
|
||||
const mutateTemplatesPromise = mutate("/api/v2/templates")
|
||||
await Promise.all([mutateWorkspacesPromise, mutateTemplatesPromise])
|
||||
|
||||
return body
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ export interface Provisioner {
|
|||
name: string
|
||||
}
|
||||
|
||||
// This must be kept in sync with the `Project` struct in the back-end
|
||||
export interface Project {
|
||||
// This must be kept in sync with the `Template` struct in the back-end
|
||||
export interface Template {
|
||||
id: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
|
@ -35,7 +35,7 @@ export interface Project {
|
|||
active_version_id: string
|
||||
}
|
||||
|
||||
export interface CreateProjectRequest {
|
||||
export interface CreateTemplateRequest {
|
||||
name: string
|
||||
organizationId: string
|
||||
provisioner: string
|
||||
|
@ -43,7 +43,7 @@ export interface CreateProjectRequest {
|
|||
|
||||
export interface CreateWorkspaceRequest {
|
||||
name: string
|
||||
project_id: string
|
||||
template_id: string
|
||||
}
|
||||
|
||||
// Must be kept in sync with backend Workspace struct
|
||||
|
@ -52,7 +52,7 @@ export interface Workspace {
|
|||
created_at: string
|
||||
updated_at: string
|
||||
owner_id: string
|
||||
project_id: string
|
||||
template_id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Story } from "@storybook/react"
|
||||
import React from "react"
|
||||
import { MockOrganization, MockProject, MockWorkspace } from "../../test_helpers"
|
||||
import { MockOrganization, MockTemplate, MockWorkspace } from "../../test_helpers"
|
||||
import { Workspace, WorkspaceProps } from "./Workspace"
|
||||
|
||||
export default {
|
||||
|
@ -14,6 +14,6 @@ const Template: Story<WorkspaceProps> = (args) => <Workspace {...args} />
|
|||
export const Example = Template.bind({})
|
||||
Example.args = {
|
||||
organization: MockOrganization,
|
||||
project: MockProject,
|
||||
template: MockTemplate,
|
||||
workspace: MockWorkspace,
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
import { screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { MockOrganization, MockProject, MockWorkspace, render } from "../../test_helpers"
|
||||
import { MockOrganization, MockTemplate, MockWorkspace, render } from "../../test_helpers"
|
||||
import { Workspace } from "./Workspace"
|
||||
|
||||
describe("Workspace", () => {
|
||||
it("renders", async () => {
|
||||
// When
|
||||
render(<Workspace organization={MockOrganization} project={MockProject} workspace={MockWorkspace} />)
|
||||
render(<Workspace organization={MockOrganization} template={MockTemplate} workspace={MockWorkspace} />)
|
||||
|
||||
// Then
|
||||
const element = await screen.findByText(MockWorkspace.name)
|
||||
|
|
|
@ -12,19 +12,19 @@ import { WorkspaceSection } from "./WorkspaceSection"
|
|||
export interface WorkspaceProps {
|
||||
organization: Types.Organization
|
||||
workspace: Types.Workspace
|
||||
project: Types.Project
|
||||
template: Types.Template
|
||||
}
|
||||
|
||||
/**
|
||||
* Workspace is the top-level component for viewing an individual workspace
|
||||
*/
|
||||
export const Workspace: React.FC<WorkspaceProps> = ({ organization, project, workspace }) => {
|
||||
export const Workspace: React.FC<WorkspaceProps> = ({ organization, template, workspace }) => {
|
||||
const styles = useStyles()
|
||||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.vertical}>
|
||||
<WorkspaceHeader organization={organization} project={project} workspace={workspace} />
|
||||
<WorkspaceHeader organization={organization} template={template} workspace={workspace} />
|
||||
<div className={styles.horizontal}>
|
||||
<div className={styles.sidebarContainer}>
|
||||
<WorkspaceSection title="Applications">
|
||||
|
@ -56,10 +56,10 @@ export const Workspace: React.FC<WorkspaceProps> = ({ organization, project, wor
|
|||
/**
|
||||
* Component for the header at the top of the workspace page
|
||||
*/
|
||||
export const WorkspaceHeader: React.FC<WorkspaceProps> = ({ organization, project, workspace }) => {
|
||||
export const WorkspaceHeader: React.FC<WorkspaceProps> = ({ organization, template, workspace }) => {
|
||||
const styles = useStyles()
|
||||
|
||||
const projectLink = `/projects/${organization.name}/${project.name}`
|
||||
const templateLink = `/templates/${organization.name}/${template.name}`
|
||||
|
||||
return (
|
||||
<Paper elevation={0} className={styles.section}>
|
||||
|
@ -68,7 +68,7 @@ export const WorkspaceHeader: React.FC<WorkspaceProps> = ({ organization, projec
|
|||
<div className={styles.vertical}>
|
||||
<Typography variant="h4">{workspace.name}</Typography>
|
||||
<Typography variant="body2" color="textSecondary">
|
||||
<Link to={projectLink}>{project.name}</Link>
|
||||
<Link to={templateLink}>{template.name}</Link>
|
||||
</Typography>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
import { render, screen } from "@testing-library/react"
|
||||
import React from "react"
|
||||
import { MockOrganization, MockProject, MockProvisioner } from "./../test_helpers"
|
||||
import { CreateProjectForm } from "./CreateProjectForm"
|
||||
import { MockOrganization, MockProvisioner, MockTemplate } from "./../test_helpers"
|
||||
import { CreateTemplateForm } from "./CreateTemplateForm"
|
||||
|
||||
describe("CreateProjectForm", () => {
|
||||
describe("CreateTemplateForm", () => {
|
||||
it("renders", async () => {
|
||||
// Given
|
||||
const provisioners = [MockProvisioner]
|
||||
const organizations = [MockOrganization]
|
||||
const onSubmit = () => Promise.resolve(MockProject)
|
||||
const onSubmit = () => Promise.resolve(MockTemplate)
|
||||
const onCancel = () => Promise.resolve()
|
||||
|
||||
// When
|
||||
render(
|
||||
<CreateProjectForm
|
||||
<CreateTemplateForm
|
||||
provisioners={provisioners}
|
||||
organizations={organizations}
|
||||
onSubmit={onSubmit}
|
||||
|
@ -23,7 +23,7 @@ describe("CreateProjectForm", () => {
|
|||
|
||||
// Then
|
||||
// Simple smoke test to verify form renders
|
||||
const element = await screen.findByText("Create Project")
|
||||
const element = await screen.findByText("Create Template")
|
||||
expect(element).toBeDefined()
|
||||
})
|
||||
})
|
|
@ -3,7 +3,7 @@ import { makeStyles } from "@material-ui/core/styles"
|
|||
import { FormikContextType, useFormik } from "formik"
|
||||
import React from "react"
|
||||
import * as Yup from "yup"
|
||||
import { CreateProjectRequest, Organization, Project, Provisioner } from "../api/types"
|
||||
import { CreateTemplateRequest, Organization, Provisioner, Template } from "../api/types"
|
||||
import { LoadingButton } from "../components/Button"
|
||||
import {
|
||||
DropdownItem,
|
||||
|
@ -14,10 +14,10 @@ import {
|
|||
FormTitle,
|
||||
} from "../components/Form"
|
||||
|
||||
export interface CreateProjectFormProps {
|
||||
export interface CreateTemplateFormProps {
|
||||
provisioners: Provisioner[]
|
||||
organizations: Organization[]
|
||||
onSubmit: (request: CreateProjectRequest) => Promise<Project>
|
||||
onSubmit: (request: CreateTemplateRequest) => Promise<Template>
|
||||
onCancel: () => void
|
||||
}
|
||||
|
||||
|
@ -27,7 +27,7 @@ const validationSchema = Yup.object({
|
|||
name: Yup.string().required("Name is required"),
|
||||
})
|
||||
|
||||
export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
||||
export const CreateTemplateForm: React.FC<CreateTemplateFormProps> = ({
|
||||
provisioners,
|
||||
organizations,
|
||||
onSubmit,
|
||||
|
@ -35,7 +35,7 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
|||
}) => {
|
||||
const styles = useStyles()
|
||||
|
||||
const form: FormikContextType<CreateProjectRequest> = useFormik<CreateProjectRequest>({
|
||||
const form: FormikContextType<CreateTemplateRequest> = useFormik<CreateTemplateRequest>({
|
||||
initialValues: {
|
||||
provisioner: provisioners[0].id,
|
||||
organizationId: organizations[0].name,
|
||||
|
@ -64,7 +64,7 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
|||
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<FormTitle title="Create Project" />
|
||||
<FormTitle title="Create Template" />
|
||||
<FormCloseButton onClose={onCancel} />
|
||||
|
||||
<FormSection title="Name">
|
||||
|
@ -72,9 +72,9 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
|||
form={form}
|
||||
formFieldName="name"
|
||||
fullWidth
|
||||
helperText="A unique name describing your project."
|
||||
label="Project Name"
|
||||
placeholder="my-project"
|
||||
helperText="A unique name describing your template."
|
||||
label="Template Name"
|
||||
placeholder="my-template"
|
||||
required
|
||||
/>
|
||||
</FormSection>
|
||||
|
@ -83,7 +83,7 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
|||
<FormDropdownField
|
||||
form={form}
|
||||
formFieldName="organizationId"
|
||||
helperText="The organization owning this project."
|
||||
helperText="The organization owning this template."
|
||||
items={organizationDropDownItems}
|
||||
fullWidth
|
||||
select
|
||||
|
@ -95,7 +95,7 @@ export const CreateProjectForm: React.FC<CreateProjectFormProps> = ({
|
|||
<FormDropdownField
|
||||
form={form}
|
||||
formFieldName="provisioner"
|
||||
helperText="The backing provisioner for this project."
|
||||
helperText="The backing provisioner for this template."
|
||||
items={provisionerDropDownItems}
|
||||
fullWidth
|
||||
select
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue