Ctrl K
ComunidadGuías…

codersdk/templatebuilder.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package codersdk

import (
	"context"
	"encoding/json"
	"io"
	"net/http"
	"net/url"

	"github.com/google/uuid"
)

// TemplateBuilderVariableType enumerates the variable types
// supported by template builder module manifests.
type TemplateBuilderVariableType string

const (
	TemplateBuilderVariableTypeString TemplateBuilderVariableType = "string"
	TemplateBuilderVariableTypeNumber TemplateBuilderVariableType = "number"
	TemplateBuilderVariableTypeBool   TemplateBuilderVariableType = "bool"
)

type TemplateBuilderModuleVariable struct {
	Name        string                      `json:"name"`
	Type        TemplateBuilderVariableType `json:"type"`
	Description string                      `json:"description"`
	// Default is the variable's default as a JSON string, number, or boolean,
	// matching the variable's type.
	Default   json.RawMessage `json:"default,omitempty"`
	Required  bool            `json:"required"`
	Sensitive bool            `json:"sensitive"`
}

// TemplateBuilderModule is the API response type returned by
// GET /api/v2/templatebuilder/modules. The Version field is
// populated from the catalog manifest's PinnedVersion at serving time.
type TemplateBuilderModule struct {
	ID            string                          `json:"id"`
	DisplayName   string                          `json:"display_name"`
	Description   string                          `json:"description"`
	Icon          string                          `json:"icon"`
	Category      string                          `json:"category"`
	Version       string                          `json:"version"`
	CompatibleOS  []string                        `json:"compatible_os"`
	ConflictsWith []string                        `json:"conflicts_with"`
	Variables     []TemplateBuilderModuleVariable `json:"variables"`
}

// TemplateBuilderModulesResponse is the response body for listing template builder modules.
type TemplateBuilderModulesResponse struct {
	Modules []TemplateBuilderModule `json:"modules"`
}

// TemplateBuilderBase is the API response type for a base template
// returned by GET /api/v2/templatebuilder/bases.
type TemplateBuilderBase struct {
	ID            string                          `json:"id"`
	Name          string                          `json:"name"`
	Description   string                          `json:"description"`
	Icon          string                          `json:"icon"`
	OS            string                          `json:"os"`
	Variables     []TemplateBuilderModuleVariable `json:"variables"`
	Prerequisites string                          `json:"prerequisites"`
	Agents        []TemplateBuilderBaseAgent      `json:"agents"`
}

// TemplateBuilderBaseAgent is a coder_agent a base template declares. Modules
// composed onto the base target one of these by Name.
type TemplateBuilderBaseAgent struct {
	Name        string `json:"name"`
	DisplayName string `json:"display_name"`
	// Default reports whether modules attach to this agent when they do not
	// name one.
	Default bool `json:"default"`
}

// TemplateBuilderBasesResponse is the response body for listing template builder bases.
type TemplateBuilderBasesResponse struct {
	Bases []TemplateBuilderBase `json:"bases"`
}

// TemplateBuilderBases returns the list of base templates available
// in the template builder.
func (c *Client) TemplateBuilderBases(ctx context.Context) (TemplateBuilderBasesResponse, error) {
	res, err := c.Request(ctx, http.MethodGet, "/api/v2/templatebuilder/bases", nil)
	if err != nil {
		return TemplateBuilderBasesResponse{}, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return TemplateBuilderBasesResponse{}, ReadBodyAsError(res)
	}
	var resp TemplateBuilderBasesResponse
	return resp, ReadBodyAsJSON(res, &resp)
}

// TemplateBuilderModules returns the list of modules available for a given
// base template. If base is empty, all modules are returned.
func (c *Client) TemplateBuilderModules(ctx context.Context, base string) (TemplateBuilderModulesResponse, error) {
	path := "/api/v2/templatebuilder/modules"
	if base != "" {
		q := url.Values{"base": {base}}
		path += "?" + q.Encode()
	}
	res, err := c.Request(ctx, http.MethodGet, path, nil)
	if err != nil {
		return TemplateBuilderModulesResponse{}, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return TemplateBuilderModulesResponse{}, ReadBodyAsError(res)
	}
	var resp TemplateBuilderModulesResponse
	return resp, ReadBodyAsJSON(res, &resp)
}

// TemplateBuilderComposeRequest is the request body for
// POST /api/v2/templatebuilder/compose.
type TemplateBuilderComposeRequest struct {
	BaseTemplateID     string                         `json:"base_template_id"`
	BaseVariableValues map[string]string              `json:"base_variable_values,omitempty"`
	Modules            []TemplateBuilderComposeModule `json:"modules"`
}

// TemplateBuilderComposeModule identifies a module and its variable
// values for the compose request.
type TemplateBuilderComposeModule struct {
	ID string `json:"id"`
	// AgentName targets a base coder_agent by name. Empty uses the base default.
	AgentName string            `json:"agent_name,omitempty"`
	Variables map[string]string `json:"variables,omitempty"`
}

// TemplateBuilderCompose renders a base template with the selected
// modules and returns the resulting tar archive bytes.
func (c *Client) TemplateBuilderCompose(ctx context.Context, req TemplateBuilderComposeRequest) ([]byte, error) {
	res, err := c.Request(ctx, http.MethodPost, "/api/v2/templatebuilder/compose", req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusOK {
		return nil, ReadBodyAsError(res)
	}
	return io.ReadAll(res.Body)
}

// TemplateBuilderCreateTemplateRequest is the request body for
// POST /api/v2/templatebuilder/compose/template.
type TemplateBuilderCreateTemplateRequest struct {
	BaseTemplateID     string                         `json:"base_template_id"`
	BaseVariableValues map[string]string              `json:"base_variable_values,omitempty"`
	Modules            []TemplateBuilderComposeModule `json:"modules"`
	OrganizationID     uuid.UUID                      `json:"organization_id" format:"uuid" validate:"required"`
	Name               string                         `json:"name" validate:"required,template_name"`
	DisplayName        string                         `json:"display_name,omitempty" validate:"template_display_name"`
	Description        string                         `json:"description,omitempty" validate:"lte=128"`
	Icon               string                         `json:"icon,omitempty"`
	ProvisionerTags    map[string]string              `json:"provisioner_tags,omitempty"`
	// SessionID is the wizard session this request belongs to, as reported to
	// POST /api/v2/templatebuilder/sessions. It is optional and used only to
	// attribute a build failure to the session that produced it.
	SessionID uuid.UUID `json:"session_id,omitempty" format:"uuid"`
}

// TemplateBuilderCreateTemplateResponse is the response body for
// POST /api/v2/templatebuilder/compose/template.
type TemplateBuilderCreateTemplateResponse struct {
	Template Template `json:"template"`
}

// TemplateBuilderSessionEventType enumerates the event types for
// template builder session telemetry.
type TemplateBuilderSessionEventType string

const (
	TemplateBuilderSessionEventWizardEntry       TemplateBuilderSessionEventType = "wizard_entry"
	TemplateBuilderSessionEventComposeCompletion TemplateBuilderSessionEventType = "compose_completion"
)

// TemplateBuilderSessionRequest is the request body for
// POST /api/v2/templatebuilder/sessions.
type TemplateBuilderSessionRequest struct {
	SessionID       uuid.UUID                       `json:"session_id" format:"uuid" validate:"required"`
	EventType       TemplateBuilderSessionEventType `json:"event_type" validate:"required,oneof=wizard_entry compose_completion"`
	BaseTemplateID  string                          `json:"base_template_id,omitempty"`
	ModuleIDs       []string                        `json:"module_ids,omitempty"`
	DurationSeconds float64                         `json:"duration_seconds,omitempty"`
	Success         bool                            `json:"success,omitempty"`
}

// TemplateBuilderSession reports a template builder session event for
// telemetry purposes.
func (c *Client) TemplateBuilderSession(ctx context.Context, req TemplateBuilderSessionRequest) error {
	res, err := c.Request(ctx, http.MethodPost, "/api/v2/templatebuilder/sessions", req)
	if err != nil {
		return err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusNoContent {
		return ReadBodyAsError(res)
	}
	return nil
}

// TemplateBuilderCreateTemplate composes a template from a base and modules,
// validates it via a provisioner import job, and creates the template.
func (c *Client) TemplateBuilderCreateTemplate(ctx context.Context, req TemplateBuilderCreateTemplateRequest) (TemplateBuilderCreateTemplateResponse, error) {
	res, err := c.Request(ctx, http.MethodPost, "/api/v2/templatebuilder/compose/template", req)
	if err != nil {
		return TemplateBuilderCreateTemplateResponse{}, err
	}
	defer res.Body.Close()
	if res.StatusCode != http.StatusCreated {
		return TemplateBuilderCreateTemplateResponse{}, ReadBodyAsError(res)
	}
	var resp TemplateBuilderCreateTemplateResponse
	return resp, ReadBodyAsJSON(res, &resp)
}