Infoblox

Infoblox NIOS enables you to receive metadata about IPs in your network and manages the DNS Firewall by configuring RPZs. It defines RPZ rules to block DNS resolution for malicious or unauthorized hostnames, or redirect clients to a walled garden by substituting responses.

Network Security · Infoblox NIOS

Details

IDInfoblox
ProviderInfoblox
CategoryNetwork Security
From Version5.0.0
Docker Imagedemisto/python3:3.12.13.10116658
Supported ModulesAgentix XSIAM

README

Infoblox NIOS enables you to receive metadata about IPs in your network and manages the DNS Firewall by configuring RPZs. It defines RPZ rules to block DNS resolution for malicious or unauthorized hostnames, or redirect clients to a walled garden by substituting responses. This integration was integrated and tested with version V2 of Infoblox

Configure Infoblox NIOS on XSOAR

Required Permissions

The API supports only HTTP Basic Authentication. Every user must have permissions that grants them access to the API.

  1. Navigate to Settings > Integrations  > Servers & Services.
  2. Search for Infoblox NIOS.
  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://example.net)
    • User Name
    • Password
    • Trust any certificate (not secure)
    • Use system proxy settings
  4. Click Test to validate the new instance.

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 IP info: infoblox-get-ip.
  2. Searches IP related objects by a given IP: infoblox-search-related-objects-by-ip.
  3. Lists all response policy rules that belong to the given response policy zone: infoblox-list-response-policy-zone-rules.
  4. List all response policy zones: infoblox-list-response-policy-zones.
  5. Creates a response policy zone: infoblox-create-response-policy-zone.
  6. Creates a response policy rule: infoblox-create-rpz-rule.
  7. Creates a substitute record rule: infoblox-create-a-substitute-record-rule.
  8. Creates a substitute rule for an AAAA record: infoblox-create-aaaa-substitute-record-rule.
  9. Creates a substitute rule for the MX record: infoblox-create-mx-substitute-record-rule.
  10. Creates a substitute rule for a NAPTR record: infoblox-create-naptr-substitute-record-rule.
  11. Creates a substitute rule of the PTR record: infoblox-create-ptr-substitute-record-rule.
  12. Creates a substitute rule of a SRV record: infoblox-create-srv-substitute-record-rule.
  13. Create a substitute rule for a txt record: infoblox-create-txt-substitute-record-rule.
  14. Create a substitute rule for an IPv4 rule: infoblox-create-ipv4-substitute-record-rule.
  15. Creates a substitute of the IPv6 record rule: infoblox-create-ipv6-substitute-record-rule.
  16. Disables a rule by its reference ID (reference ID can be extracted by running the search rules command): infoblox-enable-rule.
  17. Disable a rule by its reference ID (reference ID can be extracted by running the ‘infoblox-search-rule’ command): infoblox-disable-rule.
  18. Returns the object fields names which can be used in the search rules command: infoblox-get-object-fields.
  19. Searches a specific rule by its name: infoblox-search-rule.
  20. Deletes a rule: infoblox-delete-rpz-rule.
  21. Deletes a given response policy zone: infoblox-delete-response-policy-zone.
  22. List host information: infoblox-list-host-info.
  23. List network information: infoblox-list-network-info.
  24. Update a response policy zone rule: infoblox-update-rpz-rule.
  25. Create a host record: infoblox-create-host-record.
  26. Look up a DHCP lease: infoblox-dhcp-lease-lookup.

infoblox-get-ip


Get IP information.

Base Command

infoblox-get-ip

Input
Argument Name Description Required
ip The IP address for which to retrieve information, e.g. “192.168.1.1”, “2001:db8::1”. Cannot be used in conjunction with network or from/to_ip arguments. Optional
network The network that the IP belongs in FQDN/CIDR format, e.g. “192.168.1.0/24”, “2001:db8::/64”. Cannot be used in conjunction with ip or from/to_ip arguments. Optional
from_ip The beginning of the IP range, e.g. “192.168.1.0”, “2001:db8::”. Must be used in conjunction with to_ip. Optional
to_ip The end of the IP range, e.g. “192.168.1.254”, “2001:db8::254”. Must be used in conjunction with from_ip. Optional
status The status of the IP device. Used in conjunction with the network or ip argument. Possible values are ACTIVE, UNUSED and USED. Optional
extended_attrs Comma-separated key/value formatted filter for extended attributes, e.g. “Site=New York,OtherProp=MyValue”. Optional
max_results The maximum results to return. Maximum is 1000. Default is 50. Optional
Context Output
Path Type Description
Infoblox.IP.ReferenceID number Reference ID of the object.
Infoblox.IP.MacAddress string The Mac address of the IP.
Infoblox.IP.Network string The network that the IP belongs (in FQDN/CIDR format.)
Infoblox.IP.NetworkView string The name of the network view.
Infoblox.IP.Status string The current status of the address.
Infoblox.IP.IsConflict string Whether the IP address has either a MAC address conflict or a DHCP lease conflict detected through a network discovery (if set to true).
Infoblox.IP.Objects string The objects associated with the IP address.
Infoblox.IP.Types string The current status of the address.
Infoblox.IP.Names string The DNS names. For example, if the IP address belongs to a host record, this field contains the hostname.
Infoblox.IP.Extattrs string Extra attributes relevant for this object.
Infoblox.IP.IpAddress string The IP address.
Infoblox.IP.Usage string Indicates whether the IP address is configured for DNS or DHCP.
Command Example

!infoblox-get-ip ip="172.0.0.0"

Context Example
{
    "Infoblox.IP": [
        "Extattrs": {},
        "IpAddress": "172.0.0.0",
        "IsConflict": false,
        "MacAddress": "",
        "Names": [],
        "Network": "172.0.0.0/24",
        "NetworkView": "default",
        "Objects": [],
        "ReferenceID": "ipv4address/Li5pcHY0X2FkZHJlc3MkMTcyLjAuMC4wLzA:172.0.0.0",
        "Status": "USED",
        "Types": [
            "NETWORK"
        ],
        "Usage": []
    ]
}
Human Readable Output

Infoblox Integration

Extattrs Ip Address Is Conflict Mac Address Names Network Network View Objects Reference ID Status Types Usage
  172.0.0.0 false     172.0.0.0/24 default   ipv4address/Li5pcHY0X2FkZHJlc3MkMTcyLjAuMC4wLzA:172.0.0.0 USED NETWORK  

infoblox-search-related-objects-by-ip


Searches IP related objects by a given IP.

Base Command

infoblox-search-related-objects-by-ip

Input
Argument Name Description Required
ip The IP address for which to search. Required
max_results The maximum results to return. Optional
Context Output
Path Type Description
Infoblox.IPRelatedObjects.ReferenceID Unknown The reference ID of the related object.
Command Example

!infoblox-search-related-objects-by-ip ip="172.0.0.0"

Context Example
{
    "Infoblox.IPRelatedObjects": [
        {
            "Network": "172.0.0.0/24",
            "NetworkView": "default",
            "ReferenceID": "network/ZG5zLm5ldHdvcmskMTcyLjAuMC4wLzI0LzA:172.0.0.0/24/default"
        }
    ]
}
Human Readable Output

Infoblox Integration - IP: 172.0.0.0 search results

Network Network View Reference ID
172.0.0.0/24 default network/ZG5zLm5ldHdvcmskMTcyLjAuMC4wLzI0LzA:172.0.0.0/24/default

infoblox-list-response-policy-zone-rules


Lists all response policy rules that belong to the given response policy zone.

Base Command

infoblox-list-response-policy-zone-rules

Input
Argument Name Description Required
response_policy_zone_name The response policy zone name to list the rules (FQDN). Optional
page_size The number of results in each page. Optional
next_page_id The next page ID that was returned when last running this command. Optional
view The DNS view in which the records are located. By default, the ‘default’ DNS view is searched. Optional
Context Output
Path Type Description
Infoblox.ResponsePolicyZoneRulesList.Name string Rule name.
Infoblox.ResponsePolicyZoneRulesList.Disable boolean Whether the rule is disabled.
Infoblox.ResponsePolicyZoneRulesList.Comment string The comment for this rule.
Infoblox.ResponsePolicyZoneRulesList.Type string The object type as used in Infoblox.
Infoblox.ResponsePolicyZoneRulesList.View string View of the definition.
Infoblox.ResponsePolicyZoneRulesList.Zone string The zone to which this rule belongs.
Infoblox.RulesNextPage.NextPageID string Retrieves the next page of the search. The last NextpageID corresponds to the last search performed.
Command Example

!infoblox-list-response-policy-zone-rules response_policy_zone_name=infoblow.com page_size="8"

Context Example
{
    "Infoblox.ResponsePolicyZoneRulesList": [
        {
            "Comment": "",
            "Disable": false,
            "Name": "4.4.4.5",
            "Type": "record:rpz:cname",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "1.1.1.1",
            "Type": "record:rpz:cname:ipaddressdn",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "2.2.2.2",
            "Type": "record:rpz:a:ipaddress",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "5.5.5.111",
            "Type": "record:rpz:cname:ipaddress",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "moshe",
            "Type": "record:rpz:cname",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "moshe2",
            "Type": "record:rpz:cname",
            "View": "default",
            "Zone": "infoblow.com"
        },
        {
            "Comment": "",
            "Disable": false,
            "Name": "moshe3",
            "Type": "record:rpz:cname",
            "View": "default",
            "Zone": "infoblow.com"
        }
    ],
    "Infoblox.RulesNextPage": {
        "NextPageID": "789c9d525b4ec33010fcf739905a89cacaa3a5ed11fa83101cc0726c2735385ecb7668cbe9d935a1503e51a4489edd9d997d2c75a8d9cb02a2c953f4a2b7c6e92446d069c1428391fb054b2f8b111344908321b86587aa2654c681de6bb6d46183b91fe00dbe1fd8d2852dbeadefa17370e20a46c4774c26e29267110bd19e1d76c443c4829211ab2ba614840ba60c0c7f0a7cca71521922066bb65433eb99a31aef6432ec09eb0f886242c39410dd645db65e0806ddab5119f1963de6e75017ab3579ed219e64d4a4f8f0dd4fca326642b68810e0ec680bb09b9d0e90410448365bf002fa3e9912dfcf055a664983ab48a7a1c9f636a65cfa885abc990b4569ae34137e6d45fbc43bebb5505e8ee68e0b6d7a39b9fc3bebc4377c4d1f51b4c59e44eaa34cc29b33d968d6df9d1c8dd4242a14c09ba5a5341b36fca90ad1bc5384faafae915babdb7f5a1d211d4d4b0c38b7d42139ae225f42b1b24752e95c0c1f5f62e5a88a83db3b24b8a6636a696224b7a2135ba1d2687c5e699b64e7cc6ae66d5b3c30dce2d4fd949785b71be22e9b206cee977f02207ef4bc-1cbe432a6c562d903bd34ea2dd75f482330d98e249c3359e4e258b9"
    }
}
Human Readable Output

Infoblox Integration - Zone: Infoblow.com rule list

Comment Disable Name Type View Zone
  false 4.4.4.5 record:rpz:cname default infoblow.com
  false 1.1.1.1 record:rpz:cname:ipaddressdn default infoblow.com
  false 2.2.2.2 record:rpz:a:ipaddress default infoblow.com
  false 5.5.5.111 record:rpz:cname:ipaddress default infoblow.com
  false moshe record:rpz:cname default infoblow.com
  false moshe2 record:rpz:cname default infoblow.com
  false moshe3 record:rpz:cname default infoblow.com

infoblox-list-response-policy-zones


List all response policy zones.

Base Command

infoblox-list-response-policy-zones

Input
Argument Name Description Required
max_results Maximum results to return. (Default is 50) Optional
fqdn The name of the DNS zone in FQDN format. Optional
view The name of the DNS view in which the zone resides. Optional
comment The comment for the zone to retrieve. Optional
Context Output
Path Type Description
Infoblox.ResponsePolicyZones.Disable boolean Whether this zone is disabled.
Infoblox.ResponsePolicyZones.FQDN string The fully qualified domain name.
Infoblox.ResponsePolicyZones.ReferenceID string The reference ID of the object.
Infoblox.ResponsePolicyZones.RpzPolicy string The response policy zone override policy.
Infoblox.ResponsePolicyZones.RpzSeverity string The severity of this response policy zone.
Infoblox.ResponsePolicyZones.RpzType string The type of response policy zone.
Infoblox.ResponsePolicyZones.View string The view of the definition.
Command Example

!infoblox-list-response-policy-zones

Context Example
{
    "Infoblox.ResponsePolicyZones": [
        {
            "Disable": false,
            "FQDN": "local.rpz",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LnJwei5sb2NhbA:local.rpz/default",
            "RpzPolicy": "GIVEN",
            "RpzSeverity": "MAJOR",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "infoblow.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdw:infoblow.com/default",
            "RpzPolicy": "SUBSTITUTE",
            "RpzSeverity": "WARNING",
            "RpzType": "LOCAL",
            "SubstituteName": "infoblox.com",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGU:google.com/default",
            "RpzPolicy": "DISABLED",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "SubstituteName": "sdfdsf",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google2.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUy:google2.com/default",
            "RpzPolicy": "DISABLED",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "SubstituteName": "sdfdsf",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google3.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUz:google3.com/default",
            "RpzPolicy": "DISABLED",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "SubstituteName": "sdfdsf",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google4.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGU0:google4.com/default",
            "RpzPolicy": "DISABLED",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "SubstituteName": "sdfdsf",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google33.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUzMw:google33.com/default",
            "RpzPolicy": "GIVEN",
            "RpzSeverity": "WARNING",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google.test.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0Lmdvb2dsZQ:google.test.com/default",
            "RpzPolicy": "NXDOMAIN",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google.test2.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0Mi5nb29nbGU:google.test2.com/default",
            "RpzPolicy": "NXDOMAIN",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "google.test4.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0NC5nb29nbGU:google.test4.com/default",
            "RpzPolicy": "NXDOMAIN",
            "RpzSeverity": "INFORMATIONAL",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "test.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0:test.com/default",
            "RpzPolicy": "GIVEN",
            "RpzSeverity": "WARNING",
            "RpzType": "LOCAL",
            "View": "default"
        },
        {
            "Disable": false,
            "FQDN": "test123.com",
            "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0MTIz:test123.com/default",
            "RpzPolicy": "GIVEN",
            "RpzSeverity": "WARNING",
            "RpzType": "LOCAL",
            "View": "default"
        }
    ]
}
Human Readable Output

Infoblox Integration - Response Policy Zones list (fetched 12 results)

Disable FQDN Reference ID Rpz Policy Rpz Severity Rpz Type View
false local.rpz zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LnJwei5sb2NhbA:local.rpz/default GIVEN MAJOR LOCAL default
false infoblow.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdw:infoblow.com/default SUBSTITUTE WARNING LOCAL default
false google.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGU:google.com/default DISABLED INFORMATIONAL LOCAL default
false google2.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUy:google2.com/default DISABLED INFORMATIONAL LOCAL default
false google3.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUz:google3.com/default DISABLED INFORMATIONAL LOCAL default
false google4.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGU0:google4.com/default DISABLED INFORMATIONAL LOCAL default
false google33.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS5nb29nbGUzMw:google33.com/default GIVEN WARNING LOCAL default
false google.test.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0Lmdvb2dsZQ:google.test.com/default NXDOMAIN INFORMATIONAL LOCAL default
false google.test2.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0Mi5nb29nbGU:google.test2.com/default NXDOMAIN INFORMATIONAL LOCAL default
false google.test4.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0NC5nb29nbGU:google.test4.com/default NXDOMAIN INFORMATIONAL LOCAL default
false test.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0:test.com/default GIVEN WARNING LOCAL default
false test123.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50ZXN0MTIz:test123.com/default GIVEN WARNING LOCAL default

5. infoblox-create-response-policy-zone


Creates a response policy zone.

Base Command

infoblox-create-response-policy-zone

Input
Argument Name Description Required
FQDN The name of this DNS zone in FQDN format. Required
rpz_policy The override policy of the response policy zone. Can be: “DISABLED”, “GIVEN”, “NODATA”, “NXDOMAIN”, “PASSTHRU”, or “SUBSTITUTE”. Required
rpz_severity The severity of the response policy zone. Can be: “CRITICAL”, “MAJOR”, “WARNING”, or “INFORMATIONAL”. Required
substitute_name The alternative name of the redirect target in a substitute response policy. policy zone. Optional
rpz_type The type of the RPZ. Can be: “FEED”, “FIREEYE”, or “LOCAL”. Optional
Context Output
Path Type Description
Infoblox.ResponsePolicyZones.Disable boolean Whether this zone is disabled.
Infoblox.ResponsePolicyZones.FQDN string A fully qualified domain name.
Infoblox.ResponsePolicyZones.ReferenceID string The reference ID of the object.
Infoblox.ResponsePolicyZones.RpzPolicy string The response policy zone override policy.
Infoblox.ResponsePolicyZones.RpzSeverity string The severity of the response policy zone.
Infoblox.ResponsePolicyZones.RpzType string The type of RPZ.
Infoblox.ResponsePolicyZones.View string The view of the definition.
Command Example

!infoblox-create-response-policy-zone FQDN="infonlox.nightly.tpb.com" rpz_policy="DISABLED" rpz_severity="INFORMATIONAL" rpz_type="FEED"

Context Example
{
    "Infoblox.ResponsePolicyZones": {
        "Disable": false,
        "FQDN": "infonlox.nightly.tpb.com",
        "ReferenceID": "zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default",
        "RpzPolicy": "DISABLED",
        "RpzSeverity": "INFORMATIONAL",
        "RpzType": "LOCAL",
        "View": "default"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone: infonlox.nightly.tpb.com has been created

Disable FQDN Reference ID Rpz Policy Rpz Severity Rpz Type View
false infonlox.nightly.tpb.com zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default DISABLED INFORMATIONAL LOCAL default

infoblox-create-rpz-rule


Creates a response policy rule.

Base Command

infoblox-create-rpz-rule

Input
Argument Name Description Required
rule_type The type of the rule to create. Can be: “Passthru”, “Block” (No such domain), “Block” (No data), or “Substitute” (domain name). Required
object_type The type of the object for which to assign the rule. Can be: “Domain Name”, “IP address”, or “Client IP address”. Required
name The rule name in a FQDN format. Required
rp_zone The zone to assign the rule to. Required
comment Comment for this rule. Optional
substitute_name The substitute name to assign (substitute domain only). Optional
view The DNS view in which the records are located. By default, the ‘default’ DNS view is searched. Optional
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Canonical string Canonical value of the rule.
Command Example

!infoblox-create-rpz-rule rule_type="Passthru" object_type="Domain Name" name="nightly-test-rpz-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-rpz-sub"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Canonical": "nightly-test-rpz-sub.infoblow.com",
        "Disable": false,
        "Name": "nightly-test-rpz-sub.infoblow.com",
        "ReferenceID": "record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy5uaWdodGx5LXRlc3QtcnB6LXN1Yg:nightly-test-rpz-sub.infoblow.com/default",
        "Type": "record:rpz:cname",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-rpz-sub.infoblow.com has been created

Canonical Disable Name Reference ID Type View Zone
nightly-test-rpz-sub.infoblow.com false nightly-test-rpz-sub.infoblow.com record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy5uaWdodGx5LXRlc3QtcnB6LXN1Yg:nightly-test-rpz-sub.infoblow.com/default record:rpz:cname default infoblow.com

infoblox-create-a-substitute-record-rule


Creates a substitute record rule.

Base Command

infoblox-create-a-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to to. Required
comment Comment for this rule. Optional
ipv4addr The IPv4 address of the substitute rule. Optional
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The name of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-a-substitute-record-rule name="nightly-test-a-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-a-sub" ipv4addr="0.0.0.0"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-a-sub",
        "Disable": false,
        "Ipv4addr": "0.0.0.0",
        "Name": "nightly-test-a-sub.infoblow.com",
        "ReferenceID": "record:rpz:a/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LG5pZ2h0bHktdGVzdC1hLXN1YiwwLjAuMC4w:nightly-test-a-sub.infoblow.com/default",
        "Type": "record:rpz:a",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-a-sub.infoblow.com has been created

Comment Disable Ipv 4 Addr Name Reference ID Type View Zone
nightly-test-a-sub false 0.0.0.0 nightly-test-a-sub.infoblow.com record:rpz:a/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LG5pZ2h0bHktdGVzdC1hLXN1YiwwLjAuMC4w:nightly-test-a-sub.infoblow.com/default record:rpz:a default infoblow.com

infoblox-create-aaaa-substitute-record-rule


Creates a substitute rule for an AAAA record.

Base Command

infoblox-create-aaaa-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to to. Required
comment Comment for this rule. Optional
ipv6addr The IPv6 address of the substitute rule. Optional
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The name of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-aaaa-substitute-record-rule name="nightly-test-aaaa-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-aaaa-sub" ipv6addr="fd60:e32:f1b9::2"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-aaaa-sub",
        "Disable": false,
        "Ipv6addr": "fd60:e32:f1b9::2",
        "Name": "nightly-test-aaaa-sub.infoblow.com",
        "ReferenceID": "record:rpz:aaaa/ZG5zLmJpbmRfYWFhYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LG5pZ2h0bHktdGVzdC1hYWFhLXN1YixmZDYwOmUzMjpmMWI5Ojoy:nightly-test-aaaa-sub.infoblow.com/default",
        "Type": "record:rpz:aaaa",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-aaaa-sub.infoblow.com has been created

Comment Disable Ipv 6 Addr Name Reference ID Type View Zone
nightly-test-aaaa-sub false fd60:e32:f1b9::2 nightly-test-aaaa-sub.infoblow.com record:rpz:aaaa/ZG5zLmJpbmRfYWFhYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LG5pZ2h0bHktdGVzdC1hYWFhLXN1YixmZDYwOmUzMjpmMWI5Ojoy:nightly-test-aaaa-sub.infoblow.com/default record:rpz:aaaa default infoblow.com

infoblox-create-mx-substitute-record-rule


Creates a substitute rule for the MX record.

Base Command

infoblox-create-mx-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to to. Required
comment Comment for this rule. Optional
mail_exchanger The mail exchanger name in FQDN format. This value can be in unicode format. Required
preference Preference value, 0 to 65535 (inclusive). Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The name of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-mx-substitute-record-rule name="nightly-test-mx-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-mx-sub" mail_exchanger="0.0.0.0" preference="5"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-mx-sub",
        "Disable": false,
        "MailExchanger": "0.0.0.0",
        "Name": "nightly-test-mx-sub.infoblow.com",
        "Preference": 5,
        "ReferenceID": "record:rpz:mx/ZG5zLmJpbmRfbXgkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy5uaWdodGx5LXRlc3QtbXgtc3ViLjAuMC4wLjAuNQ:nightly-test-mx-sub.infoblow.com/default",
        "Type": "record:rpz:mx",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-mx-sub.infoblow.com has been created

Comment Disable Mail Exchanger Name Preference Reference ID Type View Zone
nightly-test-mx-sub false 0.0.0.0 nightly-test-mx-sub.infoblow.com 5 record:rpz:mx/ZG5zLmJpbmRfbXgkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy5uaWdodGx5LXRlc3QtbXgtc3ViLjAuMC4wLjAuNQ:nightly-test-mx-sub.infoblow.com/default record:rpz:mx default infoblow.com

infoblox-create-naptr-substitute-record-rule


Creates a substitute rule for a NAPTR record.

Base Command

infoblox-create-naptr-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to to. Required
comment Comment for this rule. Optional
order The order parameter of the substitute rule of the NAPTR record. This parameter specifies the order in which the NAPTR rules are applied when multiple rules are present. Can be from 0 to 65535 (inclusive). Required
preference Preference value, 0 to 65535 (inclusive). Required
replacement The substitute rule object replacement field of the NAPTR record. For non-terminal NAPTR records, this field specifies the next domain name to look up. Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The name of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-naptr-substitute-record-rule name="nightly-test-naptr-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-naptr-sub" order="0" preference="1" replacement="infoblow.com"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-naptr-sub",
        "Disable": false,
        "Name": "nightly-test-naptr-sub.infoblow.com",
        "Order": 0,
        "Preference": 1,
        "ReferenceID": "record:rpz:naptr/ZG5zLmJpbmRfbmFwdHIkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdyxuaWdodGx5LXRlc3QtbmFwdHItc3ViLDAsMSwsLCxpbmZvYmxvdy5jb20:nightly-test-naptr-sub.infoblow.com/default",
        "Regexp": "",
        "Replacement": "infoblow.com",
        "Services": "",
        "Type": "record:rpz:naptr",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-naptr-sub.infoblow.com has been created

Comment Disable Name Order Preference Reference ID Regexp Replacement Services Type View Zone
nightly-test-naptr-sub false nightly-test-naptr-sub.infoblow.com 0 1 record:rpz:naptr/ZG5zLmJpbmRfbmFwdHIkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdyxuaWdodGx5LXRlc3QtbmFwdHItc3ViLDAsMSwsLCxpbmZvYmxvdy5jb20:nightly-test-naptr-sub.infoblow.com/default   infoblow.com   record:rpz:naptr default infoblow.com

infoblox-create-ptr-substitute-record-rule


Creates a substitute rule of the PTR record.

Base Command

infoblox-create-ptr-substitute-record-rule

Input
Argument Name Description Required
rp_zone The zone to assign the rule to to. Required
comment Comment for this rule. Optional
ptrdname The domain name of the RPZ substitute rule object of the PTR record in FQDN format. Required
name The name of the RPZ Substitute rule object of the PTR record in FQDN format. Optional
ipv4addr The IPv4 address of the substitute rule. Optional
ipv6addr The IPv6 address of the substitute rule. Optional
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The name of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The Comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-ptr-substitute-record-rule rp_zone="infoblow.com" comment="nightly-test-ptr-sub" ptrdname="infoblow.com" ipv4addr="0.0.0.0"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-ptr-sub",
        "Disable": false,
        "Ipv4addr": "0.0.0.0",
        "Name": "0.0.0.0.in-addr.arpa.infoblow.com",
        "Ptrdname": "infoblow.com",
        "ReferenceID": "record:rpz:ptr/ZG5zLmJpbmRfcHRyJC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cuYXJwYS5pbi1hZGRyLjAuMC4wLjAuaW5mb2Jsb3cuY29t:0.0.0.0.in-addr.arpa.infoblow.com/default",
        "Type": "record:rpz:ptr",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: None has been created

Comment Disable Ipv 4 Addr Name Ptrdname Reference ID Type View Zone
nightly-test-ptr-sub false 0.0.0.0 0.0.0.0.in-addr.arpa.infoblow.com infoblow.com record:rpz:ptr/ZG5zLmJpbmRfcHRyJC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cuYXJwYS5pbi1hZGRyLjAuMC4wLjAuaW5mb2Jsb3cuY29t:0.0.0.0.in-addr.arpa.infoblow.com/default record:rpz:ptr default infoblow.com

infoblox-create-srv-substitute-record-rule


Creates a substitute rule of a SRV record.

Base Command

infoblox-create-srv-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to. Required
comment Comment for this rule. Optional
port The port of the substitute rule of the SRV record. Can be 0 to 65535 (inclusive). Required
priority The priority of the substitute rule for the SRV Record. Can be 0 to 65535 (inclusive). Required
target The target of the substitute rule of the SRV record in FQDN format. This value can be in unicode format. Required
weight The weight of the substitute rule of the SRV record. Can be 0 to 65535 (inclusive). Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-srv-substitute-record-rule name="nightly-test-srv-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-srv-sub" port="22" priority="10" target="infoblow.com" weight="10"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-srv-sub",
        "Disable": false,
        "Name": "nightly-test-srv-sub.infoblow.com",
        "Port": 22,
        "Priority": 10,
        "ReferenceID": "record:rpz:srv/ZG5zLmJpbmRfc3J2JC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cvbmlnaHRseS10ZXN0LXNydi1zdWIvMTAvMTAvMjIvaW5mb2Jsb3cuY29t:nightly-test-srv-sub.infoblow.com/default",
        "Target": "infoblow.com",
        "Type": "record:rpz:srv",
        "View": "default",
        "Weight": 10,
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-srv-sub.infoblow.com has been created

Comment Disable Name Port Priority Reference ID Target Type View Weight Zone
nightly-test-srv-sub false nightly-test-srv-sub.infoblow.com 22 10 record:rpz:srv/ZG5zLmJpbmRfc3J2JC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cvbmlnaHRseS10ZXN0LXNydi1zdWIvMTAvMTAvMjIvaW5mb2Jsb3cuY29t:nightly-test-srv-sub.infoblow.com/default infoblow.com record:rpz:srv default 10 infoblow.com

infoblox-create-txt-substitute-record-rule


Create a substitute rule for a txt record.

Base Command

infoblox-create-txt-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to. Required
comment Comment for this rule. Optional
text Text associated with the record. To enter leading, trailing, or embedded spaces in the text, add quotes around the text to preserve the spaces. Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-txt-substitute-record-rule name="nightly-test-txt-sub.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-txt-sub" text="nightly-test-txt-sub"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-txt-sub",
        "Disable": false,
        "Name": "nightly-test-txt-sub.infoblow.com",
        "ReferenceID": "record:rpz:txt/ZG5zLmJpbmRfdHh0JC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cubmlnaHRseS10ZXN0LXR4dC1zdWIuIm5pZ2h0bHktdGVzdC10eHQtc3ViIg:nightly-test-txt-sub.infoblow.com/default",
        "Text": "nightly-test-txt-sub",
        "Type": "record:rpz:txt",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: nightly-test-txt-sub.infoblow.com has been created

Comment Disable Name Reference ID Text Type View Zone
nightly-test-txt-sub false nightly-test-txt-sub.infoblow.com record:rpz:txt/ZG5zLmJpbmRfdHh0JC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cubmlnaHRseS10ZXN0LXR4dC1zdWIuIm5pZ2h0bHktdGVzdC10eHQtc3ViIg:nightly-test-txt-sub.infoblow.com/default nightly-test-txt-sub record:rpz:txt default infoblow.com

infoblox-create-ipv4-substitute-record-rule


Create a substitute rule for an IPv4 rule.

Base Command

infoblox-create-ipv4-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to. Required
comment Comment for this rule. Optional
ipv4addr The IPv4 Address of the substitute rule. Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-ipv4-substitute-record-rule name="3.3.3.3.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-ipv4-sub" ipv4addr="3.3.3.4"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-ipv4-sub",
        "Disable": false,
        "Ipv4addr": "3.3.3.4",
        "Name": "3.3.3.3.infoblow.com",
        "ReferenceID": "record:rpz:a:ipaddress/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LHJwei1pcC4zLjMuMy4zLjMyLDMuMy4zLjQ:3.3.3.3.infoblow.com/default",
        "Type": "record:rpz:a:ipaddress",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: 3.3.3.3.infoblow.com has been created

Comment Disable Ipv 4 Addr Name Reference ID Type View Zone
nightly-test-ipv4-sub false 3.3.3.4 3.3.3.3.infoblow.com record:rpz:a:ipaddress/ZG5zLmJpbmRfYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LHJwei1pcC4zLjMuMy4zLjMyLDMuMy4zLjQ:3.3.3.3.infoblow.com/default record:rpz:a:ipaddress default infoblow.com

infoblox-create-ipv6-substitute-record-rule


Creates a substitute of the IPv6 record rule.

Base Command

infoblox-create-ipv6-substitute-record-rule

Input
Argument Name Description Required
name The name for a record in FQDN format. Required
rp_zone The zone to assign the rule to. Required
comment Comment for this rule. Optional
ipv6addr The IPv6 Address of the substitute rule. Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Command Example

!infoblox-create-ipv6-substitute-record-rule name="000:000:000::1.infoblow.com" rp_zone="infoblow.com" comment="nightly-test-ipv6-sub" ipv6addr="fd60:e22:f1b9::2"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Comment": "nightly-test-ipv6-sub",
        "Disable": false,
        "Ipv6addr": "fd60:e22:f1b9::2",
        "Name": "::1.infoblow.com",
        "ReferenceID": "record:rpz:aaaa:ipaddress/ZG5zLmJpbmRfYWFhYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LHJwei1pcC56ei4xLjEyOCxmZDYwOmUyMjpmMWI5Ojoy:%3A%3A1.infoblow.com/default",
        "Type": "record:rpz:aaaa:ipaddress",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: 000:000:000::1.infoblow.com has been created

Comment Disable Ipv 6 Addr Name Reference ID Type View Zone
nightly-test-ipv6-sub false fd60:e22:f1b9::2 ::1.infoblow.com record:rpz:aaaa:ipaddress/ZG5zLmJpbmRfYWFhYSQuX2RlZmF1bHQuY29tLmluZm9ibG93LHJwei1pcC56ei4xLjEyOCxmZDYwOmUyMjpmMWI5Ojoy:%3A%3A1.infoblow.com/default record:rpz:aaaa:ipaddress default infoblow.com

infoblox-enable-rule


Disables a rule by its reference ID (reference ID can be extracted by running the search rules command).

Base Command

infoblox-enable-rule

Input
Argument Name Description Required
reference_id The ID of the rule reference (can be extracted by running the search rules command). Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The rule comment.
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The response policy zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Command Example

!infoblox-enable-rule reference_id="record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Canonical": "4.4.4.5.infoblow.com",
        "Disable": false,
        "Name": "4.4.4.5.infoblow.com",
        "ReferenceID": "record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: 4.4.4.5.infoblow.com has been enabled

Canonical Disable Name Reference ID View Zone
4.4.4.5.infoblow.com false 4.4.4.5.infoblow.com record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default default infoblow.com

infoblox-disable-rule


Disable a rule by its reference ID (reference ID can be extracted by running the ‘infoblox-search-rule’ command).

Base Command

infoblox-disable-rule

Input
Argument Name Description Required
reference_id The ID of the rule reference (reference ID can be extracted by running the ‘infoblox-search-rule’ command). Required
Context Output
Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether this rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The rule comment.
Infoblox.ModifiedResponsePolicyZoneRules.Name string The rule name.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The ID of the rule reference.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The response policy zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.View string The view of the definition.
Command Example

!infoblox-disable-rule reference_id="record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default"

Context Example
{
    "Infoblox.ModifiedResponsePolicyZoneRules": {
        "Canonical": "4.4.4.5.infoblow.com",
        "Disable": true,
        "Name": "4.4.4.5.infoblow.com",
        "ReferenceID": "record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default",
        "View": "default",
        "Zone": "infoblow.com"
    }
}
Human Readable Output

Infoblox Integration - Response Policy Zone rule: 4.4.4.5.infoblow.com has been disabled

Canonical Disable Name Reference ID View Zone
4.4.4.5.infoblow.com true 4.4.4.5.infoblow.com record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default default infoblow.com

infoblox-get-object-fields


Returns the object fields names which can be used in the search rules command.

Base Command

infoblox-get-object-fields

Input
Argument Name Description Required
object_type The Infoblox object type (can be retrieved by running the ‘infoblox-list-response-policy-zone-rules’ command). Required
Context Output
Path Type Description
Infoblox.ObjectFields.ObjectType string The Infoblox object type.
Infoblox.ObjectFields.SupportedFields string The list of supported fields for this object.
Command Example

!infoblox-get-object-fields object_type="record:rpz:cname"

Context Example
{
    "Infoblox.ObjectFields": {
        "ObjectType": "record:rpz:cname",
        "SupportedFields": [
            "canonical",
            "comment",
            "disable",
            "extattrs",
            "name",
            "rp_zone",
            "ttl",
            "use_ttl",
            "view",
            "zone"
        ]
    }
}
Human Readable Output

Infoblox Integration - Object record:rpz:cname supported fields

Field Names
canonical
comment
disable
extattrs
name
rp_zone
ttl
use_ttl
view
zone

infoblox-search-rule


Searches a specific rule by its name.

Base Command

infoblox-search-rule

Input
Argument Name Description Required
object_type The Infoblox object type (can be retrieved by running the ‘infoblox-list-response-policy-zone-rules’ command). Required
rule_name The full rule name (usually the rule name followed by its zone. Example: name.domain.com) Required
output_fields The fields to include in the return object (supported object fields can be retrieved by running the *infoblox-get-object-fields* command). Optional
Context Output
Path Type Description
Infoblox.RulesSearchResults.Name string The rule name.
Infoblox.RulesSearchResults.ReferenceID string The reference ID of the rule.
Infoblox.RulesSearchResults.View string The view of the definition.
Infoblox.RulesSearchResults.Canonical string The canonical value of the rule.
Command Example

!infoblox-search-rule object_type="record:rpz:cname" rule_name="4.4.4.5.infoblow.com" output_fields="canonical,comment,disable,extattrs,name,rp_zone,ttl,use_ttl,view,zone"

Context Example
{
    "Infoblox.RulesSearchResults": [
        {
            "Canonical": "4.4.4.5.infoblow.com",
            "Disable": false,
            "Extattrs": {},
            "Name": "4.4.4.5.infoblow.com",
            "ReferenceID": "record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default",
            "UseTtl": false,
            "View": "default",
            "Zone": "infoblow.com"
        }
    ]
}
Human Readable Output

Infoblox Integration - Search result for: 4.4.4.5.infoblow.com

Canonical Disable Extattrs Name Reference ID Use Ttl View Zone
4.4.4.5.infoblow.com false   4.4.4.5.infoblow.com record:rpz:cname/ZG5zLmJpbmRfY25hbWUkLl9kZWZhdWx0LmNvbS5pbmZvYmxvdy41LjQuNC40:4.4.4.5.infoblow.com/default false default infoblow.com

infoblox-delete-rpz-rule


Deletes a rule.

Base Command

infoblox-delete-rpz-rule

Input
Argument Name Description Required
reference_id The reference ID of the rule (reference ID can be retrieved by running the ‘infoblox-search-rule’ command). Required
Context Output

There are no context output for this command.

Command Example

!infoblox-delete-rpz-rule reference_id=record:rpz:ptr/ZG5zLmJpbmRfcHRyJC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cuYXJwYS5pbi1hZGRyLjAuMC4wLjAuaW5mb2Jsb3cuY29t:0.0.0.0.in-addr.arpa.infoblow.com/default

Context Example
{}
Human Readable Output

Infoblox Integration - A rule with the following id was deleted: record:rpz:ptr/ZG5zLmJpbmRfcHRyJC5fZGVmYXVsdC5jb20uaW5mb2Jsb3cuYXJwYS5pbi1hZGRyLjAuMC4wLjAuaW5mb2Jsb3cuY29t:0.0.0.0.in-addr.arpa.infoblow.com/default

infoblox-delete-response-policy-zone


Deletes a given response policy zone.

Base Command

infoblox-delete-response-policy-zone

Input
Argument Name Description Required
reference_id The reference ID of the rule (can be extracted by running the search rules command). Required
Context Output

There are no context output for this command.

Command Example

!infoblox-delete-response-policy-zone reference_id="zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default\"

Context Example
{}
Human Readable Output

Infoblox Integration - Response Policy Zone with the following id was deleted: zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default

Additional Information

In order to create new rule for a response policy zone for all rules different from substitute record use the command ‘create-rpz-rule’. For substitute record rules use the designated command for each use case.

Known Limitations

Troubleshooting

Context Output

There are no context output for this command.

 

Command Example

!infoblox-delete-response-policy-zone reference_id="zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default\"

Context Example
{}
Human Readable Output

Infoblox Integration - Response Policy Zone with the following id was deleted: zone_rp/ZG5zLnpvbmUkLl9kZWZhdWx0LmNvbS50cGIubmlnaHRseS5pbmZvbmxveA:infonlox.nightly.tpb.com/default

Additional Information

In order to create new rule for a response policy zone for all rules different from substitute record use the command 'create-rpz-rule'. For substitute record rules use the designated command for each use case.

Known Limitations

Troubleshooting

infoblox-list-host-info


Get all host records.

Base Command

infoblox-list-host-info

Input

Argument Name Description Required
host_name The hostname to retrieve records for, e.g. localhost.test. Optional
extattrs Comma-separated key/value formatted filter for extended attributes, e.g. “Site=New York,OtherProp=MyValue”. Optional
max_results The maximum number of records to return. Default is 50, maximum is 1000. Optional
additional_return_fields Comma-separated list of additional fields to return for each host, e.g. extattrs,aliases. Default is extattrs. Optional

Context Output

Path Type Description
Infoblox.Host.Reference String The host record reference ID.
Infoblox.Host.IPv4Address String The host first IPv4 address.
Infoblox.Host.ConfigureForDHCP Boolean Whether the host is configured for DHCP.
Infoblox.Host.Name String The host record name.
Infoblox.Host.ExtendedAttributes Unknown The network extended attributes.
Infoblox.Host.AdditionalFields Unknown The additional fields for network.

Command example


#### Context Example

```json
{
    "Infoblox": {
        "Host": [
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {},
                "IPv4Address": "192.168.10.10",
                "Name": "localhost.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QuMTkyLjE2OC4xMC4xMC4:192.168.10.10/localhost.test/default"
            },
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "IB Discovery Owned": "EMEA",
                    "Site": "Tel-Aviv"
                },
                "IPv4Address": "192.168.100.100",
                "Name": "localdoman.localhost.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QubG9jYWxkb21hbi4xOTIuMTY4LjEwMC4xMDAu:192.168.100.100/localdoman.localhost.test/default"
            },
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "Site": "Local"
                },
                "IPv4Address": "255.255.255.192",
                "Name": "test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC4uMjU1LjI1NS4yNTUuMTkyLg:255.255.255.192/test/default"
            },
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "IB Discovery Owned": "dummy value",
                    "Site": "ciac-5843"
                },
                "IPv4Address": "192.168.1.0",
                "Name": "ciac-3607.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5jaWFjLTM2MDcuMTkyLjE2OC4xLjAu:192.168.1.0/ciac-3607.test/default"
            }
        ]
    }
}

Human Readable Output

Host records (first 50)

ConfigureForDHCP ExtendedAttributes IPv4Address Name Reference
false   192.168.10.10 localhost.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QuMTkyLjE2OC4xMC4xMC4:192.168.10.10/localhost.test/default
false IB Discovery Owned: EMEA
Site: Tel-Aviv
192.168.100.100 localdoman.localhost.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QubG9jYWxkb21hbi4xOTIuMTY4LjEwMC4xMDAu:192.168.100.100/localdoman.localhost.test/default
false Site: Local 255.255.255.192 test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC4uMjU1LjI1NS4yNTUuMTkyLg:255.255.255.192/test/default
false IB Discovery Owned: dummy value
Site: ciac-5843
192.168.1.0 ciac-3607.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5jaWFjLTM2MDcuMTkyLjE2OC4xLjAu:192.168.1.0/ciac-3607.test/default

Command example

!infoblox-list-host-info additional_return_fields=extattrs,aliases

Context Example

{
    "Infoblox": {
        "Host": [
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {},
                "IPv4Address": "192.168.10.10",
                "Name": "localhost.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QuMTkyLjE2OC4xMC4xMC4:192.168.10.10/localhost.test/default"
            },
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "IB Discovery Owned": "EMEA",
                    "Site": "Tel-Aviv"
                },
                "IPv4Address": "192.168.100.100",
                "Name": "localdoman.localhost.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QubG9jYWxkb21hbi4xOTIuMTY4LjEwMC4xMDAu:192.168.100.100/localdoman.localhost.test/default"
            },
            {
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "Site": "Local"
                },
                "IPv4Address": "255.255.255.192",
                "Name": "test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC4uMjU1LjI1NS4yNTUuMTkyLg:255.255.255.192/test/default"
            },
            {
                "AdditionalFields": [
                    {
                        "Aliases": [
                            "test_host.test"
                        ]
                    }
                ],
                "ConfigureForDHCP": false,
                "ExtendedAttributes": {
                    "IB Discovery Owned": "dummy value",
                    "Site": "ciac-5843"
                },
                "IPv4Address": "192.168.1.0",
                "Name": "ciac-3607.test",
                "Reference": "record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5jaWFjLTM2MDcuMTkyLjE2OC4xLjAu:192.168.1.0/ciac-3607.test/default"
            }
        ]
    }
}

Human Readable Output

Host records (first 50)

ConfigureForDHCP ExtendedAttributes IPv4Address Name Reference
false   192.168.10.10 localhost.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QuMTkyLjE2OC4xMC4xMC4:192.168.10.10/localhost.test/default
false IB Discovery Owned: EMEA
Site: Tel-Aviv
192.168.100.100 localdoman.localhost.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5sb2NhbGhvc3QubG9jYWxkb21hbi4xOTIuMTY4LjEwMC4xMDAu:192.168.100.100/localdoman.localhost.test/default
false Site: Local 255.255.255.192 test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC4uMjU1LjI1NS4yNTUuMTkyLg:255.255.255.192/test/default
false IB Discovery Owned: dummy value
Site: ciac-5843
192.168.1.0 ciac-3607.test record:host_ipv4addr/ZG5zLmhvc3RfYWRkcmVzcyQuX2RlZmF1bHQudGVzdC5jaWFjLTM2MDcuMTkyLjE2OC4xLjAu:192.168.1.0/ciac-3607.test/default

infoblox-list-network-info


List network information.

Base Command

infoblox-list-network-info

Input

Argument Name Description Required
pattern Filter networks by pattern, e.g. ‘.0/24’ for netmask, ‘192.168’ for subnet. Optional
extattrs comma-separated key/value formatted filter for extended attributes, e.g. “Site=New York,OtherProp=MyValue”. Optional
max_results The maximum number of records to return. Maximum is 1000. Default is 50. Optional
additional_return_fields Comma separated list of additional fields to return for each host, e.g. extattrs,aliases. Default is extattrs. Optional

Context Output

Path Type Description
Infoblox.NetworkInfo.Reference String The network reference.
Infoblox.NetworkInfo.Name String The network name.
Infoblox.NetworkInfo.NetworkView String The network view name.
Infoblox.NetworkInfo.ExtendedAttributes Unknown The network extended attributes.
Infoblox.NetworkInfo.AdditionalFields Unknown The additional fields for network.

Command example


#### Context Example

```json
{
    "Infoblox": {
        "NetworkInfo": [
            {
                "ExtendedAttributes": {},
                "Name": "192.168.1.0/24",
                "NetworkView": "default",
                "Reference": "network/ZG5zLm5ldHdvcmskMTkyLjE2OC4xLjAvMjQvMA:192.168.1.0/24/default"
            },
            {
                "ExtendedAttributes": {
                    "Region": "EMEA"
                },
                "Name": "255.255.255.192/26",
                "NetworkView": "default",
                "Reference": "network/ZG5zLm5ldHdvcmskMjU1LjI1NS4yNTUuMTkyLzI2LzA:255.255.255.192/26/default"
            }
        ]
    }
}

Human Readable Output

Network information found (50 limit)

ExtendedAttributes Name NetworkView Reference
  192.168.1.0/24 default network/ZG5zLm5ldHdvcmskMTkyLjE2OC4xLjAvMjQvMA:192.168.1.0/24/default
Region: EMEA 255.255.255.192/26 default network/ZG5zLm5ldHdvcmskMjU1LjI1NS4yNTUuMTkyLzI2LzA:255.255.255.192/26/default

Command example

!infoblox-list-network-info pattern=255.255 extattrs="Region=EMEA"

Context Example

{
    "Infoblox": {
        "NetworkInfo": [
            {
                "ExtendedAttributes": {
                    "Region": "EMEA"
                },
                "Name": "255.255.255.192/26",
                "NetworkView": "default",
                "Reference": "network/ZG5zLm5ldHdvcmskMjU1LjI1NS4yNTUuMTkyLzI2LzA:255.255.255.192/26/default"
            }
        ]
    }
}

Human Readable Output

Network information found (50 limit)

ExtendedAttributes Name NetworkView Reference
Region: EMEA 255.255.255.192/26 default network/ZG5zLm5ldHdvcmskMjU1LjI1NS4yNTUuMTkyLzI2LzA:255.255.255.192/26/default

infoblox-update-rpz-rule


Update a response policy zone rule.

Base Command

infoblox-update-rpz-rule

Input

Argument Name Description Required
reference_id The reference ID of the existing RPZ rule to update. Required
name The name of the response policy zone rule. Required
rule_type The type of the response policy zone rule. Possible values are: Passthru, Block (No such domain), Block (No data), Substitute (domain name). Required
rp_zone The zone to assign the rule to. Required
comment The comment for this rule update. Optional
substitute_name The substitute name to assign (substitute domain only). Optional
view The DNS view in which the records are located. Default is default. Optional
additional_parameters JSON object containing additional parameters (disable, use_ttl, ttl, extattrs) to update RPZ rule. Example: {“disable”: true, “use_ttl”: true, “ttl”: 3600}. Optional

Context Output

Path Type Description
Infoblox.ModifiedResponsePolicyZoneRules.Name string Rule name.
Infoblox.ModifiedResponsePolicyZoneRules.Canonical string Canonical value of the rule.
Infoblox.ModifiedResponsePolicyZoneRules.Disable boolean Whether the rule is disabled.
Infoblox.ModifiedResponsePolicyZoneRules.Comment string The comment for this rule.
Infoblox.ModifiedResponsePolicyZoneRules.Type string The object type as used in Infoblox.
Infoblox.ModifiedResponsePolicyZoneRules.View string View of the definition.
Infoblox.ModifiedResponsePolicyZoneRules.Zone string The zone to which this rule belongs.
Infoblox.ModifiedResponsePolicyZoneRules.ReferenceID string The reference ID of the rule.

Command example

!infoblox-update-rpz-rule reference_id="record:rpz:cname/sample.example.com/default" name="sample.example.com" rp_zone="example.com" rule_type="PASSTHRU" comment="Updated passthru rule"

Context Example

{
    "Infoblox": {
        "ModifiedResponsePolicyZoneRules": {
            "Canonical": "",
            "Comment": "Updated passthru rule",
            "Disable": false,
            "Extattrs": {},
            "Name": "sample.example.com",
            "ReferenceID": "record:rpz:cname/sample.example.com/default",
            "Type": "record:rpz:cname",
            "View": "default",
            "Zone": "example.com"
        }
    }
}

Human Readable Output

Infoblox Integration - Response Policy Zone rule: sample.example.com has been updated

Comment Disable Name Reference ID Type View Zone
Updated passthru rule false sample.example.com record:rpz:cname/sample.example.com/default record:rpz:cname default example.com

infoblox-create-host-record


Creates a host record. Note: Either ipv4_address or ipv6_address is required.

Base Command

infoblox-create-host-record

Input

Argument Name Description Required
name The name of the host in FQDN format ‘{name}.{zone}’ (e.g. example.auth_zone). It must belong to an existing DNS zone. Required
view The DNS view in which the records are located. Default is default. Optional
ipv4_address The IPv4 addresses for the host record. Example: [{“ipv4addr”: “192.168.1.0”}], [{“ipv4addr”: “192.168.1.1”, “configure_for_dhcp”: true, “mac”: “00:01:00:01:00:01”}]. Optional
ipv6_address The IPv6 addresses for the host record. Example: [{“ipv6addr”: “2001:db8::1”}], [{“ipv6addr”: “2001:db8::2”, “configure_for_dhcp”: true, “duid”: “00:01:00:01:0a:1a”}]. Optional
comment The comment for this host record. Optional
aliases The aliases for this host record. Example: [“alias1”, “alias2”]. Optional
configure_for_dns Whether to configure the host record for DNS. Possible values are: Yes, No. Default is Yes. Optional
extattrs The extended attributes for this host record. Example: {“Site”: {“value”: “example”}}. Optional
additional_parameters JSON object containing additional parameters to create host record. Example: {“use_ttl”: true, “ttl”: 3600, “disable”: true}. Optional

Context Output

Path Type Description
Infoblox.Host.ReferenceID String The host record reference ID.
Infoblox.Host.IPV4Addresses String The host IPv4 addresses.
Infoblox.Host.IPV6Addresses String The host IPv6 addresses.
Infoblox.Host.ConfigureForDNS Boolean Whether the host is configured for DNS.
Infoblox.Host.Name String The host record name.
Infoblox.Host.ExtendedAttributes Unknown The network extended attributes.
Infoblox.Host.AdditionalFields Unknown The additional fields for network.
Infoblox.Host.Aliases String The aliases for this host record.
Infoblox.Host.AllowTelnet Boolean Whether the host is allowed to use telnet.
Infoblox.Host.NetworkView String The network view of the host record.
Infoblox.Host.View String The view of the host record.
Infoblox.Host.Zone String The zone of the host record.
Infoblox.Host.Disable Boolean Whether the host is disabled.
Infoblox.Host.DNSName String The DNS name of the host record.

Command example

!infoblox-create-host-record name=example.com ipv4_address="[{\"ipv4addr\": \"0.0.0.1\"}]" ipv6_address="[{\"ipv6addr\": \"0000:000:0000::0000:000:001\", \"configure_for_dhcp\": false}]" configure_for_dns=false aliases="[\"example2.com\", \"example3.com\"]"

Context Example

{
    "Infoblox": {
        "Host": {
            "Aliases": [
                "example2.com",
                "example3.com"
            ],
            "AllowTelnet": false,
            "ConfigureForDNS": false,
            "DDNSProtected": false,
            "DNSName": "example.com",
            "Disable": false,
            "DisableDiscovery": false,
            "DnsAliases": [
                "example2.com",
                "example3.com"
            ],
            "Extattrs": {},
            "IPV4Addresses": [
                {
                    "ConfigureForDHCP": false,
                    "Host": "example.com",
                    "IPV4Address": "0.0.0.1",
                    "ReferenceID": "record:host_ipv4addr/12345:0.0.0.1/example.com/ "
                }
            ],
            "IPV6Addresses": [
                {
                    "ConfigureForDHCP": false,
                    "Host": "example.com",
                    "IPV6Address": "0000:000:0000::0000:000:001",
                    "ReferenceID": "record:host_ipv6addr/23456:0000:000:0000::0000:000:001/example.com/ "
                }
            ],
            "Name": "example.com",
            "NetworkView": "default",
            "RRSetOrder": "cyclic",
            "ReferenceID": "record:host/45678:example.com/ ",
            "Type": "record:host",
            "UseCLICredentials": false,
            "UseSNMP3Credential": false,
            "UseSNMPCredential": false,
            "UseTTL": false,
            "View": " ",
            "Zone": ""
        }
    }
}

Human Readable Output

Host record created

Aliases Allow Telnet Configure For DNS DDNS Protected DNS Name Disable Disable Discovery Dns Aliases IPV4 Addresses IPV6 Addresses Name Network View RR Set Order Reference ID Type Use CLI Credentials Use SNMP3 Credential Use SNMP Credential Use TTL View
example2.com,
example3.com
false false false example.com false false example2.com,
example3.com
- ReferenceID: record:host_ipv4addr/12345:0.0.0.1/example.com/
ConfigureForDHCP: false
Host: example.com
IPV4Address: 0.0.0.1
- ReferenceID: record:host_ipv6addr/23456:0000:000:0000::0000:000:001/example.com/
ConfigureForDHCP: false
Host: example.com
IPV6Address: 0000:000:0000::0000:000:001
example.com default cyclic record:host/45678:example.com/ record:host false false false false  

infoblox-dhcp-lease-lookup


Look up a DHCP lease.

Base Command

infoblox-dhcp-lease-lookup

Input

Argument Name Description Required
ip_address Lease IP address (IPv4 or IPv6). Optional
hardware MAC address for IPv4 leases. Regex or exact search supported. Optional
hostname Hostname sent via DHCP option 12. Regex/exact search. Optional
ipv6_duid IPv6 DUID identifier for IPv6 leases. Regex/exact search. Optional
protocol The protocol of the DHCP lease. Possible values are: IPV4, IPV6, BOTH. Default is BOTH. Optional
fingerprint DHCP client fingerprint; case-insensitive or regex search. Optional
username Specify the user associated with the lease request. Optional
limit Specify the maximum number of leases to return. Default is 100. Optional

Context Output

Path Type Description
Infoblox.DHCPLease.ReferenceID String The DHCP lease reference ID.
Infoblox.DHCPLease.Address String The DHCP lease address.
Infoblox.DHCPLease.BindingState String The DHCP lease binding state.
Infoblox.DHCPLease.ClientHostname String The DHCP lease client hostname.
Infoblox.DHCPLease.CLTT String The DHCP lease client last transaction time.
Infoblox.DHCPLease.Ends String The DHCP lease ends time.
Infoblox.DHCPLease.Fingerprint String The DHCP lease fingerprint.
Infoblox.DHCPLease.Hardware String The DHCP lease hardware address.
Infoblox.DHCPLease.IPV6PrefixBits String The DHCP lease IPv6 prefix bits.
Infoblox.DHCPLease.IsInvalidMAC Boolean The Flag indicating if the MAC address is invalid.
Infoblox.DHCPLease.NetworkView String The network view of the DHCP lease record.
Infoblox.DHCPLease.Network String The network of the DHCP lease record.
Infoblox.DHCPLease.Protocol String The protocol of the DHCP lease record.
Infoblox.DHCPLease.Starts String The DHCP lease starts time.
Infoblox.DHCPLease.Variable String The DHCP lease variable.
Infoblox.DHCPLease.UID String The unique identifier of the DHCP lease record.

Command example

!infoblox-dhcp-lease-lookup limit=3

Context Example

{
    "Infoblox": {
        "DHCPLease": [
            {
                "Address": "0.0.0.2",
                "BindingState": "FREE",
                "CLTT": 1757322665,
                "Ends": 1757365865,
                "Fingerprint": "Microsoft Windows 10",
                "Hardware": "00:00:00:00:00:02",
                "IPV6PrefixBits": 0,
                "IsInvalidMAC": false,
                "Network": "0.0.0.5/20",
                "NetworkView": "default",
                "NeverEnds": false,
                "NeverStarts": false,
                "Protocol": "IPV4",
                "ReferenceID": "lease/123:0.0.0.2/default",
                "ServedBy": "0.0.0.0",
                "ServerHostName": "infoblox.localdomain",
                "Starts": 1757322665,
                "TSTP": 1757365865,
                "UID": "123",
                "Variable": "vendor-class-identifier=\"MSFT 5.0\""
            },
            {
                "Address": "0.0.0.3",
                "BindingState": "ACTIVE",
                "CLTT": 1757399758,
                "ClientHostname": "CE",
                "Ends": 1757442958,
                "Fingerprint": "Ubuntu/Debian 5/Knoppix 6",
                "Hardware": "00:00:00:00:00:03",
                "IPV6PrefixBits": 0,
                "IsInvalidMAC": false,
                "Network": "0.0.0.5/20",
                "NetworkView": "default",
                "NeverEnds": false,
                "NeverStarts": false,
                "NextBindingState": "FREE",
                "Protocol": "IPV4",
                "ReferenceID": "lease/234:0.0.0.3/default",
                "ServedBy": "0.0.0.0",
                "ServerHostName": "infoblox.localdomain",
                "Starts": 1757399758,
                "UID": "234"
            },
            {
                "Address": "0.0.0.4",
                "BindingState": "ABANDONED",
                "CLTT": 1757365722,
                "ClientHostname": "rhel",
                "Fingerprint": "Ubuntu/Debian 5/Knoppix 6",
                "IPV6PrefixBits": 0,
                "IsInvalidMAC": false,
                "Network": "0.0.0.5/20",
                "NetworkView": "default",
                "NeverEnds": true,
                "NeverStarts": false,
                "NextBindingState": "FREE",
                "Protocol": "IPV4",
                "ReferenceID": "lease/345:0.0.0.4/default",
                "ServedBy": "0.0.0.0",
                "ServerHostName": "infoblox.localdomain",
                "Starts": 1757365722
            }
        ]
    }
}

Human Readable Output

DHCP lease lookup, found 3 records

Address Binding State CLTT Ends Fingerprint Hardware IPV6 Prefix Bits Is Invalid MAC Network Network View Never Ends Never Starts Protocol Reference ID Served By Server Host Name Starts TSTP UID Variable
0.0.0.2 FREE 1757322665 1757365865 Microsoft Windows 10 00:00:00:00:00:02 0 false 0.0.0.5/20 default false false IPV4 lease/123:0.0.0.2/default 0.0.0.0 infoblox.localdomain 1757322665 1757365865 123 vendor-class-identifier=”MSFT 5.0”
0.0.0.3 ACTIVE 1757399758 1757442958 Ubuntu/Debian 5/Knoppix 6 00:00:00:00:00:03 0 false 0.0.0.5/20 default false false IPV4 lease/234:0.0.0.3/default 0.0.0.0 infoblox.localdomain 1757399758   234  
0.0.0.4 ABANDONED 1757365722   Ubuntu/Debian 5/Knoppix 6   0 false 0.0.0.5/20 default true false IPV4 lease/345:0.0.0.4/default 0.0.0.0 infoblox.localdomain 1757365722      

Configuration parameters

  • url — Server URL (e.g., https://example.net) (required)
  • credentials — User Name
  • insecure — Trust any certificate (not secure)
  • proxy — Use system proxy settings

Commands (26)

  • infoblox-create-a-substitute-record-rule

    Creates a substitute record rule.

  • infoblox-create-aaaa-substitute-record-rule

    Creates a substitute rule for an AAAA record.

  • infoblox-create-host-record

    Creates a host record. Note: Either ipv4_address or ipv6_address is required.

  • infoblox-create-ipv4-substitute-record-rule

    Create a substitute rule for an IPv4 rule.

  • infoblox-create-ipv6-substitute-record-rule

    Creates a substitute of the IPv6 record rule.

  • infoblox-create-mx-substitute-record-rule

    Creates a substitute rule for the MX record.

  • infoblox-create-naptr-substitute-record-rule

    Creates a substitute rule for a NAPTR record.

  • infoblox-create-ptr-substitute-record-rule

    Creates a substitute rule of the PTR record.

  • infoblox-create-response-policy-zone

    Creates a response policy zone.

  • infoblox-create-rpz-rule

    Creates a response policy rule.

  • infoblox-create-srv-substitute-record-rule

    Creates a substitute rule of a SRV record.

  • infoblox-create-txt-substitute-record-rule

    Create a substitute rule for a txt record.

  • infoblox-delete-response-policy-zone

    Deletes a given response policy zone.

  • infoblox-delete-rpz-rule

    Deletes a rule.

  • infoblox-dhcp-lease-lookup

    Look up a DHCP lease.

  • infoblox-disable-rule

    Disable a rule by its reference ID (reference ID can be extracted by running the 'infoblox-search-rule' command).

  • infoblox-enable-rule

    Disables a rule by its reference ID (reference ID can be extracted by running the search rules command).

  • infoblox-get-ip

    Get IP information.

  • infoblox-get-object-fields

    Returns the object fields names which can be used in the search rules command.

  • infoblox-list-host-info

    Get all host records.

  • infoblox-list-network-info

    List network information.

  • infoblox-list-response-policy-zone-rules

    Lists all response policy rules that belong to the given response policy zone.

  • infoblox-list-response-policy-zones

    List all response policy zones.

  • infoblox-search-related-objects-by-ip

    Searches IP related objects by a given IP.

  • infoblox-search-rule

    Searches a specific rule by its name.

  • infoblox-update-rpz-rule

    Update a response policy zone rule.

import json
from enum import Enum, unique

import demistomock as demisto  # noqa: F401
from CommonServerPython import *  # noqa: F401

""" IMPORTS """
from collections.abc import Callable
import ipaddress
from typing import Any, cast
from urllib.parse import unquote

import urllib3

# Disable insecure warnings
urllib3.disable_warnings()

INTEGRATION_NAME = "Infoblox Integration"
INTEGRATION_COMMAND_NAME = "infoblox"
INTEGRATION_CONTEXT_NAME = "Infoblox"
INTEGRATION_HOST_RECORDS_CONTEXT_NAME = "Host"
INTEGRATION_NETWORK_INFO_CONTEXT_KEY = "NetworkInfo"
INTEGRATION_AUTHORIZATION_EXCEPTION_MESSAGE = "Authorization error, check your credentials."

# COMMON RAW RESULT KEYS
INTEGRATION_COMMON_RAW_RESULT_REFERENCE_KEY = "_ref"
INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY = "extattrs"
INTEGRATION_COMMON_RAW_RESULT_NETWORK_KEY = "network"
INTEGRATION_COMMON_RAW_RESULT_NETWORKVIEW_KEY = "network_view"

# COMMON CONTEXT KEYS
INTEGRATION_COMMON_REFERENCE_CONTEXT_KEY = "Reference"
INTEGRATION_COMMON_REFERENCE_ID_CONTEXT_KEY = "ReferenceID"
INTEGRATION_COMMON_NAME_CONTEXT_KEY = "Name"
INTEGRATION_COMMON_EXTENSION_ATTRIBUTES_CONTEXT_KEY = "ExtendedAttributes"
INTEGRATION_COMMON_ADDITIONAL_FIELDS_CONTEXT_KEY = "AdditionalFields"
INTEGRATION_COMMON_NETWORKVIEW_CONTEXT_KEY = "NetworkView"

# IP RAW RESULT KEYS
INTEGRATION_IP_RAW_RESULT_MAC_ADDRESS_KEY = "mac_address"
INTEGRATION_IP_RAW_RESULT_NETWORK = "network"
INTEGRATION_IP_RAW_RESULT_STATUS_KEY = "status"
INTEGRATION_IP_RAW_RESULT_FQDN_KEY = "fqdn"
INTEGRATION_IP_RAW_RESULT_RP_ZONE_KEY = "rp_zone"
INTEGRATION_IP_RAW_RESULT_IS_CONFLICT_KEY = "is_conflict"
INTEGRATION_IP_RAW_RESULT_OBJECTS_KEY = "objects"
INTEGRATION_IP_RAW_RESULT_TYPES_KEY = "types"
INTEGRATION_IP_RAW_RESULT_NAMES_KEY = "names"
INTEGRATION_IP_RAW_RESULT_IP_ADDRESS_KEY = "ip_address"
INTEGRATION_IP_RAW_RESULT_USAGE_KEY = "usage"

# IP CONTEXT KEYS
INTEGRATION_IP_RP_ZONE_CONTEXT_KEY = "Zone"
INTEGRATION_IP_FQDN_CONTEXT_KEY = "FQDN"


IP_MAPPING = {
    INTEGRATION_COMMON_RAW_RESULT_REFERENCE_KEY: INTEGRATION_COMMON_REFERENCE_ID_CONTEXT_KEY,
    INTEGRATION_IP_RAW_RESULT_MAC_ADDRESS_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_MAC_ADDRESS_KEY),
    INTEGRATION_COMMON_RAW_RESULT_NETWORK_KEY: string_to_context_key(INTEGRATION_COMMON_RAW_RESULT_NETWORK_KEY),
    INTEGRATION_COMMON_RAW_RESULT_NETWORKVIEW_KEY: string_to_context_key(INTEGRATION_COMMON_RAW_RESULT_NETWORKVIEW_KEY),
    INTEGRATION_IP_RAW_RESULT_TYPES_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_TYPES_KEY),
    INTEGRATION_IP_RAW_RESULT_NAMES_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_NAMES_KEY),
    INTEGRATION_IP_RAW_RESULT_OBJECTS_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_OBJECTS_KEY),
    INTEGRATION_IP_RAW_RESULT_STATUS_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_STATUS_KEY),
    INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY: string_to_context_key(
        INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY
    ),  # noqa: E501
    INTEGRATION_IP_RAW_RESULT_IP_ADDRESS_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_IP_ADDRESS_KEY),
    INTEGRATION_IP_RAW_RESULT_USAGE_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_USAGE_KEY),
    INTEGRATION_IP_RAW_RESULT_IS_CONFLICT_KEY: string_to_context_key(INTEGRATION_IP_RAW_RESULT_IS_CONFLICT_KEY),
    INTEGRATION_IP_RAW_RESULT_FQDN_KEY: INTEGRATION_IP_FQDN_CONTEXT_KEY,
    INTEGRATION_IP_RAW_RESULT_RP_ZONE_KEY: INTEGRATION_IP_RP_ZONE_CONTEXT_KEY,
}

# Host info mapping
INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESSES_KEY = "ipv4addrs"
INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESS_KEY = "ipv4addr"
INTEGRATION_HOST_RECORDS_IPV4ADDRESS_CONTEXT_KEY = "IPv4Address"
INTEGRATION_HOST_RECORDS_RAW_RESULT_CONFIGURE_FOR_DHCP_KEY = "configure_for_dhcp"
INTEGRATION_HOST_RECORDS_CONFIGURE_FOR_DHCP_KEY_CONTEXT_KEY = "ConfigureForDHCP"
INTEGRATION_HOST_RECORDS_RAW_RESULT_NAME_KEY = "name"
INTEGRATION_HOST_RECORDS_RAW_RESULT_HOST_KEY = "host"
INTEGRATION_HOST_RECORDS_RAW_RESULT_VIEW_KEY = "view"
HOST_INFO_MAPPING: dict[str, str] = {
    INTEGRATION_COMMON_RAW_RESULT_REFERENCE_KEY: INTEGRATION_COMMON_REFERENCE_CONTEXT_KEY,
    INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESS_KEY: INTEGRATION_HOST_RECORDS_IPV4ADDRESS_CONTEXT_KEY,
    INTEGRATION_HOST_RECORDS_RAW_RESULT_CONFIGURE_FOR_DHCP_KEY: INTEGRATION_HOST_RECORDS_CONFIGURE_FOR_DHCP_KEY_CONTEXT_KEY,
    INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY: INTEGRATION_COMMON_EXTENSION_ATTRIBUTES_CONTEXT_KEY,
    INTEGRATION_HOST_RECORDS_RAW_RESULT_HOST_KEY: INTEGRATION_COMMON_NAME_CONTEXT_KEY,
}


# Network info mapping

INTEGRATION_COMMON_RAW_RESULT_NETWORKVIEW_KEY = "network_view"
INTEGRATION_COMMON_NETWORKVIEW_CONTEXT_KEY = "NetworkView"
NETWORK_INFO_MAPPING: dict[str, str] = {
    INTEGRATION_COMMON_RAW_RESULT_REFERENCE_KEY: INTEGRATION_COMMON_REFERENCE_CONTEXT_KEY,
    INTEGRATION_COMMON_RAW_RESULT_NETWORK_KEY: INTEGRATION_COMMON_NAME_CONTEXT_KEY,
    INTEGRATION_COMMON_RAW_RESULT_NETWORKVIEW_KEY: INTEGRATION_COMMON_NETWORKVIEW_CONTEXT_KEY,
    INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY: INTEGRATION_COMMON_EXTENSION_ATTRIBUTES_CONTEXT_KEY,
}

INTEGRATION_IP_CONTEXT_NAME = "IP"
INTEGRATION_MAX_RESULTS_DEFAULT = 50

RESPONSE_TRANSLATION_DICTIONARY = {"_ref": "ReferenceID", "fqdn": "FQDN", "rp_zone": "Zone"}
RESPONSE_KEY_REFACTOR_DICTIONARY = {
    "dns_name": "DNSName",
    "ddns_protected": "DDNSProtected",
    "ipv4addrs": "IPV4Addresses",
    "ipv6addrs": "IPV6Addresses",
    "ipv4addr": "IPV4Address",
    "ipv6addr": "IPV6Address",
    "configure_for_dhcp": "ConfigureForDHCP",
    "ipv6_prefix_bits": "IPV6PrefixBits",
    "rrset_order": "RRSetOrder",
    "use_cli_credentials": "UseCLICredentials",
    "use_snmp_credential": "UseSNMPCredential",
    "use_snmp3_credential": "UseSNMP3Credential",
    "use_ttl": "UseTTL",
    "is_invalid_mac": "IsInvalidMAC",
    "cltt": "CLTT",
    "uid": "UID",
    "configure_for_dns": "ConfigureForDNS",
    "tstp": "TSTP",
}

RPZ_RULES_DICT = {
    "Passthru": {
        "Domain Name": {"infoblox_object_type": "record:rpz:cname"},
        "IP address": {"infoblox_object_type": "record:rpz:a:ipaddress"},
        "Client IP address": {"infoblox_object_type": "record:rpz:cname:clientipaddress"},
    },
    "Block (No such domain)": {
        "Domain Name": {"infoblox_object_type": "record:rpz:cname"},
        "IP address": {"infoblox_object_type": "record:rpz:cname:ipaddress"},
        "Client IP address": {"infoblox_object_type": "record:rpz:cname:clientipaddress"},
    },
    "Block (No data)": {
        "Domain Name": {"infoblox_object_type": "record:rpz:cname"},
        "IP address": {"infoblox_object_type": "record:rpz:cname:ipaddress"},
        "Client IP address": {"infoblox_object_type": "record:rpz:cname:clientipaddress"},
    },
    "Substitute (domain name)": {
        "Domain Name": {"infoblox_object_type": "record:rpz:cname"},
        "IP address": {"infoblox_object_type": "record:rpz:a:ipaddress"},
        "Client IP address": {"infoblox_object_type": "record:rpz:cname:clientipaddressdn"},
    },
}


@unique
class IPv4AddressStatus(Enum):
    """Possible statuses for an IPv4 address."""

    ACTIVE = "ACTIVE"
    UNUSED = "UNUSED"
    USED = "USED"


def inject_cookies(func: Callable) -> Callable:
    """
    Decorator to manage session persistence and handle authentication for API requests.

    This decorator attempts to execute the provided function using existing session cookies
    stored in the 'integration_context'. If no valid cookies are available, or if the existing
    session is no longer valid the auth generate new cookies to save, bad credentials force the
    storage clean.

    The decorator handles saving and loading cookies between different executions, allowing for
    session persistence across multiple API calls.

    Args:
        func (Callable): The API request function to be executed.

    Raises:
        DemistoException: If the API request fails.

    Returns:
        Callable: The result from executing 'func' with the provided arguments and keyword arguments.
    """

    @wraps(wrapped=func)
    def wrapper(client: "InfoBloxNIOSClient", *args, **kwargs):
        def save_cookies_to_context(client: "InfoBloxNIOSClient") -> None:
            cookies_dict = {}
            for cookie in client._session.cookies:
                cookies_dict[cookie.name] = {"value": cookie.value, "domain": cookie.domain, "path": cookie.path}
            set_integration_context({"cookies": cookies_dict})

        def load_cookies(client: "InfoBloxNIOSClient", cookies_dict: dict) -> None:
            for name, cookie_data in cookies_dict.items():
                client._session.cookies.set(name, cookie_data["value"], domain=cookie_data["domain"], path=cookie_data["path"])

        integration_context = get_integration_context()
        if integration_context and (context_cookies := integration_context.get("cookies")):
            load_cookies(client, context_cookies)

        try:
            response = func(client, *args, **kwargs)
            save_cookies_to_context(client)
            return response
        except DemistoException as error:
            if error.message and error.message == INTEGRATION_AUTHORIZATION_EXCEPTION_MESSAGE:
                set_integration_context({})
            raise error

    return wrapper


class InfoBloxNIOSClient(BaseClient):
    REQUEST_PARAMS_RETURN_AS_OBJECT_KEY = "_return_as_object"
    REQUEST_PARAM_RETURN_FIELDS_KEY = "_return_fields+"

    REQUEST_PARAM_EXTRA_ATTRIBUTES = {REQUEST_PARAM_RETURN_FIELDS_KEY: INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY}
    REQUEST_PARAM_ZONE = {
        REQUEST_PARAM_RETURN_FIELDS_KEY: "fqdn,rpz_policy,rpz_severity,rpz_type,substitute_name,comment,disable"
    }
    REQUEST_PARAM_CREATE_RULE = {REQUEST_PARAM_RETURN_FIELDS_KEY: "name,rp_zone,comment,canonical,disable"}
    REQUEST_PARAM_LIST_RULES = {REQUEST_PARAM_RETURN_FIELDS_KEY: "name,zone,comment,disable,type"}
    REQUEST_PARAM_SEARCH_RULES = {REQUEST_PARAM_RETURN_FIELDS_KEY: "name,zone,comment,disable,canonical"}
    REQUEST_PARAM_UPDATE_RULE = {REQUEST_PARAM_RETURN_FIELDS_KEY: "name,rp_zone,comment,canonical,disable,view,zone,extattrs"}
    REQUEST_PARAM_CREATE_HOST = {
        REQUEST_PARAM_RETURN_FIELDS_KEY: (
            "aliases,allow_telnet,cli_credentials,cloud_info,comment,configure_for_dns,ddns_protected,"
            "device_description,device_location,device_type,device_vendor,disable,disable_discovery,"
            "dns_aliases,dns_name,extattrs,ipv4addrs,ipv6addrs,ms_ad_user_data,name,network_view,"
            "rrset_order,snmp3_credential,snmp_credential,ttl,use_cli_credentials,use_snmp3_credential,"
            "use_snmp_credential,use_ttl,view,zone"
        )
    }
    REQUEST_PARAM_DHCP_LEASE_LOOKUP = {
        REQUEST_PARAM_RETURN_FIELDS_KEY: (
            "address,billing_class,binding_state,client_hostname,cltt,discovered_data,ends,hardware,"
            "ipv6_duid,ipv6_iaid,ipv6_preferred_lifetime,ipv6_prefix_bits,is_invalid_mac,ms_ad_user_data,"
            "network,network_view,never_ends,never_starts,next_binding_state,on_commit,on_expiry,on_release,"
            "option,protocol,remote_id,served_by,server_host_name,starts,tsfp,tstp,uid,username,variable,"
            "fingerprint"
        )
    }

    REQUEST_PARAM_PAGING_FLAG = {"_paging": "1"}
    REQUEST_PARAM_MAX_RESULTS_KEY = "_max_results"
    REQUEST_PARAM_MAX_RESULTS_VALUE_DEFAULT = 1000

    def __init__(self, base_url, verify=True, proxy=False, ok_codes=(), headers=None, auth=None):
        super().__init__(base_url, verify, proxy, ok_codes, headers, auth)
        self.params: dict[str, Any] = {self.REQUEST_PARAMS_RETURN_AS_OBJECT_KEY: "1"}

    @inject_cookies
    def _http_request(  # type: ignore[override]
        self,
        method,
        url_suffix,
        full_url=None,
        headers=None,
        auth=None,
        json_data=None,
        params=None,
        data=None,
        files=None,
        timeout=10,
        resp_type="json",
        ok_codes=None,
        **kwargs,
    ):
        if params:
            self.params.update(params)
        try:
            return super()._http_request(
                method=method,
                url_suffix=url_suffix,
                full_url=full_url,
                headers=headers,
                auth=auth,
                json_data=json_data,
                params=self.params,
                data=data,
                files=files,
                timeout=timeout,
                resp_type=resp_type,
                ok_codes=ok_codes,
                **kwargs,
            )
        except DemistoException as error:
            raise parse_demisto_exception(error, "text")

    def test_module(self) -> dict:
        """Performs basic GET request (List Response Policy Zones) to check if the API is reachable and authentication
        is successful.

        Returns:
            Response JSON
        """
        return self.list_response_policy_zones()

    def list_response_policy_zones(
        self, max_results: int | None = None, fqdn: str | None = None, view: str | None = None, comment: str | None = None
    ) -> dict:
        """List all response policy zones.
        Args:
                max_results:  maximum number of results
                fqdn:  FQDN of the response policy zone
                view:  View of the response policy zone
                comment:  Comment of the response policy zone
        Returns:
            Response JSON
        """
        suffix = "zone_rp"
        request_params = assign_params(_max_results=max_results, fqdn=fqdn, view=view, comment=comment)
        request_params.update(self.REQUEST_PARAM_ZONE)
        return self._http_request("GET", suffix, params=request_params)

    def get_ip_address_from_ip(
        self,
        ip: str,
        status: str,
        extended_attributes: Optional[str],
        max_results: Optional[int] = INTEGRATION_MAX_RESULTS_DEFAULT,
        ip_type: Optional[str] = "ipv4",
    ) -> dict:
        """
        Get IPv4 or IPv6 information based on an IP address.
        Args:
        - `ip` (``str``): ip to retrieve.
        - `status` (``str``): status of the IP address.
        - `extended_attributes` (``str``): comma-separated list of extended attributes to return.
        - `max_results` (``int``): maximum number of results to return.

        Returns:
            Response JSON
        """

        # Dictionary of params for the request
        request_params = assign_params(ip_address=ip, status=status, _max_results=max_results)

        # Add extended attributes param if provided
        if extended_attributes:
            request_params.update(self.REQUEST_PARAM_EXTRA_ATTRIBUTES)
            extended_attributes_params = transform_ext_attrs(extended_attributes)

            for e in extended_attributes_params:
                request_params.update(e)

        return (
            self._get_ipv4_addresses(params=request_params)
            if ip_type == "ipv4"
            else self._get_ipv6_addresses(params=request_params)
        )

    def get_ip_address_from_netmask(
        self,
        network: str,
        status: str,
        extended_attributes: Optional[str],
        max_results: Optional[int] = INTEGRATION_MAX_RESULTS_DEFAULT,
        ip_type: Optional[str] = "ipv4",
    ) -> dict:
        """
        Get IPv4 or IPv6 network information based on a netmask.

        Args:
        - `network` (``str``): Netmask to retrieve the IPv4 for.
        - `status` (``str``): Status of the network.
        - `extended_attributes` (``str``): comma-separated list of extended attributes to return.
        - `max_results` (``int``): maximum number of results to return.

        Returns:
        - `dict` with response.
        """

        request_params = assign_params(network=network, status=status, _max_results=max_results)

        # Add extended attributes param if provided
        if extended_attributes:
            request_params.update(self.REQUEST_PARAM_EXTRA_ATTRIBUTES)
            extended_attributes_params = transform_ext_attrs(extended_attributes)

            for e in extended_attributes_params:
                request_params.update(e)

        return (
            self._get_ipv4_addresses(params=request_params)
            if ip_type == "ipv4"
            else self._get_ipv6_addresses(params=request_params)
        )

    def get_ip_address_range(
        self,
        start_ip: str,
        end_ip: str,
        extended_attributes: Optional[str],
        max_results: Optional[int] = INTEGRATION_MAX_RESULTS_DEFAULT,
        ip_type: Optional[str] = "ipv4",
    ) -> dict:
        """
        Get IPv4 or IPv6 address range information based on a start and end IP.

        Args:
        - `start_ip` (``str``): Start IP of the range.
        - `end_ip` (``str``): End IP of the range.
        - `extended_attributes` (``str``): comma-separated list of extended attributes to return.
        - `max_results` (``int``): maximum number of results to return.

        Returns:
        - `dict` with response.
        """

        request_params = assign_params(_max_results=max_results)
        request_params.update(transform_ipv4_range(start_ip, end_ip))

        # Add extended attributes param if provided
        if extended_attributes:
            request_params.update(self.REQUEST_PARAM_EXTRA_ATTRIBUTES)
            extended_attributes_params = transform_ext_attrs(extended_attributes)

            for e in extended_attributes_params:
                request_params.update(e)

        return (
            self._get_ipv4_addresses(params=request_params)
            if ip_type == "ipv4"
            else self._get_ipv6_addresses(params=request_params)
        )

    def _get_ipv4_addresses(self, params: dict[str, Any]) -> dict:
        return self._http_request("GET", "ipv4address", params=params)

    def _get_ipv6_addresses(self, params: dict[str, Any]) -> dict:
        return self._http_request("GET", "ipv6address", params=params)

    def search_related_objects_by_ip(self, ip: str | None, max_results: str | None) -> dict:
        """Search ip related objects.
        Args:
            ip: ip to retrieve.
            max_results: maximum number of results

        Returns:
            Response JSON
        """
        # The server endpoint to request from
        suffix = "search"

        # Dictionary of params for the request
        request_params = assign_params(address=ip, _max_results=max_results)
        return self._http_request("GET", suffix, params=request_params)

    def list_response_policy_zone_rules(
        self, zone: str | None, view: str | None, max_results: str | None, next_page_id: str | None
    ) -> dict:
        """List response policy zones rules by a given zone name.
        Args:
            zone: response policy zone name.
            view: The DNS view in which the records are located. By default, the 'default' DNS view is searched.
            max_results: maximum number of results.
            next_page_id: ID of the next page to retrieve, if given all other arguments are ignored.

        Returns:
            Response JSON
        """
        # The server endpoint to request from
        suffix = "allrpzrecords"
        # Dictionary of params for the request
        request_params = assign_params(zone=zone, view=view, _max_results=max_results, _page_id=next_page_id)
        request_params.update(self.REQUEST_PARAM_PAGING_FLAG)
        request_params.update(self.REQUEST_PARAM_LIST_RULES)

        return self._http_request("GET", suffix, params=request_params)

    def create_response_policy_zone(
        self,
        fqdn: str | None,
        rpz_policy: str | None,
        rpz_severity: str | None,
        substitute_name: str | None,
        rpz_type: str | None,
    ) -> dict:
        """Creates new response policy zone
        Args:
            fqdn: The name of this DNS zone.
            rpz_policy: The response policy zone override policy.
            rpz_severity: The severity of this response policy zone.
            substitute_name: The canonical name of redirect target in substitute policy.
            rpz_type: The type of rpz zone.
        Returns:
            Response JSON
        """

        data = assign_params(
            fqdn=fqdn, rpz_policy=rpz_policy, rpz_severity=rpz_severity, substitute_name=substitute_name, rpz_type=rpz_type
        )
        return self._http_request("POST", "zone_rp", data=json.dumps(data), params=self.REQUEST_PARAM_ZONE)

    def delete_response_policy_zone(self, ref_id: str | None) -> dict:
        """Delete new response policy zone
        Args:
            ref_id: Zone reference id to delete.
        Returns:
            Response JSON
        """

        suffix = ref_id
        return self._http_request("DELETE", suffix)

    def create_rpz_rule(
        self,
        rule_type: str | None,
        object_type: str | None,
        name: str | None,
        rp_zone: str | None,
        view: str | None,
        substitute_name: str | None,
        comment: str | None = None,
    ) -> dict:
        """Creates new response policy zone rule.
        Args:
            rule_type: Type of rule to create.
            object_type: Type of object to assign the rule on.
            name: Rule name.
            rp_zone: The zone to assign the rule.
            view: The DNS view in which the records are located. By default, the 'default' DNS view is searched.
            substitute_name: The substitute name to assign (In case of substitute domain only)
            comment: A comment for this rule.
        Returns:
            Response JSON
        """
        canonical: str | None = ""
        if rule_type == "Passthru":
            canonical = "rpz-passthru" if object_type == "Client IP address" else name
        elif rule_type == "Block (No data)":
            canonical = "*"
        elif rule_type == "Substitute (domain name)":
            canonical = substitute_name

        data = assign_params(name=name, rp_zone=rp_zone, view=view, comment=comment)
        # if rule_type is 'Block (No such domain)', then 'canonical' is '' (empty string) but API still requires 'canonical'
        data.update({"canonical": canonical})
        request_params = self.REQUEST_PARAM_CREATE_RULE
        suffix = demisto.get(RPZ_RULES_DICT, f"{rule_type}.{object_type}.infoblox_object_type")

        rule = self._http_request("POST", suffix, data=json.dumps(data), params=request_params)
        rule["result"]["type"] = suffix
        return rule

    def create_substitute_record_rule(self, suffix: str | None, **kwargs: str | int | None) -> dict:
        """Creates new response policy zone substitute rule.
        Args:
            suffix: The infoblox object to be used as a url path.
            kwargs: A dict of arguments to be passed to the rule body. The following may appear:
                - name
                - rp_zone
                - comment
                - ipv4addr
                - ipv6addr
                - mail_exchanger
                - preference
                - order
                - preference
                - replacement
                - ptrdname
                - priority
                - target
                - weight
                - port
                - text
        Returns:
            Response JSON
        """
        request_data = {key: val for key, val in kwargs.items() if val is not None}
        request_params = {"_return_fields+": ",".join(request_data.keys()) + ",disable,name"}
        rule = self._http_request("POST", suffix, data=json.dumps(request_data), params=request_params)
        rule["result"]["type"] = suffix
        return rule

    def change_rule_status(self, reference_id: str | None, disable: bool | None) -> dict:
        """Changes a given rule status.
        Args:
            reference_id: Rule reference ID
            disable: true or false string
        Returns:
            Response JSON
        """
        request_data = assign_params(disable=disable)
        suffix = reference_id
        return self._http_request("PUT", suffix, data=json.dumps(request_data), params=self.REQUEST_PARAM_SEARCH_RULES)

    def get_object_fields(self, object_type: str | None) -> dict:
        """Retrieve a given object fields.
        Args:
            object_type: Infoblox object type
        Returns:
            Response JSON
        """
        request_params = {"_schema": object_type}
        suffix = object_type
        return self._http_request("GET", suffix, params=request_params)

    def search_rule(self, object_type: str | None, rule_name: str | None, output_fields: str | None) -> dict:
        """Search rule by its name
        Args:
            object_type: Infoblox object type
            rule_name: Full rule name
            output_fields: Fields to include in the return object
        Returns:
            Response JSON
        """
        request_params = assign_params(name=rule_name)
        if output_fields:
            request_params["_return_fields+"] = output_fields
        suffix = object_type
        return self._http_request("GET", suffix, params=request_params)

    def delete_rpz_rule(self, reference_id: str | None) -> dict:
        """Deletes a rule by its reference id
        Args:
            reference_id: Rule reference ID
        Returns:
            Response JSON
        """

        suffix = reference_id
        return self._http_request("DELETE", suffix)

    def get_host_records(
        self,
        name: str | None,
        additional_return_fields: str,
        extended_attributes: Optional[str],
        max_results: Optional[int] = INTEGRATION_MAX_RESULTS_DEFAULT,
    ) -> dict:
        """
        Get the host records.

        Args:
        - `name` (``str``): Name of the host record to search for.
        - `additional_return_fields` (``Optional[str]``): Comma-separated list of additional fields to return.
        - `extended_attributes` (``str``): comma-separated list of extended attributes to return.
        - `max_results` (``int``): maximum number of results to return.

        Returns:
        - Response JSON
        """

        request_params = assign_params(name=name, _max_results=max_results)
        request_params.update({self.REQUEST_PARAM_RETURN_FIELDS_KEY: additional_return_fields})

        # Add extended attributes param if provided
        if extended_attributes:
            # If the extended attributes return field is not specified
            # add it.
            if INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY not in request_params.get(
                self.REQUEST_PARAM_RETURN_FIELDS_KEY
            ):  # noqa: E501
                request_params[self.REQUEST_PARAM_RETURN_FIELDS_KEY] += (
                    f",{INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY}"  # noqa: E501
                )
            extended_attributes_params = transform_ext_attrs(extended_attributes)

            for e in extended_attributes_params:
                request_params.update(e)

        return self._http_request("GET", "record:host", params=request_params)

    def get_network_info(
        self,
        pattern: str | None,
        additional_return_fields: Optional[str],
        extended_attributes: Optional[str],
        max_results: Optional[int] = INTEGRATION_MAX_RESULTS_DEFAULT,
    ) -> dict:
        """
        Get the network information.

        Args:
        - `pattern` (``str | None``): Filter networks by pattern, e.g. '.0/24' for netmask, '192.168' for subnet.
        - `additional_return_fields` (``Optional[str]``): Comma-separated list of additional fields to return.
        - `extended_attributes` (``str``): comma-separated list of extended attributes to return.
        - `max_results` (``int``): maximum number of results to return.

        Returns:
        - Response JSON
        """

        request_params = assign_params(_max_results=max_results)

        if pattern:
            request_params["network~"] = pattern

        request_params.update({self.REQUEST_PARAM_RETURN_FIELDS_KEY: additional_return_fields})

        # Add extended attributes param if provided
        if extended_attributes:
            # If the extended attributes return field is not specified
            # add it.
            if INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY not in request_params.get(
                self.REQUEST_PARAM_RETURN_FIELDS_KEY
            ):  # noqa: E501
                request_params[self.REQUEST_PARAM_RETURN_FIELDS_KEY] += (
                    f",{INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY}"  # noqa: E501
                )
            extended_attributes_params = transform_ext_attrs(extended_attributes)

            for e in extended_attributes_params:
                request_params.update(e)

        return self._http_request("GET", "network", params=request_params)

    def update_rpz_rule(
        self,
        reference_id: str,
        rule_type: str,
        name: str,
        rp_zone: str,
        view: str | None,
        substitute_name: str | None,
        comment: str | None = None,
        additional_parameters: dict | None = None,
    ) -> dict:
        """Updates an existing response policy zone rule.
        Args:
            reference_id: Reference ID of the rule to update.
            rule_type: Type of rule to create.
            name: Rule name.
            rp_zone: The zone to assign the rule.
            view: The DNS view in which the records are located. By default, the 'default' DNS view is searched.
            substitute_name: The substitute name to assign (In case of substitute domain only).
            comment: A comment for this rule.
        Returns:
            Response JSON
        """
        canonical: str | None = ""
        if rule_type.lower() == "passthru":  # type: ignore
            canonical = "rpz-passthru" if ":clientipaddress" in reference_id else name  # type: ignore
        elif rule_type.lower() == "block (no data)":  # type: ignore
            canonical = "*"
        elif rule_type.lower() == "block (no such domain)":  # type: ignore
            canonical = ""
        elif rule_type.lower() == "substitute (domain name)":  # type: ignore
            canonical = substitute_name

        data = assign_params(name=name, rp_zone=rp_zone, view=view, comment=comment)
        data.update({"canonical": canonical})
        if additional_parameters:
            data.update(additional_parameters)
        request_params = self.REQUEST_PARAM_UPDATE_RULE
        suffix = f"{reference_id}"
        rule = self._http_request("PUT", suffix, data=json.dumps(data), params=request_params)
        rule["result"]["type"] = suffix.split("/")[0]
        return rule

    def create_host_record(
        self,
        name: str,
        ipv4_address: list | None = [],
        ipv6_address: list | None = [],
        view: str | None = None,
        comment: str | None = None,
        aliases: list | None = [],
        configure_for_dns: bool = True,
        extended_attributes: str | None = None,
        additional_parameters: dict | None = None,
    ) -> dict:
        data = assign_params(name=name, view=view, comment=comment, extattrs=extended_attributes)
        if additional_parameters:
            data.update(additional_parameters)
        if ipv4_address:
            data.update({"ipv4addrs": ipv4_address})
        if ipv6_address:
            data.update({"ipv6addrs": ipv6_address})
        if aliases:
            data.update({"aliases": aliases})
        if configure_for_dns is not None:
            data.update({"configure_for_dns": argToBoolean(configure_for_dns)})
        request_params = self.REQUEST_PARAM_CREATE_HOST
        record = self._http_request("POST", "record:host", data=json.dumps(data), params=request_params)
        record["result"]["type"] = "record:host"
        return record

    def dhcp_lease_lookup(
        self,
        ip_address: str | None = None,
        hardware: str | None = None,
        hostname: str | None = None,
        ipv6_duid: str | None = None,
        protocol: str | None = None,
        fingerprint: str | None = None,
        username: str | None = None,
        limit: int | None = None,
    ) -> dict:
        additional_params = assign_params(
            address=ip_address,
            hardware=hardware,
            client_hostname=hostname,
            ipv6_duid=ipv6_duid,
            protocol=protocol,
            fingerprint=fingerprint,
            username=username,
            _max_results=limit,
        )
        request_params = self.REQUEST_PARAM_DHCP_LEASE_LOOKUP
        request_params.update(additional_params)
        records = self._http_request("GET", "lease", params=request_params)
        return records


""" HELPER FUNCTIONS """


def parse_demisto_exception(error: DemistoException, field_in_error: str = "text"):
    err_msg = err_string = error.args[0]
    if "[401]" in err_string:
        err_msg = INTEGRATION_AUTHORIZATION_EXCEPTION_MESSAGE
    elif "Failed to parse json object" in err_string:
        err_msg = "Cannot connect to Infoblox server, check your proxy and connection."
    elif "Error in API call" in err_string:
        err_lines = err_string.split("\n")
        infoblox_err = err_lines[1] if len(err_lines) > 1 else "{}"
        infoblox_json = json.loads(infoblox_err)
        err_msg = infoblox_json.get(field_in_error, "text") if infoblox_json else err_string
    return DemistoException(err_msg)


def transform_ext_attrs(ext_attrs: str) -> list:
    """
    Helper function to transform the extension attributes.
    The user supplies a string of key/value pairs separated by commas.

    This function parses that string and returns a list of dictionaries with "name" and "value" keys.

    Args:
    - `ext_attrs` (`str`): The string of key/value pairs separated by commas.

    Returns:
    - `list[dict]` or `None`: A `list[dict]` representing the extension attributes.
    Returns `None` in case there were no delimiters present. If the attributes
    cannot be parsed, an exception is raised.

    For example:

    ```python
    >>>> transform_ext_attrs("Site=Tel-Aviv")
    [{"Site": "Tel-Aviv"}]

    >>>> transform_ext_attrs("IB Discovery Owned=EMEA,Site=Tel-Aviv")
    [{"*IB Discovery Owned": "EMEA", "*Site": "Tel-Aviv"}]
    ```
    """

    # In case there are no delimiters present in the input
    if "," not in ext_attrs and "=" not in ext_attrs:
        return []

    l_ext_attrs: list[dict] = []

    attributes = ext_attrs.split(",")

    for ext_attr in attributes:
        try:
            key, value = ext_attr.split("=")
            if key and value:
                l_ext_attrs.append({f"*{key.strip()}": value.strip()})
        except ValueError:
            raise DemistoException(f"Unable to parse provided {ext_attrs=}. Expected format is 'ExtKey1=ExtVal1,ExtKeyN=ExtValN'")

    return l_ext_attrs


def transform_ipv4_range(from_ip: str, to_ip: str) -> dict[str, str]:
    """Transform IPv4 range to list of IPs.

    Args:
        from_ip: Start of IPv4 range.
        to_ip: End of IPv4 range.

    Returns:
        dictionary of IPv4 addresses in range.
    """

    return {"ip_address>": from_ip, "ip_address<": to_ip}


def transform_network_info_context(network_info: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """
    Helper function to transform the network info
    raw response to the expected context structure.

    Args:
    - `network_info` (``list[dict[str, Any]]``): The network info request result.

    Returns:
    - `list[dict[str, Any]]` context output.
    """

    output: list[dict[str, Any]] = []
    additional_options: list[dict[str, Any]] = []

    for network in network_info:
        n: dict[str, Any] = {}
        for k, v in network.items():
            if k == INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY:
                n[NETWORK_INFO_MAPPING[k]] = get_extended_attributes_context(v)
            elif k in NETWORK_INFO_MAPPING:
                n[NETWORK_INFO_MAPPING[k]] = v
            else:
                additional_options.append(v)
        if additional_options:
            n[INTEGRATION_COMMON_ADDITIONAL_FIELDS_CONTEXT_KEY] = additional_options
        output.append(n)

    return output


def transform_ip_context(ip_list: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """
    Helper function to transform the IP info
    raw response to the expected context structure.

    Args:
    - `network_info` (``list[dict[str, Any]]``): The network info request result.

    Returns:
    - `list[dict[str, Any]]` context output.
    """

    output: list[dict[str, Any]] = []

    for ip in ip_list:
        i: dict[str, Any] = {}
        for k, v in ip.items():
            key_transform = IP_MAPPING[k] if IP_MAPPING.get(k) else string_to_context_key(k)
            i[key_transform] = v
        output.append(i)

    return output


def get_ip_type(value: str) -> str:
    """
    Get the type of IP address or network (IPv4 or IPv6) for the given value.
    Supports both individual IP addresses and CIDR notation.

    Args:
        value (str): The string value to check (IP address or CIDR network)

    Returns:
        str: 'ipv4' if it's a valid IPv4 address or network,
             'ipv6' if it's a valid IPv6 address or network
    """
    try:
        # First try to parse as an IP address
        ip = ipaddress.ip_address(value)
        if isinstance(ip, ipaddress.IPv4Address):
            return "ipv4"
        elif isinstance(ip, ipaddress.IPv6Address):
            return "ipv6"
    except ValueError:
        # If IP address parsing fails, try to parse as a network (CIDR)
        try:
            network = ipaddress.ip_network(value, strict=False)
            if isinstance(network, ipaddress.IPv4Network):
                return "ipv4"
            elif isinstance(network, ipaddress.IPv6Network):
                return "ipv6"
        except ValueError:
            pass
    raise ValueError(f"Invalid IP address or network: {value}")


def transform_host_records_context(records: list[dict[str, Any]]) -> list[dict[str, Any]]:
    """
    Helper function to transform the host records
    raw response to the expected context structure.

    Args:
    - `records` (``list[dict[str, Any]]``): The host records request result.

    Returns:
    - `list[dict[str, Any]]` context output.
    """

    output: list[dict[str, Any]] = []
    additional_options: list[dict[str, Any]] = []

    for record in records:
        r: dict[str, Any] = {}
        for record_key, record_value in record.items():
            # We're interested in the ref ID of the first host address
            ipv4_addresses = record.get(INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESSES_KEY, [])

            # We're not interested in these fields
            if record_key == INTEGRATION_COMMON_RAW_RESULT_REFERENCE_KEY:
                continue
            elif record_key == INTEGRATION_HOST_RECORDS_RAW_RESULT_VIEW_KEY:
                continue
            elif record_key == INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY:
                r[NETWORK_INFO_MAPPING[record_key]] = get_extended_attributes_context(record_value)
            elif record_key == INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESSES_KEY:
                # We're interested in the first host address
                ipv4_addresses = record.get(INTEGRATION_HOST_RECORDS_RAW_RESULT_IPV4ADDRESSES_KEY, [])

                if ipv4_addresses:
                    first_address: dict[str, Any] = ipv4_addresses[0]
                    try:
                        for k, v in first_address.items():
                            r[HOST_INFO_MAPPING[k]] = v
                    except KeyError as err:
                        demisto.debug(f"Unable to parse key '{err}' from first host record address {record!s}: {err}")

            elif record_key == INTEGRATION_HOST_RECORDS_RAW_RESULT_NAME_KEY:
                r[INTEGRATION_COMMON_NAME_CONTEXT_KEY] = record_value
            else:
                # TODO take this out to a new function as it's used twice
                additional_options.append({string_to_context_key(record_key): record_value})
        if additional_options:
            r[INTEGRATION_COMMON_ADDITIONAL_FIELDS_CONTEXT_KEY] = additional_options

        output.append(r)

    return output


def get_extended_attributes_context(v: dict[str, Any]) -> dict:
    """
    Helper function to transform extended attributes.

    Extended attributes are returned in the following structure:

    ```json
    {
        "EXTATTR_KEY_1": {
            "value": "EXTATTR_VALUE_1"
        },
        "EXTATTR_KEY_2": {
            "value": "EXTATTR_VALUE_2"
        }
    }
    ```

    This method returns it in the following strucutre:

    ```json
    {
        "EXTATTR_KEY_1": "EXTATTR_VALUE_1",
        "EXTATTR_KEY_2": "EXTATTR_VALUE_2"
    }
    ```

    Args:
    - `v` (``dict[str, Any]``): The extended attributes dict to process.

    Returns:
    - `dict[str, Any]` Extended attributes in the expected context structure.

    """

    ext_attr_value = {}

    if isinstance(v, dict) and v:
        for ext_attr_key, ext_attr_val in v.items():
            if isinstance(ext_attr_val, dict) and ext_attr_val.get("value"):
                ext_attr_value[ext_attr_key] = cast(dict[str, Any], ext_attr_val).get("value")
            else:
                ext_attr_value[ext_attr_key] = "N/A"

    return ext_attr_value


def validate_json_arg(arg, name):
    """Validate that the argument is a valid JSON.
    Args:
        arg: The argument to validate.
        name: The name of the argument.

    Returns:
        The validated argument.
    """
    if isinstance(arg, dict):
        return arg
    try:
        arg = json.loads(arg)
        if not isinstance(arg, dict):
            raise ValueError(f"{name} is not a dictionary: {arg}")
    except Exception as e:
        raise ValueError(f"Invalid JSON for {name}: {e}")
    return arg


def validate_json_list_arg(arg, name):
    """Validate that the argument is a valid JSON list.
    Args:
        arg: The argument to validate.
        name: The name of the argument.

    Returns:
        The validated argument.
    """
    if isinstance(arg, list):
        return arg
    try:
        arg = json.loads(arg)
        if not isinstance(arg, list):
            raise ValueError(f"{name} is not a list: {arg}")
    except Exception as e:
        raise ValueError(f"Invalid JSON for {name}: {e}")
    return arg


def decode_all_strings(obj):
    """Recursively decode all string values in a JSON object
    Args:
        obj: The JSON object to decode.
    Returns:
        The decoded JSON object.
    """
    if isinstance(obj, dict):
        return {key: decode_all_strings(value) for key, value in obj.items()}
    elif isinstance(obj, list):
        return [decode_all_strings(item) for item in obj]
    elif isinstance(obj, str):
        return unquote(obj)
    else:
        return obj


def transform_keys_nested(obj, translation_dict, fallback_func):
    """Recursively transform keys in nested dictionaries.

    Args:
        obj: The object to transform (dict, list, or other)
        translation_dict: Dictionary mapping old keys to new keys
        fallback_func: Function to call for keys not in translation_dict

    Returns:
        The object with transformed keys
    """
    if isinstance(obj, dict):
        return {
            translation_dict.get(key, fallback_func(key)): transform_keys_nested(val, translation_dict, fallback_func)
            for key, val in obj.items()
        }
    elif isinstance(obj, list):
        return [transform_keys_nested(item, translation_dict, fallback_func) for item in obj]
    else:
        return obj


""" COMMANDS """


def test_module_command(client: InfoBloxNIOSClient, *_) -> tuple[str, dict, dict]:
    client.test_module()
    return "ok", {}, {}


def get_ip_command(client: InfoBloxNIOSClient, args: dict[str, str]) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    ip = args.get("ip")
    network = args.get("network")
    from_ip = args.get("from_ip")
    to_ip = args.get("to_ip")
    max_results = arg_to_number(args.get("max_results", INTEGRATION_MAX_RESULTS_DEFAULT), required=False)

    # Input validation

    # If too many arguments are supplied, return an error
    if sum(bool(arg) for arg in [ip, network, from_ip or to_ip]) > 1:
        raise ValueError("Please specify only one of the `ip`, `network` or `from_ip`/`to_ip` arguments")

    # If neither ip, network nor from/to_ip were specified, return an error.
    elif not any([ip, network, from_ip and to_ip]):
        raise ValueError("Please specify either the `ip`, `network` or `from_ip`/`to_ip` argument")

    extended_attributes = args.get("extended_attrs")

    if ip:
        ip_type = get_ip_type(ip)
        status = args.get("status", IPv4AddressStatus.USED.value)
        raw_response = client.get_ip_address_from_ip(
            ip, status=status, max_results=max_results, extended_attributes=extended_attributes, ip_type=ip_type
        )
    elif network:
        ip_type = get_ip_type(network)
        status = args.get("status", IPv4AddressStatus.USED.value)
        raw_response = client.get_ip_address_from_netmask(
            network, status=status, max_results=max_results, extended_attributes=extended_attributes, ip_type=ip_type
        )
    elif from_ip and to_ip:
        ip_type = get_ip_type(from_ip)
        raw_response = client.get_ip_address_range(
            from_ip, to_ip, max_results=max_results, extended_attributes=extended_attributes, ip_type=ip_type
        )
    else:
        raw_response = {}
        demisto.debug(f"No condition was met, {raw_response=}")

    ip_list = raw_response.get("result")

    if not ip_list:
        human_readable = f"{INTEGRATION_NAME} - Could not find any data"
        context = {}
    else:
        output = transform_ip_context(ip_list)
        title = f"{INTEGRATION_NAME}"
        context = {f"{INTEGRATION_CONTEXT_NAME}.{INTEGRATION_IP_CONTEXT_NAME}": output}
        human_readable = tableToMarkdown(title, output)
    return human_readable, context, raw_response


def search_related_objects_by_ip_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    ip = args.get("ip")
    max_results = args.get("max_results")
    raw_response = client.search_related_objects_by_ip(ip, max_results)
    obj_list = raw_response.get("result")
    if not obj_list:
        return f"{INTEGRATION_NAME} - No objects associated with ip: {ip} were found", {}, {}
    fixed_keys_obj_list = []
    for obj in obj_list:
        fixed_keys_obj = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in obj.items()}
        fixed_keys_obj_list.append(fixed_keys_obj)

    title = f"{INTEGRATION_NAME} - IP: {ip} search results."
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.IPRelatedObjects(val.ReferenceID && val.ReferenceID === obj.ReferenceID)":  # noqa: E501
        fixed_keys_obj_list
    }
    human_readable = tableToMarkdown(title, fixed_keys_obj_list, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def list_response_policy_zone_rules_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    zone = args.get("response_policy_zone_name")
    view = args.get("view")
    max_results = args.get("page_size", INTEGRATION_MAX_RESULTS_DEFAULT)
    next_page_id = args.get("next_page_id")
    if not zone and not next_page_id:
        raise DemistoException("To run this command either a zone or a next page ID must be given")
    raw_response = client.list_response_policy_zone_rules(zone, view, max_results, next_page_id)
    new_next_page_id = raw_response.get("next_page_id")

    rules_list = raw_response.get("result")
    if not rules_list:
        return f"{INTEGRATION_NAME} - No rules associated to zone: {zone} were found", {}, {}

    fixed_keys_rule_list = []
    for rule in rules_list:
        fixed_keys_rule = {
            RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val
            for key, val in rule.items()
            if key != "_ref"
        }
        fixed_keys_rule_list.append(fixed_keys_rule)
    zone_name = zone.capitalize() if zone else fixed_keys_rule_list[0].get("Name")
    title = f"{INTEGRATION_NAME} - Zone: {zone_name} rule list."
    context = {f"{INTEGRATION_CONTEXT_NAME}.ResponsePolicyZoneRulesList(val.Name && val.Name === obj.Name)": fixed_keys_rule_list}
    if new_next_page_id:
        context.update(
            {
                f"{INTEGRATION_CONTEXT_NAME}.RulesNextPage(val.NextPageID !== obj.NextPageID)": {  # type: ignore
                    "NextPageID": new_next_page_id
                }
            }
        )
    human_readable = tableToMarkdown(title, fixed_keys_rule_list, headerTransform=pascalToSpace, removeNull=True)
    return human_readable, context, raw_response


def list_response_policy_zones_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    max_results = arg_to_number(args.get("max_results", INTEGRATION_MAX_RESULTS_DEFAULT), required=False)
    fqdn = args.get("fqdn")
    view = args.get("view")
    comment = args.get("comment")
    raw_response = client.list_response_policy_zones(max_results, fqdn, view, comment)
    zones_list = raw_response.get("result")
    if not zones_list:
        return f"{INTEGRATION_NAME} - No Response Policy Zones were found", {}, {}
    fixed_keys_zone_list = []
    for zone in zones_list:
        fixed_keys_zone = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in zone.items()}
        fixed_keys_zone_list.append(fixed_keys_zone)
    display_first_x_results = f"(fetched {len(zones_list)} results)" if max_results else ""
    title = f"{INTEGRATION_NAME} - Response Policy Zones list {display_first_x_results}:"
    context = {f"{INTEGRATION_CONTEXT_NAME}.ResponsePolicyZones(val.FQDN && val.FQDN === obj.FQDN)": fixed_keys_zone_list}
    human_readable = tableToMarkdown(title, fixed_keys_zone_list, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_response_policy_zone_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    fqdn = args.get("FQDN")
    rpz_policy = args.get("rpz_policy")
    rpz_severity = args.get("rpz_severity")
    substitute_name = args.get("substitute_name")
    rpz_type = args.get("rpz_type")
    if rpz_policy == "SUBSTITUTE" and not substitute_name:
        raise DemistoException("Response policy zone with policy SUBSTITUTE requires a substitute name")
    raw_response = client.create_response_policy_zone(fqdn, rpz_policy, rpz_severity, substitute_name, rpz_type)
    zone = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in zone.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone: {fqdn} has been created"
    context = {f"{INTEGRATION_CONTEXT_NAME}.ResponsePolicyZones(val.FQDN && val.FQDN === obj.FQDN)": fixed_keys_rule_res}
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def delete_response_policy_zone_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    ref_id = args.get("reference_id")
    raw_response = client.delete_response_policy_zone(ref_id)
    deleted_rule_ref_id = raw_response.get("result", {})
    human_readable = f"{INTEGRATION_NAME} - Response Policy Zone with the following id was deleted: \n {deleted_rule_ref_id}"
    return human_readable, {}, raw_response


def create_rpz_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    rule_type = args.get("rule_type")
    object_type = args.get("object_type")
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    substitute_name = args.get("substitute_name")
    view = args.get("view")

    # need to append 'rp_zone' or else this error is returned: "'<name>'. FQDN must belong to zone '<rp_zone>'."
    if name and not name.endswith(f".{rp_zone}"):
        name = f"{name}.{rp_zone}"

    if rule_type == "Substitute (domain name)" and not substitute_name:
        raise DemistoException("Substitute (domain name) rules requires a substitute name argument")
    raw_response = client.create_rpz_rule(rule_type, object_type, name, rp_zone, view, substitute_name, comment)
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace, removeNull=True)
    return human_readable, context, raw_response


def create_a_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    ipv4addr = args.get("ipv4addr")
    infoblox_object_type = "record:rpz:a"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, ipv4addr=ipv4addr
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_aaaa_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    ipv6addr = args.get("ipv6addr")
    infoblox_object_type = "record:rpz:aaaa"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, ipv6addr=ipv6addr
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_mx_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    mail_exchanger = args.get("mail_exchanger")
    preference = int(args.get("preference", 0))
    infoblox_object_type = "record:rpz:mx"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, mail_exchanger=mail_exchanger, preference=preference
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_naptr_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    order = int(args.get("order", 0))
    preference = int(args.get("preference", 0))
    replacement = args.get("replacement")
    infoblox_object_type = "record:rpz:naptr"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type,
        name=name,
        rp_zone=rp_zone,
        comment=comment,
        order=order,
        preference=preference,
        replacement=replacement,
    )

    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_ptr_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    ptrdname = args.get("ptrdname")
    name = args.get("name")
    ipv4addr = args.get("ipv4addr")
    ipv6addr = args.get("ipv6addr")
    infoblox_object_type = "record:rpz:ptr"
    if all([not name, not ipv4addr, not ipv6addr]):
        raise DemistoException("To run this command either 'name', 'ipv4addr' or 'ipv6addr' should be given.")
    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, ptrdname=ptrdname, ipv4addr=ipv4addr, ipv6addr=ipv6addr
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_srv_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    port = int(args.get("port", 0))
    priority = int(args.get("priority", 0))
    target = args.get("target")
    weight = int(args.get("weight", 0))
    infoblox_object_type = "record:rpz:srv"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type,
        name=name,
        rp_zone=rp_zone,
        comment=comment,
        port=port,
        priority=priority,
        target=target,
        weight=weight,
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_txt_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    text = args.get("text")
    infoblox_object_type = "record:rpz:txt"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, text=text
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_ipv4_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    ipv4addr = args.get("ipv4addr")
    infoblox_object_type = "record:rpz:a:ipaddress"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, ipv4addr=ipv4addr
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def create_ipv6_substitute_record_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    ipv6addr = args.get("ipv6addr")
    infoblox_object_type = "record:rpz:aaaa:ipaddress"

    raw_response = client.create_substitute_record_rule(
        infoblox_object_type, name=name, rp_zone=rp_zone, comment=comment, ipv6addr=ipv6addr
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been created:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def enable_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    reference_id = args.get("reference_id")
    raw_response = client.change_rule_status(reference_id, disable=False)

    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f'{INTEGRATION_NAME} - Response Policy Zone rule: {fixed_keys_rule_res.get("Name")} has been enabled'
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def disable_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    reference_id = args.get("reference_id")
    raw_response = client.change_rule_status(reference_id, disable=True)

    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f'{INTEGRATION_NAME} - Response Policy Zone rule: {fixed_keys_rule_res.get("Name")} has been disabled'
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def get_object_fields_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    object_type = args.get("object_type")
    raw_response = client.get_object_fields(object_type)

    fields = raw_response.get("result", {}).get("fields", {})
    name_list = [field_obj.get("name") for field_obj in fields]
    title = f"{INTEGRATION_NAME} - Object {object_type} supported fields: "
    context_entry = {"ObjectType": object_type, "SupportedFields": name_list}
    context = {f"{INTEGRATION_CONTEXT_NAME}.ObjectFields(val.ObjectType && val.ObjectType === obj.ObjectType)": context_entry}
    human_readable = tableToMarkdown(title, name_list, headers=["Field Names"], headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def search_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    object_type = args.get("object_type")
    rule_name = args.get("rule_name")
    output_fields = args.get("output_fields")
    raw_response = client.search_rule(object_type, rule_name, output_fields)
    rule_list = raw_response.get("result")
    if not rule_list:
        return f"No rules with name: {rule_name} of type: {object_type} were found", {}, raw_response
    fixed_keys_rule_list = []
    for rule in rule_list:
        fixed_keys_rule = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
        fixed_keys_rule_list.append(fixed_keys_rule)
    title = f"{INTEGRATION_NAME} - Search result for: {rule_name}: "
    context = {f"{INTEGRATION_CONTEXT_NAME}.RulesSearchResults(val.Name && val.Name === obj.Name)": fixed_keys_rule_list}
    human_readable = tableToMarkdown(title, fixed_keys_rule_list, headerTransform=pascalToSpace)
    return human_readable, context, raw_response


def delete_rpz_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
        client: Client object
        args: Usually demisto.args()

    Returns:
        Outputs
    """
    reference_id = args.get("reference_id")
    raw_response = client.delete_rpz_rule(reference_id)
    rule_reference_id = raw_response.get("result")
    title = f"{INTEGRATION_NAME} - A rule with the following id was deleted: \n {rule_reference_id}"
    return title, {}, raw_response


def get_host_records_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict[str, Any]]:
    """
    Get host records.

    Args:
    - `client` (``InfoBloxNIOSClient``): Client object
    - `args` (``dict``): Usually demisto.args()

    Returns:
    - `tuple[str, Dict, Dict]`: The human readable output, the records and the raw response.
    """

    hostname = args.get("host_name")
    max_results = arg_to_number(args.get("max_results", INTEGRATION_MAX_RESULTS_DEFAULT))
    additional_return_fields = args.get("additional_return_fields", INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY)
    extended_attributes = args.get(INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY)

    raw = client.get_host_records(
        name=hostname,
        additional_return_fields=additional_return_fields,
        extended_attributes=extended_attributes,
        max_results=max_results,
    )

    if "Error" in raw:
        msg = raw.get("text")
        raise DemistoException(f"Error retrieving host records: {msg}", res=raw)

    records = raw.get("result", [])

    demisto.debug(f"Found {len(records)} host records")

    title = "Host records"

    if records:
        outputs = transform_host_records_context(records)
        context = {f"{INTEGRATION_CONTEXT_NAME}.{INTEGRATION_HOST_RECORDS_CONTEXT_NAME}": outputs}
        human_readable = tableToMarkdown(title, outputs)
    else:
        human_readable = "No host records found"
        context = {}

    return human_readable, context, raw


def get_network_info_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict[str, Any]]:
    """
    Get network information command.

    Args:
    - `client` (``InfoBloxNIOSClient``): Client object
    - `args` (``dict``): Usually demisto.args()

    Returns:
    - `tuple[str, Dict, Dict]`: The human readable output, the records and the raw response.
    """

    pattern = args.get("pattern")
    max_results = arg_to_number(args.get("max_results", INTEGRATION_MAX_RESULTS_DEFAULT))
    additional_return_fields = args.get("additional_return_fields", INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY)
    extended_attributes = args.get(INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY)

    raw_response = client.get_network_info(
        pattern,
        additional_return_fields=additional_return_fields,
        extended_attributes=extended_attributes,
        max_results=max_results,
    )

    if "Error" in raw_response:
        msg = raw_response.get("text")
        raise DemistoException(f"Error retrieving host records: {msg}", res=raw_response)

    network_info = raw_response.get("result")

    if not network_info:
        hr = "No networks found"
        context = {}
    else:
        output = transform_network_info_context(network_info)
        hr = tableToMarkdown("Network information", output)
        context = {f"{INTEGRATION_CONTEXT_NAME}.{INTEGRATION_NETWORK_INFO_CONTEXT_KEY}": output}

    return hr, context, raw_response


def update_rpz_rule_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
    - `client` (``InfoBloxNIOSClient``): Client object
    - `args` (``dict``): Usually demisto.args()

    Returns:
    - `tuple[str, Dict, Dict]`: The human readable output, the records and the raw response.
    """

    reference_id = args.get("reference_id")
    rule_type = args.get("rule_type")
    name = args.get("name")
    rp_zone = args.get("rp_zone")
    comment = args.get("comment")
    substitute_name = args.get("substitute_name")
    view = args.get("view")
    additional_parameters = (
        validate_json_arg(args.get("additional_parameters"), "additional_parameters")
        if args.get("additional_parameters")
        else None
    )  # type: ignore

    # need to append 'rp_zone' or else this error is returned: "'<name>'. FQDN must belong to zone '<rp_zone>'."
    if name and not name.endswith(f".{rp_zone}"):
        name = f"{name}.{rp_zone}"

    if rule_type.lower() == "substitute (domain name)" and not substitute_name:  # type: ignore
        raise DemistoException("Substitute (domain name) rules requires a substitute name argument")
    raw_response = client.update_rpz_rule(
        reference_id,  # type: ignore
        rule_type,  # type: ignore
        name,  # type: ignore
        rp_zone,  # type: ignore
        view,
        substitute_name,
        comment,
        additional_parameters,
    )
    rule = raw_response.get("result", {})
    fixed_keys_rule_res = {RESPONSE_TRANSLATION_DICTIONARY.get(key, string_to_context_key(key)): val for key, val in rule.items()}
    title = f"{INTEGRATION_NAME} - Response Policy Zone rule: {name} has been updated:"
    context = {
        f"{INTEGRATION_CONTEXT_NAME}.ModifiedResponsePolicyZoneRules(val.Name && val.Name === obj.Name)": fixed_keys_rule_res
    }
    human_readable = tableToMarkdown(title, fixed_keys_rule_res, headerTransform=pascalToSpace, removeNull=True)
    return human_readable, context, raw_response


def create_host_record_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
    - `client` (``InfoBloxNIOSClient``): Client object
    - `args` (``dict``): Usually demisto.args()

    Returns:
    - `tuple[str, Dict, Dict]`: The human readable output, the records and the raw response.
    """
    name = args.get("name")
    ipv4_address = validate_json_list_arg(args.get("ipv4_address"), "ipv4_address") if args.get("ipv4_address") else None  # type: ignore
    ipv6_address = validate_json_list_arg(args.get("ipv6_address"), "ipv6_address") if args.get("ipv6_address") else None  # type: ignore
    view = args.get("view")
    comment = args.get("comment")
    aliases = validate_json_list_arg(args.get("aliases"), "aliases") if args.get("aliases") else None  # type: ignore
    configure_for_dns = args.get("configure_for_dns")
    extended_attributes = (
        validate_json_arg(
            args.get(INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY),
            INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY,
        )
        if args.get(INTEGRATION_COMMON_RAW_RESULT_EXTENSION_ATTRIBUTES_KEY)
        else None
    )  # type: ignore
    additional_parameters = (
        validate_json_arg(args.get("additional_parameters"), "additional_parameters")
        if args.get("additional_parameters")
        else None
    )  # type: ignore

    raw_response = client.create_host_record(
        name,  # type: ignore
        ipv4_address,
        ipv6_address,
        view,
        comment,
        aliases,
        configure_for_dns,  # type: ignore
        extended_attributes,
        additional_parameters,
    )

    if "Error" in raw_response:
        msg = raw_response.get("text")
        raise DemistoException(f"Error creating host record: {msg}", res=raw_response)

    record = raw_response.get("result", {})
    record = decode_all_strings(record)
    translation_dictionary = {**RESPONSE_TRANSLATION_DICTIONARY, **RESPONSE_KEY_REFACTOR_DICTIONARY}
    fixed_keys_record = transform_keys_nested(record, translation_dictionary, string_to_context_key)
    title = "Host record created"
    context = {f"{INTEGRATION_CONTEXT_NAME}.Host(val.Name && val.Name === obj.Name)": fixed_keys_record}
    json_transformer = {"IPV4Addresses": JsonTransformer(), "IPV6Addresses": JsonTransformer()}
    human_readable = tableToMarkdown(
        title, fixed_keys_record, headerTransform=pascalToSpace, json_transform_mapping=json_transformer, removeNull=True
    )

    return human_readable, context, raw_response


def dhcp_lease_lookup_command(client: InfoBloxNIOSClient, args: dict) -> tuple[str, dict, dict]:
    """
    Args:
    - `client` (``InfoBloxNIOSClient``): Client object
    - `args` (``dict``): Usually demisto.args()

    Returns:
    - `tuple[str, Dict, Dict]`: The human readable output, the records and the raw response.
    """
    ip_address = args.get("ip_address")
    hardware = args.get("hardware")
    hostname = args.get("hostname")
    ipv6_duid = args.get("ipv6_duid")
    protocol = args.get("protocol")
    fingerprint = args.get("fingerprint")
    username = args.get("username")
    limit = arg_to_number(args.get("limit", INTEGRATION_MAX_RESULTS_DEFAULT), required=False)
    raw_response = client.dhcp_lease_lookup(ip_address, hardware, hostname, ipv6_duid, protocol, fingerprint, username, limit)  # type: ignore
    if "Error" in raw_response:
        msg = raw_response.get("text")
        raise DemistoException(f"Error looking up DHCP lease: {msg}", res=raw_response)
    records = raw_response.get("result", [])
    records = decode_all_strings(records)
    translation_dictionary = {**RESPONSE_TRANSLATION_DICTIONARY, **RESPONSE_KEY_REFACTOR_DICTIONARY}
    fixed_keys_record = [
        {translation_dictionary.get(key, string_to_context_key(key)): val for key, val in record.items()} for record in records
    ]
    title = f"DHCP lease lookup, found {len(records)} records"
    context = {f"{INTEGRATION_CONTEXT_NAME}.DHCPLease(val.Address && val.Address === obj.Address)": fixed_keys_record}
    human_readable = tableToMarkdown(title, fixed_keys_record, headerTransform=pascalToSpace, removeNull=True)
    return human_readable, context, raw_response


""" COMMANDS MANAGER / SWITCH PANEL """


def main():  # pragma: no cover
    params = demisto.params()
    base_url = f"{params.get('url', '').rstrip('/')}/wapi/v2.13.1/"
    verify = not params.get("insecure", False)
    proxy = params.get("proxy", False)
    user = demisto.get(params, "credentials.identifier")
    password = demisto.get(params, "credentials.password")
    client = InfoBloxNIOSClient(base_url, verify=verify, proxy=proxy, auth=(user, password))
    command = demisto.command()
    demisto.info(f"Command being called is {command}")

    # Switch case
    commands: dict[str, Callable[[InfoBloxNIOSClient, dict[str, str]], tuple[str, dict[Any, Any], dict[Any, Any]]]] = {
        "test-module": test_module_command,
        f"{INTEGRATION_COMMAND_NAME}-get-ip": get_ip_command,
        f"{INTEGRATION_COMMAND_NAME}-search-related-objects-by-ip": search_related_objects_by_ip_command,
        f"{INTEGRATION_COMMAND_NAME}-list-response-policy-zones": list_response_policy_zones_command,
        f"{INTEGRATION_COMMAND_NAME}-list-response-policy-zone-rules": list_response_policy_zone_rules_command,
        f"{INTEGRATION_COMMAND_NAME}-create-response-policy-zone": create_response_policy_zone_command,
        f"{INTEGRATION_COMMAND_NAME}-delete-response-policy-zone": delete_response_policy_zone_command,
        f"{INTEGRATION_COMMAND_NAME}-create-rpz-rule": create_rpz_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-a-substitute-record-rule": create_a_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-aaaa-substitute-record-rule": create_aaaa_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-mx-substitute-record-rule": create_mx_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-naptr-substitute-record-rule": create_naptr_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-ptr-substitute-record-rule": create_ptr_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-srv-substitute-record-rule": create_srv_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-txt-substitute-record-rule": create_txt_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-ipv4-substitute-record-rule": create_ipv4_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-ipv6-substitute-record-rule": create_ipv6_substitute_record_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-enable-rule": enable_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-disable-rule": disable_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-get-object-fields": get_object_fields_command,
        f"{INTEGRATION_COMMAND_NAME}-search-rule": search_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-delete-rpz-rule": delete_rpz_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-list-host-info": get_host_records_command,
        f"{INTEGRATION_COMMAND_NAME}-list-network-info": get_network_info_command,
        f"{INTEGRATION_COMMAND_NAME}-update-rpz-rule": update_rpz_rule_command,
        f"{INTEGRATION_COMMAND_NAME}-create-host-record": create_host_record_command,
        f"{INTEGRATION_COMMAND_NAME}-dhcp-lease-lookup": dhcp_lease_lookup_command,
    }
    try:
        if command in commands:
            return_outputs(*commands[command](client, demisto.args()))
    # Log exceptions
    except Exception as e:
        err_msg = f"Error in {INTEGRATION_NAME} - {e}"
        return_error(err_msg, error=e)


if __name__ in ["__builtin__", "builtins", "__main__"]:  # pragma: no cover
    main()