feat: Add templates to create working release (#422)

* Add templates

* Move API structs to codersdk

* Back to green tests!

* It all works, but now with tea! 🧋

* It works!

* Add cancellation to provisionerd

* Tests pass!

* Add deletion of workspaces and projects

* Fix agent lock

* Add clog

* Fix linting errors

* Remove unused CLI tests

* Rename daemon to start

* Fix leaking command

* Fix promptui test

* Update agent connection frequency

* Skip login tests on Windows

* Increase tunnel connect timeout

* Fix templater

* Lower test requirements

* Fix embed

* Disable promptui tests for Windows

* Fix write newline

* Fix PTY write newline

* Fix CloseReader

* Fix compilation on Windows

* Fix linting error

* Remove bubbletea

* Cleanup readwriter

* Use embedded templates instead of serving over API

* Move templates to examples

* Improve workspace create flow

* Fix Windows build

* Fix tests

* Fix linting errors

* Fix untar with extracting max size

* Fix newline char
This commit is contained in:
Kyle Carberry
2022-03-22 13:17:50 -06:00
committed by GitHub
parent 2818b3ce6d
commit c451f4e685
138 changed files with 7317 additions and 2334 deletions

View File

@ -5,25 +5,63 @@ import (
"encoding/json"
"fmt"
"net/http"
"time"
"github.com/coder/coder/coderd"
"github.com/google/uuid"
"github.com/coder/coder/database"
)
func (c *Client) Organization(ctx context.Context, id string) (coderd.Organization, error) {
// Organization is the JSON representation of a Coder organization.
type Organization struct {
ID string `json:"id" validate:"required"`
Name string `json:"name" validate:"required"`
CreatedAt time.Time `json:"created_at" validate:"required"`
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"`
StorageMethod database.ProvisionerStorageMethod `json:"storage_method" validate:"oneof=file,required"`
StorageSource string `json:"storage_source" validate:"required"`
Provisioner database.ProvisionerType `json:"provisioner" validate:"oneof=terraform echo,required"`
// ParameterValues allows for additional parameters to be provided
// during the dry-run provision stage.
ParameterValues []CreateParameterRequest `json:"parameter_values"`
}
// CreateProjectRequest provides options when creating a project.
type CreateProjectRequest 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.
//
// 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"`
ParameterValues []CreateParameterRequest `json:"parameter_values"`
}
func (c *Client) Organization(ctx context.Context, id string) (Organization, error) {
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s", id), nil)
if err != nil {
return coderd.Organization{}, err
return Organization{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return coderd.Organization{}, readBodyAsError(res)
return Organization{}, readBodyAsError(res)
}
var organization coderd.Organization
var organization Organization
return organization, json.NewDecoder(res.Body).Decode(&organization)
}
// ProvisionerDaemonsByOrganization returns provisioner daemons available for an organization.
func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organization string) ([]coderd.ProvisionerDaemon, error) {
func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organization string) ([]ProvisionerDaemon, error) {
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/provisionerdaemons", organization), nil)
if err != nil {
return nil, err
@ -32,41 +70,41 @@ func (c *Client) ProvisionerDaemonsByOrganization(ctx context.Context, organizat
if res.StatusCode != http.StatusOK {
return nil, readBodyAsError(res)
}
var daemons []coderd.ProvisionerDaemon
var daemons []ProvisionerDaemon
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, organization string, req coderd.CreateProjectVersionRequest) (coderd.ProjectVersion, error) {
func (c *Client) CreateProjectVersion(ctx context.Context, organization string, req CreateProjectVersionRequest) (ProjectVersion, error) {
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/organizations/%s/projectversions", organization), req)
if err != nil {
return coderd.ProjectVersion{}, err
return ProjectVersion{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return coderd.ProjectVersion{}, readBodyAsError(res)
return ProjectVersion{}, readBodyAsError(res)
}
var projectVersion coderd.ProjectVersion
var projectVersion ProjectVersion
return projectVersion, json.NewDecoder(res.Body).Decode(&projectVersion)
}
// CreateProject creates a new project inside an organization.
func (c *Client) CreateProject(ctx context.Context, organization string, request coderd.CreateProjectRequest) (coderd.Project, error) {
func (c *Client) CreateProject(ctx context.Context, organization string, request CreateProjectRequest) (Project, error) {
res, err := c.request(ctx, http.MethodPost, fmt.Sprintf("/api/v2/organizations/%s/projects", organization), request)
if err != nil {
return coderd.Project{}, err
return Project{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusCreated {
return coderd.Project{}, readBodyAsError(res)
return Project{}, readBodyAsError(res)
}
var project coderd.Project
var project Project
return project, json.NewDecoder(res.Body).Decode(&project)
}
// ProjectsByOrganization lists all projects inside of an organization.
func (c *Client) ProjectsByOrganization(ctx context.Context, organization string) ([]coderd.Project, error) {
func (c *Client) ProjectsByOrganization(ctx context.Context, organization string) ([]Project, error) {
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/projects", organization), nil)
if err != nil {
return nil, err
@ -75,20 +113,20 @@ func (c *Client) ProjectsByOrganization(ctx context.Context, organization string
if res.StatusCode != http.StatusOK {
return nil, readBodyAsError(res)
}
var projects []coderd.Project
var projects []Project
return projects, json.NewDecoder(res.Body).Decode(&projects)
}
// ProjectByName finds a project inside the organization provided with a case-insensitive name.
func (c *Client) ProjectByName(ctx context.Context, organization, name string) (coderd.Project, error) {
func (c *Client) ProjectByName(ctx context.Context, organization, name string) (Project, error) {
res, err := c.request(ctx, http.MethodGet, fmt.Sprintf("/api/v2/organizations/%s/projects/%s", organization, name), nil)
if err != nil {
return coderd.Project{}, err
return Project{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return coderd.Project{}, readBodyAsError(res)
return Project{}, readBodyAsError(res)
}
var project coderd.Project
var project Project
return project, json.NewDecoder(res.Body).Decode(&project)
}