Working tests of policy and policies

This commit is contained in:
2025-05-19 21:30:18 +03:00
parent 9b34cd9199
commit 9c67e03de3
7 changed files with 184 additions and 248 deletions

View File

@@ -1,13 +1,10 @@
package main
import future.keywords.in
# Import the raw input instead of using tfplan alias
import input
# Helper function to get VM resources
get_vms = vms {
planned_values := input.planned_values
vms := [r | r := planned_values.root_module.resources[_]; r.type == "proxmox_vm_qemu"]
}
vms := [r | r := input.planned_values.root_module.resources[_]; r.type == "proxmox_vm_qemu"]
# Helper function to check if a value is empty or undefined
is_empty(value) {
@@ -23,28 +20,28 @@ min_memory = 512
# Deny if VM allows password authentication
deny[msg] {
vm := get_vms[_]
some vm in vms
not is_empty(vm.values.cipassword)
msg := sprintf("VM '%s' uses password authentication. Use SSH keys only.", [vm.name])
}
# Deny if VM allows root login
deny[msg] {
vm := get_vms[_]
some vm in vms
vm.values.ciuser == "root"
msg := sprintf("VM '%s' allows root login. Use a non-root user.", [vm.name])
}
# Deny if qemu-agent is not enabled
deny[msg] {
vm := get_vms[_]
some vm in vms
vm.values.agent != 1
msg := sprintf("VM '%s' does not have qemu-agent enabled (agent = 1).", [vm.name])
}
# Deny if VM uses insecure network bridge
deny[msg] {
vm := get_vms[_]
some vm in vms
net := vm.values.network[_]
net.bridge != "vmbr2"
msg := sprintf("VM '%s' uses insecure network bridge '%s'. Use 'vmbr2'.", [vm.name, net.bridge])
@@ -52,15 +49,15 @@ deny[msg] {
# Deny if IPv6 is not disabled
deny[msg] {
vm := get_vms[_]
some vm in vms
not vm.values.skip_ipv6
msg := sprintf("VM '%s' does not have IPv6 disabled (skip_ipv6 = true).", [vm.name])
}
# Deny if TLS verification is disabled
deny[msg] {
provider := input.configuration.provider_config.proxmox
provider.expressions.pm_tls_insecure.constant_value == true
tls_enabled := input.variables.pm_tls_insecure.value
tls_enabled == true
msg := "TLS verification must be enabled (pm_tls_insecure = false)"
}
@@ -73,7 +70,7 @@ deny[msg] {
# Deny if VM memory is below minimum requirement
deny[msg] {
vm := get_vms[_]
some vm in vms
memory := to_number(vm.values.memory)
memory < min_memory
msg := sprintf("VM '%s' has insufficient memory (%dMB). Minimum required: %dMB.", [vm.name, memory, min_memory])
@@ -81,14 +78,14 @@ deny[msg] {
# Deny if VM does not have a description
deny[msg] {
vm := get_vms[_]
some vm in vms
is_empty(vm.values.desc)
msg := sprintf("VM '%s' must have a description for documentation purposes.", [vm.name])
}
# Deny if VM uses default SCSI controller
deny[msg] {
vm := get_vms[_]
some vm in vms
vm.values.scsihw == "lsi"
msg := sprintf("VM '%s' uses default SCSI controller. Use virtio-scsi-pci for better performance.", [vm.name])
}

View File

@@ -1,96 +1,111 @@
package main
# Test data
mock_secure_vm := {
"type": "proxmox_vm_qemu",
"name": "secure_vm",
"values": {
"cipassword": "",
"ciuser": "admin",
"agent": 1,
"network": [{
"bridge": "vmbr2"
}],
"skip_ipv6": true,
"memory": 2048,
"desc": "Production web server",
"scsihw": "virtio-scsi-pci",
"cpu": "host",
"backup": true,
"tags": "prod,web"
}
}
mock_insecure_vm := {
"type": "proxmox_vm_qemu",
"name": "insecure_vm",
"values": {
"cipassword": "password123",
"ciuser": "root",
"agent": 0,
"network": [{
"bridge": "vmbr0"
}],
"skip_ipv6": false,
"memory": 256,
"desc": "",
"scsihw": "lsi",
"cpu": "",
"backup": false,
"tags": ""
}
}
mock_input_secure := {
"planned_values": {
"root_module": {
"resources": [mock_secure_vm]
}
},
"configuration": {
"provider_config": {
"proxmox": {
"expressions": {
"pm_tls_insecure": {
"constant_value": false
}
}
}
},
"terraform": {
"required_providers": {
"proxmox": {
"version_constraint": "=2.9.14"
}
}
"variables":
{
"pm_tls_insecure": {
"value": false
}
},
"planned_values": {
"root_module": {
"resources": [
{
"type": "proxmox_vm_qemu",
"name": "secure_vm",
"values": {
"cipassword": "",
"ciuser": "admin",
"agent": 1,
"network": [
{
"bridge": "vmbr2"
}
],
"skip_ipv6": true,
"memory": 2048,
"desc": "Production web server",
"scsihw": "virtio-scsi-pci",
"cpu": "host",
"backup": true,
"tags": "prod,web"
}
}
]
}
},
"configuration": {
"provider_config": {
"proxmox": {
"expressions": {
"pm_tls_insecure": {
"constant_value": false
}
}
}
},
"terraform": {
"required_providers": {
"proxmox": {
"version_constraint": "=2.9.14"
}
}
}
}
}
mock_input_insecure := {
"planned_values": {
"root_module": {
"resources": [mock_insecure_vm]
}
},
"configuration": {
"provider_config": {
"proxmox": {
"expressions": {
"pm_tls_insecure": {
"constant_value": true
}
}
}
},
"terraform": {
"required_providers": {
"proxmox": {
"version_constraint": "~2.9.14"
}
}
"variables":
{
"pm_tls_insecure": {
"value": true
}
},
"planned_values": {
"root_module": {
"resources": [
{
"type": "proxmox_vm_qemu",
"name": "insecure_vm",
"values": {
"cipassword": "password123",
"ciuser": "root",
"agent": 0,
"network": [
{
"bridge": "vmbr0"
}
],
"skip_ipv6": false,
"memory": 256,
"desc": "",
"scsihw": "lsi",
"cpu": "",
"backup": false,
"tags": ""
}
}
]
}
},
"configuration": {
"provider_config": {
"proxmox": {
"expressions": {
"pm_tls_insecure": {
"constant_value": true
}
}
}
},
"terraform": {
"required_providers": {
"proxmox": {
"version_constraint": "~2.9.14"
}
}
}
}
}
# Test secure configuration passes
@@ -101,77 +116,40 @@ test_secure_config {
# Test password authentication
test_password_auth {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' uses password authentication. Use SSH keys only."]
deny["VM 'insecure_vm' uses password authentication. Use SSH keys only."] with input as mock_input_insecure
}
# Test qemu agent
test_qemu_agent {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' does not have qemu-agent enabled (agent = 1)."]
deny["VM 'insecure_vm' does not have qemu-agent enabled (agent = 1)."] with input as mock_input_insecure
}
# Test network bridge
test_network_bridge {# Deny if VM does not have proper tags for identification
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' must have tags for proper identification and management."]
test_network_bridge {
deny["VM 'insecure_vm' uses insecure network bridge 'vmbr0'. Use 'vmbr2'."] with input as mock_input_insecure
}
# Test TLS verification
test_tls_verification {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["TLS verification must be enabled (pm_tls_insecure = false)"]
deny["TLS verification must be enabled (pm_tls_insecure = false)"] with input as mock_input_insecure
}
# Test provider version pinning
test_provider_version {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["Provider version must be pinned with '=' constraint"]
deny["Provider version must be pinned with '=' constraint"] with input as mock_input_insecure
}
# Test minimum memory requirement
test_minimum_memory {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' has insufficient memory (256MB). Minimum required: 512MB."]
deny["VM 'insecure_vm' has insufficient memory (256MB). Minimum required: 512MB."] with input as mock_input_insecure
}
# Test VM description requirement
test_vm_description {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' must have a description for documentation purposes."]
deny["VM 'insecure_vm' must have a description for documentation purposes."] with input as mock_input_insecure
}
# Test SCSI controller requirement
test_scsi_controller {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' uses default SCSI controller. Use virtio-scsi-pci for better performance."]
}
# Test CPU type requirement
test_cpu_type {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' must have CPU type explicitly set for consistent performance."]
}
# Test backup requirement
test_backup_enabled {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' must have backup enabled for disaster recovery."]
}
# Test tags requirement
test_tags_required {
input := mock_input_insecure
deny_msgs := {msg | msg := deny[_]}
deny_msgs["VM 'insecure_vm' must have tags for proper identification and management."]
}
deny["VM 'insecure_vm' uses default SCSI controller. Use virtio-scsi-pci for better performance."] with input as mock_input_insecure
}

View File

@@ -0,0 +1,47 @@
{
"planned_values": {
"root_module": {
"resources": [
{
"type": "proxmox_vm_qemu",
"name": "insecure_vm",
"values": {
"cipassword": "password123",
"ciuser": "root",
"agent": 0,
"network": [
{
"bridge": "vmbr0"
}
],
"skip_ipv6": false,
"memory": 256,
"desc": "",
"scsihw": "lsi",
"cpu": "",
"backup": false,
"tags": ""
}
}
]
}
},
"configuration": {
"provider_config": {
"proxmox": {
"expressions": {
"pm_tls_insecure": {
"constant_value": true
}
}
}
},
"terraform": {
"required_providers": {
"proxmox": {
"version_constraint": "~2.9.14"
}
}
}
}
}