Skip to content

feat: add examples to api #5331

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Dec 9, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: add examples to api
  • Loading branch information
f0ssel committed Dec 6, 2022
commit 300a763560cf37f80cf036e6c54cc9884e89eace
3 changes: 2 additions & 1 deletion cli/templateinit.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"

"github.com/coder/coder/cli/cliui"
"github.com/coder/coder/codersdk"
"github.com/coder/coder/examples"
"github.com/coder/coder/provisionersdk"
)
Expand All @@ -22,7 +23,7 @@ func templateInit() *cobra.Command {
return err
}
exampleNames := []string{}
exampleByName := map[string]examples.Example{}
exampleByName := map[string]codersdk.TemplateExample{}
for _, example := range exampleList {
name := fmt.Sprintf(
"%s\n%s\n%s\n",
Expand Down
1 change: 1 addition & 0 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,7 @@ func New(options *Options) *API {
r.Post("/", api.postTemplateByOrganization)
r.Get("/", api.templatesByOrganization)
r.Get("/{templatename}", api.templateByOrganizationAndName)
r.Get("/examples", api.templateExamples)
})
r.Route("/members", func(r chi.Router) {
r.Get("/roles", api.assignableOrgRoles)
Expand Down
15 changes: 15 additions & 0 deletions coderd/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,21 @@ func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(ctx, rw, http.StatusOK, convertUser(updatedUser, organizationIDs))
}

func (_ *API) templateExamples(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()

ex, err := examples.List()
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Internal error fetching examples.",
Detail: err.Error(),
})
return
}

httpapi.Write(ctx, rw, http.StatusOK, ex)
}

// updateSiteUserRoles will ensure only site wide roles are passed in as arguments.
// If an organization role is included, an error is returned.
func (api *API) updateSiteUserRoles(ctx context.Context, args database.UpdateUserRolesParams) (database.User, error) {
Expand Down
3 changes: 2 additions & 1 deletion codersdk/organizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ type CreateTemplateVersionRequest struct {
// TemplateID optionally associates a version with a template.
TemplateID uuid.UUID `json:"template_id,omitempty"`
StorageMethod ProvisionerStorageMethod `json:"storage_method" validate:"oneof=file,required"`
FileID uuid.UUID `json:"file_id" validate:"required"`
FileID uuid.UUID `json:"file_id,omitempty" validate:"required_without=ExampleID"`
ExampleID uuid.UUID `json:"example_id,omitempty" validate:"required_without=FileID"`
Provisioner ProvisionerType `json:"provisioner" validate:"oneof=terraform echo,required"`
ProvisionerTags map[string]string `json:"tags"`

Expand Down
8 changes: 8 additions & 0 deletions codersdk/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ type UpdateTemplateMeta struct {
AllowUserCancelWorkspaceJobs bool `json:"allow_user_cancel_workspace_jobs,omitempty"`
}

type TemplateExample struct {
ID string `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Description string `json:"description"`
Markdown string `json:"markdown"`
}

// 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)
Expand Down
18 changes: 6 additions & 12 deletions examples/examples.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,24 @@ import (
"github.com/gohugoio/hugo/parser/pageparser"
"golang.org/x/sync/singleflight"
"golang.org/x/xerrors"

"github.com/coder/coder/codersdk"
)

var (
//go:embed templates
files embed.FS

exampleBasePath = "https://github.com/coder/coder/tree/main/examples/templates/"
examples = make([]Example, 0)
examples = make([]codersdk.TemplateExample, 0)
parseExamples sync.Once
archives = singleflight.Group{}
)

type Example struct {
ID string `json:"id"`
URL string `json:"url"`
Name string `json:"name"`
Description string `json:"description"`
Markdown string `json:"markdown"`
}

const rootDir = "templates"

// List returns all embedded examples.
func List() ([]Example, error) {
func List() ([]codersdk.TemplateExample, error) {
var returnError error
parseExamples.Do(func() {
files, err := fs.Sub(files, rootDir)
Expand Down Expand Up @@ -92,7 +86,7 @@ func List() ([]Example, error) {
return
}

examples = append(examples, Example{
examples = append(examples, codersdk.TemplateExample{
ID: exampleID,
URL: exampleURL,
Name: name,
Expand All @@ -112,7 +106,7 @@ func Archive(exampleID string) ([]byte, error) {
return nil, xerrors.Errorf("list: %w", err)
}

var selected Example
var selected codersdk.TemplateExample
for _, example := range examples {
if example.ID != exampleID {
continue
Expand Down
12 changes: 11 additions & 1 deletion site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ export interface CreateTemplateVersionRequest {
readonly name?: string
readonly template_id?: string
readonly storage_method: ProvisionerStorageMethod
readonly file_id: string
readonly file_id?: string
readonly example_id?: string
readonly provisioner: ProvisionerType
readonly tags: Record<string, string>
readonly parameter_values?: CreateParameterRequest[]
Expand Down Expand Up @@ -668,6 +669,15 @@ export interface TemplateDAUsResponse {
readonly entries: DAUEntry[]
}

// From codersdk/templates.go
export interface TemplateExample {
readonly id: string
readonly url: string
readonly name: string
readonly description: string
readonly markdown: string
}

// From codersdk/templates.go
export interface TemplateGroup extends Group {
readonly role: TemplateRole
Expand Down