Skip to content
33 changes: 33 additions & 0 deletions src/falconpy/hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,39 @@ def PerformActionV2(self: object, parameters: dict, body: dict, action_name: str
returned = generate_error_result("Invalid value specified for action_name parameter.")

return returned

def UpdateDeviceTags(self: object, action_name: str, ids: list or str, tags: list or str) -> dict:
"""
allows for tagging hosts. If the tags are empty
"""
ALLOWED_ACTIONS = ["add", "remove"]
# validate action is allowed AND tags is "something"
if action_name.lower() in ALLOWED_ACTIONS and tags is not None:
FULL_URL = self.base_url + '/devices/entities/devices/tags/v1'
HEADERS = self.headers
# convert ids/tags to be a list object if not already
if isinstance(ids, str):
ids = [ids]
if isinstance(tags, str):
tags = [tags]
# tags must start with FalconGroupingTags, users probably won't know this so add it for them
patch_tag = []
for tag in tags:
if tag.startswith("FalconGroupingTags/"):
patch_tag.append(tag)
else:
tag_name = "FalconGroupingTags/" + tag
patch_tag.append(tag)

BODY = {
"action": action_name,
"devices_ids": ids,
"tags": patch_tag
}
returned = service_request(caller=self, method="PATCH", body=BODY, headers=HEADERS, verify=self.ssl_verify)
else:
returned = generate_error_result("Invalid value specified for action_name parameter.")
return returned

def GetDeviceDetails(self: object, ids) -> dict:
""" Get details on one or more hosts by providing agent IDs (AID).
Expand Down
31 changes: 31 additions & 0 deletions tests/test_hosts.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,34 @@ def serviceHosts_QueryDevicesByFilter(self):
# else:
# return False

def serviceHosts_addTag(self):
id_list = []
id_list.append(
falcon.GetDeviceDetails(ids=falcon.QueryDevicesByFilter(parameters={"limit":1})["body"]["resources"][0])["body"]["resources"][0]["device_id"]
)
# test basic, id is a list, single valid tag w/o manipulation
if not falcon.UpdateDeviceTags(action_name="add", ids=id_list, tags=["FalconGroupingTags/testtag"])["status_code"] in AllowedResponses:
return False
if not falcon.UpdateDeviceTags(action_name="remove", ids=id_list, tags=["FalconGroupingTags/testtag"])["status_code"] in AllowedResponses:
return False
# id is a list, multiple tags needing manipulation
if not falcon.UpdateDeviceTags(action_name="add", ids=id_list, tags=["testtag", "tagtest", "anothertag"])["status_code"] in AllowedResponses:
return False
if not falcon.UpdateDeviceTags(action_name="remove", ids=id_list, tags=["testtag", "tagtest", "anothertag"])["status_code"] in AllowedResponses:
return False
# id is a list, mutliple tags some need manipulation
if not falcon.UpdateDeviceTags(action_name="add", ids=id_list, tags=["FalconGroupingTags/testtag", "manipulate", "FalconGroupingTags/anothertag"])["status_code"] in AllowedResponses:
return False
if not falcon.UpdateDeviceTags(action_name="remove", ids=id_list, tags=["FalconGroupingTags/testtag", "manipulate", "FalconGroupingTags/anothertag"])["status_code"] in AllowedResponses:
return False
# id is single string, single valid tag w/o manipulation
if not falcon.UpdateDeviceTags(action_name="add", ids=id_list[0], tags=["FalconGroupingTags/testtag"])["status_code"] in AllowedResponses:
return False
if not falcon.UpdateDeviceTags(action_name="remove", ids=id_list[0], tags=["FalconGroupingTags/testtag"])["status_code"] in AllowedResponses:
return False

return True

def serviceHosts_PerformActionV2(self):
id_list = []
id_list.append(
Expand Down Expand Up @@ -87,6 +115,9 @@ def test_QueryDevicesByFilterScroll(self):

def test_QueryDevicesByFilter(self):
assert self.serviceHosts_QueryDevicesByFilter() == True

def test_tagging(self):
assert self.serviceHosts_addTag() == True

# def test_GetDeviceDetails(self):
# assert self.serviceHosts_GetDeviceDetails() == True
Expand Down