Skip to content

Commit e992f77

Browse files
committed
migrate additional first-gen VMware policies
1 parent 2d6ab7d commit e992f77

File tree

19 files changed

+759
-19
lines changed

19 files changed

+759
-19
lines changed

governance/third-generation/common-functions/tfconfig-functions/tfconfig-functions.sentinel

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,8 @@ filter_attribute_does_not_match_regex = func(items, attr, expr, prtmsg) {
398398
if val is null {
399399
# Add the item and a warning message to the violators list
400400
message = to_string(index) + " has " + to_string(attr) +
401-
" that is null or undefined"
401+
" that is null or undefined. " + "It is supposed to " +
402+
"match the regex " + to_string(expr)
402403
violators[index] = item
403404
messages[index] = message
404405
if prtmsg {

governance/third-generation/common-functions/tfplan-functions/tfplan-functions.sentinel

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ filter_attribute_not_contains_list = func(resources, attr, required, prtmsg) {
323323
not (types.type_of(v) is "list" or types.type_of(v) is "map") {
324324
# Add the resource and a warning message to the violators list
325325
message = to_string(address) + " has " + to_string(attr) +
326-
" that is missing, null, or is not a map or a list" + "\nIt should have had these tags: " + to_string(required)
326+
" that is missing, null, or is not a map or a list. " + "It should have had these items: " + to_string(required)
327327
violators[address] = rc
328328
messages[address] = message
329329
if prtmsg {
@@ -486,7 +486,8 @@ filter_attribute_is_not_value = func(resources, attr, value, prtmsg) {
486486
if v is null {
487487
# Add the resource and a warning message to the violators list
488488
message = to_string(address) + " has " + to_string(attr) +
489-
" that is null or undefined"
489+
" that is null or undefined. " + "It is supposed to be " +
490+
to_string(value)
490491
violators[address] = rc
491492
messages[address] = message
492493
if prtmsg {
@@ -523,7 +524,7 @@ filter_attribute_is_value = func(resources, attr, value, prtmsg) {
523524
if v is value {
524525
# Add the resource and a warning message to the violators list
525526
message = to_string(address) + " has " + to_string(attr) + " with value " +
526-
to_string(v) + " that is equal to " + to_string(value)
527+
to_string(v) + " that is not allowed."
527528
violators[address] = rc
528529
messages[address] = message
529530
if prtmsg {
@@ -547,7 +548,8 @@ filter_attribute_greater_than_value = func(resources, attr, value, prtmsg) {
547548
if float(v) else null is null {
548549
# Add the resource and a warning message to the violators list
549550
message = to_string(address) + " has " + to_string(attr) +
550-
" that is null or undefined"
551+
" that is null or undefined. " + "It is supposed to be less " +
552+
"than or equal to " + to_string(value)
551553
violators[address] = rc
552554
messages[address] = message
553555
if prtmsg {
@@ -580,7 +582,8 @@ filter_attribute_less_than_value = func(resources, attr, value, prtmsg) {
580582
if float(v) else null is null {
581583
# Add the resource and a warning message to the violators list
582584
message = to_string(address) + " has " + to_string(attr) +
583-
" that is null or undefined"
585+
" that is null or undefined. " + "It is supposed to be greater " +
586+
"than or equal to " + to_string(value)
584587
violators[address] = rc
585588
messages[address] = message
586589
if prtmsg {
@@ -669,7 +672,8 @@ filter_attribute_does_not_have_prefix = func(resources, attr, prefix, prtmsg) {
669672
if v is null {
670673
# Add the resource and a warning message to the violators list
671674
message = to_string(address) + " has " + to_string(attr) +
672-
" that is null or undefined"
675+
" that is null or undefined. " + "It must have a value that " +
676+
"starts with " + to_string(prefix)
673677
violators[address] = rc
674678
messages[address] = message
675679
if prtmsg {
@@ -702,7 +706,8 @@ filter_attribute_has_prefix = func(resources, attr, prefix, prtmsg) {
702706
if v is null {
703707
# Add the resource and a warning message to the violators list
704708
message = to_string(address) + " has " + to_string(attr) +
705-
" that is null or undefined"
709+
" that is null or undefined. " + "It must have a value that " +
710+
"does not start with " + to_string(prefix)
706711
violators[address] = rc
707712
messages[address] = message
708713
if prtmsg {
@@ -735,7 +740,8 @@ filter_attribute_does_not_have_suffix = func(resources, attr, suffix, prtmsg) {
735740
if v is null {
736741
# Add the resource and a warning message to the violators list
737742
message = to_string(address) + " has " + to_string(attr) +
738-
" that is null or undefined"
743+
" that is null or undefined. " + "It must have a value that " +
744+
"ends with " + to_string(prefix)
739745
violators[address] = rc
740746
messages[address] = message
741747
if prtmsg {
@@ -768,7 +774,8 @@ filter_attribute_has_suffix = func(resources, attr, suffix, prtmsg) {
768774
if v is null {
769775
# Add the resource and a warning message to the violators list
770776
message = to_string(address) + " has " + to_string(attr) +
771-
" that is null or undefined"
777+
" that is null or undefined. " + "It must have a value that " +
778+
"does not end with " + to_string(suffix)
772779
violators[address] = rc
773780
messages[address] = message
774781
if prtmsg {

governance/third-generation/common-functions/tfstate-functions/tfstate-functions.sentinel

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ filter_attribute_not_contains_list = func(resources, attr, required, prtmsg) {
287287
not (types.type_of(v) is "list" or types.type_of(v) is "map") {
288288
# Add the resource and a warning message to the violators list
289289
message = to_string(address) + " has " + to_string(attr) +
290-
" that is missing, null, or is not a map or a list"
290+
" that is missing, null, or is not a map or a list. " + "It should have had these items: " + to_string(required)
291291
violators[address] = r
292292
messages[address] = message
293293
if prtmsg {
@@ -450,7 +450,8 @@ filter_attribute_is_not_value = func(resources, attr, value, prtmsg) {
450450
if v is null {
451451
# Add the resource and a warning message to the violators list
452452
message = to_string(address) + " has " + to_string(attr) +
453-
" that is null or undefined"
453+
" that is null or undefined. " + "It is supposed to be " +
454+
to_string(value)
454455
violators[address] = r
455456
messages[address] = message
456457
if prtmsg {
@@ -487,7 +488,7 @@ filter_attribute_is_value = func(resources, attr, value, prtmsg) {
487488
if v is value {
488489
# Add the resource and a warning message to the violators list
489490
message = to_string(address) + " has " + to_string(attr) + " with value " +
490-
to_string(v) + " that is equal to " + to_string(value)
491+
to_string(v) + " that is not allowed."
491492
violators[address] = r
492493
messages[address] = message
493494
if prtmsg {
@@ -511,7 +512,8 @@ filter_attribute_greater_than_value = func(resources, attr, value, prtmsg) {
511512
if float(v) else null is null {
512513
# Add the resource and a warning message to the violators list
513514
message = to_string(address) + " has " + to_string(attr) +
514-
" that is null or undefined"
515+
" that is null or undefined. " + "It is supposed to be less " +
516+
"than or equal to " + to_string(value)
515517
violators[address] = r
516518
messages[address] = message
517519
if prtmsg {
@@ -544,7 +546,8 @@ filter_attribute_less_than_value = func(resources, attr, value, prtmsg) {
544546
if float(v) else null is null {
545547
# Add the resource and a warning message to the violators list
546548
message = to_string(address) + " has " + to_string(attr) +
547-
" that is null or undefined"
549+
" that is null or undefined. " + "It is supposed to be greater " +
550+
"than or equal to " + to_string(value)
548551
violators[address] = r
549552
messages[address] = message
550553
if prtmsg {
@@ -633,7 +636,8 @@ filter_attribute_does_not_have_prefix = func(resources, attr, prefix, prtmsg) {
633636
if v is null {
634637
# Add the resource and a warning message to the violators list
635638
message = to_string(address) + " has " + to_string(attr) +
636-
" that is null or undefined"
639+
" that is null or undefined. " + "It must have a value that " +
640+
"starts with " + to_string(prefix)
637641
violators[address] = r
638642
messages[address] = message
639643
if prtmsg {
@@ -666,7 +670,8 @@ filter_attribute_has_prefix = func(resources, attr, prefix, prtmsg) {
666670
if v is null {
667671
# Add the resource and a warning message to the violators list
668672
message = to_string(address) + " has " + to_string(attr) +
669-
" that is null or undefined"
673+
" that is null or undefined. " + "It must have a value that " +
674+
"does not start with " + to_string(prefix)
670675
violators[address] = r
671676
messages[address] = message
672677
if prtmsg {
@@ -699,7 +704,8 @@ filter_attribute_does_not_have_suffix = func(resources, attr, suffix, prtmsg) {
699704
if v is null {
700705
# Add the resource and a warning message to the violators list
701706
message = to_string(address) + " has " + to_string(attr) +
702-
" that is null or undefined"
707+
" that is null or undefined. " + "It must have a value that " +
708+
"ends with " + to_string(prefix)
703709
violators[address] = r
704710
messages[address] = message
705711
if prtmsg {
@@ -732,7 +738,8 @@ filter_attribute_has_suffix = func(resources, attr, suffix, prtmsg) {
732738
if v is null {
733739
# Add the resource and a warning message to the violators list
734740
message = to_string(address) + " has " + to_string(attr) +
735-
" that is null or undefined"
741+
" that is null or undefined. " + "It must have a value that " +
742+
"does not end with " + to_string(suffix)
736743
violators[address] = r
737744
messages[address] = message
738745
if prtmsg {
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# This policy uses the Sentinel tfplan/v2 import to require that
2+
# all VMware datastore clusters enable storage DRS
3+
4+
# Import common-functions/tfplan-functions/tfplan-functions.sentinel
5+
# with alias "plan"
6+
import "tfplan-functions" as plan
7+
8+
# Get all datastore clusters
9+
allDatastoreClusters = plan.find_resources("vsphere_datastore_cluster")
10+
11+
# Filter to datastore clusters that do not enable storage DRS
12+
# Warnings will be printed for all violations since the last parameter is true
13+
datastoreClustersWithoutDRS = plan.filter_attribute_is_not_value(
14+
allDatastoreClusters, "sdrs_enabled", true, true)
15+
16+
# Main rule
17+
validated = length(datastoreClustersWithoutDRS["messages"]) is 0
18+
19+
main = rule {
20+
validated
21+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# This policy uses the Sentinel tfplan/v2 import to require that NAS
2+
# Datastores be type NFS41 and use Kerberos for security
3+
4+
# Import common-functions/tfplan-functions/tfplan-functions.sentinel
5+
# with alias "plan"
6+
import "tfplan-functions" as plan
7+
8+
# Get all NAS Datastores
9+
allDatastores = plan.find_resources("vsphere_nas_datastore")
10+
11+
# Filter to Datastores that are not NFS
12+
# Warnings will be printed for all violations since the last parameter is true
13+
nonNFSDatastores = plan.filter_attribute_is_not_value(allDatastores,
14+
"type", "NFS41", true)
15+
16+
# Filter to Datastores that do not use Kerberos
17+
# Warnings will be printed for all violations since the last parameter is true
18+
nonKerberosDatastores = plan.filter_attribute_not_in_list(allDatastores,
19+
"security_type", ["SEC_KRB5", "SEC_KRB5I"] , true)
20+
21+
# Main rule
22+
validated = length(nonNFSDatastores["messages"]) is 0 and
23+
length(nonKerberosDatastores["messages"]) is 0
24+
25+
main = rule {
26+
validated
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# This policy uses the Sentinel tfplan/v2 import to limit the size
2+
# of VMware virtual disks and require thin disks
3+
4+
# Import common-functions/tfplan-functions/tfplan-functions.sentinel
5+
# with alias "plan"
6+
import "tfplan-functions" as plan
7+
8+
# Max Disk Size Limit (in GB)
9+
maxSize = 100
10+
11+
# Get all Virtual Disks
12+
allVDs = plan.find_resources("vsphere_virtual_disk")
13+
14+
# Filter to disks with large size
15+
# Warnings will be printed for all violations since the last parameter is true
16+
largeVDs = plan.filter_attribute_greater_than_value(allVDs,
17+
"size", maxSize, true)
18+
19+
# Filter to disks that are not thin
20+
# Warnings will be printed for all violations since the last parameter is true
21+
nonThinVDs = plan.filter_attribute_is_not_value(allVDs,
22+
"type", "thin", true)
23+
24+
# Main rule
25+
validated = length(largeVDs["messages"]) is 0 and
26+
length(nonThinVDs["messages"]) is 0
27+
28+
main = rule {
29+
validated
30+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"modules": {
3+
"tfplan-functions": {
4+
"path": "../../../common-functions/tfplan-functions/tfplan-functions.sentinel"
5+
}
6+
},
7+
"mock": {
8+
"tfplan/v2": "mock-tfplan-fail.sentinel"
9+
},
10+
"test": {
11+
"main": false
12+
}
13+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
terraform_version = "0.13.5"
2+
3+
variables = {}
4+
5+
resource_changes = {
6+
"vsphere_datastore_cluster.datastore_cluster_1": {
7+
"address": "vsphere_datastore_cluster.datastore_cluster_1",
8+
"change": {
9+
"actions": [
10+
"create",
11+
],
12+
"after": {
13+
"custom_attributes": null,
14+
"datacenter_id": "datacenter-2",
15+
"folder": null,
16+
"name": "terraform-datastore-cluster-test-1",
17+
"sdrs_advanced_options": null,
18+
"sdrs_automation_level": "manual",
19+
"sdrs_default_intra_vm_affinity": true,
20+
"sdrs_enabled": false,
21+
"sdrs_free_space_threshold": 50,
22+
"sdrs_free_space_threshold_mode": "utilization",
23+
"sdrs_free_space_utilization_difference": 5,
24+
"sdrs_io_balance_automation_level": null,
25+
"sdrs_io_latency_threshold": 15,
26+
"sdrs_io_load_balance_enabled": true,
27+
"sdrs_io_load_imbalance_threshold": 5,
28+
"sdrs_io_reservable_iops_threshold": null,
29+
"sdrs_io_reservable_percent_threshold": 60,
30+
"sdrs_io_reservable_threshold_mode": "automated",
31+
"sdrs_load_balance_interval": 480,
32+
"sdrs_policy_enforcement_automation_level": null,
33+
"sdrs_rule_enforcement_automation_level": null,
34+
"sdrs_space_balance_automation_level": null,
35+
"sdrs_space_utilization_threshold": 80,
36+
"sdrs_vm_evacuation_automation_level": null,
37+
"tags": null,
38+
},
39+
"after_unknown": {
40+
"id": true,
41+
},
42+
"before": null,
43+
},
44+
"deposed": "",
45+
"index": null,
46+
"mode": "managed",
47+
"module_address": "",
48+
"name": "datastore_cluster_1",
49+
"provider_name": "registry.terraform.io/hashicorp/vsphere",
50+
"type": "vsphere_datastore_cluster",
51+
},
52+
"vsphere_datastore_cluster.datastore_cluster_2": {
53+
"address": "vsphere_datastore_cluster.datastore_cluster_2",
54+
"change": {
55+
"actions": [
56+
"create",
57+
],
58+
"after": {
59+
"custom_attributes": null,
60+
"datacenter_id": "datacenter-2",
61+
"folder": null,
62+
"name": "terraform-datastore-cluster-test-2",
63+
"sdrs_advanced_options": null,
64+
"sdrs_automation_level": "manual",
65+
"sdrs_default_intra_vm_affinity": true,
66+
"sdrs_enabled": null,
67+
"sdrs_free_space_threshold": 50,
68+
"sdrs_free_space_threshold_mode": "utilization",
69+
"sdrs_free_space_utilization_difference": 5,
70+
"sdrs_io_balance_automation_level": null,
71+
"sdrs_io_latency_threshold": 15,
72+
"sdrs_io_load_balance_enabled": true,
73+
"sdrs_io_load_imbalance_threshold": 5,
74+
"sdrs_io_reservable_iops_threshold": null,
75+
"sdrs_io_reservable_percent_threshold": 60,
76+
"sdrs_io_reservable_threshold_mode": "automated",
77+
"sdrs_load_balance_interval": 480,
78+
"sdrs_policy_enforcement_automation_level": null,
79+
"sdrs_rule_enforcement_automation_level": null,
80+
"sdrs_space_balance_automation_level": null,
81+
"sdrs_space_utilization_threshold": 80,
82+
"sdrs_vm_evacuation_automation_level": null,
83+
"tags": null,
84+
},
85+
"after_unknown": {
86+
"id": true,
87+
"sdrs_enabled": true,
88+
},
89+
"before": null,
90+
},
91+
"deposed": "",
92+
"index": null,
93+
"mode": "managed",
94+
"module_address": "",
95+
"name": "datastore_cluster_2",
96+
"provider_name": "registry.terraform.io/hashicorp/vsphere",
97+
"type": "vsphere_datastore_cluster",
98+
},
99+
}
100+
101+
output_changes = {}

0 commit comments

Comments
 (0)