Add terraform validation to linting (#170)
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
This commit is contained in:
committed by
GitHub
parent
4b04d18f39
commit
895c51bd00
@@ -69,7 +69,7 @@ resource "coder_app" "MODULE_NAME" {
|
|||||||
slug = "MODULE_NAME"
|
slug = "MODULE_NAME"
|
||||||
display_name = "MODULE_NAME"
|
display_name = "MODULE_NAME"
|
||||||
url = "http://localhost:${var.port}"
|
url = "http://localhost:${var.port}"
|
||||||
icon = loocal.icon_url
|
icon = local.icon_url
|
||||||
subdomain = false
|
subdomain = false
|
||||||
share = "owner"
|
share = "owner"
|
||||||
|
|
||||||
|
|||||||
@@ -11,18 +11,16 @@ describe("jetbrains-gateway", async () => {
|
|||||||
await testRequiredVariables(import.meta.dir, {
|
await testRequiredVariables(import.meta.dir, {
|
||||||
agent_id: "foo",
|
agent_id: "foo",
|
||||||
agent_name: "foo",
|
agent_name: "foo",
|
||||||
folder: "/baz/",
|
folder: "/home/foo",
|
||||||
});
|
});
|
||||||
|
|
||||||
it("default to first ide", async () => {
|
it("default to first ide", async () => {
|
||||||
const state = await runTerraformApply(import.meta.dir, {
|
const state = await runTerraformApply(import.meta.dir, {
|
||||||
agent_id: "foo",
|
agent_id: "foo",
|
||||||
agent_name: "foo",
|
agent_name: "foo",
|
||||||
folder: "/baz/",
|
folder: "/home/foo",
|
||||||
jetbrains_ides: '["IU", "GO", "PY"]',
|
jetbrains_ides: '["IU", "GO", "PY"]',
|
||||||
});
|
});
|
||||||
expect(state.outputs.jetbrains_ides.value).toBe(
|
expect(state.outputs.identifier.value).toBe("IU");
|
||||||
'["IU","232.10203.10","https://download.jetbrains.com/idea/ideaIU-2023.2.4.tar.gz"]',
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,6 +22,10 @@ variable "agent_name" {
|
|||||||
variable "folder" {
|
variable "folder" {
|
||||||
type = string
|
type = string
|
||||||
description = "The directory to open in the IDE. e.g. /home/coder/project"
|
description = "The directory to open in the IDE. e.g. /home/coder/project"
|
||||||
|
validation {
|
||||||
|
condition = can(regex("^(?:/[^/]+)+$", var.folder))
|
||||||
|
error_message = "The folder must be a full path and must not start with a ~."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "default" {
|
variable "default" {
|
||||||
@@ -30,10 +34,6 @@ variable "default" {
|
|||||||
description = "Default IDE"
|
description = "Default IDE"
|
||||||
}
|
}
|
||||||
|
|
||||||
locals {
|
|
||||||
supported_ides = ["IU", "PS", "WS", "PY", "CL", "GO", "RM"]
|
|
||||||
}
|
|
||||||
|
|
||||||
variable "jetbrains_ide_versions" {
|
variable "jetbrains_ide_versions" {
|
||||||
type = map(object({
|
type = map(object({
|
||||||
build_number = string
|
build_number = string
|
||||||
@@ -69,29 +69,28 @@ variable "jetbrains_ide_versions" {
|
|||||||
build_number = "232.10203.15"
|
build_number = "232.10203.15"
|
||||||
version = "2023.2.4"
|
version = "2023.2.4"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
validation {
|
validation {
|
||||||
condition = (
|
condition = (
|
||||||
alltrue([
|
alltrue([
|
||||||
for code in var.jetbrains_ide_versions : contains(local.supported_ides, code)
|
for code in keys(var.jetbrains_ide_versions) : contains(["IU", "PS", "WS", "PY", "CL", "GO", "RM"], code)
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
error_message = "The jetbrains_ide_versions must contain a map of valid product codes. Valid product codes are ${join(",", local.supported_ides)}."
|
error_message = "The jetbrains_ide_versions must contain a map of valid product codes. Valid product codes are ${join(",", ["IU", "PS", "WS", "PY", "CL", "GO", "RM"])}."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variable "jetbrains_ides" {
|
variable "jetbrains_ides" {
|
||||||
type = list(string)
|
type = list(string)
|
||||||
description = "The list of IDE product codes."
|
description = "The list of IDE product codes."
|
||||||
default = local.supported_ides
|
default = ["IU", "PS", "WS", "PY", "CL", "GO", "RM"]
|
||||||
validation {
|
validation {
|
||||||
condition = (
|
condition = (
|
||||||
alltrue([
|
alltrue([
|
||||||
for code in var.jetbrains_ides : contains(local.supported_ides, code)
|
for code in var.jetbrains_ides : contains(["IU", "PS", "WS", "PY", "CL", "GO", "RM"], code)
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
error_message = "The jetbrains_ides must be a list of valid product codes. Valid product codes are ${join(",", local.supported_ides)}."
|
error_message = "The jetbrains_ides must be a list of valid product codes. Valid product codes are ${join(",", ["IU", "PS", "WS", "PY", "CL", "GO", "RM"])}."
|
||||||
}
|
}
|
||||||
# check if the list is empty
|
# check if the list is empty
|
||||||
validation {
|
validation {
|
||||||
@@ -108,58 +107,71 @@ variable "jetbrains_ides" {
|
|||||||
locals {
|
locals {
|
||||||
jetbrains_ides = {
|
jetbrains_ides = {
|
||||||
"GO" = {
|
"GO" = {
|
||||||
icon = "/icon/goland.svg",
|
icon = "/icon/goland.svg",
|
||||||
name = "GoLand",
|
name = "GoLand",
|
||||||
value = jsonencode(["GO", var.jetbrains_ide_versions["GO"].build_number, "https://download.jetbrains.com/go/goland-${var.jetbrains_ide_versions["GO"].version}.tar.gz"])
|
identifier = "GO",
|
||||||
|
build_number = var.jetbrains_ide_versions["GO"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/go/goland-${var.jetbrains_ide_versions["GO"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"WS" = {
|
"WS" = {
|
||||||
icon = "/icon/webstorm.svg",
|
icon = "/icon/webstorm.svg",
|
||||||
name = "WebStorm",
|
name = "WebStorm",
|
||||||
value = jsonencode(["WS", var.jetbrains_ide_versions["WS"].build_number, "https://download.jetbrains.com/webstorm/WebStorm-${var.jetbrains_ide_versions["WS"].version}.tar.gz"])
|
identifier = "WS",
|
||||||
|
build_number = var.jetbrains_ide_versions["WS"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/webstorm/WebStorm-${var.jetbrains_ide_versions["WS"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"IU" = {
|
"IU" = {
|
||||||
icon = "/icon/intellij.svg",
|
icon = "/icon/intellij.svg",
|
||||||
name = "IntelliJ IDEA Ultimate",
|
name = "IntelliJ IDEA Ultimate",
|
||||||
value = jsonencode(["IU", var.jetbrains_ide_versions["IU"].build_number, "https://download.jetbrains.com/idea/ideaIU-${var.jetbrains_ide_versions["IU"].version}.tar.gz"])
|
identifier = "IU",
|
||||||
|
build_number = var.jetbrains_ide_versions["IU"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/idea/ideaIU-${var.jetbrains_ide_versions["IU"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"PY" = {
|
"PY" = {
|
||||||
icon = "/icon/pycharm.svg",
|
icon = "/icon/pycharm.svg",
|
||||||
name = "PyCharm Professional",
|
name = "PyCharm Professional",
|
||||||
value = jsonencode(["PY", var.jetbrains_ide_versions["PY"].build_number, "https://download.jetbrains.com/python/pycharm-professional-${var.jetbrains_ide_versions["PY"].version}.tar.gz"])
|
identifier = "PY",
|
||||||
|
build_number = var.jetbrains_ide_versions["PY"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/python/pycharm-professional-${var.jetbrains_ide_versions["PY"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"CL" = {
|
"CL" = {
|
||||||
icon = "/icon/clion.svg",
|
icon = "/icon/clion.svg",
|
||||||
name = "CLion",
|
name = "CLion",
|
||||||
value = jsonencode(["CL", var.jetbrains_ide_versions["CL"].build_number, "https://download.jetbrains.com/cpp/CLion-${var.jetbrains_ide_versions["CL"].version}.tar.gz"])
|
identifier = "CL",
|
||||||
|
build_number = var.jetbrains_ide_versions["CL"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/cpp/CLion-${var.jetbrains_ide_versions["CL"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"PS" = {
|
"PS" = {
|
||||||
icon = "/icon/phpstorm.svg",
|
icon = "/icon/phpstorm.svg",
|
||||||
name = "PhpStorm",
|
name = "PhpStorm",
|
||||||
value = jsonencode(["PS", var.jetbrains_ide_versions["PS"].build_number, "https://download.jetbrains.com/webide/PhpStorm-${var.jetbrains_ide_versions["PS"].version}.tar.gz"])
|
identifier = "PS",
|
||||||
|
build_number = var.jetbrains_ide_versions["PS"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/webide/PhpStorm-${var.jetbrains_ide_versions["PS"].version}.tar.gz"
|
||||||
},
|
},
|
||||||
"RM" = {
|
"RM" = {
|
||||||
icon = "/icon/rubymine.svg",
|
icon = "/icon/rubymine.svg",
|
||||||
name = "RubyMine",
|
name = "RubyMine",
|
||||||
value = jsonencode(["RM", var.jetbrains_ide_versions["RM"].build_number, "https://download.jetbrains.com/ruby/RubyMine-${var.jetbrains_ide_versions["RM"].version}.tar.gz"])
|
identifier = "RM",
|
||||||
|
build_number = var.jetbrains_ide_versions["RM"].build_number,
|
||||||
|
download_link = "https://download.jetbrains.com/ruby/RubyMine-${var.jetbrains_ide_versions["RM"].version}.tar.gz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data "coder_parameter" "jetbrains_ide" {
|
data "coder_parameter" "jetbrains_ide" {
|
||||||
type = "list(string)"
|
type = "string"
|
||||||
name = "jetbrains_ide"
|
name = "jetbrains_ide"
|
||||||
display_name = "JetBrains IDE"
|
display_name = "JetBrains IDE"
|
||||||
icon = "/icon/gateway.svg"
|
icon = "/icon/gateway.svg"
|
||||||
mutable = true
|
mutable = true
|
||||||
# check if default is in the jet_brains_ides list and if it is not empty or null otherwise set it to null
|
default = var.default == "" ? var.jetbrains_ides[0] : var.default
|
||||||
default = var.default != null && var.default != "" && contains(var.jetbrains_ides, var.default) ? local.jetbrains_ides[var.default].value : local.jetbrains_ides[var.jetbrains_ides[0]].value
|
|
||||||
|
|
||||||
dynamic "option" {
|
dynamic "option" {
|
||||||
for_each = { for key, value in local.jetbrains_ides : key => value if contains(var.jetbrains_ides, key) }
|
for_each = var.jetbrains_ides
|
||||||
content {
|
content {
|
||||||
icon = option.value.icon
|
icon = lookup(local.jetbrains_ides, option.value).icon
|
||||||
name = option.value.name
|
name = lookup(local.jetbrains_ides, option.value).name
|
||||||
value = option.value.value
|
value = lookup(local.jetbrains_ides, option.value).identifier
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,9 +180,9 @@ data "coder_workspace" "me" {}
|
|||||||
|
|
||||||
resource "coder_app" "gateway" {
|
resource "coder_app" "gateway" {
|
||||||
agent_id = var.agent_id
|
agent_id = var.agent_id
|
||||||
display_name = data.coder_parameter.jetbrains_ide.option[index(data.coder_parameter.jetbrains_ide.option.*.value, data.coder_parameter.jetbrains_ide.value)].name
|
|
||||||
slug = "gateway"
|
slug = "gateway"
|
||||||
icon = data.coder_parameter.jetbrains_ide.option[index(data.coder_parameter.jetbrains_ide.option.*.value, data.coder_parameter.jetbrains_ide.value)].icon
|
display_name = try(lookup(local.jetbrains_ides, data.coder_parameter.jetbrains_ide.value).name, "JetBrains IDE")
|
||||||
|
icon = try(lookup(local.jetbrains_ides, data.coder_parameter.jetbrains_ide.value).icon, "/icon/gateway.svg")
|
||||||
external = true
|
external = true
|
||||||
url = join("", [
|
url = join("", [
|
||||||
"jetbrains-gateway://connect#type=coder&workspace=",
|
"jetbrains-gateway://connect#type=coder&workspace=",
|
||||||
@@ -184,14 +196,38 @@ resource "coder_app" "gateway" {
|
|||||||
"&token=",
|
"&token=",
|
||||||
"$SESSION_TOKEN",
|
"$SESSION_TOKEN",
|
||||||
"&ide_product_code=",
|
"&ide_product_code=",
|
||||||
jsondecode(data.coder_parameter.jetbrains_ide.value)[0],
|
local.jetbrains_ides[data.coder_parameter.jetbrains_ide.value].identifier,
|
||||||
"&ide_build_number=",
|
"&ide_build_number=",
|
||||||
jsondecode(data.coder_parameter.jetbrains_ide.value)[1],
|
local.jetbrains_ides[data.coder_parameter.jetbrains_ide.value].build_number,
|
||||||
"&ide_download_link=",
|
"&ide_download_link=",
|
||||||
jsondecode(data.coder_parameter.jetbrains_ide.value)[2],
|
local.jetbrains_ides[data.coder_parameter.jetbrains_ide.value].download_link
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
output "jetbrains_ides" {
|
output "identifier" {
|
||||||
value = data.coder_parameter.jetbrains_ide.value
|
value = data.coder_parameter.jetbrains_ide.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
output "name" {
|
||||||
|
value = coder_app.gateway.display_name
|
||||||
|
}
|
||||||
|
|
||||||
|
output "icon" {
|
||||||
|
value = coder_app.gateway.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
output "download_link" {
|
||||||
|
value = lookup(local.jetbrains_ides, data.coder_parameter.jetbrains_ide.value).download_link
|
||||||
|
}
|
||||||
|
|
||||||
|
output "build_number" {
|
||||||
|
value = lookup(local.jetbrains_ides, data.coder_parameter.jetbrains_ide.value).build_number
|
||||||
|
}
|
||||||
|
|
||||||
|
output "version" {
|
||||||
|
value = var.jetbrains_ide_versions[data.coder_parameter.jetbrains_ide.value].version
|
||||||
|
}
|
||||||
|
|
||||||
|
output "url" {
|
||||||
|
value = coder_app.gateway.url
|
||||||
|
}
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
"test": "bun test",
|
"test": "bun test",
|
||||||
"fmt": "bun x prettier -w **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt **/*.tf .sample/main.tf",
|
"fmt": "bun x prettier -w **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt **/*.tf .sample/main.tf",
|
||||||
"fmt:ci": "bun x prettier --check **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt -check **/*.tf .sample/main.tf",
|
"fmt:ci": "bun x prettier --check **/*.sh .sample/run.sh new.sh **/*.ts **/*.md *.md && terraform fmt -check **/*.tf .sample/main.tf",
|
||||||
"lint": "bun run lint.ts",
|
"lint": "bun run lint.ts && ./terraform_validate.sh",
|
||||||
"update-version": "./update-version.sh"
|
"update-version": "./update-version.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
29
terraform_validate.sh
Executable file
29
terraform_validate.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Function to run terraform init and validate in a directory
|
||||||
|
run_terraform() {
|
||||||
|
local dir="$1"
|
||||||
|
echo "Running terraform init and validate in $dir"
|
||||||
|
pushd "$dir"
|
||||||
|
terraform init -upgrade
|
||||||
|
terraform validate
|
||||||
|
popd
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script
|
||||||
|
main() {
|
||||||
|
# Get the directory of the script
|
||||||
|
script_dir=$(dirname "$(readlink -f "$0")")
|
||||||
|
|
||||||
|
# Get all subdirectories in the repository
|
||||||
|
subdirs=$(find "$script_dir" -mindepth 1 -maxdepth 1 -type d -not -name ".*" | sort)
|
||||||
|
|
||||||
|
for dir in $subdirs; do
|
||||||
|
run_terraform "$dir"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run the main script
|
||||||
|
main
|
||||||
Reference in New Issue
Block a user