diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml index dfdfa1e..b6acd3f 100644 --- a/.github/workflows/code-quality.yml +++ b/.github/workflows/code-quality.yml @@ -32,7 +32,11 @@ jobs: - name: Install dependencies run: poetry install + - name: Run unit tests + run: poetry run py.test tests/unit_tests + - name: Lint package source with flake8 + if: success() || failure() run: | poetry run flake8 caracara/ --show-source --statistics poetry run flake8 examples/ --show-source --statistics diff --git a/caracara/common/policy_wrapper.py b/caracara/common/policy_wrapper.py index 6a03b7c..eaf3aad 100644 --- a/caracara/common/policy_wrapper.py +++ b/caracara/common/policy_wrapper.py @@ -363,7 +363,7 @@ def _load_data_dict(self, data_dict: Dict = None): self.groups.append(GroupAssignment(data_dict=group_dict)) # Load all groups of settings - settings_groups: List[Dict] = data_dict.get(self.settings_key_name) + settings_groups: List[Dict] = data_dict.get(self.settings_key_name, []) for settings_group_dict in settings_groups: self.settings_groups.append(PolicySettingGroup(data_dict=settings_group_dict)) @@ -409,7 +409,7 @@ def flat_dump(self) -> Dict: "description": self.description, "name": self.name, "platform_name": self.platform_name, - "settings": settings, + self.settings_key_name: settings, } if self.policy_id: data["id"] = self.policy_id diff --git a/caracara/modules/custom_ioa/custom_ioa.py b/caracara/modules/custom_ioa/custom_ioa.py index d8cc8ae..19e12a7 100644 --- a/caracara/modules/custom_ioa/custom_ioa.py +++ b/caracara/modules/custom_ioa/custom_ioa.py @@ -204,7 +204,6 @@ def _update_create_delete_rules(self, group: IoaRuleGroup, comment: str) -> IoaR raw_rule, rule_type=self._get_rule_types_cached()[raw_rule["ruletype_id"]], ) - new_rule.rulegroup_id = group.id_ new_rules.append(new_rule) new_group.version += 1 diff --git a/caracara/modules/custom_ioa/rules.py b/caracara/modules/custom_ioa/rules.py index e552fad..54ef912 100644 --- a/caracara/modules/custom_ioa/rules.py +++ b/caracara/modules/custom_ioa/rules.py @@ -122,7 +122,6 @@ def from_data_dict(data_dict: dict, rule_type_map: Dict[str, RuleType]) -> IoaRu # The following line might raise an index error if there's a rule type on this rule that # we don't know about. I don't catch this since I don't think it's likely to happen. rule_type = rule_type_map[raw_rule["ruletype_id"]] - raw_rule["rulegroup_id"] = rule_group.id_ # API doesn't populate this field, so we do rule = CustomIoaRule.from_data_dict(data_dict=raw_rule, rule_type=rule_type) rule_group.rules.append(rule) @@ -330,6 +329,7 @@ class CustomIoaRule: modified_on: datetime version_ids: List[str] pattern_id: str + rulegroup_id: str def __init__( self, @@ -385,6 +385,7 @@ def __init__( self.modified_on = None self.version_ids = None self.pattern_id = None + self.rulegroup_id = None def __repr__(self): """Return an unambiguous string representation of the CustomIoaRule and its properties. @@ -441,6 +442,7 @@ def from_data_dict(data_dict: dict, rule_type: RuleType) -> CustomIoaRule: rule.version_ids = data_dict["version_ids"] rule.pattern_id = data_dict["pattern_id"] rule.comment = data_dict["comment"] + rule.rulegroup_id = data_dict["rulegroup_id"] rule.fields = {} for field_value in data_dict["field_values"]: @@ -622,6 +624,7 @@ def dump(self) -> dict: "action_label": self.action_label, "ruletype_id": self.rule_type.id_, "ruletype_name": self.rule_type.name, + "rulegroup_id": self.rulegroup_id, "field_values": list(self.fields.values()), "enabled": self.enabled, "deleted": self.deleted, diff --git a/poetry.lock b/poetry.lock index 9113bb4..fa1ac4c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -903,32 +903,33 @@ wcwidth = "*" [[package]] name = "psutil" -version = "6.0.0" +version = "6.1.0" description = "Cross-platform lib for process and system monitoring in Python." optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ - {file = "psutil-6.0.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a021da3e881cd935e64a3d0a20983bda0bb4cf80e4f74fa9bfcb1bc5785360c6"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:1287c2b95f1c0a364d23bc6f2ea2365a8d4d9b726a3be7294296ff7ba97c17f0"}, - {file = "psutil-6.0.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:a9a3dbfb4de4f18174528d87cc352d1f788b7496991cca33c6996f40c9e3c92c"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6ec7588fb3ddaec7344a825afe298db83fe01bfaaab39155fa84cf1c0d6b13c3"}, - {file = "psutil-6.0.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:1e7c870afcb7d91fdea2b37c24aeb08f98b6d67257a5cb0a8bc3ac68d0f1a68c"}, - {file = "psutil-6.0.0-cp27-none-win32.whl", hash = "sha256:02b69001f44cc73c1c5279d02b30a817e339ceb258ad75997325e0e6169d8b35"}, - {file = "psutil-6.0.0-cp27-none-win_amd64.whl", hash = "sha256:21f1fb635deccd510f69f485b87433460a603919b45e2a324ad65b0cc74f8fb1"}, - {file = "psutil-6.0.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:c588a7e9b1173b6e866756dde596fd4cad94f9399daf99ad8c3258b3cb2b47a0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ed2440ada7ef7d0d608f20ad89a04ec47d2d3ab7190896cd62ca5fc4fe08bf0"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"}, - {file = "psutil-6.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2e8d0054fc88153ca0544f5c4d554d42e33df2e009c4ff42284ac9ebdef4132"}, - {file = "psutil-6.0.0-cp36-cp36m-win32.whl", hash = "sha256:fc8c9510cde0146432bbdb433322861ee8c3efbf8589865c8bf8d21cb30c4d14"}, - {file = "psutil-6.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:34859b8d8f423b86e4385ff3665d3f4d94be3cdf48221fbe476e883514fdb71c"}, - {file = "psutil-6.0.0-cp37-abi3-win32.whl", hash = "sha256:a495580d6bae27291324fe60cea0b5a7c23fa36a7cd35035a16d93bdcf076b9d"}, - {file = "psutil-6.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:33ea5e1c975250a720b3a6609c490db40dae5d83a4eb315170c4fe0d8b1f34b3"}, - {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"}, - {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"}, + {file = "psutil-6.1.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ff34df86226c0227c52f38b919213157588a678d049688eded74c76c8ba4a5d0"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:c0e0c00aa18ca2d3b2b991643b799a15fc8f0563d2ebb6040f64ce8dc027b942"}, + {file = "psutil-6.1.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:000d1d1ebd634b4efb383f4034437384e44a6d455260aaee2eca1e9c1b55f047"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:5cd2bcdc75b452ba2e10f0e8ecc0b57b827dd5d7aaffbc6821b2a9a242823a76"}, + {file = "psutil-6.1.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:045f00a43c737f960d273a83973b2511430d61f283a44c96bf13a6e829ba8fdc"}, + {file = "psutil-6.1.0-cp27-none-win32.whl", hash = "sha256:9118f27452b70bb1d9ab3198c1f626c2499384935aaf55388211ad982611407e"}, + {file = "psutil-6.1.0-cp27-none-win_amd64.whl", hash = "sha256:a8506f6119cff7015678e2bce904a4da21025cc70ad283a53b099e7620061d85"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:6e2dcd475ce8b80522e51d923d10c7871e45f20918e027ab682f94f1c6351688"}, + {file = "psutil-6.1.0-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0895b8414afafc526712c498bd9de2b063deaac4021a3b3c34566283464aff8e"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9dcbfce5d89f1d1f2546a2090f4fcf87c7f669d1d90aacb7d7582addece9fb38"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:498c6979f9c6637ebc3a73b3f87f9eb1ec24e1ce53a7c5173b8508981614a90b"}, + {file = "psutil-6.1.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d905186d647b16755a800e7263d43df08b790d709d575105d419f8b6ef65423a"}, + {file = "psutil-6.1.0-cp36-cp36m-win32.whl", hash = "sha256:6d3fbbc8d23fcdcb500d2c9f94e07b1342df8ed71b948a2649b5cb060a7c94ca"}, + {file = "psutil-6.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:1209036fbd0421afde505a4879dee3b2fd7b1e14fee81c0069807adcbbcca747"}, + {file = "psutil-6.1.0-cp37-abi3-win32.whl", hash = "sha256:1ad45a1f5d0b608253b11508f80940985d1d0c8f6111b5cb637533a0e6ddc13e"}, + {file = "psutil-6.1.0-cp37-abi3-win_amd64.whl", hash = "sha256:a8fb3752b491d246034fa4d279ff076501588ce8cbcdbb62c32fd7a377d996be"}, + {file = "psutil-6.1.0.tar.gz", hash = "sha256:353815f59a7f64cdaca1c0307ee13558a0512f6db064e92fe833784f08539c7a"}, ] [package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +dev = ["black", "check-manifest", "coverage", "packaging", "pylint", "pyperf", "pypinfo", "pytest-cov", "requests", "rstcheck", "ruff", "sphinx", "sphinx_rtd_theme", "toml-sort", "twine", "virtualenv", "wheel"] +test = ["pytest", "pytest-xdist", "setuptools"] [[package]] name = "py7zr" @@ -1448,13 +1449,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "rich" -version = "13.9.2" +version = "13.9.3" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" optional = false python-versions = ">=3.8.0" files = [ - {file = "rich-13.9.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"}, - {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"}, + {file = "rich-13.9.3-py3-none-any.whl", hash = "sha256:9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283"}, + {file = "rich-13.9.3.tar.gz", hash = "sha256:bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index 484b963..892252b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "caracara" -version = "0.9.0" +version = "0.9.1" description = "The CrowdStrike Falcon Developer Toolkit" authors = [ "CrowdStrike " ] readme = "README.md" diff --git a/tests/unit_tests/test_custom_ioas.py b/tests/unit_tests/test_custom_ioas.py index 0312283..228f3c2 100644 --- a/tests/unit_tests/test_custom_ioas.py +++ b/tests/unit_tests/test_custom_ioas.py @@ -103,6 +103,7 @@ def mock_create_rule(body, comment=None): "pattern_severity": body["pattern_severity"], "disposition_id": body["disposition_id"], "action_label": rule_type.disposition_map[body["disposition_id"]], + "rulegroup_id": "test_group_01", "ruletype_id": body["ruletype_id"], "ruletype_name": rule_type.name, "field_values": body["field_values"], @@ -332,6 +333,7 @@ def test_describe_rule_groups_with_rules( "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": simple_rule_type.id_, "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": [], "enabled": True, "deleted": False, @@ -373,7 +375,6 @@ def mock_query_rule_groups_full(offset, limit, filter): # Call caracara groups = client.custom_ioas.describe_rule_groups(filters="test_filter") - assert len(mock_groups) == len(groups) for mock_group in mock_groups: assert mock_group["id"] in groups.keys() @@ -508,6 +509,7 @@ def test_update_rule_groups_with_rule_changes( "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": simple_rule_type.id_, "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": [], "enabled": True, "deleted": False, @@ -532,6 +534,7 @@ def test_update_rule_groups_with_rule_changes( "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": simple_rule_type.id_, "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": [], "enabled": True, "deleted": False, @@ -617,6 +620,7 @@ def mock_create_rule(body): "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": body["ruletype_id"], "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": body["field_values"], "enabled": False, "deleted": False, @@ -735,6 +739,7 @@ def test_update_rule_group_with_new_rules( "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": simple_rule_type.id_, "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": [], "enabled": True, "deleted": False, @@ -759,6 +764,7 @@ def test_update_rule_group_with_new_rules( "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": simple_rule_type.id_, "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": [], "enabled": True, "deleted": False, @@ -808,6 +814,7 @@ def mock_create_rule(body): "action_label": list(simple_rule_type.disposition_map.values())[0], "ruletype_id": body["ruletype_id"], "ruletype_name": simple_rule_type.name, + "rulegroup_id": "test_group_01", "field_values": body["field_values"], "enabled": False, "deleted": False, diff --git a/tests/unit_tests/test_hosts.py b/tests/unit_tests/test_hosts.py index 9ff1dfe..ad13872 100644 --- a/tests/unit_tests/test_hosts.py +++ b/tests/unit_tests/test_hosts.py @@ -7,7 +7,7 @@ from caracara import Client from caracara.common.constants import OnlineState -from caracara.common.exceptions import InvalidOnlineState +from caracara.common.exceptions import InvalidOnlineState, MustProvideFilter # A lot of mock methods need a certain function signature, and since they only mock functionality # they do not always use all the arguments. Therefore, we disable the unused-argument warning. @@ -18,17 +18,21 @@ mock_devices = { "00000000000000000000000000000000": { "device_id": "00000000000000000000000000000000", + "hostname": "TESTTEST0", }, "00000000000000000000000000000001": { "device_id": "00000000000000000000000000000001", + "hostname": "TESTTEST1", }, "00000000000000000000000000000002": { "device_id": "00000000000000000000000000000002", "host_hidden_status": "hidden", + "hostname": "TESTTEST2", }, "00000000000000000000000000000003": { "device_id": "00000000000000000000000000000003", "host_hidden_status": "hidden", + "hostname": "TESTTEST3", }, } visible_ids = [i for i, dev in mock_devices.items() if dev.get("host_hidden_status") != "hidden"] @@ -58,9 +62,12 @@ def mock_query_devices_by_filter_scroll(*, filter, limit, offset): - """Mock method for falconpy.Hosts.query_devices_by_filter_scroll""" - assert filter is None + """Mock method for falconpy.Hosts.query_devices_by_filter_scroll. + Although we use filters (pluralised) in Caracara to avoid overwriting the native Python + filter keyword, we have to use filter here so that we match with the Falcon API spec we + are mocking. + """ if offset is None: offset = 0 @@ -77,9 +84,12 @@ def mock_query_devices_by_filter_scroll(*, filter, limit, offset): def mock_query_hidden_devices(*, filter, limit, offset): - """Mock method for falconpy.Hosts.query_hidden_devices""" - assert filter is None + """Mock method for falconpy.Hosts.query_hidden_devices. + Although we use filters (pluralised) in Caracara to avoid overwriting the native Python + filter keyword, we have to use filter here so that we match with the Falcon API spec we + are mocking. + """ if offset is None: offset = 0 @@ -326,14 +336,27 @@ def mock_query_network_address_history(ids): assert auth.hosts.describe_network_address_history() == mock_network_history +@hosts_test() +def test_contain_no_filter(auth: Client, **_): + """Unit test for HostsApiModule.contain with no filter provider.""" + with pytest.raises(MustProvideFilter): + auth.hosts.contain() + + @hosts_test() def test_contain(auth: Client, **_): """Unit test for HostsApiModule.contain""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] def mock_perform_action(*, ids, action_name): return { "body": { + "errors": None, "resources": resources, } } @@ -345,7 +368,10 @@ def mock_perform_action(*, ids, action_name): } ) - assert auth.hosts.contain() == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.contain(filters=filters) == resources auth.hosts.hosts_api.perform_action.assert_called_once_with( ids=visible_ids, action_name="contain", @@ -355,11 +381,17 @@ def mock_perform_action(*, ids, action_name): @hosts_test() def test_release(auth: Client, **_): """Unit test for HostsApiModule.release""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] def mock_perform_action(*, ids, action_name): return { "body": { + "errors": None, "resources": resources, } } @@ -371,7 +403,10 @@ def mock_perform_action(*, ids, action_name): } ) - assert auth.hosts.release() == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.release(filters=filters) == resources auth.hosts.hosts_api.perform_action.assert_called_once_with( ids=visible_ids, action_name="lift_containment", @@ -381,11 +416,17 @@ def mock_perform_action(*, ids, action_name): @hosts_test() def test_hide(auth: Client, **_): """Unit test for HostsApiModule.hide""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] def mock_perform_action(*, ids, action_name): return { "body": { + "errors": None, "resources": resources, } } @@ -397,7 +438,10 @@ def mock_perform_action(*, ids, action_name): } ) - assert auth.hosts.hide() == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.hide(filters=filters) == resources auth.hosts.hosts_api.perform_action.assert_called_once_with( ids=visible_ids, action_name="hide_host", @@ -407,11 +451,17 @@ def mock_perform_action(*, ids, action_name): @hosts_test() def test_unhide(auth: Client, **_): """Unit test for HostsApiModule.unhide""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] def mock_perform_action(*, ids, action_name): return { "body": { + "errors": None, "resources": resources, } } @@ -423,7 +473,10 @@ def mock_perform_action(*, ids, action_name): } ) - assert auth.hosts.unhide() == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.unhide(filters=filters) == resources auth.hosts.hosts_api.perform_action.assert_called_once_with( ids=hidden_ids, action_name="unhide_host", @@ -433,12 +486,18 @@ def mock_perform_action(*, ids, action_name): @hosts_test() def test_tag(auth: Client, **_): """Unit test for HostsApiModule.tag""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] tags = ["tag1", "tag2"] def mock_update_device_tags(*, action_name, ids, tags): return { "body": { + "errors": None, "resources": resources, } } @@ -450,7 +509,10 @@ def mock_update_device_tags(*, action_name, ids, tags): } ) - assert auth.hosts.tag(tags) == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.tag(filters=filters, tags=tags) == resources auth.hosts.hosts_api.update_device_tags.assert_called_once_with( action_name="add", ids=visible_ids, @@ -461,12 +523,18 @@ def mock_update_device_tags(*, action_name, ids, tags): @hosts_test() def test_untag(auth: Client, **_): """Unit test for HostsApiModule.untag""" - resources = [] + resources = [ + "00000000000000000000000000000000", + "00000000000000000000000000000001", + "00000000000000000000000000000002", + "00000000000000000000000000000003", + ] tags = ["tag1", "tag2"] def mock_update_device_tags(*, action_name, ids, tags): return { "body": { + "errors": None, "resources": resources, } } @@ -478,7 +546,10 @@ def mock_update_device_tags(*, action_name, ids, tags): } ) - assert auth.hosts.untag(tags) == resources + filters = auth.FalconFilter(dialect="hosts") + filters.create_new_filter("Hostname", "TESTTEST*") + + assert auth.hosts.untag(filters=filters, tags=tags) == resources auth.hosts.hosts_api.update_device_tags.assert_called_once_with( action_name="remove", ids=visible_ids, diff --git a/tests/unit_tests/test_prevention_policies.py b/tests/unit_tests/test_prevention_policies.py index 0e3f6f4..1dc1738 100644 --- a/tests/unit_tests/test_prevention_policies.py +++ b/tests/unit_tests/test_prevention_policies.py @@ -144,12 +144,11 @@ def mock_create_policies(body): } ) - res = auth.prevention_policies.push_policy( - Policy( - data_dict=mock_policy, - style="prevention", - ) + new_policy = Policy( + data_dict=mock_policy, + style="prevention", ) + res = auth.prevention_policies.push_policy(new_policy) assert res.cid == mock_cid