Symantec Management Center

Symantec Management Center provides a unified management environment for the Symantec Security Platform portfolio of products.

Network Security · Symantec Management Center

Details

IDSymantec Management Center
ProviderBroadcom
CategoryNetwork Security
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Symantec Management Center provides a unified management environment for the Symantec Security Platform portfolio of products. Management Center brings Symantec’s network, security, and cloud technologies to you under a single umbrella making it easier to deploy, manage, and monitor your security environment.

In Cortex XSOAR, the integration with Symantec MC allows viewing and managing devices and policies.
The integration was integrated and tested with version 2.2.1.1 of Symantec Management Center.

Use Cases

  1. View information about devices in Symantec MC
  2. View, create, update and delete policies in Symantec MC
  3. Manage shared IP/category/URL lists in Symantec MC

Configure Symantec Management Center on Cortex XSOAR

In order to access the API, user credentials for Symantec Management Center are required.

  1. Navigate to Settings > Integrations > Servers & Services.
  2. Search for Symantec Management Center.
  3. Click Add instance to create and configure a new integration instance.
    • Name: a textual name for the integration instance.
    • Server URL (e.g.: https://192.168.0.1:8082)
    • Credentials
    • Trust any certificate (not secure)
    • Use system proxy settings
  4. Click Test to validate the URLs, token, and connection.

Commands

You can execute these commands from the Cortex XSOAR CLI, as part of an automation, or in a playbook. After you successfully execute a command, a DBot message appears in the War Room with the command details.

1. Get a list of all devices


Lists all devices in Symantec MC.

Base Command

symantec-mc-list-devices

Input
Argument Name Description Required
build Filter the query filter parameter by the OS build number, for example: “GT 227900”. Optional
description Filter the query filter parameter by description, for example: “CONTAINS” desc". Optional
model Filter the query filter parameter by model, for example: “EQ VSWG-SE”. Optional
name Filter the query filter parameter by name, for example: “STARTSWITH CAS”. Optional
os_version Filter the query filter parameter by OS version, for example: “LT 2.3”. Optional
platform Filter the query filter parameter by platform, for example: “CONTAINS CAS”. Optional
type Filter the query filter parameter by device type, for example: “cas”. Optional
limit Maximum number of results to return. Optional

 

Context Output
Path Type Description
SymantecMC.Device.UUID String Device UUID.
SymantecMC.Device.Name String Device name.
SymantecMC.Device.LastChanged Date Device last changed date.
SymantecMC.Device.Type String Device type.
SymantecMC.Device.Host String Device host address.

 

Command Example
symantec-mc-list-devices name="CONTAINS Blue Coat"
Context Example
{
    "SymantecMC.Device": [
        {
            "Host": "192.168.1.207",
            "UUID": "C131C3D1-171B-4DA7-ADE2-AA736EA91540",
            "Type": "sgos6x",
            "Name": "192.168.1.207 - Blue Coat SG-VA Series",
            "LastChanged": "2019-04-08T11:27:32"
        }
    ]
}
Human Readable Output

Symantec Management Center Devices

UUID Name Last Changed Host Type
C131C3D1-171B-4DA7-ADE2-AA736EA91540 192.168.1.207 - Blue Coat SG-VA Series 2019-04-08T11:27:32 192.168.1.207 sgos6x

 

2. Get device information


Gets device information from Symantec MC.

Base Command

symantec-mc-get-device

Input
Argument Name Description Required
uuid Device UUID. Run the symantec-mc-list-devices command to get the UUID. Required

 

Context Output
Path Type Description
SymantecMC.Device.UUID String Device UUID.
SymantecMC.Device.Name String Device name.
SymantecMC.Device.LastChanged String Device last changed date.
SymantecMC.Device.LastChangedBy String User that last changed the device.
SymantecMC.Device.Description String Device description.
SymantecMC.Device.Model String Device model.
SymantecMC.Device…Platform String Device platform
SymantecMC.Device.Type String Device type.
SymantecMC.Device.OSVersion String Device OS version.
SymantecMC.Device.Build Number Device build number.
SymantecMC.Device.SerialNumber Number Device serial number.
SymantecMC.Device.Host String Device host address.
SymantecMC.Device.ManagementStatus String Device management status.
SymantecMC.Device.DeploymentStatus String Device deployment status.

 

Command Example
symantec-mc-get-device uuid="C131C3D1-171B-4DA7-ADE2-AA736EA91540"
Context Example
{
    "SymantecMC.Device": {
        "SerialNumber": "0806315479",
        "Name": "192.168.1.207 - Blue Coat SG-VA Series",
        "LastChangedBy": "admin",
        "LastChanged": "2019-04-08T11:27:32",
        "DeploymentStatus": "DEPLOYED",
        "ManagementStatus": "FULLY_MANAGED",
        "Platform": "Blue Coat SG-VA Series",
        "Host": "192.168.1.207",
        "Build": "226712",
        "Model": "VSWG-SE",
        "OSVersion": "SGOS 6.7.4.1 SWG Edition",
        "Type": "sgos6x",
        "UUID": "C131C3D1-171B-4DA7-ADE2-AA736EA91540"
    }
}
Human Readable Output

Symantec Management Center Device

UUID Name Last Changed Last Changed By Model Platform Host Type OS Version Build Serial Number Management Status Deployment Status
C131C3D1-171B-4DA7-ADE2-AA736EA91540 192.168.1.207 - Blue Coat SG-VA Series 2019-04-08T11:27:32 admin VSWG-SE Blue Coat SG-VA Series 192.168.1.207 sgos6x SGOS 6.7.4.1 SWG Edition 226712 0806315479 FULLY_MANAGED DEPLOYED

 

3. Get device health information


Gets health information for a device.

Base Command

symantec-mc-get-device-health

Input
Argument Name Description Required
uuid Device UUID. Run the symantec-mc-list-devices command to get the UUID. Required

 

Context Output
Path Type Description
SymantecMC.Device.UUID String Device UUID.
SymantecMC.Device.Name String Device name.
SymantecMC.Device.Health.Category String Device health category.
SymantecMC.Device.Health.Name String Device health name.
SymantecMC.Device.Health.State String Device health state.
SymantecMC.Device.Health.Message String Device health message.
SymantecMC.Device.Health.Status String Device health status.

 

Command Example
symantec-mc-get-device-health uuid="C131C3D1-171B-4DA7-ADE2-AA736EA91540"
Context Example
{
    "SymantecMC.Device": {
        "Health": [
            {
                "Category": "DNS Server",
                "Status": "UP",
                "Message": "Successes: 23374",
                "Name": "dns.8.8.8.8",
                "State": "OK"
            },
            {
                "Category": "External Services",
                "Status": "UP",
                "Message": "Successes: 796",
                "Name": "drtr.rating_service",
                "State": "OK"
            }
        ],
        "Name": "192.168.1.207 - Blue Coat SG-VA Series",
        "UUID": "C131C3D1-171B-4DA7-ADE2-AA736EA91540"
    }
}
Human Readable Output

Symantec Management Center Device

UUID Name
C131C3D1-171B-4DA7-ADE2-AA736EA91540 192.168.1.207 - Blue Coat SG-VA Series

Device Health

Category Name State Message Status
DNS Server dns.8.8.8.8 OK Successes: 23374 UP
External Services drtr.rating_service OK Successes: 796 UP

 

4. Get license information for a device


Gets license information for a device in Symantec MC

Base Command

symantec-mc-get-device-license

Input
Argument Name Description Required
uuid Device UUID. Run the symantec-mc-list-devices command to get the UUID. Required

 

Context Output
Path Type Description
SymantecMC.Device.UUID String Device UUID.
SymantecMC.Device.Name String Device name.
SymantecMC.Device.Type String Device type.
SymantecMC.Device.LicenseStatus String Device license status.
SymantecMC.Device.LicenseComponent.Name String Device license component name.
SymantecMC.Device.LicenseComponent.ActivationDate Date Device license component activation date.
SymantecMC.Device.LicenseComponent.ExpirationDate Date Device license component expiration date
SymantecMC.Device.LicenseComponent.Validity String Device license component validity.

 

Command Example
symantec-mc-get-device-license uuid="C131C3D1-171B-4DA7-ADE2-AA736EA91540"
Context Example
{
    "SymantecMC.Device": {
        "LicenseComponent": [
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "SGOS 6 SWG Edition"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Windows Media Streaming"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Real Media Streaming"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "QuickTime Streaming"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "SSL"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Bandwidth Management"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "ProxyClient - Acceleration"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "ProxyClient - Web Filtering"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "3rd Party Onbox Content Filtering"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "ICAP Services"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "AOL Instant Messaging"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "MSN Instant Messaging"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Yahoo Instant Messaging"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Netegrity SiteMinder"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Oracle COREid"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Peer-To-Peer"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Compression"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Flash Streaming"
            },
            {
                "ActivationDate": "2019-03-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Encrypted Tap"
            },
            {
                "ActivationDate": "2019-04-25T00:00:00",
                "ExpirationDate": "2019-09-24T00:00:00",
                "Validity": "VALID",
                "Name": "Authentication"
            }
        ],
        "Type": "sgos6x",
        "Name": "192.168.1.207 - Blue Coat SG-VA Series",
        "UUID": "C131C3D1-171B-4DA7-ADE2-AA736EA91540"
    }
}
Human Readable Output

Symantec Management Center Device

UUID Name Type
C131C3D1-171B-4DA7-ADE2-AA736EA91540 192.168.1.207 - Blue Coat SG-VA Series sgos6x

License Components

Name Activation Date Expiration Date Validity
SGOS 6 SWG Edition 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Windows Media Streaming 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Real Media Streaming 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
QuickTime Streaming 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
SSL 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Bandwidth Management 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
ProxyClient - Acceleration 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
ProxyClient - Web Filtering 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
3rd Party Onbox Content Filtering 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
ICAP Services 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
AOL Instant Messaging 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
MSN Instant Messaging 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Yahoo Instant Messaging 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Netegrity SiteMinder 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Oracle COREid 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Peer-To-Peer 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Compression 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Flash Streaming 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Encrypted Tap 2019-03-25T00:00:00 2019-09-24T00:00:00 VALID
Authentication 2019-04-25T00:00:00 2019-09-24T00:00:00 VALID

 

5. Get the status of a device


Gets the status of a device.

Base Command

symantec-mc-get-device-status

Input
Argument Name Description Required
uuid Device UUID. Run the symantec-mc-list-devices command to get the UUID. Required

 

Context Output
Path Type Description
SymantecMC.Device.UUID String Device UUID.
SymantecMC.Device.Name String Device name.
SymantecMC.Device.CheckDate Date Device check date.
SymantecMC.Device.StartDate Date Device start date.
SymantecMC.Device.MonitorState String Device monitor state.
SymantecMC.Device.Warnings Number Device warning count.
SymantecMC.Device.Errors Number Device error count.

 

Command Example
symantec-mc-get-device-status uuid="C131C3D1-171B-4DA7-ADE2-AA736EA91540"
Context Example
{
    "SymantecMC.Device": {
        "StartDate": "2019-03-25T12:37:42",
        "Errors": 0,
        "Name": "192.168.1.207 - Blue Coat SG-VA Series",
        "Warnings": 0,
        "MonitorState": "MONITORED",
        "CheckDate": "2019-04-28T13:05:40",
        "UUID": "C131C3D1-171B-4DA7-ADE2-AA736EA91540"
    }
}
Human Readable Output

Symantec Management Center Device Status

UUID Name Check Date Start Date Monitor State Warnings Errors
C131C3D1-171B-4DA7-ADE2-AA736EA91540 192.168.1.207 - Blue Coat SG-VA Series 2019-04-28T13:05:40 2019-03-25T12:37:42 MONITORED 0 0

 

6. Get a list of policies


List policies in Symantec MC.

Base Command

symantec-mc-list-policies

Input
Argument Name Description Required
content_type Filter the query filter parameter by content type of policy, e.g., “ENDSWITH URL” Optional
description Filter the query filter parameter by description, for example: “CONTAINS desc.” Optional
name Filter the query filter parameter by name, for example: “STARTSWITH my_list”. Optional
reference_id Filter the query filter parameter by referenceId, for example: “EQ my_list”. Optional
shared Parameter to filter, based on whether the policy is shared or not shared. Optional
tenant Filter the query filter parameter by tenant, e.g., “EQ TENANT_EXTERNAL_ID” Optional
limit Limit the number of results returned Optional

 

Context Output
Path Type Description
SymantecMC.Policy.UUID String Policy UUID.
SymantecMC.Policy.Name String Policy name.
SymantecMC.Policy.ContentType String Policy content type.
SymantecMC.Policy.Author String Policy author.
SymantecMC.Policy.Shared Boolean Policy shared.
SymantecMC.Policy.ReferenceID String Policy reference ID
SymantecMC.Policy.Tenant String Policy tenant.
SymantecMC.ReplaceVariables Boolean Policy replace variables.

 

Command Example
symantec-mc-list-policies content_type="EQ IP_LIST"
Context Example
{
    "SymantecMC.Policy": [
        {
            "ReferenceID": "test_ip_list",
            "ContentType": "IP_LIST",
            "Name": "test_ip_list",
            "Author": "admin",
            "ReplaceVariables": true,
            "Shared": true,
            "UUID": "0D264052-9628-4872-8C07-E04A8B95F602"
        },
        {
            "ReferenceID": "test_policy_ip",
            "ContentType": "IP_LIST",
            "Name": "test_policy_ip",
            "Author": "admin",
            "ReplaceVariables": false,
            "Shared": true,
            "Tenant": "1234",
            "UUID": "AF193330-49D0-413B-8365-6C4A5FD7A780"
        }
    ]
}
Human Readable Output

Symantec Management Center Policies

UUID Name Content Type Author Shared Reference ID Tenant Replace Variables
0D264052-9628-4872-8C07-E04A8B95F602 test_ip_list IP_LIST admin true test_ip_list   true
AF193330-49D0-413B-8365-6C4A5FD7A780 test_policy_ip IP_LIST admin true test_policy_ip 1234 false

 

7. Get policy information


Gets information for a policy.

Base Command

symantec-mc-get-policy

Input
Argument Name Description Required
uuid Device UUID. Run the symantec-mc-list-devices command to get the UUID. Optional
name The policy name Optional

 

Context Output
Path Type Description
SymantecMC.Policy.Name String Policy name.
SymantecMC.Policy.SchemaVersion Number Policy content schema version.
SymantecMC.Policy.RevisionInfo.Number Number Policy content revision number.
SymantecMC.Policy.RevisionInfo.Description String Policy content revision description.
SymantecMC.Policy.RevisionInfo.Author String Policy content revision author.
SymantecMC.Policy.RevisionInfo.Date Date Policy content revision date.
SymantecMC.Policy.IP.Address String Policy IP address.
SymantecMC.Policy.IP.Description String Policy IP description.
SymantecMC.Policy.IP.Enabled Boolean Policy IP enabled.
SymantecMC.Policy.URL.Address String Policy URL address.
SymantecMC.Policy.URL.Description String Policy URL description.
SymantecMC.Policy.URL.Enabled Boolean Policy URL enabled.
SymantecMC.Policy.Category.Name String Policy category name.
SymantecMC.Policy.UUID String Policy UUID.
SymantecMC.Policy.Description String Policy Description.
SymantecMC.Policy.ReferenceID String Policy reference ID.

 

Command Example
symantec-mc-get-policy uuid="0D264052-9628-4872-8C07-E04A8B95F602"
Context Example
{
    "SymantecMC.Policy": {
        "ReferenceID": "test_ip_list",
        "ContentType": "IP_LIST",
        "Description": "New description",
        "IP": [
            {
                "Enabled": false,
                "Description": "what?",
                "Address": "1.2.3.4"
            },
            {
                "Enabled": false,
                "Description": "Test IPs",
                "Address": "8.8.8.8"
            },
            {
                "Enabled": false,
                "Description": "Test IPs",
                "Address": "8.8.8.8"
            },
            {
                "Enabled": false,
                "Description": "Test IPs",
                "Address": "8.8.8.8"
            }
        ],
        "RevisionInfo": {
            "Date": "2019-04-28T13:03:46",
            "Number": "1.13",
            "Description": "test",
            "Author": "admin"
        },
        "UUID": "0D264052-9628-4872-8C07-E04A8B95F602",
        "SchemaVersion": "1.0",
        "Name": "test_ip_list"
    }
}
Human Readable Output

Symantec Management Center Policy

UUID Name Schema Version Reference ID Description Content Type
0D264052-9628-4872-8C07-E04A8B95F602 test_ip_list 1.0 test_ip_list New description IP_LIST

Revision Information

Number Description Author Date
1.13 test admin 2019-04-28T13:03:46

IP List

Address Description Enabled
1.2.3.4 what? false
8.8.8.8 Test IPs false
8.8.8.8 Test IPs false
8.8.8.8 Test IPs false

 

8. Create a policy


Creates a policy in Symantec MC.

Base Command

symantec-mc-create-policy

Input
Argument Name Description Required
name Policy name. Required
content_type Policy content type. Required
description Policy description. Optional
reference_id Policy reference ID. Optional
tenant UUID of the tenant associated with this policy. Run the symantec-mc-list-tenants command to get the tenant UUID. Optional
shared Share policy Optional
replace_variables Replace variables supported Optional

 

Context Output
Path Type Description
SymantecMC.Policy.UUID String Policy UUID.
SymantecMC.Policy.Name String Policy name.
SymantecMC.Policy.ContentType String Policy content type.
SymantecMC.Policy.Author String Policy author.

 

Command Example
symantec-mc-create-policy name="test_ip_policy" content_type="IP_LIST" description="This is a test" tenant="EDAD4D73-95E7-4C11-84EB-D0C73D28D50A" shared="true"
Context Example
{
    "SymantecMC.Policy": {
        "UUID": "AFD91FAE-27C7-461A-86BB-317805ED8DCC",
        "ContentType": "IP_LIST",
        "Name": "test_ip_policy",
        "Author": "admin"
    }
}
Human Readable Output

Policy created successfully

UUID Name Content Type Author
AFD91FAE-27C7-461A-86BB-317805ED8DCC test_ip_policy IP_LIST admin

 

9. Update a policy


Updates the metadata for a policy in Symantec MC.

Base Command

symantec-mc-update-policy

Input
Argument Name Description Required
uuid Policy UUID. Run the symantec-mc-list-policies command to get the UUID. Required
name New name of the policy. Optional
description New description of the policy. Optional
reference_id New reference ID of the policy. Optional
replace_variables Replace variables in the policy. Optional

 

Context Output
Path Type Description
SymantecMC.Policy.UUID String Policy UUID.
SymantecMC.Policy.Name String Policy name.

 

Command Example
symantec-mc-update-policy uuid="0D264052-9628-4872-8C07-E04A8B95F602" description="New description"
Context Example
{
    "SymantecMC.Policy": {
        "UUID": "0D264052-9628-4872-8C07-E04A8B95F602",
        "ContentType": "IP_LIST",
        "Name": "test_ip_list",
        "Author": "admin"
    }
}
Human Readable Output

Policy updated successfully

UUID Name Content Type Author
0D264052-9628-4872-8C07-E04A8B95F602 test_ip_list IP_LIST admin

 

10. Delete a policy


Deletes a policy in Symantec MC.

Base Command

symantec-mc-delete-policy

Input
Argument Name Description Required
uuid Policy UUID. Run the symantec-mc-list-policies command to get the UUID. Required
force Set to “true” to force the policy object to be removed even if it is referenced by another policy. Optional

 

Context Output

There is no context output for this command.

Command Example
symantec-mc-delete-policy uuid="DCF96A1D-1D42-493A-B377-84E682D91BF1"
Context Example

No context

Human Readable Output

Policy deleted successfully

11. Get a list of tenants


List tenants in Symantec MC.

Base Command

symantec-mc-list-tenants

Input
Argument Name Description Required
limit Maximum number of results to return. Optional

 

Context Output
Path Type Description
SymantecMC.Tenant.UUID String Tenant UUID.
SymantecMC.Tenant.Name String Tenant name.
SymantecMC.Tenant.ExternalID String Tenant external ID.
SymantecMC.Tenant.Description String Tenant description.
SymantecMC.Tenant.System Boolean Whether the system is a tenant.

 

Command Example
symantec-mc-list-tenants
Context Example
{
    "SymantecMC.Tenant": [
        {
            "System": true,
            "UUID": "54D4CDA9-293E-4861-B56F-0E50E5799F7A",
            "ExternalID": "default",
            "Description": "The tenant whose policy is used when no tenant-specific policy object is available.",
            "Name": "Default"
        },
        {
            "UUID": "EDAD4D73-95E7-4C11-84EB-D0C73D28D50A",
            "ExternalID": "1234",
            "Name": "Tenant",
            "System": false
        }
    ]
}
Human Readable Output

Symantec Management Center Tenants

UUID Name External ID Description System
54D4CDA9-293E-4861-B56F-0E50E5799F7A Default default The tenant whose policy is used when no tenant-specific policy object is available. true
EDAD4D73-95E7-4C11-84EB-D0C73D28D50A Tenant 1234   false

 

12. Add content to a policy


Adds content to a policy in Symantec MC. Can be IPs, URLs, or category names.

Base Command

symantec-mc-add-policy-content

Input
Argument Name Description Required
uuid Policy UUID. Run the symantec-mc-list-policies command to get the UUID. Optional
name The policy name to add content to. Optional
content_type Policy content type Required
change_description Description of the policy change. Required
schema_version The version of the schema for this content. This value will correspond to the format of the content. Run the symantec-mc-get-policy command to get the schema vesion. Optional
ip CSV list of IP addresses to add, for example: “1.2.3.4, 8.8.8.8”. Optional
url CSV list of URLs to add, for example: “www.google.com, www.github.com”. Optional
category CSV list of category names to add, for example: “Job Search/Careers, Content Servers”. Optional
enabled Relevant for URL and IP. Optional
description Content description. Optional

 

Context Output

There is no context output for this command.

Command Example
symantec-mc-add-policy-content uuid="0D264052-9628-4872-8C07-E04A8B95F602" content_type="IP_LIST" change_description="test" ip="2.2.2.2,4.4.4.4,8.8.8.8" description="Test IPs"
Context Example

No context output

Human Readable Output

Successfully added content to the policy

13. Delete policy content


Deletes content from a policy in Symantec MC.

Base Command

symantec-mc-delete-policy-content

Input
Argument Name Description Required
uuid Policy UUID. Run the symantec-mc-list-policies command to get the UUID. Optional
name The policy name to add content to. Optional
content_type Policy content type. Required
change_description Description of the policy change. Required
schema_version The version of the schema for this content. This value will correspond to the format of the content. Run the symantec-mc-get-policy command to get the schema version. Optional
ip CSV list of IP addresses to delete, for example: “1.2.3.4, 8.8.8.8”. Optional
url CSV list of URLs to delete, for example: “www.google.com, www.github.com”. Optional
category CSV list of category names to delete, for example: “Job Search/Careers, Content Servers”. Optional

 

Context Output

There is no context output for this command.

Command Example
symantec-mc-delete-policy-content uuid="0D264052-9628-4872-8C07-E04A8B95F602" content_type="IP_LIST" change_description="test" ip="2.2.2.2,4.4.4.4"
Context Example

No context output

Human Readable Output

Successfully deleted content from the policy

14. Update policy content


Updates content in a policy in Symantec MC.

Base Command

symantec-mc-update-policy-content

Input
Argument Name Description Required
uuid Policy UUID. Run the symantec-mc-list-policies command to get the UUID. Optional
name The policy name to update content in. Optional
content_type Policy content type. Required
change_description Description of the policy change. Required
schema_version The version of the schema for this content. This value will correspond to the format of the content. Run the symantec-mc-get-policy command to get the schema version. Optional
ip CSV list of IP addresses to update, for example: “1.2.3.4, 8.8.8.8”. Optional
url CSV list of URLs to update, for example: “www.google.com, www.github.com”. Optional
category CSV list of category names to update, for example: “Job Search/Careers, Content Servers”. Optional
enabled Relevant for URL and IP. Optional
description Content description. Optional

 

Context Output

There is no context output for this command.

Command Example
symantec-mc-update-policy-content uuid="0D264052-9628-4872-8C07-E04A8B95F602" content_type="LOCAL_CATEGORY_DB" change_description="test" ip="2.2.2.2,4.4.4.4" description="updated comment"
Context Example

No context output

Human Readable Output

Successfully updated content in the policy

Additional Information

For additional details regarding Query Filter Syntax see the Symantec Management Center API documentation.

Currently the integrations supports managing content for shared objects of types:

  • URL List
  • IP List
  • Category List
  • Local Database Category List

The API does not support running requests in parallel. An error will be thrown.

 

Troubleshooting

You may encounter the following errors while running Symantec MC commands:

HTTP 404 Not Found - The requested resource was not found. You can try to list the existing resources and search again.

HTTP 400 Bad Request - An incorrect request was sent to Symantec MC. Verify that you are sending the arguments correctly.

HTTP 500 Internal Server Error - Error in Symantec MC. Could occur if requests are made in parallel.

Configuration parameters

  • url — Server URL (e.g. https://192.168.0.1:8082) (required)
  • credentials — Username (required)
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (14)

  • symantec-mc-add-policy-content

    Adds content to a policy in Symantec MC. Can be IPs, URLs, or category names.

  • symantec-mc-create-policy

    Creates a policy in Symantec MC.

  • symantec-mc-delete-policy

    Deletes a policy in Symantec MC.

  • symantec-mc-delete-policy-content

    Deletes content from a policy in Symantec MC.

  • symantec-mc-get-device

    Gets device information from Symantec MC.

  • symantec-mc-get-device-health

    Gets health information for a device.

  • symantec-mc-get-device-license

    Gets license information for a device in Symantec MC.

  • symantec-mc-get-device-status

    Gets the status of a device.

  • symantec-mc-get-policy

    Gets information for a policy.

  • symantec-mc-list-devices

    Lists all devices in Symantec MC.

  • symantec-mc-list-policies

    List policies in Symantec MC.

  • symantec-mc-list-tenants

    List tenants in Symantec MC.

  • symantec-mc-update-policy

    Updates the metadata for a policy in Symantec MC.

  • symantec-mc-update-policy-content

    Updates content in a policy in Symantec MC.

import demistomock as demisto
from CommonServerPython import *

from CommonServerUserPython import *

""" IMPORTS """

import json


import requests

""" GLOBALS/PARAMS """

USERNAME: str
PASSWORD: str
SERVER: str
BASE_URL: str
USE_SSL: bool
HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}
URL_LIST_TYPE = "URL_LIST"
IP_LIST_TYPE = "IP_LIST"
CATEGORY_LIST_TYPE = "CATEGORY_LIST"
LOCAL_CATEGORY_DB_TYPE = "LOCAL_CATEGORY_DB"

""" HELPER FUNCTIONS """


def http_request(method, path, params=None, data=None):
    """
    Sends an HTTP request using the provided arguments
    :param method: HTTP method
    :param path: URL path
    :param params: URL query params
    :param data: Request body
    :return: JSON response (or the response itself if not serializable)
    """
    params = params if params is not None else {}
    data = data if data is not None else {}
    res = None

    try:
        res = requests.request(
            method,
            BASE_URL + path,
            auth=(USERNAME, PASSWORD),
            verify=USE_SSL,
            params=params,
            data=json.dumps(data, sort_keys=True),
            headers=HEADERS,
        )
    except (
        requests.exceptions.ConnectionError,
        requests.exceptions.Timeout,
        requests.exceptions.TooManyRedirects,
        requests.exceptions.RequestException,
    ) as e:
        return return_error(f"Could not connect to Symantec MC: {e!s}")

    if res.status_code < 200 or res.status_code > 300:
        status = res.status_code
        message = res.reason
        details = ""
        if res.status_code == 500:
            details = details + "\nA possible cause is that multiple requests were made simultaneously."
        try:
            error_json = res.json()
            message = error_json.get("statusMessage")
            details = error_json.get("message")
        except Exception:
            pass
        return_error(f"Error in API call to Symantec MC, status code: {status}, reason: {message}, details: {details}")

    try:
        return res.json()
    except Exception:
        if res.status_code == 204:
            return res
        return_error(f"Failed parsing the response from Symantec MC API: {res.text}")


def verify_policy_content(content_type, ips, categories, urls):
    if (
        (content_type == IP_LIST_TYPE and not ips)
        or (content_type == URL_LIST_TYPE and not urls)
        or (content_type == CATEGORY_LIST_TYPE and not categories)
    ):
        return_error(f"Incorrect content provided for the type {content_type}")
    if (
        (content_type == IP_LIST_TYPE and (urls or categories))
        or (content_type == URL_LIST_TYPE and (ips or categories))
        or (content_type == CATEGORY_LIST_TYPE and (ips or urls))
    ):
        return_error(f"More than one content type was provided for the type {content_type}")


def get_policy_uuid(uuid, name):
    if not uuid:
        if not name:
            return_error("Either a policy UUID or name must be provided")
        name_query = "EQ " + name
        policy = list_policies_request(name=name_query)
        if not policy or len(policy) == 0:
            return_error("Policy not found")
        if len(policy) > 1:
            return_error("Found more than one policy for the provided name")
        uuid = policy[0].get("uuid")
        if not uuid:
            return_error("Policy not found")

    return uuid


""" FUNCTIONS """


def test_module():
    """
    Performs basic get request to get system info
    """
    http_request("GET", "system/info")
    demisto.results("ok")


def list_devices_command():
    """
    List devices in Symantec MC using provided query filters
    """

    contents = []
    context = {}
    build = demisto.args().get("build")
    description = demisto.args().get("description")
    model = demisto.args().get("model")
    name = demisto.args().get("name")
    os_version = demisto.args().get("os_version")
    platform = demisto.args().get("platform")
    device_type = demisto.args().get("type")
    limit = int(demisto.args().get("limit", 10))

    devices = list_devices_request(build, description, model, name, os_version, platform, device_type)

    if devices:
        if limit:
            devices = devices[:limit]

        for device in devices:
            contents.append(
                {
                    "UUID": device.get("uuid"),
                    "Name": device.get("name"),
                    "LastChanged": device.get("lastChanged"),
                    "Host": device.get("host"),
                    "Type": device.get("type"),
                }
            )
        headers = ["UUID", "Name", "LastChanged", "Host", "Type"]
        human_readable = tableToMarkdown(
            "Symantec Management Center Devices", contents, removeNull=True, headers=headers, headerTransform=pascalToSpace
        )
        context["SymantecMC.Device(val.UUID && val.UUID === obj.UUID)"] = createContext(contents, removeNull=True)
    else:
        human_readable = "No devices found"

    return_outputs(human_readable, context, devices)


def list_devices_request(build, description, model, name, os_version, platform, device_type):
    """
    Get devices from Symantec MC
    :param build: Device build number query
    :param description: Device description query
    :param model: Device model query
    :param name: Device name query
    :param os_version: Device OS version query
    :param platform: Device platform query
    :param device_type: Device type
    :return: List of Symantec MC devices
    """

    path = "devices"
    params = {}

    if build:
        params["build"] = build
    if description:
        params["description"] = description
    if model:
        params["model"] = model
    if name:
        params["name"] = name
    if os_version:
        params["osVersion"] = os_version
    if platform:
        params["platform"] = platform
    if device_type:
        params["type"] = device_type

    response = http_request("GET", path, params)
    return response


def get_device_command():
    """
    Command to get information for a specified device
    :return: An entry with the device data
    """
    uuid = demisto.args()["uuid"]
    content: dict = {}
    context: dict = {}

    device = get_device_request(uuid)
    if device:
        content = {
            "UUID": device.get("uuid"),
            "Name": device.get("name"),
            "LastChanged": device.get("lastChanged"),
            "LastChangedBy": device.get("lastChangedBy"),
            "Description": device.get("description"),
            "Model": device.get("model"),
            "Platform": device.get("platform"),
            "Type": device.get("type"),
            "OSVersion": device.get("osVersion"),
            "Build": device.get("build"),
            "SerialNumber": device.get("serialNumber"),
            "Host": device.get("host"),
            "ManagementStatus": device.get("managementStatus"),
            "DeploymentStatus": device.get("deploymentStatus"),
        }

        context["SymantecMC.Device(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    headers = [
        "UUID",
        "Name",
        "LastChanged",
        "LastChangedBy",
        "Description",
        "Model",
        "Platform",
        "Host",
        "Type",
        "OSVersion",
        "Build",
        "SerialNumber",
        "ManagementStatus",
        "DeploymentStatus",
    ]

    return_outputs(
        tableToMarkdown(
            "Symantec Management Center Device", content, removeNull=True, headers=headers, headerTransform=pascalToSpace
        ),
        context,
        device,
    )


def get_device_request(uuid):
    """
    Return data for a specified device
    :param uuid: The device UUID
    :return: The device data
    """
    path = "devices/" + uuid

    response = http_request("GET", path)

    return response


def get_device_health_command():
    """
    Command to get health information for a specified device
    :return: An entry with the device data and health
    """
    uuid = demisto.args()["uuid"]
    health_content = []
    human_readable = ""
    context = {}

    device_health = get_device_health_request(uuid)
    if device_health:
        device_content = {"UUID": device_health.get("uuid"), "Name": device_health.get("name")}

        if device_health.get("health"):
            if not isinstance(device_health["health"], list):
                device_health["health"] = [device_health["health"]]
            for health in device_health["health"]:
                health_content.append(
                    {
                        "Category": health.get("category"),
                        "Name": health.get("name"),
                        "State": health.get("state"),
                        "Message": health.get("message"),
                        "Status": health.get("status"),
                    }
                )

        device_headers = ["UUID", "Name"]
        content = device_content
        human_readable = tableToMarkdown(
            "Symantec Management Center Device",
            device_content,
            removeNull=True,
            headers=device_headers,
            headerTransform=pascalToSpace,
        )
        if health_content:
            health_headers = ["Category", "Name", "State", "Message", "Status"]
            human_readable += tableToMarkdown(
                "Device Health", health_content, removeNull=True, headers=health_headers, headerTransform=pascalToSpace
            )
            content["Health"] = health_content
        else:
            human_readable += "\n\nNo health details found for this device\n"

        context["SymantecMC.Device(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    return_outputs(human_readable, context, device_health)


def get_device_health_request(uuid):
    """
    Return health for a specified device
    :param uuid: The device UUID
    :return: The device health data
    """
    path = "devices/" + uuid + "/health"

    response = http_request("GET", path)

    return response


def get_device_license_command():
    """
    Command to get license information for a specified device
    :return: An entry with the device data and license information
    """
    uuid = demisto.args()["uuid"]
    license_content = []
    human_readable = ""
    context = {}

    device_license = get_device_license_request(uuid)
    if device_license:
        if not isinstance(device_license["components"], list):
            device_license["components"] = [device_license["components"]]

        device_content = {
            "UUID": device_license.get("uuid"),
            "Name": device_license.get("name"),
            "Type": device_license.get("deviceType"),
            "LicenseStatus": device_license.get("licenseStatus"),
        }

        for component in device_license["components"]:
            license_content.append(
                {
                    "Name": component.get("componentName"),
                    "ActivationDate": component.get("activationDate"),
                    "ExpirationDate": component.get("expirationDate"),
                    "Validity": component.get("validity"),
                }
            )

        device_headers = ["UUID", "Name", "Type", "LicenseStatus"]
        content = device_content
        human_readable = tableToMarkdown(
            "Symantec Management Center Device",
            device_content,
            removeNull=True,
            headers=device_headers,
            headerTransform=pascalToSpace,
        )
        if license_content:
            license_headers = ["Name", "ActivationDate", "ExpirationDate", "Validity"]
            human_readable += tableToMarkdown(
                "License Components", license_content, removeNull=True, headers=license_headers, headerTransform=pascalToSpace
            )
            content["LicenseComponent"] = license_content

        context["SymantecMC.Device(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    return_outputs(human_readable, context, device_license)


def get_device_license_request(uuid):
    """
    Return the license for a specified device
    :param uuid: The device UUID
    :return: The device license data
    """
    path = "devices/" + uuid + "/license"

    response = http_request("GET", path)

    return response


def get_device_status_command():
    """
    Command to get the status for a specified device
    :return: An entry with the device status data
    """
    uuid = demisto.args()["uuid"]
    content: dict = {}
    context: dict = {}

    device = get_device_status_request(uuid)
    if device:
        content = {
            "UUID": device.get("uuid"),
            "Name": device.get("name"),
            "CheckDate": device.get("checkDate"),
            "StartDate": device.get("startDate"),
            "MonitorState": device.get("monitorState"),
            "Warnings": len(device.get("warnings", [])),
            "Errors": len(device.get("errors", [])),
        }

        context["SymantecMC.Device(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    headers = ["UUID", "Name", "CheckDate", "StartDate", "MonitorState", "Warnings", "Errors"]

    return_outputs(
        tableToMarkdown(
            "Symantec Management Center Device Status", content, removeNull=True, headers=headers, headerTransform=pascalToSpace
        ),
        context,
        device,
    )


def get_device_status_request(uuid):
    """
    Return data for a specified device status
    :param uuid: The device UUID
    :return: The device status data
    """
    path = "devices/" + uuid + "/status"

    response = http_request("GET", path)

    return response


def list_policies_command():
    """
    List policies in Symantec MC using provided query filters
    """

    contents = []
    context = {}
    content_type = demisto.args().get("content_type")
    description = demisto.args().get("description")
    name = demisto.args().get("name")
    reference_id = demisto.args().get("reference_id")
    shared = demisto.args().get("shared")
    tenant = demisto.args().get("tenant")
    limit = int(demisto.args().get("limit", 10))

    policies = list_policies_request(content_type, description, name, reference_id, shared, tenant)

    if policies:
        if limit:
            policies = policies[:limit]

        for policy in policies:
            contents.append(
                {
                    "UUID": policy.get("uuid"),
                    "Name": policy.get("name"),
                    "ContentType": policy.get("contentType"),
                    "Author": policy.get("author"),
                    "Shared": policy.get("shared"),
                    "ReferenceID": policy.get("referenceId"),
                    "Tenant": policy.get("tenant"),
                    "ReplaceVariables": policy.get("replaceVariables"),
                }
            )
        headers = ["UUID", "Name", "ContentType", "Author", "Shared", "ReferenceID", "Tenant", "ReplaceVariables"]
        human_readable = tableToMarkdown(
            "Symantec Management Center Policies", contents, removeNull=True, headers=headers, headerTransform=pascalToSpace
        )
        context["SymantecMC.Policy(val.UUID && val.UUID === obj.UUID)"] = createContext(contents, removeNull=True)
    else:
        human_readable = "No policies found"

    return_outputs(human_readable, context, policies)


def list_policies_request(content_type=None, description=None, name=None, reference_id=None, shared=None, tenant=None):
    """
    Get policies in Symantec MC
    :param content_type: Policy content type query
    :param description: Policy description query
    :param name: Policy name query
    :param reference_id: Policy reference ID query
    :param shared: Policy shared query
    :param tenant: Policy tenant query
    :return: List of policies in Symantec MC
    """
    path = "policies"
    params = {}

    if content_type:
        params["contentType"] = content_type
    if description:
        params["description"] = description
    if name:
        params["name"] = name
    if reference_id:
        params["referenceId"] = reference_id
    if shared:
        params["shared"] = shared
    if tenant:
        params["tenant"] = tenant

    response = http_request("GET", path, params)
    return response


def get_policy_command():
    """
    Command to get information for a specified policy including it's contents
    :return: An entry with the policy data
    """
    uuid = demisto.args().get("uuid")
    name = demisto.args().get("name")
    policy_content_data: dict = {}
    revision_content: dict = {}
    policy_content_content = []
    content_title = ""
    human_readable = ""
    content_headers: list = []
    content_key = ""
    context: dict = {}

    if not name and not uuid:
        return_error("Either a UUID or a name must be provided")

    uuid = get_policy_uuid(uuid, name)

    policy = get_policy_request(uuid)
    if policy:
        policy_content = {
            "UUID": policy.get("uuid"),
            "Name": policy.get("name"),
            "Description": policy.get("description"),
            "ContentType": policy.get("contentType"),
            "ReferenceID": policy.get("referenceId"),
        }
        policy_content_data = get_policy_content_request(uuid)

        if policy_content_data and policy_content_data.get("revisionInfo"):
            policy_content["SchemaVersion"] = policy_content_data.get("schemaVersion")
            revision_content = {
                "Number": policy_content_data["revisionInfo"].get("revisionNumber"),
                "Description": policy_content_data["revisionInfo"].get("revisionDescription"),
                "Author": policy_content_data["revisionInfo"].get("author"),
                "Date": policy_content_data["revisionInfo"].get("revisionDate"),
            }

        if policy.get("contentType") == URL_LIST_TYPE:
            content_title = "URL List"
            content_headers = ["Address", "Description", "Enabled"]
            content_key = "URL"
            urls = policy_content_data.get("content", {}).get("urls", [])
            for url in urls:
                policy_content_content.append(
                    {"Address": url.get("url"), "Description": url.get("description"), "Enabled": url.get("enabled")}
                )
        elif policy.get("contentType") == IP_LIST_TYPE:
            content_title = "IP List"
            content_headers = ["Address", "Description", "Enabled"]
            content_key = "IP"
            ips = policy_content_data.get("content", {}).get("ipAddresses", [])
            for ip in ips:
                policy_content_content.append(
                    {"Address": ip.get("ipAddress"), "Description": ip.get("description"), "Enabled": ip.get("enabled")}
                )
        elif policy.get("contentType") == CATEGORY_LIST_TYPE:
            content_title = "Category List"
            content_headers = ["Name"]
            content_key = "Category"
            categories = policy_content_data.get("content", {}).get("categories", [])
            for category in categories:
                policy_content_content.append({"Name": category.get("categoryName")})

        policy_headers = ["UUID", "Name", "SchemaVersion", "ReferenceID", "Description", "ContentType"]
        human_readable = tableToMarkdown(
            "Symantec Management Center Policy",
            policy_content,
            removeNull=True,
            headers=policy_headers,
            headerTransform=pascalToSpace,
        )
        content = policy_content
        if revision_content:
            revision_headers = ["Number", "Description", "Author", "Date"]
            content["RevisionInfo"] = revision_content
            human_readable += tableToMarkdown(
                "Revision Information", revision_content, removeNull=True, headers=revision_headers, headerTransform=pascalToSpace
            )

        if policy_content_content:
            content[content_key] = policy_content_content
            human_readable += tableToMarkdown(
                content_title, policy_content_content, removeNull=True, headers=content_headers, headerTransform=pascalToSpace
            )

        context["SymantecMC.Policy(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    policy.update(policy_content_data)
    return_outputs(human_readable, context, policy)


def get_policy_request(uuid):
    """
    Return data for a specified policy
    :param uuid: The policy UUID
    :return: The policy data
    """
    path = "policies/" + uuid

    response = http_request("GET", path)

    return response


def get_policy_content_request(uuid):
    """
    Return content data for a specified policy
    :param uuid: The policy UUID
    :return: The policy content data
    """
    path = "policies/" + uuid + "/content"

    response = http_request("GET", path)

    return response


def create_policy_command():
    """
    Command to create a new policy in Symantec MC
    :return: An entry with the new policy data
    """
    name = demisto.args()["name"]
    content_type = demisto.args()["content_type"]
    description = demisto.args().get("description")
    reference_id = demisto.args().get("reference_id")
    tenant = demisto.args().get("tenant")
    shared = demisto.args().get("shared")
    replace_variables = demisto.args().get("replace_variables")

    content: dict = {}
    context: dict = {}

    policy = create_policy_request(name, content_type, description, reference_id, tenant, shared, replace_variables)
    if policy:
        content = {
            "UUID": policy.get("uuid"),
            "Name": policy.get("name"),
            "ContentType": policy.get("contentType"),
            "Author": policy.get("author"),
        }

        context["SymantecMC.Policy(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    headers = ["UUID", "Name", "ContentType", "Author"]

    return_outputs(
        tableToMarkdown("Policy created successfully", content, removeNull=True, headers=headers, headerTransform=pascalToSpace),
        context,
        policy,
    )


def create_policy_request(name, content_type, description, reference_id, tenant, shared, replace_variables):
    """
    Creates a policy in Symantec MC using the provided arguments
    :param name: Policy name
    :param content_type: Policy content type
    :param description: Policy description
    :param reference_id: Policy reference ID
    :param tenant: Policy tenant
    :param shared: Policy shared
    :param replace_variables: Policy replace variables
    :return: The created policy data
    """
    path = "policies"

    body = {"name": name, "contentType": content_type}

    if description:
        body["description"] = description
    if reference_id:
        body["referenceId"] = reference_id
    if tenant:
        body["tenant"] = tenant
    if shared:
        body["shared"] = shared
    if replace_variables:
        body["replaceVariables"] = replace_variables

    response = http_request("POST", path, data=body)
    return response


def update_policy_command():
    """
    Command to update an existing policy in Symantec MC
    :return: An entry with the policy data
    """
    uuid = demisto.args()["uuid"]
    name = demisto.args().get("name")
    description = demisto.args().get("description")
    reference_id = demisto.args().get("reference_id")
    replace_variables = demisto.args().get("replace_variables")

    content: dict = {}
    context: dict = {}

    policy = update_policy_request(uuid, name, description, reference_id, replace_variables)
    if policy:
        content = {
            "UUID": policy.get("uuid"),
            "Name": policy.get("name"),
            "ContentType": policy.get("contentType"),
            "Author": policy.get("author"),
        }

        context["SymantecMC.Policy(val.UUID && val.UUID === obj.UUID)"] = createContext(content, removeNull=True)

    headers = ["UUID", "Name", "ContentType", "Author"]

    return_outputs(
        tableToMarkdown("Policy updated successfully", content, removeNull=True, headers=headers, headerTransform=pascalToSpace),
        context,
        policy,
    )


def update_policy_request(uuid, name, description, reference_id, replace_variables):
    """
    Updates a policy in Symantec MC using the provided arguments
    :param uuid: Policy UUID
    :param name: New policy name
    :param description: New policy description
    :param reference_id: New policy reference ID
    :param replace_variables: New policy replace variables
    :return: The updated policy data
    """
    path = "policies/" + uuid

    body = {}

    if name:
        body["name"] = name
    if description:
        body["description"] = description
    if reference_id:
        body["referenceId"] = reference_id
    if replace_variables:
        body["replaceVariables"] = replace_variables

    response = http_request("PUT", path, data=body)
    return response


def delete_policy_command():
    """
    Command to delete an existing policy in Symantec MC
    :return: An entry indicating whether the deletion was successful
    """
    uuid = demisto.args()["uuid"]
    force = demisto.args().get("force")

    delete_policy_request(uuid, force)
    return_outputs("Policy deleted successfully", {}, {})


def delete_policy_request(uuid, force):
    """
    Deletes a policy in Symantec MC using the provided arguments
    :param uuid: Policy UUID
    :param force: Force policy delete
    :return: The deletion response
    """
    path = "policies/" + uuid

    response = http_request("DELETE", path, data=force)
    return response


def add_policy_content_command():
    """
    Command to add content to an existing policy in Symantec MC
    :return: An entry indicating whether the addition was successful
    """
    uuid = demisto.args().get("uuid")
    name = demisto.args().get("name")
    content_type = demisto.args()["content_type"]
    change_description = demisto.args()["change_description"]
    schema_version = demisto.args().get("schema_version")
    ips = argToList(demisto.args().get("ip", []))
    urls = argToList(demisto.args().get("url", []))
    categories = argToList(demisto.args().get("category", []))
    enabled = demisto.args().get("enabled")
    description = demisto.args().get("description")

    verify_policy_content(content_type, ips, categories, urls)

    uuid = get_policy_uuid(uuid, name)

    if content_type == IP_LIST_TYPE:
        add_policy_content_request(
            uuid, content_type, change_description, schema_version, ips=ips, enabled=enabled, description=description
        )
    elif content_type == URL_LIST_TYPE:
        add_policy_content_request(
            uuid, content_type, change_description, schema_version, urls=urls, enabled=enabled, description=description
        )
    elif content_type == CATEGORY_LIST_TYPE:
        add_policy_content_request(uuid, content_type, change_description, schema_version, categories=categories)
    elif content_type == LOCAL_CATEGORY_DB_TYPE:
        add_policy_content_request(
            uuid,
            content_type,
            change_description,
            schema_version,
            urls=urls,
            categories=categories,
            ips=ips,
            description=description,
        )

    # parsing input arguments as outputs to display the added content
    output = demisto.args()
    human_readable = tableToMarkdown("Successfully added content to the policy", output)
    return_outputs(human_readable, {}, output)


def add_policy_content_request(
    uuid, content_type, change_description, schema_version, ips=None, urls=None, categories=None, enabled=None, description=""
):
    """
    Add content to a specified policy using the provided arguments
    :param uuid: Policy UUID
    :param content_type: Policy content type
    :param change_description: Policy update change description
    :param schema_version: Policy schema version
    :param ips: IPs to add to the content
    :param urls: URLs to add to the content
    :param categories: Category names to add to the content
    :param enabled:  Policy content enabled
    :param description: Policy content description
    :return: Content update response
    """
    path = "policies/" + uuid + "/content"

    body = {"contentType": content_type, "changeDescription": change_description}

    if schema_version:
        body["schemaVersion"] = schema_version

    content = get_policy_content_request(uuid)
    if not content or "content" not in content:
        return_error("Could not update policy content - failed retrieving the current content")

    if content_type == LOCAL_CATEGORY_DB_TYPE:
        if "categories" not in content["content"]:
            content["content"]["categories"] = []
        for category in categories:
            content_entities = []
            if ips:
                content_entities.extend(ips)
            if urls:
                content_entities.extend(urls)
            entries = []
            for entity in content_entities:
                entries.append({"type": "url", "url": entity, "comment": description})
            found_existing_category = False
            for existing_category in content["content"]["categories"]:
                if existing_category.get("name") == category:
                    existing_category["entries"].extend(entries)
                    found_existing_category = True
                    break
            if not found_existing_category:
                content["content"]["categories"].append({"type": "inline", "name": category, "entries": entries})
    elif ips:
        if "ipAddresses" not in content["content"]:
            content["content"]["ipAddresses"] = []
        content["content"]["ipAddresses"] += [
            {"ipAddress": ip, "description": description, "enabled": argToBoolean(enabled)} for ip in ips
        ]
    elif urls:
        existing_urls = [x["url"].lower() for x in content["content"]["urls"]]
        if "urls" not in content["content"]:
            content["content"]["urls"] = []
        content["content"]["urls"] += [
            {"url": url, "description": description, "enabled": argToBoolean(enabled)}
            for url in urls
            if url.lower() not in existing_urls
        ]
    elif categories:
        if "categories" not in content["content"]:
            content["content"]["categories"] = []
        content["content"]["categories"] += [
            {
                "categoryName": category,
            }
            for category in categories
        ]

    body["content"] = content["content"]
    response = http_request("POST", path, data=body)

    return response


def delete_policy_content_command():
    """
    Command to delete content from an existing policy in Symantec MC
    :return: An entry indicating whether the deletion was successful
    """
    uuid = demisto.args().get("uuid")
    name = demisto.args().get("name")
    content_type = demisto.args()["content_type"]
    change_description = demisto.args()["change_description"]
    schema_version = demisto.args().get("schema_version")
    ips = argToList(demisto.args().get("ip", []))
    urls = argToList(demisto.args().get("url", []))
    categories = argToList(demisto.args().get("category", []))

    verify_policy_content(content_type, ips, categories, urls)

    uuid = get_policy_uuid(uuid, name)

    content_deleted = []

    if content_type == IP_LIST_TYPE:
        delete_policy_content_request(uuid, content_type, change_description, schema_version, ips=ips)
    elif content_type == URL_LIST_TYPE:
        delete_policy_content_request(uuid, content_type, change_description, schema_version, urls=urls)
    elif content_type == CATEGORY_LIST_TYPE:
        delete_policy_content_request(uuid, content_type, change_description, schema_version, categories=categories)
    elif content_type == LOCAL_CATEGORY_DB_TYPE:
        content_deleted = delete_policy_content_request(
            uuid, content_type, change_description, schema_version, ips=ips, urls=urls, categories=categories
        )

    if content_deleted:
        human_readable = tableToMarkdown("Successfully deleted content from the policy", content_deleted)
        return_outputs(human_readable, {}, content_deleted)
    else:
        return_outputs("Successfully deleted content from the policy", {}, {})


def delete_policy_content_request(uuid, content_type, change_description, schema_version, ips=None, urls=None, categories=None):
    """
    Add content to a specified policy using the provided arguments
    :param uuid: Policy UUID
    :param content_type: Policy content type
    :param change_description: Policy update change description
    :param schema_version: Policy schema version
    :param ips: IPs to delete from the content
    :param urls: URLs to delete from the content
    :param categories: Category names to delete from the content
    :return: Content update response
    """
    path = "policies/" + uuid + "/content"

    body = {"contentType": content_type, "changeDescription": change_description}

    if schema_version:
        body["schemaVersion"] = schema_version

    content = get_policy_content_request(uuid)
    if not content or "content" not in content:
        return_error("Could not update policy content - failed retrieving the current content")

    content_deleted = []

    if content_type == LOCAL_CATEGORY_DB_TYPE:
        found_object_to_delete = False
        content_entities = []
        if ips:
            content_entities.extend(ips)
        if urls:
            content_entities.extend(urls)
        if "categories" in content["content"]:
            if not categories:
                categories = [category.get("name") for category in content["content"]["categories"]]
            categories_to_keep = []
            for category in content["content"]["categories"]:
                if category.get("name") in categories:
                    entries_to_keep = []
                    for entry in category.get("entries"):
                        if entry.get("url") in content_entities:
                            content_deleted.append({"CategoryName": category.get("name"), "ObjectDeleted": entry.get("url")})
                            found_object_to_delete = True
                        else:
                            entries_to_keep.append(entry)
                    if entries_to_keep:
                        categories_to_keep.append({"name": category.get("name"), "type": "inline", "entries": entries_to_keep})
                    else:
                        content_deleted.append(
                            {
                                "CategoryName": category.get("name"),
                                "ObjectDeleted": "The category was deleted. Category cannot be empty.",
                            }
                        )
                else:
                    categories_to_keep.append(category)
            content["content"]["categories"] = categories_to_keep
        if not found_object_to_delete:
            raise Exception("Deletion failed - Could not find object to delete.")
    elif ips:
        if "ipAddresses" in content["content"]:
            ips_to_keep = [ip for ip in content["content"]["ipAddresses"] if ip["ipAddress"] not in ips]
            content["content"]["ipAddresses"] = ips_to_keep
    elif urls:
        if "urls" in content["content"]:
            urls_to_delete = [x.lower() for x in urls]
            urls_to_keep = [url for url in content["content"]["urls"] if url["url"] not in urls_to_delete]
            content["content"]["urls"] = urls_to_keep
    elif categories and "categories" in content["content"]:
        categories_to_keep = [
            category for category in content["content"]["categories"] if category["categoryName"] not in categories
        ]
        content["content"]["categories"] = categories_to_keep

    body["content"] = content["content"]
    http_request("POST", path, data=body)

    return content_deleted


def update_policy_content_command():
    """
    Command to update existing policy content in Symantec MC
    :return: An entry indicating whether the update was successful
    """
    uuid = demisto.args().get("uuid")
    name = demisto.args().get("name")
    content_type = demisto.args()["content_type"]
    change_description = demisto.args()["change_description"]
    schema_version = demisto.args().get("schema_version")
    ips = argToList(demisto.args().get("ip", []))
    urls = argToList(demisto.args().get("url", []))
    categories = argToList(demisto.args().get("category", []))
    content_description = demisto.args().get("description")
    content_enabled = demisto.args().get("enabled")

    if not (content_description or content_enabled):
        raise ValueError("No attributes to update were provided.")

    verify_policy_content(content_type, ips, categories, urls)

    uuid = get_policy_uuid(uuid, name)

    if content_type == IP_LIST_TYPE:
        update_policy_content_request(
            uuid,
            content_type,
            change_description,
            schema_version,
            ips=ips,
            content_description=content_description,
            content_enabled=content_enabled,
        )
    elif content_type == URL_LIST_TYPE:
        update_policy_content_request(
            uuid,
            content_type,
            change_description,
            schema_version,
            urls=urls,
            content_description=content_description,
            content_enabled=content_enabled,
        )
    elif content_type == LOCAL_CATEGORY_DB_TYPE:
        update_policy_content_request(
            uuid,
            content_type,
            change_description,
            schema_version,
            ips=ips,
            urls=urls,
            categories=categories,
            content_description=content_description,
            content_enabled=content_enabled,
        )

    # parsing input arguments as outputs to display the updated content
    output = demisto.args()
    human_readable = tableToMarkdown("Successfully updated content in the policy", output)
    return_outputs(human_readable, {}, output)


def update_policy_content_request(
    uuid,
    content_type,
    change_description,
    schema_version,
    ips=None,
    urls=None,
    categories=None,
    content_description=None,
    content_enabled=None,
):
    """
    Update content of a specified policy using the provided arguments
    :param uuid: Policy UUID
    :param content_type: Policy content type
    :param change_description: Policy update change description
    :param schema_version: Policy schema version
    :param ips: IPs to update from the content
    :param urls: URLs to update from the content
    :param categories: Category names to update from the content
    :param content_description: Content description to update.
    :param content_enabled: Content enablement to update.
    :return: Content update response
    """
    path = "policies/" + uuid + "/content"

    body = {"contentType": content_type, "changeDescription": change_description}

    if schema_version:
        body["schemaVersion"] = schema_version

    content = get_policy_content_request(uuid)

    if not content or "content" not in content:
        return_error("Could not update policy content - failed retrieving the current content")

    found_object_to_update = False

    if content_type == LOCAL_CATEGORY_DB_TYPE:
        if "categories" in content["content"]:
            content_entities = []
            if ips:
                content_entities.extend(ips)
            if urls:
                content_entities.extend(urls)
            for category in content["content"]["categories"]:
                if category.get("name") in categories:
                    for entry_index, entry in enumerate(category.get("entries")):
                        if entry.get("url") in content_entities:
                            found_object_to_update = True
                            category["entries"][entry_index]["comment"] = content_description
    elif ips:
        if "ipAddresses" in content["content"]:
            for ip in content["content"]["ipAddresses"]:
                if ip["ipAddress"] in ips:
                    found_object_to_update = True
                    if content_description:
                        ip["description"] = content_description
                    if content_enabled:
                        ip["enabled"] = argToBoolean(content_enabled)
    elif urls and "urls" in content["content"]:
        for url in content["content"]["urls"]:
            found_object_to_update = True
            if url["url"] in urls:
                found_object_to_update = True
                if content_description:
                    url["description"] = content_description
                if content_enabled:
                    url["enabled"] = argToBoolean(content_enabled)

    if not found_object_to_update:
        raise Exception("Update failed - Could not find object to update.")

    body["content"] = content["content"]
    response = http_request("POST", path, data=body)

    return response


def list_tenants_command():
    """
    List tenants in Symantec MC
    """

    contents = []
    context = {}
    limit = int(demisto.args().get("limit", 10))

    tenants = list_tenants_request()

    if tenants:
        if limit:
            tenants = tenants[:limit]

        for tenant in tenants:
            contents.append(
                {
                    "UUID": tenant.get("uuid"),
                    "Name": tenant.get("name"),
                    "ExternalID": tenant.get("externalId"),
                    "Description": tenant.get("description"),
                    "System": tenant.get("system"),
                }
            )
        headers = ["UUID", "Name", "ExternalID", "Description", "System"]
        human_readable = tableToMarkdown(
            "Symantec Management Center Tenants", contents, removeNull=True, headers=headers, headerTransform=pascalToSpace
        )
        context["SymantecMC.Tenant(val.UUID && val.UUID === obj.UUID)"] = createContext(contents, removeNull=True)
    else:
        human_readable = "No tenants found"

    return_outputs(human_readable, context, tenants)


def list_tenants_request():
    """
    Get devices from Symantec MC
    :return: List of Symantec MC tenants
    """

    path = "tenants"
    params: dict = {}

    response = http_request("GET", path, params)
    return response


def main():
    global USERNAME, PASSWORD, SERVER, BASE_URL, USE_SSL
    USERNAME = demisto.params().get("credentials").get("identifier")
    PASSWORD = demisto.params().get("credentials").get("password")
    SERVER = (
        demisto.params()["url"][:-1]
        if (demisto.params()["url"] and demisto.params()["url"].endswith("/"))
        else demisto.params()["url"]
    )
    BASE_URL = SERVER + "/api/"
    USE_SSL = not demisto.params().get("insecure", False)

    LOG("Command being called is " + demisto.command())
    handle_proxy()

    command_dictionary = {
        "test-module": test_module,
        "symantec-mc-list-devices": list_devices_command,
        "symantec-mc-get-device": get_device_command,
        "symantec-mc-get-device-health": get_device_health_command,
        "symantec-mc-get-device-license": get_device_license_command,
        "symantec-mc-get-device-status": get_device_status_command,
        "symantec-mc-list-policies": list_policies_command,
        "symantec-mc-get-policy": get_policy_command,
        "symantec-mc-create-policy": create_policy_command,
        "symantec-mc-update-policy": update_policy_command,
        "symantec-mc-delete-policy": delete_policy_command,
        "symantec-mc-add-policy-content": add_policy_content_command,
        "symantec-mc-delete-policy-content": delete_policy_content_command,
        "symantec-mc-update-policy-content": update_policy_content_command,
        "symantec-mc-list-tenants": list_tenants_command,
    }

    try:
        command_func = command_dictionary[demisto.command()]
        command_func()
    except Exception as e:
        return_error(str(e))


if __name__ in ["__main__", "__builtin__", "builtins"]:
    main()