mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
feat: Add parameter querying to the API (#143)
This commit is contained in:
@ -62,6 +62,10 @@ func New(options *Options) http.Handler {
|
||||
r.Use(httpmw.ExtractProjectParam(options.Database))
|
||||
r.Get("/", api.projectByOrganization)
|
||||
r.Get("/workspaces", api.workspacesByProject)
|
||||
r.Route("/parameters", func(r chi.Router) {
|
||||
r.Get("/", api.parametersByProject)
|
||||
r.Post("/", api.postParametersByProject)
|
||||
})
|
||||
r.Route("/history", func(r chi.Router) {
|
||||
r.Get("/", api.projectHistoryByOrganization)
|
||||
r.Post("/", api.postProjectHistoryByOrganization)
|
||||
|
107
coderd/parameters.go
Normal file
107
coderd/parameters.go
Normal file
@ -0,0 +1,107 @@
|
||||
package coderd
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/render"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/coder/coder/database"
|
||||
"github.com/coder/coder/httpapi"
|
||||
)
|
||||
|
||||
// CreateParameterValueRequest is used to create a new parameter value for a scope.
|
||||
type CreateParameterValueRequest struct {
|
||||
Name string `json:"name"`
|
||||
SourceValue string `json:"source_value"`
|
||||
SourceScheme database.ParameterSourceScheme `json:"source_scheme"`
|
||||
DestinationScheme database.ParameterDestinationScheme `json:"destination_scheme"`
|
||||
DestinationValue string `json:"destination_value"`
|
||||
}
|
||||
|
||||
// ParameterValue represents a set value for the scope.
|
||||
type ParameterValue struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Scope database.ParameterScope `json:"scope"`
|
||||
ScopeID string `json:"scope_id"`
|
||||
SourceScheme database.ParameterSourceScheme `json:"source_scheme"`
|
||||
DestinationScheme database.ParameterDestinationScheme `json:"destination_scheme"`
|
||||
DestinationValue string `json:"destination_value"`
|
||||
}
|
||||
|
||||
// Abstracts creating parameters into a single request/response format.
|
||||
// Callers are in charge of validating the requester has permissions to
|
||||
// perform the creation.
|
||||
func postParameterValueForScope(rw http.ResponseWriter, r *http.Request, db database.Store, scope database.ParameterScope, scopeID string) {
|
||||
var createRequest CreateParameterValueRequest
|
||||
if !httpapi.Read(rw, r, &createRequest) {
|
||||
return
|
||||
}
|
||||
parameterValue, err := db.InsertParameterValue(r.Context(), database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: createRequest.Name,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Scope: scope,
|
||||
ScopeID: scopeID,
|
||||
SourceScheme: createRequest.SourceScheme,
|
||||
SourceValue: createRequest.SourceValue,
|
||||
DestinationScheme: createRequest.DestinationScheme,
|
||||
DestinationValue: createRequest.DestinationValue,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("insert parameter value: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(rw, r, parameterValue)
|
||||
}
|
||||
|
||||
// Abstracts returning parameters for a scope into a standardized
|
||||
// request/response format. Callers are responsible for checking
|
||||
// requester permissions.
|
||||
func parametersForScope(rw http.ResponseWriter, r *http.Request, db database.Store, req database.GetParameterValuesByScopeParams) {
|
||||
parameterValues, err := db.GetParameterValuesByScope(r.Context(), req)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
parameterValues = []database.ParameterValue{}
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
||||
Message: fmt.Sprintf("get parameter values: %s", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
apiParameterValues := make([]ParameterValue, 0, len(parameterValues))
|
||||
for _, parameterValue := range parameterValues {
|
||||
apiParameterValues = append(apiParameterValues, convertParameterValue(parameterValue))
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, apiParameterValues)
|
||||
}
|
||||
|
||||
func convertParameterValue(parameterValue database.ParameterValue) ParameterValue {
|
||||
return ParameterValue{
|
||||
ID: parameterValue.ID,
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: parameterValue.CreatedAt,
|
||||
UpdatedAt: parameterValue.UpdatedAt,
|
||||
Scope: parameterValue.Scope,
|
||||
ScopeID: parameterValue.ScopeID,
|
||||
SourceScheme: parameterValue.SourceScheme,
|
||||
DestinationScheme: parameterValue.DestinationScheme,
|
||||
DestinationValue: parameterValue.DestinationValue,
|
||||
}
|
||||
}
|
@ -149,3 +149,21 @@ func (api *api) workspacesByProject(rw http.ResponseWriter, r *http.Request) {
|
||||
render.Status(r, http.StatusOK)
|
||||
render.JSON(rw, r, apiWorkspaces)
|
||||
}
|
||||
|
||||
// Creates parameters for a project.
|
||||
// This should validate the calling user has permissions!
|
||||
func (api *api) postParametersByProject(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
|
||||
postParameterValueForScope(rw, r, api.Database, database.ParameterScopeProject, project.ID.String())
|
||||
}
|
||||
|
||||
// Lists parameters for a project.
|
||||
func (api *api) parametersByProject(rw http.ResponseWriter, r *http.Request) {
|
||||
project := httpmw.ProjectParam(r)
|
||||
|
||||
parametersForScope(rw, r, api.Database, database.GetParameterValuesByScopeParams{
|
||||
Scope: database.ParameterScopeProject,
|
||||
ScopeID: project.ID.String(),
|
||||
})
|
||||
}
|
||||
|
@ -92,4 +92,36 @@ func TestProjects(t *testing.T) {
|
||||
_, err = server.Client.Project(context.Background(), user.Organization, project.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Parameters", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
server := coderdtest.New(t)
|
||||
user := server.RandomInitialUser(t)
|
||||
project, err := server.Client.CreateProject(context.Background(), user.Organization, coderd.CreateProjectRequest{
|
||||
Name: "someproject",
|
||||
Provisioner: database.ProvisionerTypeTerraform,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = server.Client.ProjectParameters(context.Background(), user.Organization, project.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("CreateParameter", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
server := coderdtest.New(t)
|
||||
user := server.RandomInitialUser(t)
|
||||
project, err := server.Client.CreateProject(context.Background(), user.Organization, coderd.CreateProjectRequest{
|
||||
Name: "someproject",
|
||||
Provisioner: database.ProvisionerTypeTerraform,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = server.Client.CreateProjectParameter(context.Background(), user.Organization, project.Name, coderd.CreateParameterValueRequest{
|
||||
Name: "hi",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
DestinationValue: "moo",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
Reference in New Issue
Block a user