mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
* Add client for agent * Cleanup code * Fix linting error * Rename routes to be simpler * Rename workspace history to workspace build * Refactor HTTP middlewares to use UUIDs * Cleanup routes * Compiles! * Fix files and organizations * Fix querying * Fix agent lock * Cleanup database abstraction * Add parameters * Fix linting errors * Fix log race * Lock on close wait * Fix log cleanup * Fix e2e tests * Fix upstream version of opencensus-go * Update coderdtest.go * Fix coverpkg * Fix codecov ignore
190 lines
6.3 KiB
Go
190 lines
6.3 KiB
Go
package coderd
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/go-chi/chi/v5"
|
|
"github.com/go-chi/render"
|
|
"github.com/google/uuid"
|
|
|
|
"github.com/coder/coder/database"
|
|
"github.com/coder/coder/httpapi"
|
|
)
|
|
|
|
type ParameterScope string
|
|
|
|
const (
|
|
ParameterOrganization ParameterScope = "organization"
|
|
ParameterProject ParameterScope = "project"
|
|
ParameterUser ParameterScope = "user"
|
|
ParameterWorkspace ParameterScope = "workspace"
|
|
)
|
|
|
|
// Parameter represents a set value for the scope.
|
|
type Parameter 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"`
|
|
Scope ParameterScope `db:"scope" json:"scope"`
|
|
ScopeID string `db:"scope_id" json:"scope_id"`
|
|
Name string `db:"name" json:"name"`
|
|
SourceScheme database.ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
|
|
DestinationScheme database.ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
|
|
}
|
|
|
|
// CreateParameterRequest is used to create a new parameter value for a scope.
|
|
type CreateParameterRequest struct {
|
|
Name string `json:"name" validate:"required"`
|
|
SourceValue string `json:"source_value" validate:"required"`
|
|
SourceScheme database.ParameterSourceScheme `json:"source_scheme" validate:"oneof=data,required"`
|
|
DestinationScheme database.ParameterDestinationScheme `json:"destination_scheme" validate:"oneof=environment_variable provisioner_variable,required"`
|
|
}
|
|
|
|
func (api *api) postParameter(rw http.ResponseWriter, r *http.Request) {
|
|
var createRequest CreateParameterRequest
|
|
if !httpapi.Read(rw, r, &createRequest) {
|
|
return
|
|
}
|
|
scope, scopeID, valid := readScopeAndID(rw, r)
|
|
if !valid {
|
|
return
|
|
}
|
|
_, err := api.Database.GetParameterValueByScopeAndName(r.Context(), database.GetParameterValueByScopeAndNameParams{
|
|
Scope: scope,
|
|
ScopeID: scopeID,
|
|
Name: createRequest.Name,
|
|
})
|
|
if err == nil {
|
|
httpapi.Write(rw, http.StatusConflict, httpapi.Response{
|
|
Message: fmt.Sprintf("a parameter already exists in scope %q with name %q", scope, createRequest.Name),
|
|
})
|
|
return
|
|
}
|
|
if !errors.Is(err, sql.ErrNoRows) {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get parameter value: %s", err),
|
|
})
|
|
return
|
|
}
|
|
parameterValue, err := api.Database.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,
|
|
})
|
|
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, convertParameterValue(parameterValue))
|
|
}
|
|
|
|
func (api *api) parameters(rw http.ResponseWriter, r *http.Request) {
|
|
scope, scopeID, valid := readScopeAndID(rw, r)
|
|
if !valid {
|
|
return
|
|
}
|
|
parameterValues, err := api.Database.GetParameterValuesByScope(r.Context(), database.GetParameterValuesByScopeParams{
|
|
Scope: scope,
|
|
ScopeID: scopeID,
|
|
})
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
err = nil
|
|
}
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get parameter values by scope: %s", err),
|
|
})
|
|
return
|
|
}
|
|
apiParameterValues := make([]Parameter, 0, len(parameterValues))
|
|
for _, parameterValue := range parameterValues {
|
|
apiParameterValues = append(apiParameterValues, convertParameterValue(parameterValue))
|
|
}
|
|
|
|
render.Status(r, http.StatusOK)
|
|
render.JSON(rw, r, apiParameterValues)
|
|
}
|
|
|
|
func (api *api) deleteParameter(rw http.ResponseWriter, r *http.Request) {
|
|
scope, scopeID, valid := readScopeAndID(rw, r)
|
|
if !valid {
|
|
return
|
|
}
|
|
name := chi.URLParam(r, "name")
|
|
parameterValue, err := api.Database.GetParameterValueByScopeAndName(r.Context(), database.GetParameterValueByScopeAndNameParams{
|
|
Scope: scope,
|
|
ScopeID: scopeID,
|
|
Name: name,
|
|
})
|
|
if errors.Is(err, sql.ErrNoRows) {
|
|
httpapi.Write(rw, http.StatusNotFound, httpapi.Response{
|
|
Message: fmt.Sprintf("parameter doesn't exist in the provided scope with name %q", name),
|
|
})
|
|
return
|
|
}
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("get parameter value: %s", err),
|
|
})
|
|
return
|
|
}
|
|
err = api.Database.DeleteParameterValueByID(r.Context(), parameterValue.ID)
|
|
if err != nil {
|
|
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
|
|
Message: fmt.Sprintf("delete parameter: %s", err),
|
|
})
|
|
return
|
|
}
|
|
httpapi.Write(rw, http.StatusOK, httpapi.Response{
|
|
Message: "parameter deleted",
|
|
})
|
|
}
|
|
|
|
func convertParameterValue(parameterValue database.ParameterValue) Parameter {
|
|
return Parameter{
|
|
ID: parameterValue.ID,
|
|
CreatedAt: parameterValue.CreatedAt,
|
|
UpdatedAt: parameterValue.UpdatedAt,
|
|
Scope: ParameterScope(parameterValue.Scope),
|
|
ScopeID: parameterValue.ScopeID,
|
|
Name: parameterValue.Name,
|
|
SourceScheme: parameterValue.SourceScheme,
|
|
DestinationScheme: parameterValue.DestinationScheme,
|
|
}
|
|
}
|
|
|
|
func readScopeAndID(rw http.ResponseWriter, r *http.Request) (database.ParameterScope, string, bool) {
|
|
var scope database.ParameterScope
|
|
switch chi.URLParam(r, "scope") {
|
|
case string(ParameterOrganization):
|
|
scope = database.ParameterScopeOrganization
|
|
case string(ParameterProject):
|
|
scope = database.ParameterScopeProject
|
|
case string(ParameterUser):
|
|
scope = database.ParameterScopeUser
|
|
case string(ParameterWorkspace):
|
|
scope = database.ParameterScopeWorkspace
|
|
default:
|
|
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
|
|
Message: fmt.Sprintf("invalid scope %q", scope),
|
|
})
|
|
return scope, "", false
|
|
}
|
|
|
|
return scope, chi.URLParam(r, "id"), true
|
|
}
|