mirror of
https://github.com/coder/coder.git
synced 2025-07-06 15:41:45 +00:00
feat!: drop support for legacy parameters (#7663)
This commit is contained in:
531
coderd/apidoc/docs.go
generated
531
coderd/apidoc/docs.go
generated
@ -1595,167 +1595,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Parameters"
|
||||
],
|
||||
"summary": "Get parameters",
|
||||
"operationId": "get-parameters",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"template",
|
||||
"workspace",
|
||||
"import_job"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.Parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"consumes": [
|
||||
"application/json"
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Parameters"
|
||||
],
|
||||
"summary": "Create parameter",
|
||||
"operationId": "create-parameter",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Parameter request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": [
|
||||
"template",
|
||||
"workspace",
|
||||
"import_job"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.Parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}/{name}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Parameters"
|
||||
],
|
||||
"summary": "Delete parameter",
|
||||
"operationId": "delete-parameter",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": [
|
||||
"template",
|
||||
"workspace",
|
||||
"import_job"
|
||||
],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Name",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/regions": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -2764,14 +2603,11 @@ const docTemplate = `{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get parameters by template version",
|
||||
"operationId": "get-parameters-by-template-version",
|
||||
"summary": "Removed: Get parameters by template version",
|
||||
"operationId": "removed-get-parameters-by-template-version",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@ -2784,13 +2620,7 @@ const docTemplate = `{
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/parameter.ComputedValue"
|
||||
}
|
||||
}
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2878,14 +2708,11 @@ const docTemplate = `{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
"tags": [
|
||||
"Templates"
|
||||
],
|
||||
"summary": "Get schema by template version",
|
||||
"operationId": "get-schema-by-template-version",
|
||||
"summary": "Removed: Get schema by template version",
|
||||
"operationId": "removed-get-schema-by-template-version",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@ -2898,13 +2725,7 @@ const docTemplate = `{
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.ParameterSchema"
|
||||
}
|
||||
}
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6810,52 +6631,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateParameterRequest": {
|
||||
"description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"destination_scheme",
|
||||
"name",
|
||||
"source_scheme",
|
||||
"source_value"
|
||||
],
|
||||
"properties": {
|
||||
"copy_from_parameter": {
|
||||
"description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.",
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"environment_variable",
|
||||
"provisioner_variable"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"data"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateTemplateRequest": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
@ -6907,12 +6682,6 @@ const docTemplate = `{
|
||||
"description": "Name is the name of the template.",
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"template_version_id": {
|
||||
"description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.",
|
||||
"type": "string",
|
||||
@ -6923,12 +6692,6 @@ const docTemplate = `{
|
||||
"codersdk.CreateTemplateVersionDryRunRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -6963,13 +6726,6 @@ const docTemplate = `{
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"provisioner": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
@ -7137,14 +6893,8 @@ const docTemplate = `{
|
||||
"description": "Orphan may be set for the Destroy transition.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
|
||||
@ -7205,14 +6955,8 @@ const docTemplate = `{
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
|
||||
@ -8063,186 +7807,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.Parameter": {
|
||||
"description": "Parameter represents a set value for the scope.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"environment_variable",
|
||||
"provisioner_variable"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"enum": [
|
||||
"template",
|
||||
"workspace",
|
||||
"import_job"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterScope"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"source_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"data"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.ParameterDestinationScheme": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"environment_variable",
|
||||
"provisioner_variable"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterDestinationSchemeNone",
|
||||
"ParameterDestinationSchemeEnvironmentVariable",
|
||||
"ParameterDestinationSchemeProvisionerVariable"
|
||||
]
|
||||
},
|
||||
"codersdk.ParameterSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_override_destination": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_override_source": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"default_destination_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"environment_variable",
|
||||
"provisioner_variable"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_refresh": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_source_scheme": {
|
||||
"enum": [
|
||||
"none",
|
||||
"data"
|
||||
],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"redisplay_value": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"validation_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_contains": {
|
||||
"description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"validation_error": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_type_system": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_value_type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.ParameterScope": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"template",
|
||||
"workspace",
|
||||
"import_job"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterTemplate",
|
||||
"ParameterWorkspace",
|
||||
"ParameterImportJob"
|
||||
]
|
||||
},
|
||||
"codersdk.ParameterSourceScheme": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"data"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterSourceSchemeNone",
|
||||
"ParameterSourceSchemeData"
|
||||
]
|
||||
},
|
||||
"codersdk.PatchTemplateVersionRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -9250,10 +8814,10 @@ const docTemplate = `{
|
||||
"codersdk.TemplateVersionWarning": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"DEPRECATED_PARAMETERS"
|
||||
"UNSUPPORTED_WORKSPACES"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"TemplateVersionWarningDeprecatedParameters"
|
||||
"TemplateVersionWarningUnsupportedWorkspaces"
|
||||
]
|
||||
},
|
||||
"codersdk.TokenConfig": {
|
||||
@ -10265,43 +9829,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"database.ParameterDestinationScheme": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"environment_variable",
|
||||
"provisioner_variable"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterDestinationSchemeNone",
|
||||
"ParameterDestinationSchemeEnvironmentVariable",
|
||||
"ParameterDestinationSchemeProvisionerVariable"
|
||||
]
|
||||
},
|
||||
"database.ParameterScope": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"template",
|
||||
"import_job",
|
||||
"workspace"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterScopeTemplate",
|
||||
"ParameterScopeImportJob",
|
||||
"ParameterScopeWorkspace"
|
||||
]
|
||||
},
|
||||
"database.ParameterSourceScheme": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"none",
|
||||
"data"
|
||||
],
|
||||
"x-enum-varnames": [
|
||||
"ParameterSourceSchemeNone",
|
||||
"ParameterSourceSchemeData"
|
||||
]
|
||||
},
|
||||
"derp.ServerInfoMessage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -10572,44 +10099,6 @@ const docTemplate = `{
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameter.ComputedValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_source_value": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"$ref": "#/definitions/database.ParameterDestinationScheme"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"schema_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"$ref": "#/definitions/database.ParameterScope"
|
||||
},
|
||||
"scope_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_scheme": {
|
||||
"$ref": "#/definitions/database.ParameterSourceScheme"
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sql.NullTime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
454
coderd/apidoc/swagger.json
generated
454
coderd/apidoc/swagger.json
generated
@ -1391,141 +1391,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}": {
|
||||
"get": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Parameters"],
|
||||
"summary": "Get parameters",
|
||||
"operationId": "get-parameters",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": ["template", "workspace", "import_job"],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.Parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"consumes": ["application/json"],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Parameters"],
|
||||
"summary": "Create parameter",
|
||||
"operationId": "create-parameter",
|
||||
"parameters": [
|
||||
{
|
||||
"description": "Parameter request",
|
||||
"name": "request",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
{
|
||||
"enum": ["template", "workspace", "import_job"],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Created",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.Parameter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/parameters/{scope}/{id}/{name}": {
|
||||
"delete": {
|
||||
"security": [
|
||||
{
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Parameters"],
|
||||
"summary": "Delete parameter",
|
||||
"operationId": "delete-parameter",
|
||||
"parameters": [
|
||||
{
|
||||
"enum": ["template", "workspace", "import_job"],
|
||||
"type": "string",
|
||||
"description": "Scope",
|
||||
"name": "scope",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID",
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Name",
|
||||
"name": "name",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/codersdk.Response"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/regions": {
|
||||
"get": {
|
||||
"security": [
|
||||
@ -2426,10 +2291,9 @@
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get parameters by template version",
|
||||
"operationId": "get-parameters-by-template-version",
|
||||
"summary": "Removed: Get parameters by template version",
|
||||
"operationId": "removed-get-parameters-by-template-version",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@ -2442,13 +2306,7 @@
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/parameter.ComputedValue"
|
||||
}
|
||||
}
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2528,10 +2386,9 @@
|
||||
"CoderSessionToken": []
|
||||
}
|
||||
],
|
||||
"produces": ["application/json"],
|
||||
"tags": ["Templates"],
|
||||
"summary": "Get schema by template version",
|
||||
"operationId": "get-schema-by-template-version",
|
||||
"summary": "Removed: Get schema by template version",
|
||||
"operationId": "removed-get-schema-by-template-version",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
@ -2544,13 +2401,7 @@
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.ParameterSchema"
|
||||
}
|
||||
}
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -6054,45 +5905,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateParameterRequest": {
|
||||
"description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.",
|
||||
"type": "object",
|
||||
"required": [
|
||||
"destination_scheme",
|
||||
"name",
|
||||
"source_scheme",
|
||||
"source_value"
|
||||
],
|
||||
"properties": {
|
||||
"copy_from_parameter": {
|
||||
"description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.",
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"enum": ["none", "environment_variable", "provisioner_variable"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_scheme": {
|
||||
"enum": ["none", "data"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.CreateTemplateRequest": {
|
||||
"type": "object",
|
||||
"required": ["name", "template_version_id"],
|
||||
@ -6141,12 +5953,6 @@
|
||||
"description": "Name is the name of the template.",
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"template_version_id": {
|
||||
"description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.",
|
||||
"type": "string",
|
||||
@ -6157,12 +5963,6 @@
|
||||
"codersdk.CreateTemplateVersionDryRunRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -6194,13 +5994,6 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"provisioner": {
|
||||
"type": "string",
|
||||
"enum": ["terraform", "echo"]
|
||||
@ -6342,14 +6135,8 @@
|
||||
"description": "Orphan may be set for the Destroy transition.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
|
||||
@ -6400,14 +6187,8 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.CreateParameterRequest"
|
||||
}
|
||||
},
|
||||
"rich_parameter_values": {
|
||||
"description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.WorkspaceBuildParameter"
|
||||
@ -7212,157 +6993,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.Parameter": {
|
||||
"description": "Parameter represents a set value for the scope.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"enum": ["none", "environment_variable", "provisioner_variable"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"enum": ["template", "workspace", "import_job"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterScope"
|
||||
}
|
||||
]
|
||||
},
|
||||
"scope_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"source_scheme": {
|
||||
"enum": ["none", "data"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.ParameterDestinationScheme": {
|
||||
"type": "string",
|
||||
"enum": ["none", "environment_variable", "provisioner_variable"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterDestinationSchemeNone",
|
||||
"ParameterDestinationSchemeEnvironmentVariable",
|
||||
"ParameterDestinationSchemeProvisionerVariable"
|
||||
]
|
||||
},
|
||||
"codersdk.ParameterSchema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allow_override_destination": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"allow_override_source": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time"
|
||||
},
|
||||
"default_destination_scheme": {
|
||||
"enum": ["none", "environment_variable", "provisioner_variable"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterDestinationScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_refresh": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_source_scheme": {
|
||||
"enum": ["none", "data"],
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.ParameterSourceScheme"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default_source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"redisplay_value": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"validation_condition": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_contains": {
|
||||
"description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"validation_error": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_type_system": {
|
||||
"type": "string"
|
||||
},
|
||||
"validation_value_type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"codersdk.ParameterScope": {
|
||||
"type": "string",
|
||||
"enum": ["template", "workspace", "import_job"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterTemplate",
|
||||
"ParameterWorkspace",
|
||||
"ParameterImportJob"
|
||||
]
|
||||
},
|
||||
"codersdk.ParameterSourceScheme": {
|
||||
"type": "string",
|
||||
"enum": ["none", "data"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterSourceSchemeNone",
|
||||
"ParameterSourceSchemeData"
|
||||
]
|
||||
},
|
||||
"codersdk.PatchTemplateVersionRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -8309,8 +7939,8 @@
|
||||
},
|
||||
"codersdk.TemplateVersionWarning": {
|
||||
"type": "string",
|
||||
"enum": ["DEPRECATED_PARAMETERS"],
|
||||
"x-enum-varnames": ["TemplateVersionWarningDeprecatedParameters"]
|
||||
"enum": ["UNSUPPORTED_WORKSPACES"],
|
||||
"x-enum-varnames": ["TemplateVersionWarningUnsupportedWorkspaces"]
|
||||
},
|
||||
"codersdk.TokenConfig": {
|
||||
"type": "object",
|
||||
@ -9261,32 +8891,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"database.ParameterDestinationScheme": {
|
||||
"type": "string",
|
||||
"enum": ["none", "environment_variable", "provisioner_variable"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterDestinationSchemeNone",
|
||||
"ParameterDestinationSchemeEnvironmentVariable",
|
||||
"ParameterDestinationSchemeProvisionerVariable"
|
||||
]
|
||||
},
|
||||
"database.ParameterScope": {
|
||||
"type": "string",
|
||||
"enum": ["template", "import_job", "workspace"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterScopeTemplate",
|
||||
"ParameterScopeImportJob",
|
||||
"ParameterScopeWorkspace"
|
||||
]
|
||||
},
|
||||
"database.ParameterSourceScheme": {
|
||||
"type": "string",
|
||||
"enum": ["none", "data"],
|
||||
"x-enum-varnames": [
|
||||
"ParameterSourceSchemeNone",
|
||||
"ParameterSourceSchemeData"
|
||||
]
|
||||
},
|
||||
"derp.ServerInfoMessage": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -9557,44 +9161,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameter.ComputedValue": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"default_source_value": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"destination_scheme": {
|
||||
"$ref": "#/definitions/database.ParameterDestinationScheme"
|
||||
},
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"schema_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"scope": {
|
||||
"$ref": "#/definitions/database.ParameterScope"
|
||||
},
|
||||
"scope_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"source_scheme": {
|
||||
"$ref": "#/definitions/database.ParameterSourceScheme"
|
||||
},
|
||||
"source_value": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sql.NullTime": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
@ -551,14 +551,6 @@ func New(options *Options) *API {
|
||||
})
|
||||
})
|
||||
})
|
||||
r.Route("/parameters/{scope}/{id}", func(r chi.Router) {
|
||||
r.Use(apiKeyMiddleware)
|
||||
r.Post("/", api.postParameter)
|
||||
r.Get("/", api.parameters)
|
||||
r.Route("/{name}", func(r chi.Router) {
|
||||
r.Delete("/", api.deleteParameter)
|
||||
})
|
||||
})
|
||||
r.Route("/templates/{template}", func(r chi.Router) {
|
||||
r.Use(
|
||||
apiKeyMiddleware,
|
||||
@ -582,8 +574,10 @@ func New(options *Options) *API {
|
||||
r.Get("/", api.templateVersion)
|
||||
r.Patch("/", api.patchTemplateVersion)
|
||||
r.Patch("/cancel", api.patchCancelTemplateVersion)
|
||||
r.Get("/schema", api.templateVersionSchema)
|
||||
r.Get("/parameters", api.templateVersionParameters)
|
||||
// Old agents may expect a non-error response from /schema and /parameters endpoints.
|
||||
// The idea is to return an empty [], so that the coder CLI won't get blocked accidentally.
|
||||
r.Get("/schema", templateVersionSchemaDeprecated)
|
||||
r.Get("/parameters", templateVersionParametersDeprecated)
|
||||
r.Get("/rich-parameters", api.templateVersionRichParameters)
|
||||
r.Get("/gitauth", api.templateVersionGitAuth)
|
||||
r.Get("/variables", api.templateVersionVariables)
|
||||
|
@ -356,6 +356,6 @@ func assertProduce(t *testing.T, comment SwaggerComment) {
|
||||
return // Exception: HTTP 200 is returned without response entity
|
||||
}
|
||||
|
||||
assert.True(t, comment.produce == "", "Response model is undefined, so we can't predict the content type", comment)
|
||||
assert.Truef(t, comment.produce == "", "Response model is undefined, so we can't predict the content type: %v", comment)
|
||||
}
|
||||
}
|
||||
|
@ -77,28 +77,6 @@ func TemplateVersionParameter(param database.TemplateVersionParameter) (codersdk
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Parameters(params []database.ParameterValue) []codersdk.Parameter {
|
||||
out := make([]codersdk.Parameter, len(params))
|
||||
for i, p := range params {
|
||||
out[i] = Parameter(p)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func Parameter(parameterValue database.ParameterValue) codersdk.Parameter {
|
||||
return codersdk.Parameter{
|
||||
ID: parameterValue.ID,
|
||||
CreatedAt: parameterValue.CreatedAt,
|
||||
UpdatedAt: parameterValue.UpdatedAt,
|
||||
Scope: codersdk.ParameterScope(parameterValue.Scope),
|
||||
ScopeID: parameterValue.ScopeID,
|
||||
Name: parameterValue.Name,
|
||||
SourceScheme: codersdk.ParameterSourceScheme(parameterValue.SourceScheme),
|
||||
DestinationScheme: codersdk.ParameterDestinationScheme(parameterValue.DestinationScheme),
|
||||
SourceValue: parameterValue.SourceValue,
|
||||
}
|
||||
}
|
||||
|
||||
func ProvisionerJobStatus(provisionerJob database.ProvisionerJob) codersdk.ProvisionerJobStatus {
|
||||
switch {
|
||||
case provisionerJob.CanceledAt.Valid:
|
||||
|
@ -526,100 +526,6 @@ func (q *querier) canAssignRoles(ctx context.Context, orgID *uuid.UUID, added, r
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *querier) parameterRBACResource(ctx context.Context, scope database.ParameterScope, scopeID uuid.UUID) (rbac.Objecter, error) {
|
||||
var resource rbac.Objecter
|
||||
var err error
|
||||
switch scope {
|
||||
case database.ParameterScopeWorkspace:
|
||||
return q.db.GetWorkspaceByID(ctx, scopeID)
|
||||
case database.ParameterScopeImportJob:
|
||||
var version database.TemplateVersion
|
||||
version, err = q.db.GetTemplateVersionByJobID(ctx, scopeID)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
resource = version.RBACObjectNoTemplate()
|
||||
|
||||
var template database.Template
|
||||
template, err = q.db.GetTemplateByID(ctx, version.TemplateID.UUID)
|
||||
if err == nil {
|
||||
resource = version.RBACObject(template)
|
||||
} else if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
|
||||
return nil, err
|
||||
}
|
||||
return resource, nil
|
||||
case database.ParameterScopeTemplate:
|
||||
return q.db.GetTemplateByID(ctx, scopeID)
|
||||
default:
|
||||
return nil, xerrors.Errorf("Parameter scope %q unsupported", scope)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *querier) InsertParameterValue(ctx context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
|
||||
resource, err := q.parameterRBACResource(ctx, arg.Scope, arg.ScopeID)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
err = q.authorizeContext(ctx, rbac.ActionUpdate, resource)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
return q.db.InsertParameterValue(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) ParameterValue(ctx context.Context, id uuid.UUID) (database.ParameterValue, error) {
|
||||
parameter, err := q.db.ParameterValue(ctx, id)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
resource, err := q.parameterRBACResource(ctx, parameter.Scope, parameter.ScopeID)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
err = q.authorizeContext(ctx, rbac.ActionRead, resource)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
return parameter, nil
|
||||
}
|
||||
|
||||
// ParameterValues is implemented as an all or nothing query. If the user is not
|
||||
// able to read a single parameter value, then the entire query is denied.
|
||||
// This should likely be revisited and see if the usage of this function cannot be changed.
|
||||
func (q *querier) ParameterValues(ctx context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
|
||||
// This is a bit of a special case. Each parameter value returned might have a different scope. This could likely
|
||||
// be implemented in a more efficient manner.
|
||||
values, err := q.db.ParameterValues(ctx, arg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cached := make(map[uuid.UUID]bool)
|
||||
for _, value := range values {
|
||||
// If we already checked this scopeID, then we can skip it.
|
||||
// All scope ids are uuids of objects and universally unique.
|
||||
if allowed := cached[value.ScopeID]; allowed {
|
||||
continue
|
||||
}
|
||||
rbacObj, err := q.parameterRBACResource(ctx, value.Scope, value.ScopeID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = q.authorizeContext(ctx, rbac.ActionRead, rbacObj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cached[value.ScopeID] = true
|
||||
}
|
||||
|
||||
return values, nil
|
||||
}
|
||||
|
||||
func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]database.ParameterSchema, error) {
|
||||
version, err := q.db.GetTemplateVersionByJobID(ctx, jobID)
|
||||
if err != nil {
|
||||
@ -641,40 +547,6 @@ func (q *querier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUI
|
||||
return q.db.GetParameterSchemasByJobID(ctx, jobID)
|
||||
}
|
||||
|
||||
func (q *querier) GetParameterValueByScopeAndName(ctx context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
|
||||
resource, err := q.parameterRBACResource(ctx, arg.Scope, arg.ScopeID)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
err = q.authorizeContext(ctx, rbac.ActionRead, resource)
|
||||
if err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
return q.db.GetParameterValueByScopeAndName(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
|
||||
parameter, err := q.db.ParameterValue(ctx, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resource, err := q.parameterRBACResource(ctx, parameter.Scope, parameter.ScopeID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// A deleted param is still updating the underlying resource for the scope.
|
||||
err = q.authorizeContext(ctx, rbac.ActionUpdate, resource)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return q.db.DeleteParameterValueByID(ctx, id)
|
||||
}
|
||||
|
||||
func (q *querier) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
|
||||
// An actor can read the previous template version if they can read the related template.
|
||||
// If no linked template exists, we check if the actor can read *a* template.
|
||||
|
@ -468,106 +468,6 @@ func (s *MethodTestSuite) TestWorkspaceProxy() {
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestParameters() {
|
||||
s.Run("Workspace/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
check.Args(database.InsertParameterValueParams{
|
||||
ScopeID: w.ID,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
SourceScheme: database.ParameterSourceSchemeNone,
|
||||
DestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
}).Asserts(w, rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("TemplateVersionNoTemplate/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{JobID: j.ID, TemplateID: uuid.NullUUID{Valid: false}})
|
||||
check.Args(database.InsertParameterValueParams{
|
||||
ScopeID: j.ID,
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
SourceScheme: database.ParameterSourceSchemeNone,
|
||||
DestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
}).Asserts(v.RBACObjectNoTemplate(), rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("TemplateVersionTemplate/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
v := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{
|
||||
JobID: j.ID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: tpl.ID,
|
||||
Valid: true,
|
||||
},
|
||||
},
|
||||
)
|
||||
check.Args(database.InsertParameterValueParams{
|
||||
ScopeID: j.ID,
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
SourceScheme: database.ParameterSourceSchemeNone,
|
||||
DestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
}).Asserts(v.RBACObject(tpl), rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("Template/InsertParameterValue", s.Subtest(func(db database.Store, check *expects) {
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
check.Args(database.InsertParameterValueParams{
|
||||
ScopeID: tpl.ID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
SourceScheme: database.ParameterSourceSchemeNone,
|
||||
DestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
}).Asserts(tpl, rbac.ActionUpdate)
|
||||
}))
|
||||
s.Run("Template/ParameterValue", s.Subtest(func(db database.Store, check *expects) {
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
pv := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
|
||||
ScopeID: tpl.ID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
})
|
||||
check.Args(pv.ID).Asserts(tpl, rbac.ActionRead).Returns(pv)
|
||||
}))
|
||||
s.Run("ParameterValues", s.Subtest(func(db database.Store, check *expects) {
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
a := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
|
||||
ScopeID: tpl.ID,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
})
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
b := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
|
||||
ScopeID: w.ID,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
})
|
||||
check.Args(database.ParameterValuesParams{
|
||||
IDs: []uuid.UUID{a.ID, b.ID},
|
||||
}).Asserts(tpl, rbac.ActionRead, w, rbac.ActionRead).Returns(slice.New(a, b))
|
||||
}))
|
||||
s.Run("GetParameterSchemasByJobID", s.Subtest(func(db database.Store, check *expects) {
|
||||
j := dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{})
|
||||
tpl := dbgen.Template(s.T(), db, database.Template{})
|
||||
tv := dbgen.TemplateVersion(s.T(), db, database.TemplateVersion{JobID: j.ID, TemplateID: uuid.NullUUID{UUID: tpl.ID, Valid: true}})
|
||||
a := dbgen.ParameterSchema(s.T(), db, database.ParameterSchema{JobID: j.ID})
|
||||
check.Args(j.ID).Asserts(tv.RBACObject(tpl), rbac.ActionRead).
|
||||
Returns([]database.ParameterSchema{a})
|
||||
}))
|
||||
s.Run("Workspace/GetParameterValueByScopeAndName", s.Subtest(func(db database.Store, check *expects) {
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
v := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: w.ID,
|
||||
})
|
||||
check.Args(database.GetParameterValueByScopeAndNameParams{
|
||||
Scope: v.Scope,
|
||||
ScopeID: v.ScopeID,
|
||||
Name: v.Name,
|
||||
}).Asserts(w, rbac.ActionRead).Returns(v)
|
||||
}))
|
||||
s.Run("Workspace/DeleteParameterValueByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
w := dbgen.Workspace(s.T(), db, database.Workspace{})
|
||||
v := dbgen.ParameterValue(s.T(), db, database.ParameterValue{
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: w.ID,
|
||||
})
|
||||
check.Args(v.ID).Asserts(w, rbac.ActionUpdate).Returns()
|
||||
}))
|
||||
}
|
||||
|
||||
func (s *MethodTestSuite) TestTemplate() {
|
||||
s.Run("GetPreviousTemplateVersion", s.Subtest(func(db database.Store, check *expects) {
|
||||
tvid := uuid.New()
|
||||
|
@ -314,13 +314,6 @@ func (q *querier) GetWorkspacesEligibleForAutoStartStop(ctx context.Context, now
|
||||
return q.db.GetWorkspacesEligibleForAutoStartStop(ctx, now)
|
||||
}
|
||||
|
||||
func (q *querier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ParameterSchema, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.db.GetParameterSchemasCreatedAfter(ctx, createdAt)
|
||||
}
|
||||
|
||||
// TODO: We need to create a ProvisionerJob resource type
|
||||
func (q *querier) GetProvisionerJobsCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ProvisionerJob, error) {
|
||||
// if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
@ -432,13 +425,6 @@ func (q *querier) InsertWorkspaceResource(ctx context.Context, arg database.Inse
|
||||
return q.db.InsertWorkspaceResource(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) InsertParameterSchema(ctx context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionCreate, rbac.ResourceSystem); err != nil {
|
||||
return database.ParameterSchema{}, err
|
||||
}
|
||||
return q.db.InsertParameterSchema(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) GetWorkspaceProxyByHostname(ctx context.Context, params database.GetWorkspaceProxyByHostnameParams) (database.WorkspaceProxy, error) {
|
||||
if err := q.authorizeContext(ctx, rbac.ActionRead, rbac.ResourceSystem); err != nil {
|
||||
return database.WorkspaceProxy{}, err
|
||||
|
@ -133,10 +133,6 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
s.Run("DeleteOldWorkspaceAgentStats", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args().Asserts(rbac.ResourceSystem, rbac.ActionDelete)
|
||||
}))
|
||||
s.Run("GetParameterSchemasCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
_ = dbgen.ParameterSchema(s.T(), db, database.ParameterSchema{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
check.Args(time.Now()).Asserts(rbac.ResourceSystem, rbac.ActionRead)
|
||||
}))
|
||||
s.Run("GetProvisionerJobsCreatedAfter", s.Subtest(func(db database.Store, check *expects) {
|
||||
// TODO: add provisioner job resource type
|
||||
_ = dbgen.ProvisionerJob(s.T(), db, database.ProvisionerJob{CreatedAt: time.Now().Add(-time.Hour)})
|
||||
@ -297,12 +293,4 @@ func (s *MethodTestSuite) TestSystemFunctions() {
|
||||
Transition: database.WorkspaceTransitionStart,
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
s.Run("InsertParameterSchema", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args(database.InsertParameterSchemaParams{
|
||||
ID: uuid.New(),
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
ValidationTypeSystem: database.ParameterTypeSystemNone,
|
||||
}).Asserts(rbac.ResourceSystem, rbac.ActionCreate)
|
||||
}))
|
||||
}
|
||||
|
@ -55,7 +55,6 @@ func New() database.Store {
|
||||
files: make([]database.File, 0),
|
||||
gitSSHKey: make([]database.GitSSHKey, 0),
|
||||
parameterSchemas: make([]database.ParameterSchema, 0),
|
||||
parameterValues: make([]database.ParameterValue, 0),
|
||||
provisionerDaemons: make([]database.ProvisionerDaemon, 0),
|
||||
workspaceAgents: make([]database.WorkspaceAgent, 0),
|
||||
provisionerJobLogs: make([]database.ProvisionerJobLog, 0),
|
||||
@ -124,7 +123,6 @@ type data struct {
|
||||
groups []database.Group
|
||||
licenses []database.License
|
||||
parameterSchemas []database.ParameterSchema
|
||||
parameterValues []database.ParameterValue
|
||||
provisionerDaemons []database.ProvisionerDaemon
|
||||
provisionerJobLogs []database.ProvisionerJobLog
|
||||
provisionerJobs []database.ProvisionerJob
|
||||
@ -575,34 +573,6 @@ func (q *fakeQuerier) GetTemplateAverageBuildTime(ctx context.Context, arg datab
|
||||
return row, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) ParameterValue(_ context.Context, id uuid.UUID) (database.ParameterValue, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, parameterValue := range q.parameterValues {
|
||||
if parameterValue.ID != id {
|
||||
continue
|
||||
}
|
||||
return parameterValue, nil
|
||||
}
|
||||
return database.ParameterValue{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) DeleteParameterValueByID(_ context.Context, id uuid.UUID) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
for index, parameterValue := range q.parameterValues {
|
||||
if parameterValue.ID != id {
|
||||
continue
|
||||
}
|
||||
q.parameterValues[index] = q.parameterValues[len(q.parameterValues)-1]
|
||||
q.parameterValues = q.parameterValues[:len(q.parameterValues)-1]
|
||||
return nil
|
||||
}
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetAPIKeyByID(_ context.Context, id string) (database.APIKey, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@ -1893,40 +1863,6 @@ func (q *fakeQuerier) GetOrganizationsByUserID(_ context.Context, userID uuid.UU
|
||||
return organizations, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) ParameterValues(_ context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
parameterValues := make([]database.ParameterValue, 0)
|
||||
for _, parameterValue := range q.parameterValues {
|
||||
if len(arg.Scopes) > 0 {
|
||||
if !slice.Contains(arg.Scopes, parameterValue.Scope) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if len(arg.ScopeIds) > 0 {
|
||||
if !slice.Contains(arg.ScopeIds, parameterValue.ScopeID) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if len(arg.IDs) > 0 {
|
||||
if !slice.Contains(arg.IDs, parameterValue.ID) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
parameterValues = append(parameterValues, parameterValue)
|
||||
}
|
||||
if len(parameterValues) == 0 {
|
||||
return nil, sql.ErrNoRows
|
||||
}
|
||||
return parameterValues, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetTemplateByID(ctx context.Context, id uuid.UUID) (database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@ -2329,42 +2265,6 @@ func (q *fakeQuerier) GetParameterSchemasByJobID(_ context.Context, jobID uuid.U
|
||||
return parameters, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetParameterSchemasCreatedAfter(_ context.Context, after time.Time) ([]database.ParameterSchema, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
parameters := make([]database.ParameterSchema, 0)
|
||||
for _, parameterSchema := range q.parameterSchemas {
|
||||
if parameterSchema.CreatedAt.After(after) {
|
||||
parameters = append(parameters, parameterSchema)
|
||||
}
|
||||
}
|
||||
return parameters, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetParameterValueByScopeAndName(_ context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
for _, parameterValue := range q.parameterValues {
|
||||
if parameterValue.Scope != arg.Scope {
|
||||
continue
|
||||
}
|
||||
if parameterValue.ScopeID != arg.ScopeID {
|
||||
continue
|
||||
}
|
||||
if parameterValue.Name != arg.Name {
|
||||
continue
|
||||
}
|
||||
return parameterValue, nil
|
||||
}
|
||||
return database.ParameterValue{}, sql.ErrNoRows
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) GetTemplates(_ context.Context) ([]database.Template, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@ -2977,30 +2877,6 @@ func (q *fakeQuerier) InsertOrganizationMember(_ context.Context, arg database.I
|
||||
return organizationMember, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertParameterValue(_ context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ParameterValue{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
parameterValue := database.ParameterValue{
|
||||
ID: arg.ID,
|
||||
Name: arg.Name,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
UpdatedAt: arg.UpdatedAt,
|
||||
Scope: arg.Scope,
|
||||
ScopeID: arg.ScopeID,
|
||||
SourceScheme: arg.SourceScheme,
|
||||
SourceValue: arg.SourceValue,
|
||||
DestinationScheme: arg.DestinationScheme,
|
||||
}
|
||||
q.parameterValues = append(q.parameterValues, parameterValue)
|
||||
return parameterValue, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertTemplate(_ context.Context, arg database.InsertTemplateParams) (database.Template, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.Template{}, err
|
||||
@ -3139,38 +3015,6 @@ func (q *fakeQuerier) InsertProvisionerJobLogs(_ context.Context, arg database.I
|
||||
return logs, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertParameterSchema(_ context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ParameterSchema{}, err
|
||||
}
|
||||
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
//nolint:gosimple
|
||||
param := database.ParameterSchema{
|
||||
ID: arg.ID,
|
||||
CreatedAt: arg.CreatedAt,
|
||||
JobID: arg.JobID,
|
||||
Name: arg.Name,
|
||||
Description: arg.Description,
|
||||
DefaultSourceScheme: arg.DefaultSourceScheme,
|
||||
DefaultSourceValue: arg.DefaultSourceValue,
|
||||
AllowOverrideSource: arg.AllowOverrideSource,
|
||||
DefaultDestinationScheme: arg.DefaultDestinationScheme,
|
||||
AllowOverrideDestination: arg.AllowOverrideDestination,
|
||||
DefaultRefresh: arg.DefaultRefresh,
|
||||
RedisplayValue: arg.RedisplayValue,
|
||||
ValidationError: arg.ValidationError,
|
||||
ValidationCondition: arg.ValidationCondition,
|
||||
ValidationTypeSystem: arg.ValidationTypeSystem,
|
||||
ValidationValueType: arg.ValidationValueType,
|
||||
Index: arg.Index,
|
||||
}
|
||||
q.parameterSchemas = append(q.parameterSchemas, param)
|
||||
return param, nil
|
||||
}
|
||||
|
||||
func (q *fakeQuerier) InsertProvisionerDaemon(_ context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
if err := validateDatabaseType(arg); err != nil {
|
||||
return database.ProvisionerDaemon{}, err
|
||||
|
@ -439,46 +439,6 @@ func TemplateVersionVariable(t testing.TB, db database.Store, orig database.Temp
|
||||
return version
|
||||
}
|
||||
|
||||
func ParameterSchema(t testing.TB, db database.Store, seed database.ParameterSchema) database.ParameterSchema {
|
||||
scheme, err := db.InsertParameterSchema(context.Background(), database.InsertParameterSchemaParams{
|
||||
ID: takeFirst(seed.ID, uuid.New()),
|
||||
JobID: takeFirst(seed.JobID, uuid.New()),
|
||||
CreatedAt: takeFirst(seed.CreatedAt, database.Now()),
|
||||
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
|
||||
Description: takeFirst(seed.Description, namesgenerator.GetRandomName(1)),
|
||||
DefaultSourceScheme: takeFirst(seed.DefaultSourceScheme, database.ParameterSourceSchemeNone),
|
||||
DefaultSourceValue: takeFirst(seed.DefaultSourceValue, ""),
|
||||
AllowOverrideSource: takeFirst(seed.AllowOverrideSource, false),
|
||||
DefaultDestinationScheme: takeFirst(seed.DefaultDestinationScheme, database.ParameterDestinationSchemeNone),
|
||||
AllowOverrideDestination: takeFirst(seed.AllowOverrideDestination, false),
|
||||
DefaultRefresh: takeFirst(seed.DefaultRefresh, ""),
|
||||
RedisplayValue: takeFirst(seed.RedisplayValue, false),
|
||||
ValidationError: takeFirst(seed.ValidationError, ""),
|
||||
ValidationCondition: takeFirst(seed.ValidationCondition, ""),
|
||||
ValidationTypeSystem: takeFirst(seed.ValidationTypeSystem, database.ParameterTypeSystemNone),
|
||||
ValidationValueType: takeFirst(seed.ValidationValueType, ""),
|
||||
Index: takeFirst(seed.Index, 1),
|
||||
})
|
||||
require.NoError(t, err, "insert parameter scheme")
|
||||
return scheme
|
||||
}
|
||||
|
||||
func ParameterValue(t testing.TB, db database.Store, seed database.ParameterValue) database.ParameterValue {
|
||||
scheme, err := db.InsertParameterValue(context.Background(), database.InsertParameterValueParams{
|
||||
ID: takeFirst(seed.ID, uuid.New()),
|
||||
Name: takeFirst(seed.Name, namesgenerator.GetRandomName(1)),
|
||||
CreatedAt: takeFirst(seed.CreatedAt, database.Now()),
|
||||
UpdatedAt: takeFirst(seed.UpdatedAt, database.Now()),
|
||||
Scope: takeFirst(seed.Scope, database.ParameterScopeWorkspace),
|
||||
ScopeID: takeFirst(seed.ScopeID, uuid.New()),
|
||||
SourceScheme: takeFirst(seed.SourceScheme, database.ParameterSourceSchemeNone),
|
||||
SourceValue: takeFirst(seed.SourceValue, ""),
|
||||
DestinationScheme: takeFirst(seed.DestinationScheme, database.ParameterDestinationSchemeNone),
|
||||
})
|
||||
require.NoError(t, err, "insert parameter value")
|
||||
return scheme
|
||||
}
|
||||
|
||||
func WorkspaceAgentStat(t testing.TB, db database.Store, orig database.WorkspaceAgentStat) database.WorkspaceAgentStat {
|
||||
if orig.ConnectionsByProto == nil {
|
||||
orig.ConnectionsByProto = json.RawMessage([]byte("{}"))
|
||||
|
@ -153,24 +153,6 @@ func TestGenerator(t *testing.T) {
|
||||
require.Equal(t, exp, must(db.GetTemplateVersionByID(context.Background(), exp.ID)))
|
||||
})
|
||||
|
||||
t.Run("ParameterSchema", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
exp := dbgen.ParameterSchema(t, db, database.ParameterSchema{})
|
||||
require.Equal(t, []database.ParameterSchema{exp}, must(db.GetParameterSchemasByJobID(context.Background(), exp.JobID)))
|
||||
})
|
||||
|
||||
t.Run("ParameterValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
exp := dbgen.ParameterValue(t, db, database.ParameterValue{})
|
||||
require.Equal(t, exp, must(db.GetParameterValueByScopeAndName(context.Background(), database.GetParameterValueByScopeAndNameParams{
|
||||
Scope: exp.Scope,
|
||||
ScopeID: exp.ScopeID,
|
||||
Name: exp.Name,
|
||||
})))
|
||||
})
|
||||
|
||||
t.Run("WorkspaceBuild", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
|
@ -154,13 +154,6 @@ func (m metricsStore) DeleteOldWorkspaceAgentStats(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (m metricsStore) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
|
||||
start := time.Now()
|
||||
err := m.s.DeleteParameterValueByID(ctx, id)
|
||||
m.queryLatencies.WithLabelValues("DeleteParameterValueByID").Observe(time.Since(start).Seconds())
|
||||
return err
|
||||
}
|
||||
|
||||
func (m metricsStore) DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error {
|
||||
start := time.Now()
|
||||
err := m.s.DeleteReplicasUpdatedBefore(ctx, updatedAt)
|
||||
@ -441,20 +434,6 @@ func (m metricsStore) GetParameterSchemasByJobID(ctx context.Context, jobID uuid
|
||||
return schemas, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]database.ParameterSchema, error) {
|
||||
start := time.Now()
|
||||
schemas, err := m.s.GetParameterSchemasCreatedAfter(ctx, createdAt)
|
||||
m.queryLatencies.WithLabelValues("GetParameterSchemasCreatedAfter").Observe(time.Since(start).Seconds())
|
||||
return schemas, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetParameterValueByScopeAndName(ctx context.Context, arg database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
|
||||
start := time.Now()
|
||||
value, err := m.s.GetParameterValueByScopeAndName(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("GetParameterValueByScopeAndName").Observe(time.Since(start).Seconds())
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetPreviousTemplateVersion(ctx context.Context, arg database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
|
||||
start := time.Now()
|
||||
version, err := m.s.GetPreviousTemplateVersion(ctx, arg)
|
||||
@ -1022,20 +1001,6 @@ func (m metricsStore) InsertOrganizationMember(ctx context.Context, arg database
|
||||
return member, err
|
||||
}
|
||||
|
||||
func (m metricsStore) InsertParameterSchema(ctx context.Context, arg database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
|
||||
start := time.Now()
|
||||
schema, err := m.s.InsertParameterSchema(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("InsertParameterSchema").Observe(time.Since(start).Seconds())
|
||||
return schema, err
|
||||
}
|
||||
|
||||
func (m metricsStore) InsertParameterValue(ctx context.Context, arg database.InsertParameterValueParams) (database.ParameterValue, error) {
|
||||
start := time.Now()
|
||||
value, err := m.s.InsertParameterValue(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("InsertParameterValue").Observe(time.Since(start).Seconds())
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (m metricsStore) InsertProvisionerDaemon(ctx context.Context, arg database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
start := time.Now()
|
||||
daemon, err := m.s.InsertProvisionerDaemon(ctx, arg)
|
||||
@ -1190,20 +1155,6 @@ func (m metricsStore) InsertWorkspaceResourceMetadata(ctx context.Context, arg d
|
||||
return metadata, err
|
||||
}
|
||||
|
||||
func (m metricsStore) ParameterValue(ctx context.Context, id uuid.UUID) (database.ParameterValue, error) {
|
||||
start := time.Now()
|
||||
value, err := m.s.ParameterValue(ctx, id)
|
||||
m.queryLatencies.WithLabelValues("ParameterValue").Observe(time.Since(start).Seconds())
|
||||
return value, err
|
||||
}
|
||||
|
||||
func (m metricsStore) ParameterValues(ctx context.Context, arg database.ParameterValuesParams) ([]database.ParameterValue, error) {
|
||||
start := time.Now()
|
||||
values, err := m.s.ParameterValues(ctx, arg)
|
||||
m.queryLatencies.WithLabelValues("ParameterValues").Observe(time.Since(start).Seconds())
|
||||
return values, err
|
||||
}
|
||||
|
||||
func (m metricsStore) RegisterWorkspaceProxy(ctx context.Context, arg database.RegisterWorkspaceProxyParams) (database.WorkspaceProxy, error) {
|
||||
start := time.Now()
|
||||
proxy, err := m.s.RegisterWorkspaceProxy(ctx, arg)
|
||||
|
@ -209,20 +209,6 @@ func (mr *MockStoreMockRecorder) DeleteOldWorkspaceAgentStats(arg0 interface{})
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteOldWorkspaceAgentStats", reflect.TypeOf((*MockStore)(nil).DeleteOldWorkspaceAgentStats), arg0)
|
||||
}
|
||||
|
||||
// DeleteParameterValueByID mocks base method.
|
||||
func (m *MockStore) DeleteParameterValueByID(arg0 context.Context, arg1 uuid.UUID) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "DeleteParameterValueByID", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// DeleteParameterValueByID indicates an expected call of DeleteParameterValueByID.
|
||||
func (mr *MockStoreMockRecorder) DeleteParameterValueByID(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteParameterValueByID", reflect.TypeOf((*MockStore)(nil).DeleteParameterValueByID), arg0, arg1)
|
||||
}
|
||||
|
||||
// DeleteReplicasUpdatedBefore mocks base method.
|
||||
func (m *MockStore) DeleteReplicasUpdatedBefore(arg0 context.Context, arg1 time.Time) error {
|
||||
m.ctrl.T.Helper()
|
||||
@ -867,36 +853,6 @@ func (mr *MockStoreMockRecorder) GetParameterSchemasByJobID(arg0, arg1 interface
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasByJobID", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasByJobID), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetParameterSchemasCreatedAfter mocks base method.
|
||||
func (m *MockStore) GetParameterSchemasCreatedAfter(arg0 context.Context, arg1 time.Time) ([]database.ParameterSchema, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetParameterSchemasCreatedAfter", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.ParameterSchema)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetParameterSchemasCreatedAfter indicates an expected call of GetParameterSchemasCreatedAfter.
|
||||
func (mr *MockStoreMockRecorder) GetParameterSchemasCreatedAfter(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterSchemasCreatedAfter", reflect.TypeOf((*MockStore)(nil).GetParameterSchemasCreatedAfter), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetParameterValueByScopeAndName mocks base method.
|
||||
func (m *MockStore) GetParameterValueByScopeAndName(arg0 context.Context, arg1 database.GetParameterValueByScopeAndNameParams) (database.ParameterValue, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetParameterValueByScopeAndName", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.ParameterValue)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetParameterValueByScopeAndName indicates an expected call of GetParameterValueByScopeAndName.
|
||||
func (mr *MockStoreMockRecorder) GetParameterValueByScopeAndName(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetParameterValueByScopeAndName", reflect.TypeOf((*MockStore)(nil).GetParameterValueByScopeAndName), arg0, arg1)
|
||||
}
|
||||
|
||||
// GetPreviousTemplateVersion mocks base method.
|
||||
func (m *MockStore) GetPreviousTemplateVersion(arg0 context.Context, arg1 database.GetPreviousTemplateVersionParams) (database.TemplateVersion, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -2153,36 +2109,6 @@ func (mr *MockStoreMockRecorder) InsertOrganizationMember(arg0, arg1 interface{}
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertOrganizationMember", reflect.TypeOf((*MockStore)(nil).InsertOrganizationMember), arg0, arg1)
|
||||
}
|
||||
|
||||
// InsertParameterSchema mocks base method.
|
||||
func (m *MockStore) InsertParameterSchema(arg0 context.Context, arg1 database.InsertParameterSchemaParams) (database.ParameterSchema, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InsertParameterSchema", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.ParameterSchema)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// InsertParameterSchema indicates an expected call of InsertParameterSchema.
|
||||
func (mr *MockStoreMockRecorder) InsertParameterSchema(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertParameterSchema", reflect.TypeOf((*MockStore)(nil).InsertParameterSchema), arg0, arg1)
|
||||
}
|
||||
|
||||
// InsertParameterValue mocks base method.
|
||||
func (m *MockStore) InsertParameterValue(arg0 context.Context, arg1 database.InsertParameterValueParams) (database.ParameterValue, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "InsertParameterValue", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.ParameterValue)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// InsertParameterValue indicates an expected call of InsertParameterValue.
|
||||
func (mr *MockStoreMockRecorder) InsertParameterValue(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertParameterValue", reflect.TypeOf((*MockStore)(nil).InsertParameterValue), arg0, arg1)
|
||||
}
|
||||
|
||||
// InsertProvisionerDaemon mocks base method.
|
||||
func (m *MockStore) InsertProvisionerDaemon(arg0 context.Context, arg1 database.InsertProvisionerDaemonParams) (database.ProvisionerDaemon, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@ -2510,36 +2436,6 @@ func (mr *MockStoreMockRecorder) InsertWorkspaceResourceMetadata(arg0, arg1 inte
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWorkspaceResourceMetadata", reflect.TypeOf((*MockStore)(nil).InsertWorkspaceResourceMetadata), arg0, arg1)
|
||||
}
|
||||
|
||||
// ParameterValue mocks base method.
|
||||
func (m *MockStore) ParameterValue(arg0 context.Context, arg1 uuid.UUID) (database.ParameterValue, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ParameterValue", arg0, arg1)
|
||||
ret0, _ := ret[0].(database.ParameterValue)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ParameterValue indicates an expected call of ParameterValue.
|
||||
func (mr *MockStoreMockRecorder) ParameterValue(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParameterValue", reflect.TypeOf((*MockStore)(nil).ParameterValue), arg0, arg1)
|
||||
}
|
||||
|
||||
// ParameterValues mocks base method.
|
||||
func (m *MockStore) ParameterValues(arg0 context.Context, arg1 database.ParameterValuesParams) ([]database.ParameterValue, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "ParameterValues", arg0, arg1)
|
||||
ret0, _ := ret[0].([]database.ParameterValue)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// ParameterValues indicates an expected call of ParameterValues.
|
||||
func (mr *MockStoreMockRecorder) ParameterValues(arg0, arg1 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ParameterValues", reflect.TypeOf((*MockStore)(nil).ParameterValues), arg0, arg1)
|
||||
}
|
||||
|
||||
// Ping mocks base method.
|
||||
func (m *MockStore) Ping(arg0 context.Context) (time.Duration, error) {
|
||||
m.ctrl.T.Helper()
|
||||
|
@ -38,7 +38,6 @@ type sqlcQuerier interface {
|
||||
// Logs can take up a lot of space, so it's important we clean up frequently.
|
||||
DeleteOldWorkspaceAgentStartupLogs(ctx context.Context) error
|
||||
DeleteOldWorkspaceAgentStats(ctx context.Context) error
|
||||
DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error
|
||||
DeleteReplicasUpdatedBefore(ctx context.Context, updatedAt time.Time) error
|
||||
GetAPIKeyByID(ctx context.Context, id string) (APIKey, error)
|
||||
// there is no unique constraint on empty token names
|
||||
@ -86,8 +85,6 @@ type sqlcQuerier interface {
|
||||
GetOrganizations(ctx context.Context) ([]Organization, error)
|
||||
GetOrganizationsByUserID(ctx context.Context, userID uuid.UUID) ([]Organization, error)
|
||||
GetParameterSchemasByJobID(ctx context.Context, jobID uuid.UUID) ([]ParameterSchema, error)
|
||||
GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error)
|
||||
GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error)
|
||||
GetPreviousTemplateVersion(ctx context.Context, arg GetPreviousTemplateVersionParams) (TemplateVersion, error)
|
||||
GetProvisionerDaemons(ctx context.Context) ([]ProvisionerDaemon, error)
|
||||
GetProvisionerJobByID(ctx context.Context, id uuid.UUID) (ProvisionerJob, error)
|
||||
@ -183,8 +180,6 @@ type sqlcQuerier interface {
|
||||
InsertLicense(ctx context.Context, arg InsertLicenseParams) (License, error)
|
||||
InsertOrganization(ctx context.Context, arg InsertOrganizationParams) (Organization, error)
|
||||
InsertOrganizationMember(ctx context.Context, arg InsertOrganizationMemberParams) (OrganizationMember, error)
|
||||
InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error)
|
||||
InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error)
|
||||
InsertProvisionerDaemon(ctx context.Context, arg InsertProvisionerDaemonParams) (ProvisionerDaemon, error)
|
||||
InsertProvisionerJob(ctx context.Context, arg InsertProvisionerJobParams) (ProvisionerJob, error)
|
||||
InsertProvisionerJobLogs(ctx context.Context, arg InsertProvisionerJobLogsParams) ([]ProvisionerJobLog, error)
|
||||
@ -208,8 +203,6 @@ type sqlcQuerier interface {
|
||||
InsertWorkspaceProxy(ctx context.Context, arg InsertWorkspaceProxyParams) (WorkspaceProxy, error)
|
||||
InsertWorkspaceResource(ctx context.Context, arg InsertWorkspaceResourceParams) (WorkspaceResource, error)
|
||||
InsertWorkspaceResourceMetadata(ctx context.Context, arg InsertWorkspaceResourceMetadataParams) ([]WorkspaceResourceMetadatum, error)
|
||||
ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error)
|
||||
ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error)
|
||||
RegisterWorkspaceProxy(ctx context.Context, arg RegisterWorkspaceProxyParams) (WorkspaceProxy, error)
|
||||
// Non blocking lock. Returns true if the lock was acquired, false otherwise.
|
||||
//
|
||||
|
@ -1935,358 +1935,6 @@ func (q *sqlQuerier) GetParameterSchemasByJobID(ctx context.Context, jobID uuid.
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getParameterSchemasCreatedAfter = `-- name: GetParameterSchemasCreatedAfter :many
|
||||
SELECT id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index FROM parameter_schemas WHERE created_at > $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetParameterSchemasCreatedAfter(ctx context.Context, createdAt time.Time) ([]ParameterSchema, error) {
|
||||
rows, err := q.db.QueryContext(ctx, getParameterSchemasCreatedAfter, createdAt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ParameterSchema
|
||||
for rows.Next() {
|
||||
var i ParameterSchema
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.JobID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.DefaultSourceScheme,
|
||||
&i.DefaultSourceValue,
|
||||
&i.AllowOverrideSource,
|
||||
&i.DefaultDestinationScheme,
|
||||
&i.AllowOverrideDestination,
|
||||
&i.DefaultRefresh,
|
||||
&i.RedisplayValue,
|
||||
&i.ValidationError,
|
||||
&i.ValidationCondition,
|
||||
&i.ValidationTypeSystem,
|
||||
&i.ValidationValueType,
|
||||
&i.Index,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const insertParameterSchema = `-- name: InsertParameterSchema :one
|
||||
INSERT INTO
|
||||
parameter_schemas (
|
||||
id,
|
||||
created_at,
|
||||
job_id,
|
||||
"name",
|
||||
description,
|
||||
default_source_scheme,
|
||||
default_source_value,
|
||||
allow_override_source,
|
||||
default_destination_scheme,
|
||||
allow_override_destination,
|
||||
default_refresh,
|
||||
redisplay_value,
|
||||
validation_error,
|
||||
validation_condition,
|
||||
validation_type_system,
|
||||
validation_value_type,
|
||||
index
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
$1,
|
||||
$2,
|
||||
$3,
|
||||
$4,
|
||||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11,
|
||||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15,
|
||||
$16,
|
||||
$17
|
||||
) RETURNING id, created_at, job_id, name, description, default_source_scheme, default_source_value, allow_override_source, default_destination_scheme, allow_override_destination, default_refresh, redisplay_value, validation_error, validation_condition, validation_type_system, validation_value_type, index
|
||||
`
|
||||
|
||||
type InsertParameterSchemaParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
JobID uuid.UUID `db:"job_id" json:"job_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
Description string `db:"description" json:"description"`
|
||||
DefaultSourceScheme ParameterSourceScheme `db:"default_source_scheme" json:"default_source_scheme"`
|
||||
DefaultSourceValue string `db:"default_source_value" json:"default_source_value"`
|
||||
AllowOverrideSource bool `db:"allow_override_source" json:"allow_override_source"`
|
||||
DefaultDestinationScheme ParameterDestinationScheme `db:"default_destination_scheme" json:"default_destination_scheme"`
|
||||
AllowOverrideDestination bool `db:"allow_override_destination" json:"allow_override_destination"`
|
||||
DefaultRefresh string `db:"default_refresh" json:"default_refresh"`
|
||||
RedisplayValue bool `db:"redisplay_value" json:"redisplay_value"`
|
||||
ValidationError string `db:"validation_error" json:"validation_error"`
|
||||
ValidationCondition string `db:"validation_condition" json:"validation_condition"`
|
||||
ValidationTypeSystem ParameterTypeSystem `db:"validation_type_system" json:"validation_type_system"`
|
||||
ValidationValueType string `db:"validation_value_type" json:"validation_value_type"`
|
||||
Index int32 `db:"index" json:"index"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertParameterSchema(ctx context.Context, arg InsertParameterSchemaParams) (ParameterSchema, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertParameterSchema,
|
||||
arg.ID,
|
||||
arg.CreatedAt,
|
||||
arg.JobID,
|
||||
arg.Name,
|
||||
arg.Description,
|
||||
arg.DefaultSourceScheme,
|
||||
arg.DefaultSourceValue,
|
||||
arg.AllowOverrideSource,
|
||||
arg.DefaultDestinationScheme,
|
||||
arg.AllowOverrideDestination,
|
||||
arg.DefaultRefresh,
|
||||
arg.RedisplayValue,
|
||||
arg.ValidationError,
|
||||
arg.ValidationCondition,
|
||||
arg.ValidationTypeSystem,
|
||||
arg.ValidationValueType,
|
||||
arg.Index,
|
||||
)
|
||||
var i ParameterSchema
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.JobID,
|
||||
&i.Name,
|
||||
&i.Description,
|
||||
&i.DefaultSourceScheme,
|
||||
&i.DefaultSourceValue,
|
||||
&i.AllowOverrideSource,
|
||||
&i.DefaultDestinationScheme,
|
||||
&i.AllowOverrideDestination,
|
||||
&i.DefaultRefresh,
|
||||
&i.RedisplayValue,
|
||||
&i.ValidationError,
|
||||
&i.ValidationCondition,
|
||||
&i.ValidationTypeSystem,
|
||||
&i.ValidationValueType,
|
||||
&i.Index,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const deleteParameterValueByID = `-- name: DeleteParameterValueByID :exec
|
||||
DELETE FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) DeleteParameterValueByID(ctx context.Context, id uuid.UUID) error {
|
||||
_, err := q.db.ExecContext(ctx, deleteParameterValueByID, id)
|
||||
return err
|
||||
}
|
||||
|
||||
const getParameterValueByScopeAndName = `-- name: GetParameterValueByScopeAndName :one
|
||||
SELECT
|
||||
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
||||
FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
scope = $1
|
||||
AND scope_id = $2
|
||||
AND NAME = $3
|
||||
LIMIT
|
||||
1
|
||||
`
|
||||
|
||||
type GetParameterValueByScopeAndNameParams struct {
|
||||
Scope ParameterScope `db:"scope" json:"scope"`
|
||||
ScopeID uuid.UUID `db:"scope_id" json:"scope_id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) GetParameterValueByScopeAndName(ctx context.Context, arg GetParameterValueByScopeAndNameParams) (ParameterValue, error) {
|
||||
row := q.db.QueryRowContext(ctx, getParameterValueByScopeAndName, arg.Scope, arg.ScopeID, arg.Name)
|
||||
var i ParameterValue
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Scope,
|
||||
&i.ScopeID,
|
||||
&i.Name,
|
||||
&i.SourceScheme,
|
||||
&i.SourceValue,
|
||||
&i.DestinationScheme,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertParameterValue = `-- name: InsertParameterValue :one
|
||||
INSERT INTO
|
||||
parameter_values (
|
||||
id,
|
||||
"name",
|
||||
created_at,
|
||||
updated_at,
|
||||
scope,
|
||||
scope_id,
|
||||
source_scheme,
|
||||
source_value,
|
||||
destination_scheme
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
||||
`
|
||||
|
||||
type InsertParameterValueParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
Name string `db:"name" json:"name"`
|
||||
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 uuid.UUID `db:"scope_id" json:"scope_id"`
|
||||
SourceScheme ParameterSourceScheme `db:"source_scheme" json:"source_scheme"`
|
||||
SourceValue string `db:"source_value" json:"source_value"`
|
||||
DestinationScheme ParameterDestinationScheme `db:"destination_scheme" json:"destination_scheme"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertParameterValue(ctx context.Context, arg InsertParameterValueParams) (ParameterValue, error) {
|
||||
row := q.db.QueryRowContext(ctx, insertParameterValue,
|
||||
arg.ID,
|
||||
arg.Name,
|
||||
arg.CreatedAt,
|
||||
arg.UpdatedAt,
|
||||
arg.Scope,
|
||||
arg.ScopeID,
|
||||
arg.SourceScheme,
|
||||
arg.SourceValue,
|
||||
arg.DestinationScheme,
|
||||
)
|
||||
var i ParameterValue
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Scope,
|
||||
&i.ScopeID,
|
||||
&i.Name,
|
||||
&i.SourceScheme,
|
||||
&i.SourceValue,
|
||||
&i.DestinationScheme,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const parameterValue = `-- name: ParameterValue :one
|
||||
SELECT id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
id = $1
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) ParameterValue(ctx context.Context, id uuid.UUID) (ParameterValue, error) {
|
||||
row := q.db.QueryRowContext(ctx, parameterValue, id)
|
||||
var i ParameterValue
|
||||
err := row.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Scope,
|
||||
&i.ScopeID,
|
||||
&i.Name,
|
||||
&i.SourceScheme,
|
||||
&i.SourceValue,
|
||||
&i.DestinationScheme,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const parameterValues = `-- name: ParameterValues :many
|
||||
SELECT
|
||||
id, created_at, updated_at, scope, scope_id, name, source_scheme, source_value, destination_scheme
|
||||
FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
CASE
|
||||
WHEN cardinality($1 :: parameter_scope[]) > 0 THEN
|
||||
scope = ANY($1 :: parameter_scope[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality($2 :: uuid[]) > 0 THEN
|
||||
scope_id = ANY($2 :: uuid[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality($3 :: uuid[]) > 0 THEN
|
||||
id = ANY($3 :: uuid[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality($4 :: text[]) > 0 THEN
|
||||
"name" = ANY($4 :: text[])
|
||||
ELSE true
|
||||
END
|
||||
`
|
||||
|
||||
type ParameterValuesParams struct {
|
||||
Scopes []ParameterScope `db:"scopes" json:"scopes"`
|
||||
ScopeIds []uuid.UUID `db:"scope_ids" json:"scope_ids"`
|
||||
IDs []uuid.UUID `db:"ids" json:"ids"`
|
||||
Names []string `db:"names" json:"names"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) ParameterValues(ctx context.Context, arg ParameterValuesParams) ([]ParameterValue, error) {
|
||||
rows, err := q.db.QueryContext(ctx, parameterValues,
|
||||
pq.Array(arg.Scopes),
|
||||
pq.Array(arg.ScopeIds),
|
||||
pq.Array(arg.IDs),
|
||||
pq.Array(arg.Names),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
var items []ParameterValue
|
||||
for rows.Next() {
|
||||
var i ParameterValue
|
||||
if err := rows.Scan(
|
||||
&i.ID,
|
||||
&i.CreatedAt,
|
||||
&i.UpdatedAt,
|
||||
&i.Scope,
|
||||
&i.ScopeID,
|
||||
&i.Name,
|
||||
&i.SourceScheme,
|
||||
&i.SourceValue,
|
||||
&i.DestinationScheme,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items = append(items, i)
|
||||
}
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return items, nil
|
||||
}
|
||||
|
||||
const getProvisionerDaemons = `-- name: GetProvisionerDaemons :many
|
||||
SELECT
|
||||
id, created_at, updated_at, name, provisioners, replica_id, tags
|
||||
|
@ -7,48 +7,3 @@ WHERE
|
||||
job_id = $1
|
||||
ORDER BY
|
||||
index;
|
||||
|
||||
-- name: GetParameterSchemasCreatedAfter :many
|
||||
SELECT * FROM parameter_schemas WHERE created_at > $1;
|
||||
|
||||
-- name: InsertParameterSchema :one
|
||||
INSERT INTO
|
||||
parameter_schemas (
|
||||
id,
|
||||
created_at,
|
||||
job_id,
|
||||
"name",
|
||||
description,
|
||||
default_source_scheme,
|
||||
default_source_value,
|
||||
allow_override_source,
|
||||
default_destination_scheme,
|
||||
allow_override_destination,
|
||||
default_refresh,
|
||||
redisplay_value,
|
||||
validation_error,
|
||||
validation_condition,
|
||||
validation_type_system,
|
||||
validation_value_type,
|
||||
index
|
||||
)
|
||||
VALUES
|
||||
(
|
||||
$1,
|
||||
$2,
|
||||
$3,
|
||||
$4,
|
||||
$5,
|
||||
$6,
|
||||
$7,
|
||||
$8,
|
||||
$9,
|
||||
$10,
|
||||
$11,
|
||||
$12,
|
||||
$13,
|
||||
$14,
|
||||
$15,
|
||||
$16,
|
||||
$17
|
||||
) RETURNING *;
|
||||
|
@ -1,68 +0,0 @@
|
||||
-- name: ParameterValue :one
|
||||
SELECT * FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
|
||||
-- name: DeleteParameterValueByID :exec
|
||||
DELETE FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
id = $1;
|
||||
|
||||
-- name: ParameterValues :many
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
CASE
|
||||
WHEN cardinality(@scopes :: parameter_scope[]) > 0 THEN
|
||||
scope = ANY(@scopes :: parameter_scope[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality(@scope_ids :: uuid[]) > 0 THEN
|
||||
scope_id = ANY(@scope_ids :: uuid[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality(@ids :: uuid[]) > 0 THEN
|
||||
id = ANY(@ids :: uuid[])
|
||||
ELSE true
|
||||
END
|
||||
AND CASE
|
||||
WHEN cardinality(@names :: text[]) > 0 THEN
|
||||
"name" = ANY(@names :: text[])
|
||||
ELSE true
|
||||
END
|
||||
;
|
||||
|
||||
-- name: GetParameterValueByScopeAndName :one
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
parameter_values
|
||||
WHERE
|
||||
scope = $1
|
||||
AND scope_id = $2
|
||||
AND NAME = $3
|
||||
LIMIT
|
||||
1;
|
||||
|
||||
-- name: InsertParameterValue :one
|
||||
INSERT INTO
|
||||
parameter_values (
|
||||
id,
|
||||
"name",
|
||||
created_at,
|
||||
updated_at,
|
||||
scope,
|
||||
scope_id,
|
||||
source_scheme,
|
||||
source_value,
|
||||
destination_scheme
|
||||
)
|
||||
VALUES
|
||||
($1, $2, $3, $4, $5, $6, $7, $8, $9) RETURNING *;
|
29
coderd/deprecated.go
Normal file
29
coderd/deprecated.go
Normal file
@ -0,0 +1,29 @@
|
||||
package coderd
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
)
|
||||
|
||||
// @Summary Removed: Get parameters by template version
|
||||
// @ID removed-get-parameters-by-template-version
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Templates
|
||||
// @Param templateversion path string true "Template version ID" format(uuid)
|
||||
// @Success 200
|
||||
// @Router /templateversions/{templateversion}/parameters [get]
|
||||
func templateVersionParametersDeprecated(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(r.Context(), rw, http.StatusOK, []struct{}{})
|
||||
}
|
||||
|
||||
// @Summary Removed: Get schema by template version
|
||||
// @ID removed-get-schema-by-template-version
|
||||
// @Security CoderSessionToken
|
||||
// @Tags Templates
|
||||
// @Param templateversion path string true "Template version ID" format(uuid)
|
||||
// @Success 200
|
||||
// @Router /templateversions/{templateversion}/schema [get]
|
||||
func templateVersionSchemaDeprecated(rw http.ResponseWriter, r *http.Request) {
|
||||
httpapi.Write(r.Context(), rw, http.StatusOK, []struct{}{})
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
package parameter
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
)
|
||||
|
||||
// ComputeScope targets identifiers to pull parameters from.
|
||||
type ComputeScope struct {
|
||||
TemplateImportJobID uuid.UUID
|
||||
TemplateID uuid.NullUUID
|
||||
WorkspaceID uuid.NullUUID
|
||||
AdditionalParameterValues []database.ParameterValue
|
||||
}
|
||||
|
||||
type ComputeOptions struct {
|
||||
// HideRedisplayValues removes the value from parameters that
|
||||
// come from schemas with RedisplayValue set to false.
|
||||
HideRedisplayValues bool
|
||||
}
|
||||
|
||||
// ComputedValue represents a computed parameter value.
|
||||
type ComputedValue struct {
|
||||
database.ParameterValue
|
||||
SchemaID uuid.UUID `json:"schema_id"`
|
||||
DefaultSourceValue bool `json:"default_source_value"`
|
||||
index int32 // Track parameter schema index for sorting.
|
||||
}
|
||||
|
||||
// Compute accepts a scope in which parameter values are sourced.
|
||||
// These sources are iterated in a hierarchical fashion to determine
|
||||
// the runtime parameter values for schemas provided.
|
||||
func Compute(ctx context.Context, db database.Store, scope ComputeScope, options *ComputeOptions) ([]ComputedValue, error) {
|
||||
if options == nil {
|
||||
options = &ComputeOptions{}
|
||||
}
|
||||
compute := &compute{
|
||||
options: options,
|
||||
db: db,
|
||||
computedParameterByName: map[string]ComputedValue{},
|
||||
parameterSchemasByName: map[string]database.ParameterSchema{},
|
||||
}
|
||||
|
||||
// All parameters for the import job ID!
|
||||
parameterSchemas, err := db.GetParameterSchemasByJobID(ctx, scope.TemplateImportJobID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get template parameters: %w", err)
|
||||
}
|
||||
for _, parameterSchema := range parameterSchemas {
|
||||
compute.parameterSchemasByName[parameterSchema.Name] = parameterSchema
|
||||
}
|
||||
|
||||
// Job parameters come second!
|
||||
err = compute.injectScope(ctx, database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{database.ParameterScopeImportJob},
|
||||
ScopeIds: []uuid.UUID{scope.TemplateImportJobID},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Default template parameter values come second!
|
||||
for _, parameterSchema := range parameterSchemas {
|
||||
if parameterSchema.DefaultSourceScheme == database.ParameterSourceSchemeNone {
|
||||
continue
|
||||
}
|
||||
if _, ok := compute.computedParameterByName[parameterSchema.Name]; ok {
|
||||
// We already have a value! No need to use the default.
|
||||
continue
|
||||
}
|
||||
|
||||
switch parameterSchema.DefaultSourceScheme {
|
||||
case database.ParameterSourceSchemeData:
|
||||
// Inject a default value scoped to the import job ID.
|
||||
// This doesn't need to be inserted into the database,
|
||||
// because it's a dynamic value associated with the schema.
|
||||
err = compute.injectSingle(database.ParameterValue{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
Name: parameterSchema.Name,
|
||||
DestinationScheme: parameterSchema.DefaultDestinationScheme,
|
||||
SourceValue: parameterSchema.DefaultSourceValue,
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
ScopeID: scope.TemplateImportJobID,
|
||||
}, true)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert default value: %w", err)
|
||||
}
|
||||
default:
|
||||
return nil, xerrors.Errorf("unsupported source scheme for template version parameter %q: %q", parameterSchema.Name, string(parameterSchema.DefaultSourceScheme))
|
||||
}
|
||||
}
|
||||
|
||||
if scope.TemplateID.Valid {
|
||||
// Template parameters come third!
|
||||
err = compute.injectScope(ctx, database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{database.ParameterScopeTemplate},
|
||||
ScopeIds: []uuid.UUID{scope.TemplateID.UUID},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if scope.WorkspaceID.Valid {
|
||||
// Workspace parameters come last!
|
||||
err = compute.injectScope(ctx, database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
|
||||
ScopeIds: []uuid.UUID{scope.WorkspaceID.UUID},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, any additional parameter values declared in the input
|
||||
for _, v := range scope.AdditionalParameterValues {
|
||||
err = compute.injectSingle(v, false)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("inject single parameter value: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
values := make([]ComputedValue, 0, len(compute.computedParameterByName))
|
||||
for _, value := range compute.computedParameterByName {
|
||||
values = append(values, value)
|
||||
}
|
||||
slices.SortFunc(values, func(a, b ComputedValue) bool {
|
||||
return a.index < b.index
|
||||
})
|
||||
return values, nil
|
||||
}
|
||||
|
||||
type compute struct {
|
||||
options *ComputeOptions
|
||||
db database.Store
|
||||
computedParameterByName map[string]ComputedValue
|
||||
parameterSchemasByName map[string]database.ParameterSchema
|
||||
}
|
||||
|
||||
// Validates and computes the value for parameters; setting the value on "parameterByName".
|
||||
func (c *compute) injectScope(ctx context.Context, scopeParams database.ParameterValuesParams) error {
|
||||
scopedParameters, err := c.db.ParameterValues(ctx, scopeParams)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get %s parameters: %w", scopeParams.Scopes, err)
|
||||
}
|
||||
|
||||
for _, scopedParameter := range scopedParameters {
|
||||
err = c.injectSingle(scopedParameter, false)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("inject single %q: %w", scopedParameter.Name, err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *compute) injectSingle(scopedParameter database.ParameterValue, defaultValue bool) error {
|
||||
parameterSchema, hasParameterSchema := c.parameterSchemasByName[scopedParameter.Name]
|
||||
if !hasParameterSchema {
|
||||
// Don't inject parameters that aren't defined by the template.
|
||||
return nil
|
||||
}
|
||||
|
||||
_, hasParameterValue := c.computedParameterByName[scopedParameter.Name]
|
||||
if hasParameterValue {
|
||||
if !parameterSchema.AllowOverrideSource &&
|
||||
// Workspaces cannot override anything on a template!
|
||||
scopedParameter.Scope == database.ParameterScopeWorkspace {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
switch scopedParameter.SourceScheme {
|
||||
case database.ParameterSourceSchemeData:
|
||||
value := ComputedValue{
|
||||
ParameterValue: scopedParameter,
|
||||
SchemaID: parameterSchema.ID,
|
||||
DefaultSourceValue: defaultValue,
|
||||
index: parameterSchema.Index,
|
||||
}
|
||||
if c.options.HideRedisplayValues && !parameterSchema.RedisplayValue {
|
||||
value.SourceValue = ""
|
||||
}
|
||||
c.computedParameterByName[scopedParameter.Name] = value
|
||||
default:
|
||||
return xerrors.Errorf("unsupported source scheme: %q", string(parameterSchema.DefaultSourceScheme))
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,173 +0,0 @@
|
||||
package parameter_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/database/dbfake"
|
||||
"github.com/coder/coder/coderd/database/dbgen"
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
)
|
||||
|
||||
func TestCompute(t *testing.T) {
|
||||
t.Parallel()
|
||||
generateScope := func() parameter.ComputeScope {
|
||||
return parameter.ComputeScope{
|
||||
TemplateImportJobID: uuid.New(),
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: uuid.New(),
|
||||
Valid: true,
|
||||
},
|
||||
WorkspaceID: uuid.NullUUID{
|
||||
UUID: uuid.New(),
|
||||
Valid: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
type parameterOptions struct {
|
||||
AllowOverrideSource bool
|
||||
AllowOverrideDestination bool
|
||||
DefaultDestinationScheme database.ParameterDestinationScheme
|
||||
TemplateImportJobID uuid.UUID
|
||||
}
|
||||
generateParameter := func(t *testing.T, db database.Store, opts parameterOptions) database.ParameterSchema {
|
||||
if opts.DefaultDestinationScheme == "" {
|
||||
opts.DefaultDestinationScheme = database.ParameterDestinationSchemeEnvironmentVariable
|
||||
}
|
||||
|
||||
param := dbgen.ParameterSchema(t, db, database.ParameterSchema{
|
||||
JobID: opts.TemplateImportJobID,
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeData,
|
||||
AllowOverrideSource: opts.AllowOverrideSource,
|
||||
AllowOverrideDestination: opts.AllowOverrideDestination,
|
||||
DefaultDestinationScheme: opts.DefaultDestinationScheme,
|
||||
ValidationTypeSystem: database.ParameterTypeSystemNone,
|
||||
})
|
||||
|
||||
return param
|
||||
}
|
||||
|
||||
t.Run("NoValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
_ = dbgen.ParameterSchema(t, db, database.ParameterSchema{
|
||||
JobID: scope.TemplateImportJobID,
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
ValidationTypeSystem: database.ParameterTypeSystemNone,
|
||||
})
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 0)
|
||||
})
|
||||
|
||||
t.Run("UseDefaultTemplateValue", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 1)
|
||||
computedValue := computed[0]
|
||||
require.True(t, computedValue.DefaultSourceValue)
|
||||
require.Equal(t, database.ParameterScopeImportJob, computedValue.Scope)
|
||||
require.Equal(t, scope.TemplateImportJobID, computedValue.ScopeID)
|
||||
require.Equal(t, computedValue.SourceValue, parameterSchema.DefaultSourceValue)
|
||||
})
|
||||
|
||||
t.Run("TemplateOverridesTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
value := dbgen.ParameterValue(t, db, database.ParameterValue{
|
||||
Name: parameterSchema.Name,
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
ScopeID: scope.TemplateID.UUID,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: "nop",
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
})
|
||||
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 1)
|
||||
require.Equal(t, false, computed[0].DefaultSourceValue)
|
||||
require.Equal(t, value.SourceValue, computed[0].SourceValue)
|
||||
})
|
||||
|
||||
t.Run("WorkspaceCannotOverwriteTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
|
||||
_ = dbgen.ParameterValue(t, db, database.ParameterValue{
|
||||
Name: parameterSchema.Name,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: scope.WorkspaceID.UUID,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: "nop",
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
})
|
||||
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 1)
|
||||
require.Equal(t, true, computed[0].DefaultSourceValue)
|
||||
})
|
||||
|
||||
t.Run("WorkspaceOverwriteTemplateDefault", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
parameterSchema := generateParameter(t, db, parameterOptions{
|
||||
AllowOverrideSource: true,
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
})
|
||||
_ = dbgen.ParameterValue(t, db, database.ParameterValue{
|
||||
Name: parameterSchema.Name,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: scope.WorkspaceID.UUID,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: "nop",
|
||||
DestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
})
|
||||
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, nil)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 1)
|
||||
require.Equal(t, false, computed[0].DefaultSourceValue)
|
||||
})
|
||||
|
||||
t.Run("HideRedisplay", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
db := dbfake.New()
|
||||
scope := generateScope()
|
||||
_ = generateParameter(t, db, parameterOptions{
|
||||
TemplateImportJobID: scope.TemplateImportJobID,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
computed, err := parameter.Compute(context.Background(), db, scope, ¶meter.ComputeOptions{
|
||||
HideRedisplayValues: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, computed, 1)
|
||||
computedValue := computed[0]
|
||||
require.True(t, computedValue.DefaultSourceValue)
|
||||
require.Equal(t, computedValue.SourceValue, "")
|
||||
})
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package parameter
|
||||
|
||||
import (
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclsyntax"
|
||||
"golang.org/x/xerrors"
|
||||
)
|
||||
|
||||
// Contains parses possible values for a conditional.
|
||||
func Contains(condition string) ([]string, bool, error) {
|
||||
if condition == "" {
|
||||
return nil, false, nil
|
||||
}
|
||||
expression, diags := hclsyntax.ParseExpression([]byte(condition), "", hcl.InitialPos)
|
||||
if len(diags) > 0 {
|
||||
return nil, false, xerrors.Errorf("parse condition: %s", diags.Error())
|
||||
}
|
||||
functionCallExpression, valid := expression.(*hclsyntax.FunctionCallExpr)
|
||||
if !valid {
|
||||
return nil, false, nil
|
||||
}
|
||||
if functionCallExpression.Name != "contains" {
|
||||
return nil, false, nil
|
||||
}
|
||||
if len(functionCallExpression.Args) < 2 {
|
||||
return nil, false, nil
|
||||
}
|
||||
value, diags := functionCallExpression.Args[0].Value(&hcl.EvalContext{})
|
||||
if len(diags) > 0 {
|
||||
return nil, false, xerrors.Errorf("parse value: %s", diags.Error())
|
||||
}
|
||||
possible := make([]string, 0)
|
||||
for _, subValue := range value.AsValueSlice() {
|
||||
if subValue.Type().FriendlyName() != "string" {
|
||||
continue
|
||||
}
|
||||
possible = append(possible, subValue.AsString())
|
||||
}
|
||||
sort.Strings(possible)
|
||||
return possible, true, nil
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package parameter_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
)
|
||||
|
||||
func TestValidate(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Contains", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
values, valid, err := parameter.Contains(`contains(["us-east1-a", "us-central1-a"], var.region)`)
|
||||
require.NoError(t, err)
|
||||
require.True(t, valid)
|
||||
require.Len(t, values, 2)
|
||||
})
|
||||
}
|
@ -1,241 +0,0 @@
|
||||
package coderd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/coder/coder/coderd/database"
|
||||
"github.com/coder/coder/coderd/httpapi"
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
// @Summary Create parameter
|
||||
// @ID create-parameter
|
||||
// @Security CoderSessionToken
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Tags Parameters
|
||||
// @Param request body codersdk.CreateParameterRequest true "Parameter request"
|
||||
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
|
||||
// @Param id path string true "ID" format(uuid)
|
||||
// @Success 201 {object} codersdk.Parameter
|
||||
// @Router /parameters/{scope}/{id} [post]
|
||||
func (api *API) postParameter(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
|
||||
if !valid {
|
||||
return
|
||||
}
|
||||
|
||||
var createRequest codersdk.CreateParameterRequest
|
||||
if !httpapi.Read(ctx, rw, r, &createRequest) {
|
||||
return
|
||||
}
|
||||
_, err := api.Database.GetParameterValueByScopeAndName(ctx, database.GetParameterValueByScopeAndNameParams{
|
||||
Scope: scope,
|
||||
ScopeID: scopeID,
|
||||
Name: createRequest.Name,
|
||||
})
|
||||
if err == nil {
|
||||
httpapi.Write(ctx, rw, http.StatusConflict, codersdk.Response{
|
||||
Message: fmt.Sprintf("Parameter already exists in scope %q and name %q.", scope, createRequest.Name),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !errors.Is(err, sql.ErrNoRows) {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching parameter.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
parameterValue, err := api.Database.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: createRequest.Name,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Scope: scope,
|
||||
ScopeID: scopeID,
|
||||
SourceScheme: database.ParameterSourceScheme(createRequest.SourceScheme),
|
||||
SourceValue: createRequest.SourceValue,
|
||||
DestinationScheme: database.ParameterDestinationScheme(createRequest.DestinationScheme),
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error inserting parameter.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, convertParameterValue(parameterValue))
|
||||
}
|
||||
|
||||
// @Summary Get parameters
|
||||
// @ID get-parameters
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Parameters
|
||||
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
|
||||
// @Param id path string true "ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.Parameter
|
||||
// @Router /parameters/{scope}/{id} [get]
|
||||
func (api *API) parameters(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
|
||||
if !valid {
|
||||
return
|
||||
}
|
||||
|
||||
parameterValues, err := api.Database.ParameterValues(ctx, database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{scope},
|
||||
ScopeIds: []uuid.UUID{scopeID},
|
||||
})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching parameter scope values.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
apiParameterValues := make([]codersdk.Parameter, 0, len(parameterValues))
|
||||
for _, parameterValue := range parameterValues {
|
||||
apiParameterValues = append(apiParameterValues, convertParameterValue(parameterValue))
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, apiParameterValues)
|
||||
}
|
||||
|
||||
// @Summary Delete parameter
|
||||
// @ID delete-parameter
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Parameters
|
||||
// @Param scope path string true "Scope" Enums(template,workspace,import_job)
|
||||
// @Param id path string true "ID" format(uuid)
|
||||
// @Param name path string true "Name"
|
||||
// @Success 200 {object} codersdk.Response
|
||||
// @Router /parameters/{scope}/{id}/{name} [delete]
|
||||
func (api *API) deleteParameter(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
scope, scopeID, valid := readScopeAndID(ctx, rw, r)
|
||||
if !valid {
|
||||
return
|
||||
}
|
||||
|
||||
name := chi.URLParam(r, "name")
|
||||
parameterValue, err := api.Database.GetParameterValueByScopeAndName(ctx, database.GetParameterValueByScopeAndNameParams{
|
||||
Scope: scope,
|
||||
ScopeID: scopeID,
|
||||
Name: name,
|
||||
})
|
||||
if httpapi.Is404Error(err) {
|
||||
httpapi.ResourceNotFound(rw)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching parameter.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
err = api.Database.DeleteParameterValueByID(ctx, parameterValue.ID)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error deleting parameter.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
httpapi.Write(ctx, rw, http.StatusOK, codersdk.Response{
|
||||
Message: "Parameter deleted.",
|
||||
})
|
||||
}
|
||||
|
||||
func convertParameterSchema(parameterSchema database.ParameterSchema) (codersdk.ParameterSchema, error) {
|
||||
contains := []string{}
|
||||
if parameterSchema.ValidationCondition != "" {
|
||||
var err error
|
||||
contains, _, err = parameter.Contains(parameterSchema.ValidationCondition)
|
||||
if err != nil {
|
||||
return codersdk.ParameterSchema{}, xerrors.Errorf("parse validation condition for %q: %w", parameterSchema.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
return codersdk.ParameterSchema{
|
||||
ID: parameterSchema.ID,
|
||||
CreatedAt: parameterSchema.CreatedAt,
|
||||
JobID: parameterSchema.JobID,
|
||||
Name: parameterSchema.Name,
|
||||
Description: parameterSchema.Description,
|
||||
DefaultSourceScheme: codersdk.ParameterSourceScheme(parameterSchema.DefaultSourceScheme),
|
||||
DefaultSourceValue: parameterSchema.DefaultSourceValue,
|
||||
AllowOverrideSource: parameterSchema.AllowOverrideSource,
|
||||
DefaultDestinationScheme: codersdk.ParameterDestinationScheme(parameterSchema.DefaultDestinationScheme),
|
||||
AllowOverrideDestination: parameterSchema.AllowOverrideDestination,
|
||||
DefaultRefresh: parameterSchema.DefaultRefresh,
|
||||
RedisplayValue: parameterSchema.RedisplayValue,
|
||||
ValidationError: parameterSchema.ValidationError,
|
||||
ValidationCondition: parameterSchema.ValidationCondition,
|
||||
ValidationTypeSystem: string(parameterSchema.ValidationTypeSystem),
|
||||
ValidationValueType: parameterSchema.ValidationValueType,
|
||||
ValidationContains: contains,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertParameterValue(parameterValue database.ParameterValue) codersdk.Parameter {
|
||||
return codersdk.Parameter{
|
||||
ID: parameterValue.ID,
|
||||
CreatedAt: parameterValue.CreatedAt,
|
||||
UpdatedAt: parameterValue.UpdatedAt,
|
||||
Scope: codersdk.ParameterScope(parameterValue.Scope),
|
||||
ScopeID: parameterValue.ScopeID,
|
||||
Name: parameterValue.Name,
|
||||
SourceScheme: codersdk.ParameterSourceScheme(parameterValue.SourceScheme),
|
||||
DestinationScheme: codersdk.ParameterDestinationScheme(parameterValue.DestinationScheme),
|
||||
SourceValue: parameterValue.SourceValue,
|
||||
}
|
||||
}
|
||||
|
||||
func readScopeAndID(ctx context.Context, rw http.ResponseWriter, r *http.Request) (database.ParameterScope, uuid.UUID, bool) {
|
||||
scope := database.ParameterScope(chi.URLParam(r, "scope"))
|
||||
switch scope {
|
||||
case database.ParameterScopeTemplate, database.ParameterScopeImportJob, database.ParameterScopeWorkspace:
|
||||
default:
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: fmt.Sprintf("Invalid scope %q.", scope),
|
||||
Validations: []codersdk.ValidationError{
|
||||
{Field: "scope", Detail: "invalid scope"},
|
||||
},
|
||||
})
|
||||
return scope, uuid.Nil, false
|
||||
}
|
||||
|
||||
id := chi.URLParam(r, "id")
|
||||
uid, err := uuid.Parse(id)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: fmt.Sprintf("Invalid UUID %q.", id),
|
||||
Detail: err.Error(),
|
||||
Validations: []codersdk.ValidationError{
|
||||
{Field: "id", Detail: "Invalid UUID"},
|
||||
},
|
||||
})
|
||||
return scope, uuid.Nil, false
|
||||
}
|
||||
|
||||
return scope, uid, true
|
||||
}
|
@ -1,181 +0,0 @@
|
||||
package coderd_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/coder/coder/provisioner/echo"
|
||||
"github.com/coder/coder/provisionersdk/proto"
|
||||
"github.com/coder/coder/testutil"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/coder/coder/coderd/coderdtest"
|
||||
"github.com/coder/coder/codersdk"
|
||||
)
|
||||
|
||||
func TestPostParameter(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("BadScope", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.CreateParameter(ctx, codersdk.ParameterScope("something"), user.OrganizationID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
})
|
||||
|
||||
t.Run("Create", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("AlreadyExists", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusConflict, apiErr.StatusCode())
|
||||
})
|
||||
}
|
||||
|
||||
func TestParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListEmpty", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.Parameters(ctx, codersdk.ParameterTemplate, template.ID)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
params, err := client.Parameters(ctx, codersdk.ParameterTemplate, template.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, params, 1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestDeleteParameter(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("NotExist", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
err := client.DeleteParameter(ctx, codersdk.ParameterTemplate, template.ID, "something")
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusNotFound, apiErr.StatusCode())
|
||||
})
|
||||
t.Run("Delete", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
template := createTemplate(t, client, user)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
param, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{
|
||||
Name: "example",
|
||||
SourceValue: "tomato",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
err = client.DeleteParameter(ctx, codersdk.ParameterTemplate, template.ID, param.Name)
|
||||
require.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func createTemplate(t *testing.T, client *codersdk.Client, user codersdk.CreateFirstUserResponse) codersdk.Template {
|
||||
instanceID := "instanceidentifier"
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionApply: []*proto.Provision_Response{{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
Complete: &proto.Provision_Complete{
|
||||
Resources: []*proto.Resource{{
|
||||
Name: "somename",
|
||||
Type: "someinstance",
|
||||
Agents: []*proto.Agent{{
|
||||
Auth: &proto.Agent_InstanceId{
|
||||
InstanceId: instanceID,
|
||||
},
|
||||
}},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
})
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
return template
|
||||
}
|
@ -33,7 +33,6 @@ import (
|
||||
"github.com/coder/coder/coderd/database/dbauthz"
|
||||
"github.com/coder/coder/coderd/gitauth"
|
||||
"github.com/coder/coder/coderd/httpmw"
|
||||
"github.com/coder/coder/coderd/parameter"
|
||||
"github.com/coder/coder/coderd/schedule"
|
||||
"github.com/coder/coder/coderd/telemetry"
|
||||
"github.com/coder/coder/coderd/tracing"
|
||||
@ -209,27 +208,6 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
|
||||
}
|
||||
}
|
||||
|
||||
// Compute parameters for the workspace to consume.
|
||||
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
|
||||
TemplateImportJobID: templateVersion.JobID,
|
||||
TemplateID: uuid.NullUUID{
|
||||
UUID: template.ID,
|
||||
Valid: true,
|
||||
},
|
||||
WorkspaceID: uuid.NullUUID{
|
||||
UUID: workspace.ID,
|
||||
Valid: true,
|
||||
},
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("compute parameters: %s", err))
|
||||
}
|
||||
|
||||
// Convert types to their corresponding protobuf types.
|
||||
protoParameters, err := convertComputedParameterValues(parameters)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("convert computed parameters to protobuf: %s", err))
|
||||
}
|
||||
transition, err := convertWorkspaceTransition(workspaceBuild.Transition)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("convert workspace transition: %s", err))
|
||||
@ -287,7 +265,6 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
|
||||
WorkspaceBuildId: workspaceBuild.ID.String(),
|
||||
WorkspaceName: workspace.Name,
|
||||
State: workspaceBuild.ProvisionerState,
|
||||
ParameterValues: protoParameters,
|
||||
RichParameterValues: convertRichParameterValues(workspaceBuildParameters),
|
||||
VariableValues: asVariableValues(templateVariables),
|
||||
GitAuthProviders: gitAuthProviders,
|
||||
@ -323,26 +300,8 @@ func (server *Server) AcquireJob(ctx context.Context, _ *proto.Empty) (*proto.Ac
|
||||
return nil, failJob(fmt.Sprintf("get template version variables: %s", err))
|
||||
}
|
||||
|
||||
// Compute parameters for the dry-run to consume.
|
||||
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
|
||||
TemplateImportJobID: templateVersion.JobID,
|
||||
TemplateID: templateVersion.TemplateID,
|
||||
WorkspaceID: uuid.NullUUID{},
|
||||
AdditionalParameterValues: input.ParameterValues,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("compute parameters: %s", err))
|
||||
}
|
||||
|
||||
// Convert types to their corresponding protobuf types.
|
||||
protoParameters, err := convertComputedParameterValues(parameters)
|
||||
if err != nil {
|
||||
return nil, failJob(fmt.Sprintf("convert computed parameters to protobuf: %s", err))
|
||||
}
|
||||
|
||||
protoJob.Type = &proto.AcquiredJob_TemplateDryRun_{
|
||||
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
|
||||
ParameterValues: protoParameters,
|
||||
RichParameterValues: convertRichParameterValues(input.RichParameterValues),
|
||||
VariableValues: asVariableValues(templateVariables),
|
||||
Metadata: &sdkproto.Provision_Metadata{
|
||||
@ -617,91 +576,6 @@ func (server *Server) UpdateJob(ctx context.Context, request *proto.UpdateJobReq
|
||||
}, nil
|
||||
}
|
||||
|
||||
if len(request.ParameterSchemas) > 0 {
|
||||
for index, protoParameter := range request.ParameterSchemas {
|
||||
validationTypeSystem, err := convertValidationTypeSystem(protoParameter.ValidationTypeSystem)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("convert validation type system for %q: %w", protoParameter.Name, err)
|
||||
}
|
||||
|
||||
parameterSchema := database.InsertParameterSchemaParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: database.Now(),
|
||||
JobID: job.ID,
|
||||
Name: protoParameter.Name,
|
||||
Description: protoParameter.Description,
|
||||
RedisplayValue: protoParameter.RedisplayValue,
|
||||
ValidationError: protoParameter.ValidationError,
|
||||
ValidationCondition: protoParameter.ValidationCondition,
|
||||
ValidationValueType: protoParameter.ValidationValueType,
|
||||
ValidationTypeSystem: validationTypeSystem,
|
||||
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
|
||||
AllowOverrideDestination: protoParameter.AllowOverrideDestination,
|
||||
AllowOverrideSource: protoParameter.AllowOverrideSource,
|
||||
|
||||
Index: int32(index),
|
||||
}
|
||||
|
||||
// It's possible a parameter doesn't define a default source!
|
||||
if protoParameter.DefaultSource != nil {
|
||||
parameterSourceScheme, err := convertParameterSourceScheme(protoParameter.DefaultSource.Scheme)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("convert parameter source scheme: %w", err)
|
||||
}
|
||||
parameterSchema.DefaultSourceScheme = parameterSourceScheme
|
||||
parameterSchema.DefaultSourceValue = protoParameter.DefaultSource.Value
|
||||
}
|
||||
|
||||
// It's possible a parameter doesn't define a default destination!
|
||||
if protoParameter.DefaultDestination != nil {
|
||||
parameterDestinationScheme, err := convertParameterDestinationScheme(protoParameter.DefaultDestination.Scheme)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("convert parameter destination scheme: %w", err)
|
||||
}
|
||||
parameterSchema.DefaultDestinationScheme = parameterDestinationScheme
|
||||
}
|
||||
|
||||
_, err = server.Database.InsertParameterSchema(ctx, parameterSchema)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert parameter schema: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
var templateID uuid.NullUUID
|
||||
if job.Type == database.ProvisionerJobTypeTemplateVersionImport {
|
||||
templateVersion, err := server.Database.GetTemplateVersionByJobID(ctx, job.ID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("get template version by job id: %w", err)
|
||||
}
|
||||
templateID = templateVersion.TemplateID
|
||||
}
|
||||
|
||||
parameters, err := parameter.Compute(ctx, server.Database, parameter.ComputeScope{
|
||||
TemplateImportJobID: job.ID,
|
||||
TemplateID: templateID,
|
||||
}, nil)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("compute parameters: %w", err)
|
||||
}
|
||||
// Convert parameters to the protobuf type.
|
||||
protoParameters := make([]*sdkproto.ParameterValue, 0, len(parameters))
|
||||
for _, computedParameter := range parameters {
|
||||
converted, err := convertComputedParameterValue(computedParameter)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("convert parameter: %s", err)
|
||||
}
|
||||
protoParameters = append(protoParameters, converted)
|
||||
}
|
||||
|
||||
return &proto.UpdateJobResponse{
|
||||
Canceled: job.CanceledAt.Valid,
|
||||
ParameterValues: protoParameters,
|
||||
}, nil
|
||||
}
|
||||
|
||||
return &proto.UpdateJobResponse{
|
||||
Canceled: job.CanceledAt.Valid,
|
||||
}, nil
|
||||
@ -1545,37 +1419,6 @@ func obtainOIDCAccessToken(ctx context.Context, db database.Store, oidcConfig ht
|
||||
return link.OAuthAccessToken, nil
|
||||
}
|
||||
|
||||
func convertValidationTypeSystem(typeSystem sdkproto.ParameterSchema_TypeSystem) (database.ParameterTypeSystem, error) {
|
||||
switch typeSystem {
|
||||
case sdkproto.ParameterSchema_None:
|
||||
return database.ParameterTypeSystemNone, nil
|
||||
case sdkproto.ParameterSchema_HCL:
|
||||
return database.ParameterTypeSystemHCL, nil
|
||||
default:
|
||||
return database.ParameterTypeSystem(""), xerrors.Errorf("unknown type system: %d", typeSystem)
|
||||
}
|
||||
}
|
||||
|
||||
func convertParameterSourceScheme(sourceScheme sdkproto.ParameterSource_Scheme) (database.ParameterSourceScheme, error) {
|
||||
switch sourceScheme {
|
||||
case sdkproto.ParameterSource_DATA:
|
||||
return database.ParameterSourceSchemeData, nil
|
||||
default:
|
||||
return database.ParameterSourceScheme(""), xerrors.Errorf("unknown parameter source scheme: %d", sourceScheme)
|
||||
}
|
||||
}
|
||||
|
||||
func convertParameterDestinationScheme(destinationScheme sdkproto.ParameterDestination_Scheme) (database.ParameterDestinationScheme, error) {
|
||||
switch destinationScheme {
|
||||
case sdkproto.ParameterDestination_ENVIRONMENT_VARIABLE:
|
||||
return database.ParameterDestinationSchemeEnvironmentVariable, nil
|
||||
case sdkproto.ParameterDestination_PROVISIONER_VARIABLE:
|
||||
return database.ParameterDestinationSchemeProvisionerVariable, nil
|
||||
default:
|
||||
return database.ParameterDestinationScheme(""), xerrors.Errorf("unknown parameter destination scheme: %d", destinationScheme)
|
||||
}
|
||||
}
|
||||
|
||||
func convertLogLevel(logLevel sdkproto.LogLevel) (database.LogLevel, error) {
|
||||
switch logLevel {
|
||||
case sdkproto.LogLevel_TRACE:
|
||||
@ -1627,37 +1470,6 @@ func convertVariableValues(variableValues []codersdk.VariableValue) []*sdkproto.
|
||||
return protoVariableValues
|
||||
}
|
||||
|
||||
func convertComputedParameterValues(parameters []parameter.ComputedValue) ([]*sdkproto.ParameterValue, error) {
|
||||
protoParameters := make([]*sdkproto.ParameterValue, len(parameters))
|
||||
for i, computedParameter := range parameters {
|
||||
converted, err := convertComputedParameterValue(computedParameter)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("convert parameter: %w", err)
|
||||
}
|
||||
protoParameters[i] = converted
|
||||
}
|
||||
|
||||
return protoParameters, nil
|
||||
}
|
||||
|
||||
func convertComputedParameterValue(param parameter.ComputedValue) (*sdkproto.ParameterValue, error) {
|
||||
var scheme sdkproto.ParameterDestination_Scheme
|
||||
switch param.DestinationScheme {
|
||||
case database.ParameterDestinationSchemeEnvironmentVariable:
|
||||
scheme = sdkproto.ParameterDestination_ENVIRONMENT_VARIABLE
|
||||
case database.ParameterDestinationSchemeProvisionerVariable:
|
||||
scheme = sdkproto.ParameterDestination_PROVISIONER_VARIABLE
|
||||
default:
|
||||
return nil, xerrors.Errorf("unrecognized destination scheme: %q", param.DestinationScheme)
|
||||
}
|
||||
|
||||
return &sdkproto.ParameterValue{
|
||||
DestinationScheme: scheme,
|
||||
Name: param.Name,
|
||||
Value: param.SourceValue,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func convertWorkspaceTransition(transition database.WorkspaceTransition) (sdkproto.WorkspaceTransition, error) {
|
||||
switch transition {
|
||||
case database.WorkspaceTransitionStart:
|
||||
@ -1700,7 +1512,6 @@ type WorkspaceProvisionJob struct {
|
||||
type TemplateVersionDryRunJob struct {
|
||||
TemplateVersionID uuid.UUID `json:"template_version_id"`
|
||||
WorkspaceName string `json:"workspace_name"`
|
||||
ParameterValues []database.ParameterValue `json:"parameter_values"`
|
||||
RichParameterValues []database.WorkspaceBuildParameter `json:"rich_parameter_values"`
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,6 @@ func TestAcquireJob(t *testing.T) {
|
||||
WorkspaceBuild: &proto.AcquiredJob_WorkspaceBuild{
|
||||
WorkspaceBuildId: build.ID.String(),
|
||||
WorkspaceName: workspace.Name,
|
||||
ParameterValues: []*sdkproto.ParameterValue{},
|
||||
VariableValues: []*sdkproto.VariableValue{
|
||||
{
|
||||
Name: "first",
|
||||
@ -339,7 +338,6 @@ func TestAcquireJob(t *testing.T) {
|
||||
Input: must(json.Marshal(provisionerdserver.TemplateVersionDryRunJob{
|
||||
TemplateVersionID: version.ID,
|
||||
WorkspaceName: "testing",
|
||||
ParameterValues: []database.ParameterValue{},
|
||||
})),
|
||||
})
|
||||
|
||||
@ -351,7 +349,6 @@ func TestAcquireJob(t *testing.T) {
|
||||
|
||||
want, err := json.Marshal(&proto.AcquiredJob_TemplateDryRun_{
|
||||
TemplateDryRun: &proto.AcquiredJob_TemplateDryRun{
|
||||
ParameterValues: []*sdkproto.ParameterValue{},
|
||||
Metadata: &sdkproto.Provision_Metadata{
|
||||
CoderUrl: srv.AccessURL.String(),
|
||||
WorkspaceName: "testing",
|
||||
|
@ -308,22 +308,6 @@ func (r *remoteReporter) createSnapshot() (*Snapshot, error) {
|
||||
}
|
||||
return nil
|
||||
})
|
||||
eg.Go(func() error {
|
||||
schemas, err := r.options.Database.GetParameterSchemasCreatedAfter(ctx, createdAfter)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get parameter schemas: %w", err)
|
||||
}
|
||||
snapshot.ParameterSchemas = make([]ParameterSchema, 0, len(schemas))
|
||||
for _, schema := range schemas {
|
||||
snapshot.ParameterSchemas = append(snapshot.ParameterSchemas, ParameterSchema{
|
||||
ID: schema.ID,
|
||||
JobID: schema.JobID,
|
||||
Name: schema.Name,
|
||||
ValidationCondition: schema.ValidationCondition,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
})
|
||||
eg.Go(func() error {
|
||||
jobs, err := r.options.Database.GetProvisionerJobsCreatedAfter(ctx, createdAfter)
|
||||
if err != nil {
|
||||
@ -688,7 +672,6 @@ type Snapshot struct {
|
||||
DeploymentID string `json:"deployment_id"`
|
||||
|
||||
APIKeys []APIKey `json:"api_keys"`
|
||||
ParameterSchemas []ParameterSchema `json:"parameter_schemas"`
|
||||
ProvisionerJobs []ProvisionerJob `json:"provisioner_jobs"`
|
||||
Licenses []License `json:"licenses"`
|
||||
Templates []Template `json:"templates"`
|
||||
|
@ -39,11 +39,6 @@ func TestTelemetry(t *testing.T) {
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitMedium)
|
||||
_, _ = dbgen.APIKey(t, db, database.APIKey{})
|
||||
_ = dbgen.ParameterSchema(t, db, database.ParameterSchema{
|
||||
DefaultSourceScheme: database.ParameterSourceSchemeNone,
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeNone,
|
||||
ValidationTypeSystem: database.ParameterTypeSystemNone,
|
||||
})
|
||||
_ = dbgen.ProvisionerJob(t, db, database.ProvisionerJob{
|
||||
Provisioner: database.ProvisionerTypeTerraform,
|
||||
StorageMethod: database.ProvisionerStorageMethodFile,
|
||||
@ -87,7 +82,6 @@ func TestTelemetry(t *testing.T) {
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
_, snapshot := collectSnapshot(t, db)
|
||||
require.Len(t, snapshot.ParameterSchemas, 1)
|
||||
require.Len(t, snapshot.ProvisionerJobs, 1)
|
||||
require.Len(t, snapshot.Licenses, 1)
|
||||
require.Len(t, snapshot.Templates, 1)
|
||||
|
@ -334,23 +334,6 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque
|
||||
}
|
||||
templateVersionAudit.New = newTemplateVersion
|
||||
|
||||
for _, parameterValue := range createTemplate.ParameterValues {
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Scope: database.ParameterScopeTemplate,
|
||||
ScopeID: template.ID,
|
||||
SourceScheme: database.ParameterSourceScheme(parameterValue.SourceScheme),
|
||||
SourceValue: parameterValue.SourceValue,
|
||||
DestinationScheme: database.ParameterDestinationScheme(parameterValue.DestinationScheme),
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert parameter value: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, tx, []database.Template{dbTemplate})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("get creator name: %w", err)
|
||||
|
@ -74,7 +74,12 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
|
||||
var warnings []codersdk.TemplateVersionWarning
|
||||
if len(schemas) > 0 {
|
||||
warnings = append(warnings, codersdk.TemplateVersionWarningUnsupportedWorkspaces)
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, warnings))
|
||||
}
|
||||
|
||||
// @Summary Patch template version by ID
|
||||
@ -168,19 +173,7 @@ func (api *API) patchTemplateVersion(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, schemas))
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(updatedTemplateVersion, convertProvisionerJob(job), user, nil))
|
||||
}
|
||||
|
||||
// @Summary Cancel template version by ID
|
||||
@ -239,58 +232,6 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Get schema by template version
|
||||
// @ID get-schema-by-template-version
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Templates
|
||||
// @Param templateversion path string true "Template version ID" format(uuid)
|
||||
// @Success 200 {array} codersdk.ParameterSchema
|
||||
// @Router /templateversions/{templateversion}/schema [get]
|
||||
func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
|
||||
job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching provisioner job.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !job.CompletedAt.Valid {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Template version job hasn't completed!",
|
||||
})
|
||||
return
|
||||
}
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
apiSchemas := make([]codersdk.ParameterSchema, 0)
|
||||
for _, schema := range schemas {
|
||||
apiSchema, err := convertParameterSchema(schema)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: fmt.Sprintf("Internal error converting schema %s.", schema.Name),
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
apiSchemas = append(apiSchemas, apiSchema)
|
||||
}
|
||||
httpapi.Write(ctx, rw, http.StatusOK, apiSchemas)
|
||||
}
|
||||
|
||||
// @Summary Get rich parameters by template version
|
||||
// @ID get-rich-parameters-by-template-version
|
||||
// @Security CoderSessionToken
|
||||
@ -470,52 +411,6 @@ func (api *API) templateVersionVariables(rw http.ResponseWriter, r *http.Request
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersionVariables(dbTemplateVersionVariables))
|
||||
}
|
||||
|
||||
// @Summary Get parameters by template version
|
||||
// @ID get-parameters-by-template-version
|
||||
// @Security CoderSessionToken
|
||||
// @Produce json
|
||||
// @Tags Templates
|
||||
// @Param templateversion path string true "Template version ID" format(uuid)
|
||||
// @Success 200 {array} parameter.ComputedValue
|
||||
// @Router /templateversions/{templateversion}/parameters [get]
|
||||
func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
templateVersion := httpmw.TemplateVersionParam(r)
|
||||
|
||||
job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error fetching provisioner job.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if !job.CompletedAt.Valid {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Job hasn't completed!",
|
||||
})
|
||||
return
|
||||
}
|
||||
values, err := parameter.Compute(ctx, api.Database, parameter.ComputeScope{
|
||||
TemplateImportJobID: job.ID,
|
||||
}, ¶meter.ComputeOptions{
|
||||
// We *never* want to send the client secret parameter values.
|
||||
HideRedisplayValues: true,
|
||||
})
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error computing values.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
if values == nil {
|
||||
values = []parameter.ComputedValue{}
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, values)
|
||||
}
|
||||
|
||||
// @Summary Create template version dry-run
|
||||
// @ID create-template-version-dry-run
|
||||
// @Security CoderSessionToken
|
||||
@ -561,20 +456,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
|
||||
return
|
||||
}
|
||||
|
||||
// Convert parameters from request to parameters for the job
|
||||
parameterValues := make([]database.ParameterValue, len(req.ParameterValues))
|
||||
for i, v := range req.ParameterValues {
|
||||
parameterValues[i] = database.ParameterValue{
|
||||
ID: uuid.Nil,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: uuid.Nil,
|
||||
Name: v.Name,
|
||||
SourceScheme: database.ParameterSourceSchemeData,
|
||||
SourceValue: v.SourceValue,
|
||||
DestinationScheme: database.ParameterDestinationSchemeProvisionerVariable,
|
||||
}
|
||||
}
|
||||
|
||||
richParameterValues := make([]database.WorkspaceBuildParameter, len(req.RichParameterValues))
|
||||
for i, v := range req.RichParameterValues {
|
||||
richParameterValues[i] = database.WorkspaceBuildParameter{
|
||||
@ -589,7 +470,6 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques
|
||||
input, err := json.Marshal(provisionerdserver.TemplateVersionDryRunJob{
|
||||
TemplateVersionID: templateVersion.ID,
|
||||
WorkspaceName: req.WorkspaceName,
|
||||
ParameterValues: parameterValues,
|
||||
RichParameterValues: richParameterValues,
|
||||
})
|
||||
if err != nil {
|
||||
@ -911,18 +791,7 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque
|
||||
})
|
||||
return err
|
||||
}
|
||||
schemas, err := store.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return err
|
||||
}
|
||||
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, schemas))
|
||||
apiVersions = append(apiVersions, convertTemplateVersion(version, convertProvisionerJob(job), user, nil))
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -986,19 +855,7 @@ func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
|
||||
}
|
||||
|
||||
// @Summary Get template version by organization, template, and name
|
||||
@ -1072,19 +929,7 @@ func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWri
|
||||
return
|
||||
}
|
||||
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, schemas))
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(templateVersion, convertProvisionerJob(job), user, nil))
|
||||
}
|
||||
|
||||
// @Summary Get previous template version by organization, template, and name
|
||||
@ -1179,19 +1024,7 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res
|
||||
return
|
||||
}
|
||||
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, job.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, schemas))
|
||||
httpapi.Write(ctx, rw, http.StatusOK, convertTemplateVersion(previousTemplateVersion, convertProvisionerJob(job), user, nil))
|
||||
}
|
||||
|
||||
// @Summary Update active template version by template ID
|
||||
@ -1423,68 +1256,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
var provisionerJob database.ProvisionerJob
|
||||
err = api.Database.InTx(func(tx database.Store) error {
|
||||
jobID := uuid.New()
|
||||
inherits := make([]uuid.UUID, 0)
|
||||
for _, parameterValue := range req.ParameterValues {
|
||||
if parameterValue.CloneID != uuid.Nil {
|
||||
inherits = append(inherits, parameterValue.CloneID)
|
||||
}
|
||||
}
|
||||
|
||||
// Expand inherited params
|
||||
if len(inherits) > 0 {
|
||||
if req.TemplateID == uuid.Nil {
|
||||
return xerrors.Errorf("cannot inherit parameters if template_id is not set")
|
||||
}
|
||||
|
||||
inheritedParams, err := tx.ParameterValues(ctx, database.ParameterValuesParams{
|
||||
IDs: inherits,
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fetch inherited params: %w", err)
|
||||
}
|
||||
for _, copy := range inheritedParams {
|
||||
// This is a bit inefficient, as we make a new db call for each
|
||||
// param.
|
||||
version, err := tx.GetTemplateVersionByJobID(ctx, copy.ScopeID)
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fetch template version for param %q: %w", copy.Name, err)
|
||||
}
|
||||
if !version.TemplateID.Valid || version.TemplateID.UUID != req.TemplateID {
|
||||
return xerrors.Errorf("cannot inherit parameters from other templates")
|
||||
}
|
||||
if copy.Scope != database.ParameterScopeImportJob {
|
||||
return xerrors.Errorf("copy parameter scope is %q, must be %q", copy.Scope, database.ParameterScopeImportJob)
|
||||
}
|
||||
// Add the copied param to the list to process
|
||||
req.ParameterValues = append(req.ParameterValues, codersdk.CreateParameterRequest{
|
||||
Name: copy.Name,
|
||||
SourceValue: copy.SourceValue,
|
||||
SourceScheme: codersdk.ParameterSourceScheme(copy.SourceScheme),
|
||||
DestinationScheme: codersdk.ParameterDestinationScheme(copy.DestinationScheme),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for _, parameterValue := range req.ParameterValues {
|
||||
if parameterValue.CloneID != uuid.Nil {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = tx.InsertParameterValue(ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: parameterValue.Name,
|
||||
CreatedAt: database.Now(),
|
||||
UpdatedAt: database.Now(),
|
||||
Scope: database.ParameterScopeImportJob,
|
||||
ScopeID: jobID,
|
||||
SourceScheme: database.ParameterSourceScheme(parameterValue.SourceScheme),
|
||||
SourceValue: parameterValue.SourceValue,
|
||||
DestinationScheme: database.ParameterDestinationScheme(parameterValue.DestinationScheme),
|
||||
})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("insert parameter value: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
templateVersionID := uuid.New()
|
||||
jobInput, err := json.Marshal(provisionerdserver.TemplateVersionImportJob{
|
||||
@ -1565,19 +1336,7 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht
|
||||
return
|
||||
}
|
||||
|
||||
schemas, err := api.Database.GetParameterSchemasByJobID(ctx, provisionerJob.ID)
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Internal error listing parameter schemas.",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, schemas))
|
||||
httpapi.Write(ctx, rw, http.StatusCreated, convertTemplateVersion(templateVersion, convertProvisionerJob(provisionerJob), user, nil))
|
||||
}
|
||||
|
||||
// templateVersionResources returns the workspace agent resources associated
|
||||
@ -1644,7 +1403,7 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) {
|
||||
api.provisionerJobLogs(rw, r, job)
|
||||
}
|
||||
|
||||
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, schemas []database.ParameterSchema) codersdk.TemplateVersion {
|
||||
func convertTemplateVersion(version database.TemplateVersion, job codersdk.ProvisionerJob, user database.User, warnings []codersdk.TemplateVersionWarning) codersdk.TemplateVersion {
|
||||
createdBy := codersdk.User{
|
||||
ID: user.ID,
|
||||
Username: user.Username,
|
||||
@ -1655,11 +1414,6 @@ func convertTemplateVersion(version database.TemplateVersion, job codersdk.Provi
|
||||
AvatarURL: user.AvatarURL.String,
|
||||
}
|
||||
|
||||
var warnings []codersdk.TemplateVersionWarning
|
||||
if len(schemas) > 0 {
|
||||
warnings = append(warnings, codersdk.TemplateVersionWarningDeprecatedParameters)
|
||||
}
|
||||
|
||||
return codersdk.TemplateVersion{
|
||||
ID: version.ID,
|
||||
TemplateID: &version.TemplateID.UUID,
|
||||
|
@ -124,12 +124,6 @@ func TestPostTemplateVersionsByOrganization(t *testing.T) {
|
||||
StorageMethod: codersdk.ProvisionerStorageMethodFile,
|
||||
FileID: file.ID,
|
||||
Provisioner: codersdk.ProvisionerTypeEcho,
|
||||
ParameterValues: []codersdk.CreateParameterRequest{{
|
||||
Name: "example",
|
||||
SourceValue: "value",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable,
|
||||
}},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "bananas", version.Name)
|
||||
@ -296,153 +290,6 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionSchema(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListRunning", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.TemplateVersionSchema(ctx, version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
})
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{{
|
||||
Name: "example",
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
schemas, err := client.TemplateVersionSchema(ctx, version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, schemas)
|
||||
require.Len(t, schemas, 1)
|
||||
})
|
||||
t.Run("ListContains", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{{
|
||||
Name: "example",
|
||||
ValidationTypeSystem: proto.ParameterSchema_HCL,
|
||||
ValidationValueType: "string",
|
||||
ValidationCondition: `contains(["first", "second"], var.example)`,
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
}},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
schemas, err := client.TemplateVersionSchema(ctx, version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, schemas)
|
||||
require.Len(t, schemas, 1)
|
||||
require.Equal(t, []string{"first", "second"}, schemas[0].ValidationContains)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("ListRunning", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, nil)
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.TemplateVersionParameters(ctx, version.ID)
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
})
|
||||
t.Run("List", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{
|
||||
{
|
||||
Name: "example",
|
||||
RedisplayValue: true,
|
||||
DefaultSource: &proto.ParameterSource{
|
||||
Scheme: proto.ParameterSource_DATA,
|
||||
Value: "hello",
|
||||
},
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "abcd",
|
||||
RedisplayValue: true,
|
||||
DefaultSource: &proto.ParameterSource{
|
||||
Scheme: proto.ParameterSource_DATA,
|
||||
Value: "world",
|
||||
},
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
params, err := client.TemplateVersionParameters(ctx, version.ID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, params)
|
||||
require.Len(t, params, 2)
|
||||
require.Equal(t, "hello", params[0].SourceValue)
|
||||
require.Equal(t, "world", params[1].SourceValue)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionsGitAuth(t *testing.T) {
|
||||
t.Parallel()
|
||||
t.Run("Empty", func(t *testing.T) {
|
||||
@ -757,9 +604,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// Create template version dry-run
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
|
||||
ParameterValues: []codersdk.CreateParameterRequest{},
|
||||
})
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Fetch template version dry-run
|
||||
@ -815,9 +660,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
_, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
|
||||
ParameterValues: []codersdk.CreateParameterRequest{},
|
||||
})
|
||||
_, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
|
||||
var apiErr *codersdk.Error
|
||||
require.ErrorAs(t, err, &apiErr)
|
||||
require.Equal(t, http.StatusBadRequest, apiErr.StatusCode())
|
||||
@ -858,9 +701,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// Create the dry-run
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
|
||||
ParameterValues: []codersdk.CreateParameterRequest{},
|
||||
})
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, codersdk.ProvisionerJobPending, job.Status)
|
||||
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
|
||||
@ -881,9 +722,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// Create the dry-run
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
|
||||
ParameterValues: []codersdk.CreateParameterRequest{},
|
||||
})
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Eventually(t, func() bool {
|
||||
@ -933,9 +772,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// Create the dry-run
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{
|
||||
ParameterValues: []codersdk.CreateParameterRequest{},
|
||||
})
|
||||
job, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{})
|
||||
require.NoError(t, err)
|
||||
|
||||
err = client.CancelTemplateVersionDryRun(ctx, version.ID, job.ID)
|
||||
@ -1454,45 +1291,3 @@ func TestTemplateVersionPatch(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTemplateVersionWarnings(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{
|
||||
{
|
||||
AllowOverrideSource: true,
|
||||
Name: "example",
|
||||
Description: "description 1",
|
||||
DefaultSource: &proto.ParameterSource{
|
||||
Scheme: proto.ParameterSource_DATA,
|
||||
Value: "tomato",
|
||||
},
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
ProvisionPlan: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
templateVersion, err := client.TemplateVersion(ctx, template.ActiveVersionID)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Contains(t, templateVersion.Warnings, codersdk.TemplateVersionWarningDeprecatedParameters)
|
||||
}
|
||||
|
@ -313,7 +313,6 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
|
||||
|
||||
builder := wsbuilder.New(workspace, database.WorkspaceTransition(createBuild.Transition)).
|
||||
Initiator(apiKey.UserID).
|
||||
LegacyParameterValues(createBuild.ParameterValues).
|
||||
RichParameterValues(createBuild.RichParameterValues).
|
||||
LogLevel(string(createBuild.LogLevel))
|
||||
|
||||
|
@ -637,173 +637,6 @@ func TestWorkspaceBuildStatus(t *testing.T) {
|
||||
require.EqualValues(t, codersdk.WorkspaceStatusDeleted, workspace.LatestBuild.Status)
|
||||
}
|
||||
|
||||
func TestMigrateLegacyToRichParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
|
||||
user := coderdtest.CreateFirstUser(t, client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
|
||||
// 1. Prepare a template with legacy parameters.
|
||||
templateVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{
|
||||
{
|
||||
AllowOverrideSource: true,
|
||||
Name: "example",
|
||||
Description: "description 1",
|
||||
DefaultSource: &proto.ParameterSource{
|
||||
Scheme: proto.ParameterSource_DATA,
|
||||
Value: "tomato",
|
||||
},
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
ProvisionPlan: echo.ProvisionComplete,
|
||||
})
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, templateVersion.ID)
|
||||
|
||||
// Create a workspace
|
||||
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID, func(cwr *codersdk.CreateWorkspaceRequest) {
|
||||
cwr.ParameterValues = []codersdk.CreateParameterRequest{
|
||||
{
|
||||
Name: "example",
|
||||
SourceValue: "carrot",
|
||||
SourceScheme: codersdk.ParameterSourceSchemeData,
|
||||
DestinationScheme: codersdk.ParameterDestinationSchemeEnvironmentVariable,
|
||||
},
|
||||
}
|
||||
})
|
||||
workspaceBuild := coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
require.Equal(t, codersdk.WorkspaceStatusRunning, workspaceBuild.Status)
|
||||
|
||||
// 2. Upload the template with legacy and rich parameters.
|
||||
templateWithParameters := &echo.Responses{
|
||||
Parse: []*proto.Parse_Response{{
|
||||
Type: &proto.Parse_Response_Complete{
|
||||
Complete: &proto.Parse_Complete{
|
||||
ParameterSchemas: []*proto.ParameterSchema{
|
||||
{
|
||||
AllowOverrideSource: true,
|
||||
Name: "example",
|
||||
Description: "description 1",
|
||||
DefaultSource: &proto.ParameterSource{
|
||||
Scheme: proto.ParameterSource_DATA,
|
||||
Value: "tomato",
|
||||
},
|
||||
DefaultDestination: &proto.ParameterDestination{
|
||||
Scheme: proto.ParameterDestination_PROVISIONER_VARIABLE,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}},
|
||||
ProvisionPlan: []*proto.Provision_Response{
|
||||
{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
Complete: &proto.Provision_Complete{
|
||||
Parameters: []*proto.RichParameter{
|
||||
{
|
||||
Name: "new_example",
|
||||
Type: "string",
|
||||
Mutable: true,
|
||||
Required: true,
|
||||
LegacyVariableName: "example",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
}
|
||||
templateVersion = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, templateWithParameters, template.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
|
||||
// Check if rich parameters are expected
|
||||
richParameters, err := client.TemplateVersionRichParameters(ctx, templateVersion.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, richParameters, 1)
|
||||
require.Equal(t, "new_example", richParameters[0].Name)
|
||||
|
||||
// Update workspace to use rich parameters and template variables
|
||||
workspaceBuild, err = client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
TemplateVersionID: templateVersion.ID,
|
||||
Transition: codersdk.WorkspaceTransitionStart,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Eventually(t, func() bool {
|
||||
workspaceBuild = coderdtest.AwaitWorkspaceBuildJob(t, client, workspaceBuild.ID)
|
||||
return codersdk.WorkspaceStatusRunning == workspaceBuild.Status
|
||||
}, testutil.WaitLong, testutil.IntervalFast)
|
||||
|
||||
// Check if variable value has been imported
|
||||
buildParameters, err := client.WorkspaceBuildParameters(ctx, workspaceBuild.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, buildParameters, 1)
|
||||
require.Equal(t, "carrot", buildParameters[0].Value)
|
||||
|
||||
// 3. Upload the template with rich parameters only
|
||||
templateWithParameters = &echo.Responses{
|
||||
Parse: echo.ParseComplete,
|
||||
ProvisionPlan: []*proto.Provision_Response{
|
||||
{
|
||||
Type: &proto.Provision_Response_Complete{
|
||||
Complete: &proto.Provision_Complete{
|
||||
Parameters: []*proto.RichParameter{
|
||||
{
|
||||
Name: "new_example",
|
||||
Type: "string",
|
||||
Mutable: true,
|
||||
Required: true,
|
||||
LegacyVariableName: "example",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
ProvisionApply: echo.ProvisionComplete,
|
||||
}
|
||||
templateVersion = coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, templateWithParameters, template.ID)
|
||||
coderdtest.AwaitTemplateVersionJob(t, client, templateVersion.ID)
|
||||
|
||||
// Check if rich parameters are expected
|
||||
richParameters, err = client.TemplateVersionRichParameters(ctx, templateVersion.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, richParameters, 1)
|
||||
require.Equal(t, "new_example", richParameters[0].Name)
|
||||
|
||||
// Update workspace to use rich parameters and template variables
|
||||
workspaceBuild, err = client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
|
||||
TemplateVersionID: templateVersion.ID,
|
||||
Transition: codersdk.WorkspaceTransitionStart,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Eventually(t, func() bool {
|
||||
workspaceBuild = coderdtest.AwaitWorkspaceBuildJob(t, client, workspaceBuild.ID)
|
||||
return codersdk.WorkspaceStatusRunning == workspaceBuild.Status
|
||||
}, testutil.WaitLong, testutil.IntervalFast)
|
||||
|
||||
// Check if build parameters have been pulled from last build
|
||||
buildParameters, err = client.WorkspaceBuildParameters(ctx, workspaceBuild.ID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, buildParameters, 1)
|
||||
require.Equal(t, "carrot", buildParameters[0].Value)
|
||||
}
|
||||
|
||||
func TestWorkspaceBuildDebugMode(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
@ -425,7 +425,6 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
|
||||
Reason(database.BuildReasonInitiator).
|
||||
Initiator(apiKey.UserID).
|
||||
ActiveVersion().
|
||||
LegacyParameterValues(createWorkspace.ParameterValues).
|
||||
RichParameterValues(createWorkspace.RichParameterValues)
|
||||
workspaceBuild, provisionerJob, err = builder.Build(
|
||||
ctx, db, func(action rbac.Action, object rbac.Objecter) bool {
|
||||
|
@ -34,15 +34,14 @@ import (
|
||||
// build, job, err := b.Build(...)
|
||||
type Builder struct {
|
||||
// settings that control the kind of build you get
|
||||
workspace database.Workspace
|
||||
trans database.WorkspaceTransition
|
||||
version versionTarget
|
||||
state stateTarget
|
||||
logLevel string
|
||||
legacyParameterValues []codersdk.CreateParameterRequest
|
||||
richParameterValues []codersdk.WorkspaceBuildParameter
|
||||
initiator uuid.UUID
|
||||
reason database.BuildReason
|
||||
workspace database.Workspace
|
||||
trans database.WorkspaceTransition
|
||||
version versionTarget
|
||||
state stateTarget
|
||||
logLevel string
|
||||
richParameterValues []codersdk.WorkspaceBuildParameter
|
||||
initiator uuid.UUID
|
||||
reason database.BuildReason
|
||||
|
||||
// used during build, makes function arguments less verbose
|
||||
ctx context.Context
|
||||
@ -56,8 +55,9 @@ type Builder struct {
|
||||
lastBuild *database.WorkspaceBuild
|
||||
lastBuildErr *error
|
||||
lastBuildParameters *[]database.WorkspaceBuildParameter
|
||||
lastParameterValues *[]database.ParameterValue
|
||||
lastBuildJob *database.ProvisionerJob
|
||||
|
||||
verifyNoLegacyParametersOnce bool
|
||||
}
|
||||
|
||||
type Option func(Builder) Builder
|
||||
@ -140,12 +140,6 @@ func (b Builder) Reason(r database.BuildReason) Builder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) LegacyParameterValues(p []codersdk.CreateParameterRequest) Builder {
|
||||
// nolint: revive
|
||||
b.legacyParameterValues = p
|
||||
return b
|
||||
}
|
||||
|
||||
func (b Builder) RichParameterValues(p []codersdk.WorkspaceBuildParameter) Builder {
|
||||
// nolint: revive
|
||||
b.richParameterValues = p
|
||||
@ -271,15 +265,6 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
|
||||
}
|
||||
}
|
||||
|
||||
legacyParameters, err := b.getLastParameterValues()
|
||||
if err != nil {
|
||||
return nil, nil, BuildError{
|
||||
http.StatusInternalServerError,
|
||||
"failed to fetch previous legacy parameters.",
|
||||
err,
|
||||
}
|
||||
}
|
||||
|
||||
// if we haven't been told specifically who initiated, default to owner
|
||||
if b.initiator == uuid.Nil {
|
||||
b.initiator = b.workspace.OwnerID
|
||||
@ -289,45 +274,6 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
|
||||
b.reason = database.BuildReasonInitiator
|
||||
}
|
||||
|
||||
// Write/Update any new params
|
||||
now := database.Now()
|
||||
for _, param := range b.legacyParameterValues {
|
||||
for _, exists := range legacyParameters {
|
||||
// If the param exists, delete the old param before inserting the new one
|
||||
if exists.Name == param.Name {
|
||||
err = b.store.DeleteParameterValueByID(b.ctx, exists.ID)
|
||||
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil, BuildError{
|
||||
http.StatusInternalServerError,
|
||||
fmt.Sprintf("Failed to delete old param %q", exists.Name),
|
||||
err,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the value is empty, we don't want to save it on database so
|
||||
// Terraform can use the default value
|
||||
if param.SourceValue == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = b.store.InsertParameterValue(b.ctx, database.InsertParameterValueParams{
|
||||
ID: uuid.New(),
|
||||
Name: param.Name,
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
Scope: database.ParameterScopeWorkspace,
|
||||
ScopeID: b.workspace.ID,
|
||||
SourceScheme: database.ParameterSourceScheme(param.SourceScheme),
|
||||
SourceValue: param.SourceValue,
|
||||
DestinationScheme: database.ParameterDestinationScheme(param.DestinationScheme),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, nil, BuildError{http.StatusInternalServerError, "insert parameter value", err}
|
||||
}
|
||||
}
|
||||
|
||||
workspaceBuildID := uuid.New()
|
||||
input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{
|
||||
WorkspaceBuildID: workspaceBuildID,
|
||||
@ -346,6 +292,7 @@ func (b *Builder) buildTx(authFunc func(action rbac.Action, object rbac.Objecter
|
||||
}
|
||||
tags := provisionerdserver.MutateTags(b.workspace.OwnerID, templateVersionJob.Tags)
|
||||
|
||||
now := database.Now()
|
||||
provisionerJob, err := b.store.InsertProvisionerJob(b.ctx, database.InsertProvisionerJobParams{
|
||||
ID: uuid.New(),
|
||||
CreatedAt: now,
|
||||
@ -536,13 +483,12 @@ func (b *Builder) getParameters() (names, values []string, err error) {
|
||||
if err != nil {
|
||||
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last build parameters", err}
|
||||
}
|
||||
lastParameterValues, err := b.getLastParameterValues()
|
||||
err = b.verifyNoLegacyParameters()
|
||||
if err != nil {
|
||||
return nil, nil, BuildError{http.StatusInternalServerError, "failed to fetch last parameter values", err}
|
||||
return nil, nil, BuildError{http.StatusBadRequest, "Unable to build workspace with unsupported parameters", err}
|
||||
}
|
||||
resolver := codersdk.ParameterResolver{
|
||||
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
|
||||
Legacy: db2sdk.Parameters(lastParameterValues),
|
||||
Rich: db2sdk.WorkspaceBuildParameters(lastBuildParameters),
|
||||
}
|
||||
for _, templateVersionParameter := range templateVersionParameters {
|
||||
tvp, err := db2sdk.TemplateVersionParameter(templateVersionParameter)
|
||||
@ -611,19 +557,36 @@ func (b *Builder) getTemplateVersionParameters() ([]database.TemplateVersionPara
|
||||
return tvp, nil
|
||||
}
|
||||
|
||||
func (b *Builder) getLastParameterValues() ([]database.ParameterValue, error) {
|
||||
if b.lastParameterValues != nil {
|
||||
return *b.lastParameterValues, nil
|
||||
// verifyNoLegacyParameters verifies that initiator can't start the workspace build
|
||||
// if it uses legacy parameters (database.ParameterSchemas).
|
||||
func (b *Builder) verifyNoLegacyParameters() error {
|
||||
if b.verifyNoLegacyParametersOnce {
|
||||
return nil
|
||||
}
|
||||
pv, err := b.store.ParameterValues(b.ctx, database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
|
||||
ScopeIds: []uuid.UUID{b.workspace.ID},
|
||||
})
|
||||
if err != nil && !xerrors.Is(err, sql.ErrNoRows) {
|
||||
return nil, xerrors.Errorf("get workspace %w parameter values: %w", b.workspace.ID, err)
|
||||
b.verifyNoLegacyParametersOnce = true
|
||||
|
||||
// Block starting the workspace with legacy parameters.
|
||||
if b.trans != database.WorkspaceTransitionStart {
|
||||
return nil
|
||||
}
|
||||
b.lastParameterValues = &pv
|
||||
return pv, nil
|
||||
|
||||
templateVersionJob, err := b.getTemplateVersionJob()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to fetch template version job: %w", err)
|
||||
}
|
||||
|
||||
parameterSchemas, err := b.store.GetParameterSchemasByJobID(b.ctx, templateVersionJob.ID)
|
||||
if xerrors.Is(err, sql.ErrNoRows) {
|
||||
return nil
|
||||
}
|
||||
if err != nil {
|
||||
return xerrors.Errorf("failed to get parameter schemas: %w", err)
|
||||
}
|
||||
|
||||
if len(parameterSchemas) > 0 {
|
||||
return xerrors.Errorf("Legacy parameters in use on this version are not supported anymore. Contact your administrator for assistance.")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Builder) getLastBuildJob() (*database.ProvisionerJob, error) {
|
||||
|
@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"testing"
|
||||
"time"
|
||||
@ -24,21 +23,19 @@ import (
|
||||
|
||||
var (
|
||||
// use fixed IDs so logs are easier to read
|
||||
templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000")
|
||||
activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000")
|
||||
inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000")
|
||||
activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000")
|
||||
inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000")
|
||||
orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000")
|
||||
workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000")
|
||||
userID = uuid.MustParse("12341234-0000-0000-0008-000000000000")
|
||||
activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000")
|
||||
inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000")
|
||||
lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000")
|
||||
lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-000000000000")
|
||||
otherUserID = uuid.MustParse("12341234-0000-0000-000d-000000000000")
|
||||
notReplacedParamID = uuid.MustParse("12341234-0000-0000-000e-000000000000")
|
||||
replacedParamID = uuid.MustParse("12341234-0000-0000-000f-000000000000")
|
||||
templateID = uuid.MustParse("12341234-0000-0000-0001-000000000000")
|
||||
activeVersionID = uuid.MustParse("12341234-0000-0000-0002-000000000000")
|
||||
inactiveVersionID = uuid.MustParse("12341234-0000-0000-0003-000000000000")
|
||||
activeJobID = uuid.MustParse("12341234-0000-0000-0004-000000000000")
|
||||
inactiveJobID = uuid.MustParse("12341234-0000-0000-0005-000000000000")
|
||||
orgID = uuid.MustParse("12341234-0000-0000-0006-000000000000")
|
||||
workspaceID = uuid.MustParse("12341234-0000-0000-0007-000000000000")
|
||||
userID = uuid.MustParse("12341234-0000-0000-0008-000000000000")
|
||||
activeFileID = uuid.MustParse("12341234-0000-0000-0009-000000000000")
|
||||
inactiveFileID = uuid.MustParse("12341234-0000-0000-000a-000000000000")
|
||||
lastBuildID = uuid.MustParse("12341234-0000-0000-000b-000000000000")
|
||||
lastBuildJobID = uuid.MustParse("12341234-0000-0000-000c-000000000000")
|
||||
otherUserID = uuid.MustParse("12341234-0000-0000-000d-000000000000")
|
||||
)
|
||||
|
||||
func TestBuilder_NoOptions(t *testing.T) {
|
||||
@ -56,7 +53,8 @@ func TestBuilder_NoOptions(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(nil),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil), withRichParameters(nil),
|
||||
withRichParameters(nil),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
|
||||
@ -104,7 +102,8 @@ func TestBuilder_Initiator(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(nil),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil), withRichParameters(nil),
|
||||
withRichParameters(nil),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
|
||||
@ -136,7 +135,8 @@ func TestBuilder_Reason(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(nil),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil), withRichParameters(nil),
|
||||
withRichParameters(nil),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
|
||||
@ -167,7 +167,7 @@ func TestBuilder_ActiveVersion(t *testing.T) {
|
||||
withTemplate,
|
||||
withActiveVersion(nil),
|
||||
withLastBuildNotFound,
|
||||
withLegacyParameters(nil),
|
||||
withParameterSchemas(activeJobID, nil),
|
||||
// previous rich parameters are not queried because there is no previous build.
|
||||
|
||||
// Outputs
|
||||
@ -190,47 +190,6 @@ func TestBuilder_ActiveVersion(t *testing.T) {
|
||||
req.NoError(err)
|
||||
}
|
||||
|
||||
func TestBuilder_LegacyParams(t *testing.T) {
|
||||
t.Parallel()
|
||||
req := require.New(t)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
oldParams := []database.ParameterValue{
|
||||
{Name: "not-replaced", SourceValue: "nr", ID: notReplacedParamID},
|
||||
{Name: "replaced", SourceValue: "r", ID: replacedParamID},
|
||||
}
|
||||
newParams := []codersdk.CreateParameterRequest{
|
||||
{Name: "replaced", SourceValue: "s"},
|
||||
{Name: "new", SourceValue: "n"},
|
||||
}
|
||||
|
||||
mDB := expectDB(t,
|
||||
// Inputs
|
||||
withTemplate,
|
||||
withActiveVersion(nil),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(oldParams),
|
||||
withRichParameters(nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {
|
||||
}),
|
||||
expectBuild(func(bld database.InsertWorkspaceBuildParams) {
|
||||
}),
|
||||
expectBuildParameters(func(params database.InsertWorkspaceBuildParametersParams) {
|
||||
}),
|
||||
expectReplacedParam(replacedParamID, "replaced", "s"),
|
||||
expectInsertedParam("new", "n"),
|
||||
)
|
||||
|
||||
ws := database.Workspace{ID: workspaceID, TemplateID: templateID, OwnerID: userID}
|
||||
uut := wsbuilder.New(ws, database.WorkspaceTransitionStart).ActiveVersion().LegacyParameterValues(newParams)
|
||||
_, _, err := uut.Build(ctx, mDB, nil)
|
||||
req.NoError(err)
|
||||
}
|
||||
|
||||
func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@ -285,8 +244,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(richParameters),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -326,8 +285,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(richParameters),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -348,6 +307,47 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
req.NoError(err)
|
||||
})
|
||||
|
||||
t.Run("StartWorkspaceWithLegacyParameterValues", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
req := require.New(t)
|
||||
asrt := assert.New(t)
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
schemas := []database.ParameterSchema{
|
||||
{
|
||||
Name: "not-replaced",
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
},
|
||||
{
|
||||
Name: "replaced",
|
||||
DefaultDestinationScheme: database.ParameterDestinationSchemeEnvironmentVariable,
|
||||
},
|
||||
}
|
||||
|
||||
mDB := expectDB(t,
|
||||
// Inputs
|
||||
withTemplate,
|
||||
withInactiveVersion(richParameters),
|
||||
withLastBuildFound,
|
||||
withRichParameters(nil),
|
||||
withParameterSchemas(inactiveJobID, schemas),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
expectBuild(func(bld database.InsertWorkspaceBuildParams) {}),
|
||||
)
|
||||
|
||||
ws := database.Workspace{ID: workspaceID, TemplateID: templateID, OwnerID: userID}
|
||||
uut := wsbuilder.New(ws, database.WorkspaceTransitionStart)
|
||||
_, _, err := uut.Build(ctx, mDB, nil)
|
||||
bldErr := wsbuilder.BuildError{}
|
||||
req.ErrorAs(err, &bldErr)
|
||||
asrt.Equal(http.StatusBadRequest, bldErr.Status)
|
||||
})
|
||||
|
||||
t.Run("DoNotModifyImmutables", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@ -366,8 +366,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withInactiveVersion(richParameters),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(inactiveJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -418,8 +418,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withActiveVersion(version2params),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(activeJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -476,8 +476,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withActiveVersion(version2params),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(activeJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -532,8 +532,8 @@ func TestWorkspaceBuildWithRichParameters(t *testing.T) {
|
||||
withTemplate,
|
||||
withActiveVersion(version2params),
|
||||
withLastBuildFound,
|
||||
withLegacyParameters(nil),
|
||||
withRichParameters(initialBuildParameters),
|
||||
withParameterSchemas(activeJobID, nil),
|
||||
|
||||
// Outputs
|
||||
expectProvisionerJob(func(job database.InsertProvisionerJobParams) {}),
|
||||
@ -710,17 +710,14 @@ func withLastBuildNotFound(mTx *dbmock.MockStore) {
|
||||
Return(database.WorkspaceBuild{}, sql.ErrNoRows)
|
||||
}
|
||||
|
||||
func withLegacyParameters(params []database.ParameterValue) func(mTx *dbmock.MockStore) {
|
||||
func withParameterSchemas(jobID uuid.UUID, schemas []database.ParameterSchema) func(mTx *dbmock.MockStore) {
|
||||
return func(mTx *dbmock.MockStore) {
|
||||
c := mTx.EXPECT().ParameterValues(
|
||||
c := mTx.EXPECT().GetParameterSchemasByJobID(
|
||||
gomock.Any(),
|
||||
database.ParameterValuesParams{
|
||||
Scopes: []database.ParameterScope{database.ParameterScopeWorkspace},
|
||||
ScopeIds: []uuid.UUID{workspaceID},
|
||||
}).
|
||||
jobID).
|
||||
Times(1)
|
||||
if len(params) > 0 {
|
||||
c.Return(params, nil)
|
||||
if len(schemas) > 0 {
|
||||
c.Return(schemas, nil)
|
||||
} else {
|
||||
c.Return(nil, sql.ErrNoRows)
|
||||
}
|
||||
@ -797,43 +794,3 @@ func expectBuildParameters(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
type insertParameterMatcher struct {
|
||||
name string
|
||||
value string
|
||||
}
|
||||
|
||||
func (m insertParameterMatcher) Matches(x interface{}) bool {
|
||||
p, ok := x.(database.InsertParameterValueParams)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
if p.Name != m.name {
|
||||
return false
|
||||
}
|
||||
return p.SourceValue == m.value
|
||||
}
|
||||
|
||||
func (m insertParameterMatcher) String() string {
|
||||
return fmt.Sprintf("ParameterValue %s=%s", m.name, m.value)
|
||||
}
|
||||
|
||||
func expectReplacedParam(oldID uuid.UUID, name, newValue string) func(store *dbmock.MockStore) {
|
||||
return func(mTx *dbmock.MockStore) {
|
||||
del := mTx.EXPECT().DeleteParameterValueByID(gomock.Any(), oldID).
|
||||
Times(1).
|
||||
Return(nil)
|
||||
mTx.EXPECT().InsertParameterValue(gomock.Any(), insertParameterMatcher{name, newValue}).
|
||||
Times(1).
|
||||
After(del).
|
||||
Return(database.ParameterValue{}, nil)
|
||||
}
|
||||
}
|
||||
|
||||
func expectInsertedParam(name, newValue string) func(store *dbmock.MockStore) {
|
||||
return func(mTx *dbmock.MockStore) {
|
||||
mTx.EXPECT().InsertParameterValue(gomock.Any(), insertParameterMatcher{name, newValue}).
|
||||
Times(1).
|
||||
Return(database.ParameterValue{}, nil)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user