feat!: drop support for legacy parameters (#7663)

This commit is contained in:
Marcin Tojek
2023-06-02 11:16:46 +02:00
committed by GitHub
parent 2b63492649
commit a7366a8b76
106 changed files with 1153 additions and 8553 deletions

531
coderd/apidoc/docs.go generated
View File

@ -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": {

View File

@ -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": {

View File

@ -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)

View File

@ -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)
}
}

View File

@ -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:

View File

@ -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.

View File

@ -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()

View File

@ -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

View File

@ -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)
}))
}

View File

@ -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

View File

@ -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("{}"))

View File

@ -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()

View File

@ -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)

View File

@ -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()

View File

@ -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.
//

View File

@ -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

View File

@ -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 *;

View File

@ -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
View 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{}{})
}

View File

@ -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
}

View File

@ -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, &parameter.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, "")
})
}

View File

@ -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
}

View File

@ -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)
})
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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"`
}

View File

@ -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",

View File

@ -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"`

View File

@ -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)

View File

@ -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)

View File

@ -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,
}, &parameter.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,

View File

@ -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)
}

View File

@ -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))

View File

@ -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()

View File

@ -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 {

View File

@ -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) {

View File

@ -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)
}
}