From 7dfefe48d288351cd78f0da7eaaba02ccd150ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20Fr=C3=B6hlich?= Date: Mon, 20 Mar 2023 23:07:44 +0100 Subject: [PATCH] docs: example --- example/example1/example1.conf.hcl | 9 + example/example1/example1.nomad | 15 ++ .../example1/validators/costcenter_meta.rego | 29 +++ .../validators/costcenter_meta_test.rego | 34 +++ example/example2/example2.conf.hcl | 9 + example/example2/example2.nomad | 15 ++ .../example2/mutators/hello_world_meta.rego | 30 +++ .../mutators/hello_world_meta_test.rego | 68 ++++++ example/example3/example3.conf.hcl | 9 + example/example3/example3.nomad | 19 ++ example/example3/example3.ref.nomad | 36 +++ example/example3/mutators/pg.rego | 134 +++++++++++ example/example3/mutators/pg_test.rego | 216 ++++++++++++++++++ example/infra/nomad/conf/nomad.hcl | 16 ++ example/infra/nomad/jobs/.terraform.lock.hcl | 22 ++ example/infra/nomad/jobs/nomad.tf | 15 ++ example/infra/nomad/jobs/pg.nomad | 42 ++++ example/infra/readme.md | 10 + example/infra/vault/.terraform.lock.hcl | 22 ++ example/infra/vault/vault.hcl | 0 example/infra/vault/vault.tf | 66 ++++++ example/readme.md | 12 + 22 files changed, 828 insertions(+) create mode 100644 example/example1/example1.conf.hcl create mode 100644 example/example1/example1.nomad create mode 100644 example/example1/validators/costcenter_meta.rego create mode 100644 example/example1/validators/costcenter_meta_test.rego create mode 100644 example/example2/example2.conf.hcl create mode 100644 example/example2/example2.nomad create mode 100644 example/example2/mutators/hello_world_meta.rego create mode 100644 example/example2/mutators/hello_world_meta_test.rego create mode 100644 example/example3/example3.conf.hcl create mode 100644 example/example3/example3.nomad create mode 100644 example/example3/example3.ref.nomad create mode 100644 example/example3/mutators/pg.rego create mode 100644 example/example3/mutators/pg_test.rego create mode 100644 example/infra/nomad/conf/nomad.hcl create mode 100644 example/infra/nomad/jobs/.terraform.lock.hcl create mode 100644 example/infra/nomad/jobs/nomad.tf create mode 100644 example/infra/nomad/jobs/pg.nomad create mode 100644 example/infra/readme.md create mode 100644 example/infra/vault/.terraform.lock.hcl create mode 100644 example/infra/vault/vault.hcl create mode 100644 example/infra/vault/vault.tf create mode 100644 example/readme.md diff --git a/example/example1/example1.conf.hcl b/example/example1/example1.conf.hcl new file mode 100644 index 0000000..aa50efe --- /dev/null +++ b/example/example1/example1.conf.hcl @@ -0,0 +1,9 @@ +validator "opa" "costcenter_opa_validator" { + + opa_rule { + query = <= 0.6.1" + }] + operation := { + "op": "add", + "path": sprintf("/TaskGroups/%d/Constraints/-", [g]), + "value": { + "LTarget": "${attr.vault.version}", + "Operand": "semver", + "RTarget": ">= 0.6.1", + }, + } +} diff --git a/example/example3/mutators/pg_test.rego b/example/example3/mutators/pg_test.rego new file mode 100644 index 0000000..9233bf3 --- /dev/null +++ b/example/example3/mutators/pg_test.rego @@ -0,0 +1,216 @@ +package pginject_test + +import data.pginject.error +import data.pginject.patch + +import future.keywords + +test_pginject if { + patch_ops := patch with input as { + "Affinities": null, + "AllAtOnce": false, + "Constraints": null, + "ConsulNamespace": "", + "ConsulToken": "", + "CreateIndex": 289, + "Datacenters": ["*"], + "DispatchIdempotencyToken": "", + "Dispatched": false, + "ID": "app", + "JobModifyIndex": 459, + "Meta": null, + "ModifyIndex": 468, + "Multiregion": null, + "Name": "app", + "Namespace": "default", + "NomadTokenID": "", + "ParameterizedJob": null, + "ParentID": "", + "Payload": null, + "Periodic": null, + "Priority": 50, + "Region": "global", + "Spreads": null, + "Stable": true, + "Status": "running", + "StatusDescription": "", + "Stop": false, + "SubmitTime": 1679091610901210000, + "TaskGroups": [{ + "Affinities": null, + "Constraints": null, + "Consul": {"Namespace": ""}, + "Count": 1, + "EphemeralDisk": { + "Migrate": false, + "SizeMB": 300, + "Sticky": false, + }, + "MaxClientDisconnect": null, + "Meta": null, + "Migrate": { + "HealthCheck": "checks", + "HealthyDeadline": 300000000000, + "MaxParallel": 1, + "MinHealthyTime": 10000000000, + }, + "Name": "app", + "Networks": null, + "ReschedulePolicy": { + "Attempts": 0, + "Delay": 30000000000, + "DelayFunction": "exponential", + "Interval": 0, + "MaxDelay": 3600000000000, + "Unlimited": true, + }, + "RestartPolicy": { + "Attempts": 2, + "Delay": 15000000000, + "Interval": 1800000000000, + "Mode": "fail", + }, + "Scaling": null, + "Services": null, + "ShutdownDelay": null, + "Spreads": null, + "StopAfterClientDisconnect": null, + "Tasks": [{ + "Affinities": null, + "Artifacts": null, + "CSIPluginConfig": null, + "Config": { + "args": [ + "-c", + "while true; do echo 'hello $(date)'; sleep 5; done", + ], + "command": "sh", + "image": "busybox:latest", + }, + "Constraints": null, + "DispatchPayload": null, + "Driver": "docker", + "Env": null, + "Identity": null, + "KillSignal": "", + "KillTimeout": 5000000000, + "Kind": "", + "Leader": false, + "Lifecycle": null, + "LogConfig": { + "MaxFileSizeMB": 10, + "MaxFiles": 10, + }, + "Meta": {"postgres": "native"}, + "Name": "app", + "Resources": { + "CPU": 100, + "Cores": 0, + "Devices": null, + "DiskMB": 0, + "IOPS": 0, + "MemoryMB": 300, + "MemoryMaxMB": 0, + "Networks": null, + }, + "RestartPolicy": { + "Attempts": 2, + "Delay": 15000000000, + "Interval": 1800000000000, + "Mode": "fail", + }, + "ScalingPolicies": null, + "Services": null, + "ShutdownDelay": 0, + "Templates": null, + "User": "", + "Vault": null, + "VolumeMounts": null, + }], + "Update": { + "AutoPromote": false, + "AutoRevert": false, + "Canary": 0, + "HealthCheck": "checks", + "HealthyDeadline": 300000000000, + "MaxParallel": 1, + "MinHealthyTime": 10000000000, + "ProgressDeadline": 600000000000, + "Stagger": 30000000000, + }, + "Volumes": null, + }], + "Type": "service", + "Update": { + "AutoPromote": false, + "AutoRevert": false, + "Canary": 0, + "HealthCheck": "", + "HealthyDeadline": 0, + "MaxParallel": 1, + "MinHealthyTime": 0, + "ProgressDeadline": 0, + "Stagger": 30000000000, + }, + "VaultNamespace": "", + "VaultToken": "", + "Version": 6, + } + + count(patch_ops) == 4 + patch_ops == { + { + "op": "add", + "path": "/TaskGroups/0/Tasks/0/Vault", + "value": { + "ChangeMode": "restart", + "ChangeSignal": "SIGHUP", + "Env": true, + "Namespace": "", + "Policies": [], + }, + }, + { + "op": "add", + "path": "/TaskGroups/0/Tasks/0/Vault/Policies/-", + "value": "db-access", + }, + + { + "op": "add", + "path": "/TaskGroups/0/Tasks/0/Templates", + "value": [], + }, + { + "op": "replace", + "path": "/TaskGroups/0/Tasks/0/Templates/-", + "value": [{ + "ChangeMode": "restart", + "ChangeScript": null, + "ChangeSignal": "", + "DestPath": "${NOMAD_SECRETS_DIR}/postgres.env", + "EmbeddedTmpl": "{{ range nomadService \"postgres\" }}\n PGHOSTADDR={{ .Address }}\n PGPORT={{ .Port }}\n{{ end }}\nPGDATABASE=postgres\n{{ with secret \"postgres/creds/dev\" }}\n PGUSER={{ .Data.username }}\n PGPASSWORD={{ .Data.password }}\n{{ end }}\n\n", + "Envvars": true, + "ErrMissingKey": false, + "Gid": null, + "LeftDelim": "{{", + "Perms": "0644", + "RightDelim": "}}", + "SourcePath": "", + "Splay": 5000000000, + "Uid": null, + "VaultGrace": 0, + "Wait": null, + }], + }, + } +} + +# test_error_foo_not_set if { +# err := error with input as {} +# err["please set foo"] +# } +# test_error_foo_is_null if { +# err := error with input as {"foo": null} +# err["please set foo"] +# } diff --git a/example/infra/nomad/conf/nomad.hcl b/example/infra/nomad/conf/nomad.hcl new file mode 100644 index 0000000..1fdaa1e --- /dev/null +++ b/example/infra/nomad/conf/nomad.hcl @@ -0,0 +1,16 @@ + + +bind_addr = "0.0.0.0" # the default +server { + enabled = true +} + +client { + enabled = true +} + +vault { + enabled = true + address = "http://localhost:8200" + token = "root" +} diff --git a/example/infra/nomad/jobs/.terraform.lock.hcl b/example/infra/nomad/jobs/.terraform.lock.hcl new file mode 100644 index 0000000..b63db47 --- /dev/null +++ b/example/infra/nomad/jobs/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/nomad" { + version = "1.4.19" + constraints = "1.4.19" + hashes = [ + "h1:Pj+LeWXHK1ejOKxIMN7k6kX5uK7lD6P1gmflX3vhs3M=", + "zh:2f3ceeb3318a6304026035b0ac9ee3e52df04913bb9ee78827e58c5398b41254", + "zh:3fbe76c7d957d20dfe3c8c0528b33084651f22a95be9e0452b658e0922916e2a", + "zh:595671a05828cfe6c42ef73aac894ac39f81a52cc662a76f37eb74ebe04ddf75", + "zh:5d76e8788d2af3e60daf8076babf763ec887480bbb9734baccccd8fcddf4f03e", + "zh:676985afeaca6e67b22d60d43fd0ed7055763029ffebc3026089fe2fd3b4a288", + "zh:69152ce6164ac999a640cff962ece45208270e1ac37c10dac484eeea5cf47275", + "zh:6da0b15c05b81f947ec8e139bd81eeeb05c0d36eb5a967b985d0625c60998b40", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:822c0a3bbada5e38099a379db8b2e339526843699627c3be3664cc3b3752bab7", + "zh:af23af2f98a84695b25c8eba7028a81ad4aad63c44aefb79e01bbe2dc82e7f78", + "zh:e36cac9960b7506d92925b667254322520966b9c3feb3ca6102e57a1fb9b1761", + "zh:ffd1e096c1cc35de879c740a91918e9f06b627818a3cb4b1d87b829b54a6985f", + ] +} diff --git a/example/infra/nomad/jobs/nomad.tf b/example/infra/nomad/jobs/nomad.tf new file mode 100644 index 0000000..1934ce6 --- /dev/null +++ b/example/infra/nomad/jobs/nomad.tf @@ -0,0 +1,15 @@ +terraform { + required_providers { + nomad = { + source = "hashicorp/nomad" + version = "1.4.19" + } + + } +} +provider "nomad" { + address = "http://localhost:4646" +} +resource "nomad_job" "pg" { + jobspec = file("${path.module}/pg.nomad") +} diff --git a/example/infra/nomad/jobs/pg.nomad b/example/infra/nomad/jobs/pg.nomad new file mode 100644 index 0000000..4cb19cf --- /dev/null +++ b/example/infra/nomad/jobs/pg.nomad @@ -0,0 +1,42 @@ +job "postgres" { + + type = "service" + + datacenters = ["dc1"] + + group "pg" { + + network { + port "db" { + to = 5432 + static = 5432 + } + } + task "postgres" { + driver = "docker" + + config { + image = "postgres:15" + ports = ["db"] + + } + env { + POSTGRES_PASSWORD = "secret" + } + resources { + cpu = 500 + memory = 1024 + } + } + service { + name = "postgres" + port = "db" + provider = "nomad" + check { + type = "tcp" + interval = "10s" + timeout = "2s" + } + } + } +} diff --git a/example/infra/readme.md b/example/infra/readme.md new file mode 100644 index 0000000..2a5dc0d --- /dev/null +++ b/example/infra/readme.md @@ -0,0 +1,10 @@ +# Start Vault in dev mode +```bash +$ vault server -dev -dev-root-token-id=root -dev-listen-address=0.0.0.0:8200 +``` + + +# Start Nomad in dev mode +```bash +$ nomad agent -dev -dev-connect -dev-root-token-id=root -dev-listen-address= +``` diff --git a/example/infra/vault/.terraform.lock.hcl b/example/infra/vault/.terraform.lock.hcl new file mode 100644 index 0000000..575bb02 --- /dev/null +++ b/example/infra/vault/.terraform.lock.hcl @@ -0,0 +1,22 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/vault" { + version = "3.14.0" + constraints = "3.14.0" + hashes = [ + "h1:tDYvtN07fBPn1uCsAXKyxGcwgGagDPcWs4FV1driTgU=", + "zh:07e797c3b14cc45f1a3fa3adb6269f28f182630b9af9403a2a447919d4e9992a", + "zh:0d88c6c50f7975f60c84d446bf95b26652c9457e62f2d5b24221b769d6daf809", + "zh:1670c513f85788308d317e45038234ac367f52f7bd0ea8f527f0a6291dd23659", + "zh:1b5a07fd053a0d7d1da80cb3e929b44c000c614d3738bb7ff82b4d56ed854017", + "zh:34a43de7f3d3749cbc50b81b84fe38961c3dfbda819708a814c2206045ecf69b", + "zh:416f710365d060c8239522363257e162a267c01463ac95ad2c2dd0acf05b6d35", + "zh:73956090e0e9b69adbcfe1bcaad20ec45779f2e7f3f2fb3a5f865402a2cd2485", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:e2df6077e925a8438cfd2deb3bce5f1029a2e3edd2a635b12636d426390600dd", + "zh:e3e2797ae1cfc6aff66329ee81baaf780e1f5f295ad887ac7ff4c1e2754a8c8c", + "zh:f34ec435d16244ecf0f909872850070428aeadd352b6a21ab1f787d81f8bae9f", + "zh:f3a930e64b2c10d2ece5acc856d3438cdd375ccfc5ac10fc4a8fe163f74af93a", + ] +} diff --git a/example/infra/vault/vault.hcl b/example/infra/vault/vault.hcl new file mode 100644 index 0000000..e69de29 diff --git a/example/infra/vault/vault.tf b/example/infra/vault/vault.tf new file mode 100644 index 0000000..c9dda0f --- /dev/null +++ b/example/infra/vault/vault.tf @@ -0,0 +1,66 @@ +terraform { + required_providers { + vault = { + source = "hashicorp/vault" + version = "3.14.0" + } + } +} + +provider "vault" { + address = "http://localhost:8200" + token = "root" +} + + +resource "vault_mount" "db" { + path = "postgres" + type = "database" +} + +resource "vault_database_secret_backend_connection" "postgres" { + backend = vault_mount.db.path + name = "postgres" + allowed_roles = ["dev", "prod"] + + postgresql { + connection_url = "postgres://postgres:secret@localhost:5432/postgres" + } +} + + +resource "vault_database_secret_backend_role" "role" { + backend = vault_mount.db.path + name = "dev" + db_name = vault_database_secret_backend_connection.postgres.name + creation_statements = ["CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';"] +} +resource "vault_policy" "db_access" { + name = "db-access" + policy = <<-EOT + path "postgres/creds/dev" { + capabilities = ["read"] + } + + EOT + + +} + +# terraform { +# required_providers { +# postgresql = { +# source = "cyrilgdn/postgresql" +# version = "1.18.0" +# } +# } +# } +# provider "postgresql" { +# host = "localhost" +# port = 5432 +# database = "postgres" +# username = "postgres" +# password = "secret" +# sslmode = "disable" +# connect_timeout = 15 +# } diff --git a/example/readme.md b/example/readme.md new file mode 100644 index 0000000..9d6971f --- /dev/null +++ b/example/readme.md @@ -0,0 +1,12 @@ +# Examples + +## Cost Center + +This example demonstrates a validator that checks wether a job contains meta data information a cost center code and if the code starts with `cccode-` + +[cost center mutator](validators/costcenter/costcenter_meta.rego). + + +```bash +nacp -config example1.conf.hcl +```