Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(terraform): add CKV_NCP_1 about lb target group health check, CKV_NCP_2 about access control group description #3569

Merged
merged 16 commits into from
Oct 2, 2022
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions checkov/terraform/checks/resource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@
from checkov.terraform.checks.resource.alicloud import * # noqa
from checkov.terraform.checks.resource.kubernetes import * # noqa
from checkov.terraform.checks.resource.yandexcloud import * # noqa
from checkov.terraform.checks.resource.ncp import * # noqa
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck


class AccessControlGroupRuleDescription(BaseResourceCheck):
def __init__(self):
name = "Ensure every access control groups rule has a description"
id = "CKV_NCP_002"
supported_resource = [
'ncloud_access_control_group',
'ncloud_access_control_group_rule',
]
categories = [CheckCategories.NETWORKING]
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resource)

def scan_resource_conf(self, conf):
"""
https://registry.terraform.io/providers/NaverCloudPlatform/ncloud/latest/docs/resources/access_control_group
:return: <CheckResult>
"""
group_result = self.check_rule(rule_type='group_or_rule_description', conf=conf)
if 'type' not in conf.keys():
outbound_result = self.check_rule(rule_type='outbound', conf=conf)
inbound_result = self.check_rule(rule_type='inbound', conf=conf)
if group_result == CheckResult.PASSED and outbound_result == CheckResult.PASSED and inbound_result == CheckResult.PASSED:
return CheckResult.PASSED
return CheckResult.FAILED

return group_result

def check_rule(self, rule_type, conf):
if rule_type == 'group_or_rule_description':
self.evaluated_keys = ['description']
if conf.get('description'):
return CheckResult.PASSED
return CheckResult.FAILED

if rule_type in conf.keys():
for rule in conf[rule_type]:
if isinstance(rule, dict) and rule.get('description'):
self.evaluated_keys.append(f'{rule_type}/[{conf[rule_type].index(rule)}]')
return CheckResult.FAILED
return CheckResult.PASSED


check = AccessControlGroupRuleDescription()
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck


class LBTargetGroupDefinesHealthCheck(BaseResourceCheck):
def __init__(self):
name = "Ensure HTTP HTTPS Target group defines Healthcheck"
id = "CKV_NCP_1"
supported_resources = ['ncloud_lb_target_group']
categories = [CheckCategories.GENERAL_SECURITY]
super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)

def scan_resource_conf(self, conf):
if conf.get("protocol") in (["HTTP"], ["HTTPS"]):
health_checks = conf.get("health_check")
if health_checks and isinstance(health_checks, list):
healthcheck = health_checks[0]
if isinstance(healthcheck, dict) and healthcheck.get("url_path"):
return CheckResult.PASSED
return CheckResult.FAILED
return CheckResult.UNKNOWN


check = LBTargetGroupDefinesHealthCheck()
4 changes: 4 additions & 0 deletions checkov/terraform/checks/resource/ncp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from pathlib import Path

modules = Path(__file__).parent.glob("*.py")
__all__ = [f.stem for f in modules if f.is_file() and not f.stem == "__init__"]
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[pytest]
addopts = -n 2 --dist loadfile
asyncio_mode = auto

Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
resource "ncloud_access_control_group" "pass" {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you also add a passing + failing resource for ncloud_access_control_group_rule

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll check additional resource ncloud_access_control_group_rule!! thanks!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I add resource ncloud_access_control_group_rule !

And Does resources to be tested mean what we commited?

name = "example-acg"
vpc_no = data.ncloud_vpc.selected.id
description = "description"
}

resource "ncloud_access_control_group" "fail" {
name = "example-acg"
vpc_no = data.ncloud_vpc.selected.id
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

resource "ncloud_lb_target_group" "pass" {
vpc_no = ncloud_vpc.main.vpc_no
protocol = "HTTP"
target_type = "VSVR"
port = 8080
description = "for test"
health_check {
protocol = "HTTP"
http_method = "GET"
port = 8080
url_path = "/monitor/l7check"
cycle = 30
up_threshold = 2
down_threshold = 2
}
algorithm_type = "RR"
}
resource "ncloud_lb_target_group" "fail" {
vpc_no = ncloud_vpc.main.vpc_no
protocol = "HTTP"
target_type = "VSVR"
port = 8080
description = "for test"
algorithm_type = "RR"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import unittest
from pathlib import Path

from checkov.runner_filter import RunnerFilter
from checkov.terraform.checks.resource.ncp.AccessControlGroupRuleDescription import check
from checkov.terraform.runner import Runner


class TestAccessControlGroupRuleDescription(unittest.TestCase):
def test(self):
# given
test_files_dir = Path(__file__).parent / "example_AccessControlGroupRuleDescription"

# when
report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id]))

# then
summary = report.get_summary()

passing_resources = {
"ncloud_access_control_group.pass",
}
failing_resources = {
"ncloud_access_control_group.fail",
}

passed_check_resources = {c.resource for c in report.passed_checks}
failed_check_resources = {c.resource for c in report.failed_checks}

self.assertEqual(summary["passed"], 1)
self.assertEqual(summary["failed"], 1)
self.assertEqual(summary["skipped"], 0)
self.assertEqual(summary["parsing_errors"], 0)

self.assertEqual(passing_resources, passed_check_resources)
self.assertEqual(failing_resources, failed_check_resources)


if __name__ == '__main__':
unittest.main()
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import unittest
from pathlib import Path

from checkov.runner_filter import RunnerFilter
from checkov.terraform.checks.resource.ncp.LBTargetGroupDefinesHealthCheck import check
from checkov.terraform.runner import Runner


class TestLBTargetGroupDefinesHealthCheck(unittest.TestCase):
def test(self):
# given
test_files_dir = Path(__file__).parent / "example_LBTargetGroupDefinesHealthCheck"

# when
report = Runner().run(root_folder=str(test_files_dir), runner_filter=RunnerFilter(checks=[check.id]))

# then
summary = report.get_summary()

passing_resources = {
"ncloud_lb_target_group.pass",
}
failing_resources = {
"ncloud_lb_target_group.fail",
}

passed_check_resources = {c.resource for c in report.passed_checks}
failed_check_resources = {c.resource for c in report.failed_checks}

self.assertEqual(summary["passed"], 1)
self.assertEqual(summary["failed"], 1)
self.assertEqual(summary["skipped"], 0)
self.assertEqual(summary["parsing_errors"], 0)

self.assertEqual(passing_resources, passed_check_resources)
self.assertEqual(failing_resources, failed_check_resources)


if __name__ == "__main__":
unittest.main()