import demistomock as demisto
from CommonServerPython import *
import requests
import json
import re
import urllib.request
import urllib.parse
import urllib.error
import urllib3
urllib3.disable_warnings()
handle_proxy()
ENDPOINTS_INFO_DEFAULT_COLUMNS = [
"computerName",
"ipAddresses",
"operatingSystem",
"osBitness",
"cidsDefsetVersion",
"lastScanTime",
"description",
"quarantineDesc",
"domainOrWorkgroup",
"macAddresses",
"group",
"dhcpServer",
"biosVersion",
"virtualizationPlatform",
"computerTimeStamp",
"creationTime",
"agentTimestamp",
"hardwareKey",
]
GROUPS_INFO_DEFAULT_COLUMNS = [
"fullPathName",
"numberOfPhysicalComputers",
"numberOfRegisteredUsers",
"policySerialNumber",
"policyDate",
"description",
"created",
"id",
]
"""LITERALS"""
EPOCH_MINUTE = 60 * 1000
EPOCH_HOUR = 60 * EPOCH_MINUTE
"""HELPER FUNCTIONS"""
def fix_url(base):
return base if base.endswith("/") else (base + "/")
def endpoint_ip_extract(raw_json):
ips_array = []
for content in raw_json:
ip = {"Address": content.get("ipAddresses", [""])[0], "Mac": content.get("computerName")}
ip = createContext(ip, removeNull=True)
if ip:
ips_array.append(ip)
return ips_array
def endpoint_endpoint_extract(raw_json):
endpoints_arr = []
for content in raw_json:
endpoint = {
"Hostname": content.get("computerName"),
"MACAddress": content.get("macAddresses", [""])[0],
"Domain": content.get("domainOrWorkgroup"),
"IPAddress": content.get("ipAddresses", [""])[0],
"DHCPServer": content.get("dhcpServer"),
"OS": content.get("operatingSystem"),
"OSVersion": content.get("osVersion"),
"BIOSVersion": content.get("biosVersion"),
"Memory": content.get("memory"),
"Processors": content.get("processorType"),
}
endpoint = createContext(endpoint, removeNull=True)
if endpoint:
endpoints_arr.append(endpoint)
return endpoints_arr
def build_query_params(params):
list_params = [key + "=" + str(params[key]) for key in params]
query_params = "&".join(list_params)
return "?" + query_params if query_params else ""
def do_auth(server, crads, insecure, domain):
url = fix_url(str(server)) + "sepm/api/v1/identity/authenticate"
body = {
"username": crads.get("identifier") if crads.get("identifier") else "",
"password": urllib.parse.quote(crads.get("password")) if crads.get("password") else "",
"domain": domain if domain else "",
}
res = requests.post(url, headers={"Content-Type": "application/json"}, data=json.dumps(body), verify=not insecure)
res.raise_for_status()
return parse_response(res)
def do_get(token, raw, suffix):
insecure = demisto.getParam("insecure")
server = demisto.getParam("server")
url = fix_url(server) + suffix
res = requests.get(url, headers={"Authorization": "Bearer " + token}, verify=not insecure)
res.raise_for_status()
if raw:
return res
else:
return parse_response(res)
def do_post(token, is_xml, suffix, body):
insecure = demisto.getParam("insecure")
server = demisto.getParam("server")
url = fix_url(server) + suffix
res = requests.post(url, headers={"Authorization": "Bearer " + token}, data=body, verify=not insecure)
res.raise_for_status()
parsed_response = {}
if is_xml:
if res.content:
parsed_response = xml2json(res.content)
else:
return_error(f"Unable to parse the following response: {res}")
else:
parsed_response = parse_response(res)
return parsed_response
def do_put(token, suffix, body):
insecure = demisto.getParam("insecure")
server = demisto.getParam("server")
url = fix_url(server) + suffix
res = requests.put(
url,
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
data=json.dumps(body),
verify=not insecure,
)
parsed_response = parse_response(res)
return parsed_response
def do_patch(token, suffix, body):
insecure = demisto.getParam("insecure")
server = demisto.getParam("server")
url = fix_url(server) + suffix
res = requests.patch(
url,
headers={"Authorization": "Bearer " + token, "Content-Type": "application/json"},
data=json.dumps(body),
verify=not insecure,
)
res.raise_for_status()
parsed_response = parse_response(res)
return parsed_response
def parse_response(resp):
if resp.status_code == 200 or resp.status_code == 207:
if resp.text == "":
return resp
try:
return resp.json()
except Exception as ex:
return_error(f"Unable to parse response: {ex}")
else:
try:
message = resp.json().get("errorMessage")
return_error(f"Error: {message}")
except Exception:
return_error(f"Error: {resp}")
def get_token_from_response(resp):
if resp.get("token"):
return resp.get("token")
else:
return_error(f"No token: {resp}") # noqa: RET503
def choose_columns(column_arg, default_list):
if not column_arg:
columns_list = default_list
columns_list.sort()
elif column_arg == "all" or column_arg == "*":
columns_list = []
else:
columns_list = argToList(column_arg)
return columns_list
def build_command_xml(data):
return (
' \
{data}'
)
def build_client_xml(data):
return (
' \
{data}'
)
def get_command_status_details(token, command_id):
xml = build_command_xml(f"{command_id}")
res_json = do_post(token, True, "sepm/ws/v1/CommandService", xml)
return res_json
def build_command_response_output(title, command_id, message, response):
cmd_status_details = response.get("cmdStatusDetail")
cmd_status_details.pop("hardwareKey", None)
md = tableToMarkdown(title, cmd_status_details) + "\n"
md += f"### Command ID: {command_id}\n"
md += "### " + message
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": {"cmdStatusDetail": cmd_status_details, "commandId": command_id},
"HumanReadable": md,
"EntryContext": {
"SEPM.LastCommand": createContext(
{"CommandDetails": cmd_status_details, "CommandId": command_id}, removeNull=True
)
},
}
)
def get_computer_id_by_ip(token, ip):
xml = build_client_xml(f"{ip}")
res_json = do_post(token, True, "sepm/ws/v1/ClientService", xml)
return demisto.get(json.loads(res_json), "Envelope.Body.getComputersByIPResponse.ComputerResult.computers.computerId")
def get_computer_id_by_hostname(token, hostname):
xml = build_client_xml(
f"{hostname}"
)
res_json = do_post(token, True, "sepm/ws/v1/ClientService", xml)
return demisto.get(json.loads(res_json), "Envelope.Body.getComputersByHostNameResponse.ComputerResult.computers.computerId")
def get_computer_id(token, endpoint_ip, endpoint_host_name):
computer_id = ""
if endpoint_ip:
try:
computer_id = get_computer_id_by_ip(token, endpoint_ip)
except Exception:
return_error("Failed to locate the endpoint by its IP address.")
elif endpoint_host_name:
try:
computer_id = get_computer_id_by_hostname(token, endpoint_host_name)
except Exception:
return_error("Failed to locat the endpoint by its hostname.")
else:
return_error("Please provide the IP address or the hostname of endpoint.")
return computer_id
def update_content(token, computer_id):
xml = build_command_xml(
f"{computer_id}"
""
)
res_json = do_post(token, True, "sepm/ws/v1/CommandService", xml)
command_id = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandUpdateContentResponse.CommandClientResult.commandId"
)
if not command_id:
error_code = demisto.get(
res_json, "Envelope.Body.runClientCommandUpdateContentResponse.CommandClientResult.inputErrors.errorCode"
)
error_message = demisto.get(
res_json, "Envelope.Body.runClientCommandUpdateContentResponse.CommandClientResult.inputErrors.errorMessage"
)
if error_code or error_message:
return_error(f"An error response has returned from server: {error_message} with code: {error_code}")
else:
return_error("Could not retrieve command ID, no error was returned from server")
return command_id
def scan(token, computer_id, scan_type):
xml = build_command_xml(
f"{computer_id}"
f"{scan_type}"
)
res_json = do_post(token, True, "sepm/ws/v1/CommandService", xml)
command_id = demisto.get(json.loads(res_json), "Envelope.Body.runClientCommandScanResponse.CommandClientResult.commandId")
if not command_id:
error_code = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandScanResponse.CommandClientResult.inputErrors.errorCode"
)
error_message = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandScanResponse.CommandClientResult.inputErrors.errorMessage"
)
if error_code or error_message:
return_error(f"An error response has returned from server: {error_message} with code: {error_code}")
else:
return_error("Could not retrieve command ID, no error was returned from server")
return command_id
def quarantine(token, computer_id, action_type):
xml = build_command_xml(
f"{action_type}{computer_id}"
"COMPUTER"
""
)
res_json = do_post(token, True, "sepm/ws/v1/CommandService", xml)
command_id = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandQuarantineResponse.CommandClientResult.commandId"
)
if not command_id:
error_code = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandQuarantineResponse.CommandClientResult.inputErrors.errorCode"
)
error_message = demisto.get(
json.loads(res_json), "Envelope.Body.runClientCommandQuarantineResponse.CommandClientResult.inputErrors.errorMessage"
)
if error_code or error_message:
return_error(f"An error response has returned from server: {error_message} with code: {error_code}")
else:
return_error("Could not retrieve command ID, no error was returned from server")
return command_id
def validate_time_zone(time_zone):
pattern = re.compile("^[+-][0-9][0-9]:[0-9][0-9]")
return bool(pattern.match(time_zone))
def parse_epoch_to_local(epoch, time_zone):
if not validate_time_zone(time_zone):
return_error("timeZone param should be in the format of [+/-][h][h]:[m][m]. For exmaple +04:30")
operator = time_zone[0]
hour = int(time_zone[1:3])
minutes = int(time_zone[4:6])
time_zone_epoch = hour * EPOCH_HOUR + minutes * EPOCH_MINUTE
local = int(epoch) + time_zone_epoch if operator == "+" else int(epoch) - time_zone_epoch
return local
def change_assigined(policy):
new_format = {
"Policy Name": policy.get("PolicyName"),
"Type": policy.get("Type"),
"ID": policy.get("ID"),
"Assigned": bool(policy.get("AssignedLocations")) or bool(policy.get("AssignedCloudGroups")),
"Discription": policy.get("Discription"),
"Enabled": policy.get("Enabled"),
}
return new_format
def sanitize_policies_list_for_md(policies_list):
return list(map(change_assigined, policies_list))
def sanitize_policies_list(policies_list):
return list( # noqa: C417
map(
lambda policy: {
"PolicyName": policy["name"],
"Type": policy["policytype"],
"ID": policy["id"],
"Description": policy["desc"],
"Enabled": policy["enabled"],
"AssignedLocations": list( # noqa: C417
map(
lambda location: {"GroupID": location.get("groupId"), "Locations": location.get("locationIds")},
policy.get("assignedtolocations") if policy.get("assignedtolocations") else [],
)
),
"AssignedCloudGroups": list( # noqa: C417
map(
lambda location: {"GroupID": location.get("groupId"), "Locations": location.get("locationIds")},
policy.get("assignedtocloudgroups") if policy.get("assignedtocloudgroups") else [],
)
),
},
policies_list,
)
)
def validate_ip(ip):
pattern = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
return bool(pattern.match(ip))
def get_client_content(token, time_zone):
client_content_json = do_get(token, False, "sepm/api/v1/stats/client/content")
epoch_time = client_content_json.get("lastUpdated")
if time_zone:
epoch_time = parse_epoch_to_local(epoch_time, time_zone)
last_update_date = timestamp_to_datestring(epoch_time, "%a %b %d %y %H:%M:%S %z")
client_version = client_content_json.get("clientDefStatusList")
return client_content_json, client_version, last_update_date
def get_endpoints_info(token, computer_name, last_update, os, page_size, columns, group_name=None):
params = {"computerName": computer_name, "lastUpdate": last_update, "os": os, "pageSize": page_size, "columns": columns}
params = createContext(params, removeNull=True)
json_response = do_get(token, False, "sepm/api/v1/computers" + build_query_params(params))
filtered_json_response = json_response.get("content")
final_json = []
entry_context = []
for content in filtered_json_response:
group = content.get("group", {"name": ""})
bool_start = group.get("name").startswith(group_name[:-1]) if group_name and group_name[-1] == "*" else False
if (not group_name) or group.get("name") == group_name or bool_start: # No group name filter
# used `set` on the mac address list as it sometimes contained duplicated values
content["macAddresses"] = list(set(content.get("macAddresses")))
entry_context.append(
{
"Hostname": content.get("computerName"),
"Domain": content.get("domainOrWorkgroup"),
"IPAddresses": content.get("ipAddresses"),
"OS": content.get("operatingSystem", "") + " | " + content.get("osBitness", ""),
"Description": content.get("content.description"),
"MACAddresses": content.get("macAddresses"),
"BIOSVesrsion": content.get("biosVersion"),
"DHCPServer": content.get("dhcpServer"),
"HardwareKey": content.get("hardwareKey"),
"LastScanTime": epochToTimestamp(content.get("lastScanTime")),
"RunningVersion": content.get("deploymentRunningVersion"),
"TargetVersion": content.get("deploymentTargetVersion"),
"Group": group.get("name"),
"PatternIdx": content.get("patternIdx"),
"OnlineStatus": content.get("onlineStatus"),
"UpdateTime": epochToTimestamp(content.get("lastUpdateTime")),
}
)
final_json.append(content)
return final_json, entry_context
def create_endpints_filter_string(computer_name, last_update, os, page_size, group_name=None):
md = "## Endpoints Information"
if last_update != "0":
md += f", filtered for last updated status: {last_update}" if last_update else ""
md += f", filtered for hostname: {computer_name}" if computer_name else ""
md += f", filtered for os: {os}" if os else ""
md += f", filtered for group name: {group_name}" if group_name else ""
md += f", page size: {page_size}" if page_size else ""
md += "\n"
return md
def get_groups_info(token, columns):
json_res = do_get(token, False, "sepm/api/v1/groups" + build_query_params({"columns": columns}))
sepm_groups = []
filtered_json_response = json_res.get("content")
for entry in filtered_json_response:
group = {}
for header in GROUPS_INFO_DEFAULT_COLUMNS:
group[header] = entry[header]
sepm_groups.append(group)
return filtered_json_response, json_res, sepm_groups
def get_command_status(token, command_id):
command_status_json = get_command_status_details(token, command_id)
cmd_status_detail = demisto.get(
json.loads(command_status_json),
"Envelope.Body.getCommandStatusDetailsResponse.CommandStatusDetailResult.cmdStatusDetail",
)
cmd_status_detail.pop("hardwareKey", None)
state_id = cmd_status_detail.get("stateId")
is_done = False
if state_id == "2" or state_id == "3":
is_done = True
message = "Command is done." if is_done else "Command is in progress. Run !sep-command-status to check again."
return cmd_status_detail, message
def get_list_of_policies(token):
policies_list = do_get(token, False, "sepm/api/v1/policies/summary").get("content")
fixed_policy_list = sanitize_policies_list(policies_list)
md_list = sanitize_policies_list_for_md(fixed_policy_list)
return md_list, policies_list, fixed_policy_list
def endpoint_quarantine(token, endpoint, action):
action_type = "Quarantine" if action == "Add" else "Undo"
computer_id = get_id_by_endpoint(token, endpoint)
command_id = quarantine(token, computer_id, action_type)
return command_id
def get_location_list(token, group_id):
url = f"sepm/api/v1/groups/{group_id}/locations"
url_resp = do_get(token, False, url)
location_ids = list(map(lambda location_string: {"ID": location_string.split("/")[-1]}, url_resp)) # noqa: C417
return url_resp, location_ids
def get_id_by_endpoint(token, endpoint):
computer_id = ""
if not endpoint:
return_error("Please provide the IP address or the hostname of endpoint.")
elif validate_ip(endpoint):
computer_id = get_computer_id(token, endpoint, None)
else:
computer_id = get_computer_id(token, None, endpoint)
return computer_id
def scan_endpoint(token, endpoint, scan_type):
computer_id = get_id_by_endpoint(token, endpoint)
command_id = scan(token, computer_id, scan_type)
return command_id
def update_endpoint_content(token, endpoint):
computer_id = get_id_by_endpoint(token, endpoint)
command_id = update_content(token, computer_id)
return command_id
def filter_only_old_clients(filtered_json_response, desired_version):
filtered = []
for content in filtered_json_response:
RunningVersion = content.get("deploymentRunningVersion")
TargetVersion = content.get("deploymentTargetVersion")
if (desired_version and RunningVersion != desired_version) or (not desired_version and RunningVersion != TargetVersion):
filtered.append(content)
return filtered
"""COMMANDS"""
def system_info_command(token):
version_json = do_get(token, False, "sepm/api/v1/version")
avdef_json = do_get(token, False, "sepm/api/v1/content/avdef/latest")
system_info_json = {"version": version_json, "avdef": avdef_json}
md = "## System Information\n"
md += tableToMarkdown("Version", version_json)
md += tableToMarkdown("AV Definitions", avdef_json)
context = avdef_json.get("publishedBySymantec")
if type(context) is dict:
context = createContext(context, removeNull=True)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": system_info_json,
"HumanReadable": md,
"EntryContext": {"SEPM.ServerAVDefVersion": context},
}
)
def old_clients_command(token):
computer_name = demisto.getArg("computerName")
last_update = demisto.getArg("lastUpdate")
os = demisto.getArg("os")
page_size = demisto.getArg("pageSize")
columns = demisto.getArg("columns")
group_name = demisto.getArg("groupName")
desired_version = demisto.getArg("desiredVersion")
filtered_json_response, entry_context = get_endpoints_info(
token, computer_name, last_update, os, page_size, columns, group_name
)
columns_list = choose_columns(columns, ENDPOINTS_INFO_DEFAULT_COLUMNS)
filtered_json_response = filter_only_old_clients(filtered_json_response, desired_version)
md = create_endpints_filter_string(computer_name, last_update, os, page_size, group_name)
md += tableToMarkdown("Old Endpoints", filtered_json_response, columns_list)
demisto.results(
{"Type": entryTypes["note"], "ContentsFormat": formats["json"], "Contents": filtered_json_response, "HumanReadable": md}
)
def client_content_command(token):
time_zone = demisto.getParam("timeZone")
client_content_json, client_version, last_update_date = get_client_content(token, time_zone)
md = f"## Client Content, last updated on {last_update_date}\n"
md += tableToMarkdown("Client Content Versions", client_version)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": client_content_json,
"HumanReadable": md,
"EntryContext": {"SEPM.ClientContentVersions": client_version, "SEPM.LastUpdated": last_update_date},
}
)
def endpoints_info_command(token):
computer_name = demisto.getArg("computerName")
last_update = demisto.getArg("lastUpdate")
os = demisto.getArg("os")
page_size = demisto.getArg("pageSize")
columns = demisto.getArg("columns")
group_name = demisto.getArg("groupName")
filtered_json_response, entry_context = get_endpoints_info(
token, computer_name, last_update, os, page_size, columns, group_name
)
columns_list = choose_columns(columns, ENDPOINTS_INFO_DEFAULT_COLUMNS)
md = create_endpints_filter_string(computer_name, last_update, os, page_size, group_name)
md += tableToMarkdown("Endpoints", filtered_json_response, columns_list)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": filtered_json_response,
"HumanReadable": md,
"IgnoreAutoExtract": True,
"EntryContext": {
"SEPM.Endpoint(val.Hostname == obj.Hostname)": createContext(entry_context, removeNull=True),
"IP(val.Address === obj.Address)": endpoint_ip_extract(filtered_json_response),
"Endpoint(val.Hostname == obj.Hostname)": endpoint_endpoint_extract(filtered_json_response),
},
}
)
def groups_info_command(token):
columns = demisto.getArg("columns")
filtered_json_response, json_res, sepm_groups = get_groups_info(token, columns)
columns_list = choose_columns(columns, GROUPS_INFO_DEFAULT_COLUMNS)
md = tableToMarkdown("Groups Information", filtered_json_response, columns_list)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": json_res,
"HumanReadable": md,
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.Groups": sepm_groups},
}
)
def command_status(token):
command_id = demisto.getArg("commandId")
cmd_status_detail, message = get_command_status(token, command_id)
md = f"### Command ID: {command_id}\n"
md += f"### State ID: {cmd_status_detail.get('stateId')}\n"
md += "### " + message
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": {"cmdStatusDetail": cmd_status_detail, "commandId": command_id},
"HumanReadable": md,
"IgnoreAutoExtract": True,
"EntryContext": {
"SEPM.LastCommand(val.CommandID && val.CommandID == obj.CommandID)": createContext(
{"CommandDetails": cmd_status_detail, "CommandID": command_id}, removeNull=True
)
},
}
)
def list_policies_command(token):
md_list, policies_list, fixed_policy_list = get_list_of_policies(token)
md = tableToMarkdown(
"List of existing policies", md_list, ["Policy Name", "Type", "ID", "Enabled", "Assigned", "Description"]
)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": policies_list,
"HumanReadable": md,
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.PoliciesList": createContext(fixed_policy_list, removeNull=True)},
}
)
def assign_policie_command(token):
group_id = demisto.getArg("groupID")
locatoion_id = demisto.getArg("locationID")
policy_type = demisto.getArg("policyType").lower()
policy_id = demisto.getArg("policyID")
do_put(token, f"sepm/api/v1/groups/{group_id}/locations/{locatoion_id}/policies/{policy_type}", {"id": policy_id})
md = f"### Policy: {policy_id}, of type: {policy_type}, was assigned to location: {locatoion_id}, in group: {group_id}"
demisto.results(
{"Type": entryTypes["note"], "ContentsFormat": formats["json"], "Contents": "", "HumanReadable": md, "EntryContext": {}}
)
def list_locations_command(token):
group_id = demisto.getArg("groupID")
url_resp, location_ids = get_location_list(token, group_id)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["json"],
"Contents": url_resp,
"HumanReadable": tableToMarkdown(
"Locations",
list(map(lambda location: {"Location ID": location.get("ID")}, location_ids)), # noqa: C417
),
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.Locations": location_ids},
}
)
def endpoint_quarantine_command(token):
endpoint = demisto.getArg("endpoint")
action = demisto.getArg("actionType")
command_id = endpoint_quarantine(token, endpoint, action)
message = (
f"### Initiated quarantine for endpoint {endpoint}. Command ID: {command_id}."
if action == "Add"
else f"### Removing endpoint: {endpoint} from quarantine. Command ID: {command_id}."
)
context = {"CommandID": command_id, "Action": action, "Endpoint": endpoint}
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["text"],
"Contents": command_id,
"HumanReadable": message,
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.Quarantine": context},
}
)
def scan_endpoint_command(token):
endpoint = demisto.getArg("endpoint")
scan_type = demisto.getArg("scanType")
command_id = scan_endpoint(token, endpoint, scan_type)
message = f"### Initiated scan on endpoint: {endpoint} with type: {scan_type}. Command ID: {command_id}."
context = {"CommandID": command_id, "Type": scan_type, "Endpoint": endpoint}
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["text"],
"Contents": command_id,
"HumanReadable": message,
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.Scan": context},
}
)
def update_endpoint_content_command(token):
endpoint = demisto.getArg("endpoint")
command_id = update_endpoint_content(token, endpoint)
message = f"### Updating endpoint: {endpoint}. Command ID: {command_id}."
context = {"CommandID": command_id, "Endpoint": endpoint}
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["text"],
"Contents": command_id,
"HumanReadable": message,
"IgnoreAutoExtract": True,
"EntryContext": {"SEPM.Update": context},
}
)
def move_client_to_group(token, group_id, hardware_key):
body = [{"group": {"id": group_id}, "hardwareKey": hardware_key}]
response = do_patch(token, "sepm/api/v1/computers", body)
message = (
"### Moved client to requested group successfully"
if response[0].get("responseCode") == "200"
else "### Error moving client"
)
return response, message
def move_client_to_group_command(token):
group_id = demisto.getArg("groupID")
hardware_key = demisto.getArg("hardwareKey")
response, message = move_client_to_group(token, group_id, hardware_key)
demisto.results(
{
"Type": entryTypes["note"],
"ContentsFormat": formats["text"],
"Contents": response,
"HumanReadable": message,
"IgnoreAutoExtract": True,
}
)
def main():
current_command = demisto.command()
try:
"""
Before EVERY command the following tow lines are performed (do_auth and get_token_from_response)
"""
resp = do_auth(
server=demisto.getParam("server"),
crads=demisto.getParam("authentication"),
insecure=demisto.getParam("insecure"),
domain=demisto.getParam("domain"),
)
token = get_token_from_response(resp)
if current_command == "test-module" and token:
# This is the call made when pressing the integration test button.
demisto.results("ok")
if current_command == "sep-system-info":
system_info_command(token)
if current_command == "sep-client-content":
client_content_command(token)
if current_command == "sep-endpoints-info":
endpoints_info_command(token)
if current_command == "sep-groups-info":
groups_info_command(token)
if current_command == "sep-command-status":
command_status(token)
if current_command == "sep-list-policies":
list_policies_command(token)
if current_command == "sep-assign-policy":
assign_policie_command(token)
if current_command == "sep-list-locations":
list_locations_command(token)
if current_command == "sep-endpoint-quarantine":
endpoint_quarantine_command(token)
if current_command == "sep-scan-endpoint":
scan_endpoint_command(token)
if current_command == "sep-update-endpoint-content":
update_endpoint_content_command(token)
if current_command == "sep-move-client-to-group":
move_client_to_group_command(token)
if current_command == "sep-identify-old-clients":
old_clients_command(token)
except Exception as ex:
return_error(f"Cannot perform the command: {current_command}. Error: {ex}")
if __name__ in ("__main__", "__builtin__", "builtins"):
main()