diff --git a/pyproject.toml b/pyproject.toml index fbea1b0..346a3fd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ name = "sophosfirewall-python" packages = [ { include = "sophosfirewall_python" }, ] -version = "0.1.58" +version = "0.1.59" description = "Python SDK for Sophos Firewall" authors = ["Matt Mullen "] readme = "README.md" diff --git a/sophosfirewall_python/firewallapi.py b/sophosfirewall_python/firewallapi.py index 26334a1..6e670d0 100644 --- a/sophosfirewall_python/firewallapi.py +++ b/sophosfirewall_python/firewallapi.py @@ -16,9 +16,10 @@ SophosFirewallInvalidArgument, SophosFirewallAPIError, SophosFirewallAuthFailure, - SophosFirewallOperatorError + SophosFirewallOperatorError, ) from sophosfirewall_python.firewallrule import FirewallRule +from sophosfirewall_python.firewallrulegroup import FirewallRuleGroup from sophosfirewall_python.host import ( IPHost, IPHostGroup, @@ -40,6 +41,7 @@ urllib3.disable_warnings() + class SophosFirewall: """Class used for interacting with the Sophos Firewall XML API""" @@ -73,7 +75,7 @@ def get_tag(self, xml_tag: str, output_format: str = "dict"): output_format(str): Output format. Valid options are "dict" or "xml". Defaults to dict. """ return self.client.get_tag(xml_tag, output_format) - + def get_tag_with_filter( self, xml_tag: str, @@ -91,7 +93,9 @@ def get_tag_with_filter( operator (str, optional): Operator for search (“=”,”!=”,”like”). Defaults to "like". output_format(str): Output format. Valid options are "dict" or "xml". Defaults to dict. """ - return self.client.get_tag_with_filter(xml_tag, key, value, operator, output_format) + return self.client.get_tag_with_filter( + xml_tag, key, value, operator, output_format + ) def submit_template( self, @@ -120,18 +124,22 @@ def submit_xml( set_operation: str = "add", debug: bool = False, ) -> dict: - """Submits XML payload as a string to the API. + """Submits XML payload as a string to the API. Args: template_data (str): A string containing the XML payload. Variables can be optionally passed in the string using Jinja2 syntax (ex. {{ some_var }}) - template_vars (dict, optional): Dictionary of variables to inject into the XML string. - set_operation (str): Specify 'add' or 'update' set operation. Default is add. + template_vars (dict, optional): Dictionary of variables to inject into the XML string. + set_operation (str): Specify 'add' or 'update' set operation. Default is add. Returns: dict """ - return self.client.submit_xml(template_data, template_vars, set_operation, debug) + return self.client.submit_xml( + template_data, template_vars, set_operation, debug + ) - def remove(self, xml_tag: str, name: str, key: str = "Name", output_format: str = "dict"): + def remove( + self, xml_tag: str, name: str, key: str = "Name", output_format: str = "dict" + ): """Remove an object from the firewall. Args: @@ -161,7 +169,9 @@ def update( output_format(str): Output format. Valid options are "dict" or "xml". Defaults to dict. debug (bool): Displays the XML payload that was submitted """ - return self.client.update(xml_tag, update_params, name, lookup_key, output_format, debug) + return self.client.update( + xml_tag, update_params, name, lookup_key, output_format, debug + ) # METHODS FOR OBJECT RETRIEVAL (GET) @@ -173,7 +183,7 @@ def get_fw_rule(self, name: str = None, operator: str = "="): operator (str, optional): Operator for search. Default is "=". Valid operators: =, !=, like. """ return FirewallRule(self.client).get(name=name, operator=operator) - + def get_rule(self, name: str = None, operator: str = "="): """Get firewall rule(s) @@ -183,6 +193,15 @@ def get_rule(self, name: str = None, operator: str = "="): """ return FirewallRule(self.client).get(name=name, operator=operator) + def get_rulegroup(self, name: str = None, operator: str = "="): + """Get firewall rule group(s) + + Args: + name (str, optional): Firewall Rule Group name. Returns all rule groups if not specified. + operator (str, optional): Operator for search. Default is "=". Valid operators: =, !=, like. + """ + return FirewallRuleGroup(self.client).get(name=name, operator=operator) + def get_ip_host( self, name: str = None, ip_address: str = None, operator: str = "=" ): @@ -430,40 +449,46 @@ def get_service( # METHODS FOR OBJECT CREATION - def create_acl_rule(self, - name: str, - description: str = None, - position: str = "Bottom", - source_zone: str = "Any", - source_list: list = None, - dest_list: list = None, - service_list: list = None, - action: str = "Accept", - debug: bool = False): + def create_acl_rule( + self, + name: str, + description: str = None, + position: str = "Bottom", + source_zone: str = "Any", + source_list: list = None, + dest_list: list = None, + service_list: list = None, + action: str = "Accept", + debug: bool = False, + ): """Create Local Service ACL Exception Rule (System > Administration > Device Access > Local service ACL exception) Args: name (str): Name of the ACL exception rule to create. - description (str): Rule description. - position (str): Location to place the ACL (Top or Bottom). - source_zone (str): Source Zone. Defaults to Any. + description (str): Rule description. + position (str): Location to place the ACL (Top or Bottom). + source_zone (str): Source Zone. Defaults to Any. source_list (list, optional): List of source network or host groups. Defaults to None. dest_list (list, optional): List of destination hosts. Defaults to None. service_list (list, optional): List of services. Defaults to None. action (str, optional): Accept or Drop. Default is Accept. debug (bool, optional): Enable debug mode. Defaults to False. """ - return AclRule(self.client).create(name, - description, - position, - source_zone, - source_list, - dest_list, - service_list, - action, - debug) - - def create_admin_profile(self, name: str, default_permission: str=None, debug: bool=False, **kwargs): + return AclRule(self.client).create( + name, + description, + position, + source_zone, + source_list, + dest_list, + service_list, + action, + debug, + ) + + def create_admin_profile( + self, name: str, default_permission: str = None, debug: bool = False, **kwargs + ): """Create an administration profile. Args: @@ -535,7 +560,9 @@ def create_admin_profile(self, name: str, default_permission: str=None, debug: b Returns: dict: XML response converted to Python dictionary """ - return AdminProfile(self.client).create(name=name, default_permission=default_permission, debug=debug, **kwargs) + return AdminProfile(self.client).create( + name=name, default_permission=default_permission, debug=debug, **kwargs + ) def create_rule(self, rule_params: dict, debug: bool = False): """Create a firewall rule @@ -562,6 +589,33 @@ def create_rule(self, rule_params: dict, debug: bool = False): """ return FirewallRule(self.client).create(rule_params, debug) + def create_rulegroup( + self, + name: str, + description: str, + policy_list: list, + source_zones: list, + dest_zones: list, + policy_type: str, + debug: bool = False, + ): + """Create a firewall rule group + + Args: + name(str): Name of the firewall rule group + description(str): Description for the firewall rule group + policy_list(list): List of firewall rules to add to firewall group + source_zones(list): List of source zones + dest_zones(list): List of destination zones + policy_type(str): Policy type. Valid values are User/network rule, Network rule, User rule, WAF rule, Any + + Returns: + dict: XML response converted to Python dictionary + """ + return FirewallRuleGroup(self.client).create( + name, description, policy_list, source_zones, dest_zones, policy_type, debug + ) + def create_ip_host( self, name: str, @@ -778,7 +832,9 @@ def create_user(self, debug: bool = False, **kwargs): """ return User(self.client).create(debug, **kwargs) - def create_zone(self, name: str, zone_type: str, zone_params: dict = None, debug: bool = False): + def create_zone( + self, name: str, zone_type: str, zone_params: dict = None, debug: bool = False + ): """Create a zone. Args: @@ -808,11 +864,13 @@ def create_zone(self, name: str, zone_type: str, zone_params: dict = None, debug dynamic_routing (str, optional): Enable/Disable dynamic routing smtp_relay (str, optional): Enable/Disable SMTP Relay snmp (str, optional): Enable/Disable SNMP - + Returns: dict: XML response converted to Python dictionary """ - return Zone(self.client).create(name=name, zone_type=zone_type, zone_params=zone_params, debug=debug) + return Zone(self.client).create( + name=name, zone_type=zone_type, zone_params=zone_params, debug=debug + ) def update_user_password( self, username: str, new_password: str, debug: bool = False @@ -846,7 +904,7 @@ def update_admin_password( current_password, new_password, debug ) - def update_admin_profile(self, name: str, debug: bool=False, **kwargs): + def update_admin_profile(self, name: str, debug: bool = False, **kwargs): """Update an administration profile. Args: @@ -1075,7 +1133,7 @@ def update_acl_rule( Args: name (str): Name of the ACL rule to update. description (str): Rule description. - source_zone (str): Name of the source zone. Defaults to None. + source_zone (str): Name of the source zone. Defaults to None. source_list (list, optional): List of network or host groups. Defaults to []. dest_list (list, optional): List of destinations. Defaults to []. service_list (list, optional): List of services. Defaults to []. @@ -1084,16 +1142,16 @@ def update_acl_rule( debug (bool, optional): Enable debug mode. Defaults to False. """ params = { - "name": name, - "description": description, - "source_zone": source_zone, - "source_list": source_list, - "dest_list": dest_list, - "service_list": service_list, - "action": action, - "update_action": update_action, - "debug": debug - } + "name": name, + "description": description, + "source_zone": source_zone, + "source_list": source_list, + "dest_list": dest_list, + "service_list": service_list, + "action": action, + "update_action": update_action, + "debug": debug, + } return AclRule(self.client).update(**params) def update_rule(self, name: str, rule_params: dict, debug: bool = False): @@ -1119,8 +1177,49 @@ def update_rule(self, name: str, rule_params: dict, debug: bool = False): dict: XML response converted to Python dictionary """ return FirewallRule(self.client).update(name, rule_params, debug) - - def update_hostname_settings(self, hostname: str = None, description: str = None, debug: bool = False): + + def update_rulegroup( + self, + name: str, + description: str = None, + policy_list: list = None, + source_zones: list = None, + dest_zones: list = None, + policy_type: str = None, + source_zone_action: str = "add", + dest_zone_action: str = "add", + debug: bool = False, + ): + """Create a firewall rule group + + Args: + name(str): Name of the firewall rule group + description(str): Description for the firewall rule group + policy_list(list): List of firewall rules to add to firewall group + source_zones(list): List of source zones + dest_zones(list): List of destination zones + policy_type(str): Policy type. Valid values are User/network rule, Network rule, User rule, WAF rule, Any + source_zone_action(str): Specify add to add a new rule to the list. Specify remove to remove a rule from the list. Specify replace to replace the list. Default=add. + dest_zone_action(str): Specify add to add a new rule to the list. Specify remove to remove a rule from the list. Specify replace to replace the list. Default=add. + Returns: + dict: XML response converted to Python dictionary + """ + + return FirewallRuleGroup(self.client).update( + name, + description, + policy_list, + source_zones, + dest_zones, + policy_type, + source_zone_action, + dest_zone_action, + debug, + ) + + def update_hostname_settings( + self, hostname: str = None, description: str = None, debug: bool = False + ): """Update hostname admin settings. System > Administration > Admin and user settings. Args: @@ -1130,15 +1229,20 @@ def update_hostname_settings(self, hostname: str = None, description: str = None Returns: dict: XML response converted to Python dictionary """ - return AdminSettings(self.client).update_hostname_settings(hostname, description, debug) - - def update_webadmin_settings(self, certificate: str = None, - https_port: str = None, - userportal_https_port: str = None, - vpnportal_https_port: str = None, - portal_redirect_mode: str = None, - portal_custom_hostname: str = None, - debug: bool = False): + return AdminSettings(self.client).update_hostname_settings( + hostname, description, debug + ) + + def update_webadmin_settings( + self, + certificate: str = None, + https_port: str = None, + userportal_https_port: str = None, + vpnportal_https_port: str = None, + portal_redirect_mode: str = None, + portal_custom_hostname: str = None, + debug: bool = False, + ): """Update webadmin settings. System > Administration > Admin and user settings. Args: @@ -1152,46 +1256,51 @@ def update_webadmin_settings(self, certificate: str = None, Returns: dict: XML response converted to Python dictionary """ - return AdminSettings(self.client).update_webadmin_settings(certificate, - https_port, - userportal_https_port, - vpnportal_https_port, - portal_redirect_mode, - portal_custom_hostname, - debug) - - def update_loginsecurity_settings(self, logout_session: str = None, - block_login: str = None, - unsuccessful_attempt: str = None, - duration: str = None, - minutes: str = None, - debug: bool = False): - """Update login security settings. System > Administration > Admin and user settings. - - Args: - logout_session (str, optional): Enable to logout Admin Session after configured timeout. Specify number of minutes to enable (1-120). Defaults to None. - block_login (str, optional): Enable to block Admin login after configured number of failed attempts within configured time span. Defaults to None. - unsuccessful_attempt (str, optional): Allowed number of failed Admin login attempts from the same IP address (1-5). Defaults to None. - duration (str, optional): Time span within which if Admin Login attempts exceed configured Unsuccessful Attempts, then Admin Login gets blocked. (1-120). Defaults to None. - minutes (str, optional): Time interval for which Admin Login is blocked (1-60). Defaults to None. - - Returns: - dict: XML response converted to Python dictionary - """ - return AdminSettings(self.client).update_loginsecurity_settings(logout_session, - block_login, - unsuccessful_attempt, - duration, - minutes, - debug) - - def update_passwordcomplexity_settings(self, complexity_check: str = None, - enforce_min_length: str = None, - include_alpha: str = None, - include_numeric: str = None, - include_special: str = None, - min_length: str = None, - debug: bool = False): + return AdminSettings(self.client).update_webadmin_settings( + certificate, + https_port, + userportal_https_port, + vpnportal_https_port, + portal_redirect_mode, + portal_custom_hostname, + debug, + ) + + def update_loginsecurity_settings( + self, + logout_session: str = None, + block_login: str = None, + unsuccessful_attempt: str = None, + duration: str = None, + minutes: str = None, + debug: bool = False, + ): + """Update login security settings. System > Administration > Admin and user settings. + + Args: + logout_session (str, optional): Enable to logout Admin Session after configured timeout. Specify number of minutes to enable (1-120). Defaults to None. + block_login (str, optional): Enable to block Admin login after configured number of failed attempts within configured time span. Defaults to None. + unsuccessful_attempt (str, optional): Allowed number of failed Admin login attempts from the same IP address (1-5). Defaults to None. + duration (str, optional): Time span within which if Admin Login attempts exceed configured Unsuccessful Attempts, then Admin Login gets blocked. (1-120). Defaults to None. + minutes (str, optional): Time interval for which Admin Login is blocked (1-60). Defaults to None. + + Returns: + dict: XML response converted to Python dictionary + """ + return AdminSettings(self.client).update_loginsecurity_settings( + logout_session, block_login, unsuccessful_attempt, duration, minutes, debug + ) + + def update_passwordcomplexity_settings( + self, + complexity_check: str = None, + enforce_min_length: str = None, + include_alpha: str = None, + include_numeric: str = None, + include_special: str = None, + min_length: str = None, + debug: bool = False, + ): """Update hostname admin settings. System > Administration > Admin and user settings. Args: @@ -1199,26 +1308,28 @@ def update_passwordcomplexity_settings(self, complexity_check: str = None, enforce_min_length (str, optional): Enforce minimum required password length. Defaults to None. include_alpha (str, optional): Enforce inclusion of alphanumeric characters. Defaults to None. include_numeric (str, optional): Enforce inclusion numeric characters. Defaults to None. - include_special (str, optional): Enforce inclusion of special characters. Defaults to None. - min_length (str, optional): Minimul required password length. Defaults to None. + include_special (str, optional): Enforce inclusion of special characters. Defaults to None. + min_length (str, optional): Minimul required password length. Defaults to None. Returns: dict: XML response converted to Python dictionary """ - return AdminSettings(self.client).update_passwordcomplexity_settings(complexity_check, - enforce_min_length, - include_alpha, - include_numeric, - include_special, - min_length, - debug) - + return AdminSettings(self.client).update_passwordcomplexity_settings( + complexity_check, + enforce_min_length, + include_alpha, + include_numeric, + include_special, + min_length, + debug, + ) + def update_login_disclaimer(self, enabled: bool = False, debug: bool = False): """Update login disclaimer. System > Administration > Admin and user settings. Args: enabled (bool, optional): Enable or disable Login Disclaimer. Defaults to True. - + Returns: dict: XML response converted to Python dictionary """ @@ -1252,12 +1363,13 @@ def update_zone(self, name: str, zone_params: dict = None, debug: bool = False): dynamic_routing (str, optional): Enable/Disable dynamic routing smtp_relay (str, optional): Enable/Disable SMTP Relay snmp (str, optional): Enable/Disable SNMP - + Returns: dict: XML response converted to Python dictionary """ return Zone(self.client).update(name, zone_params, debug) + # Export the error classes for backward compatibility __all__ = [ "SophosFirewall", @@ -1266,4 +1378,4 @@ def update_zone(self, name: str, zone_params: dict = None, debug: bool = False): "SophosFirewallAuthFailure", "SophosFirewallInvalidArgument", "SophosFirewallOperatorError", -] \ No newline at end of file +] diff --git a/sophosfirewall_python/firewallrulegroup.py b/sophosfirewall_python/firewallrulegroup.py new file mode 100644 index 0000000..33cb1b4 --- /dev/null +++ b/sophosfirewall_python/firewallrulegroup.py @@ -0,0 +1,203 @@ +""" +Copyright 2023 Sophos Ltd. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing +permissions and limitations under the License. +""" +from sophosfirewall_python.api_client import SophosFirewallInvalidArgument + + +class FirewallRuleGroup: + """Class for working with firewall rule group(s).""" + + def __init__(self, api_client): + self.client = api_client + + def get(self, name, operator="="): + """Get firewall rule group(s) + + Args: + name (str, optional): Firewall Rule Group name. Returns all rule groups if not specified. + operator (str, optional): Operator for search. Default is "=". Valid operators: =, !=, like. + """ + if name: + return self.client.get_tag_with_filter( + xml_tag="FirewallRuleGroup", key="Name", value=name, operator=operator + ) + return self.client.get_tag(xml_tag="FirewallRuleGroup") + + def create( + self, + name, + description, + policy_list, + source_zones, + dest_zones, + policy_type, + debug, + ): + """Create a firewall rule group + + Args: + name(str): Name of the firewall rule group + description(str): Description for the firewall rule group + policy_list(list): List of firewall rules to add to firewall group + source_zones(list): List of source zones + dest_zones(list): List of destination zones + policy_type(str): Policy type. Valid values are User/network rule, Network rule, User rule, WAF rule, Any + + Returns: + dict: XML response converted to Python dictionary + """ + if "Any" in source_zones: + source_zones = None + if "Any" in dest_zones: + dest_zones = None + + template_vars = dict( + name=name, + description=description, + policy_list=policy_list, + source_zones=source_zones, + dest_zones=dest_zones, + policy_type=policy_type, + ) + + resp = self.client.submit_template( + "createfwrulegroup.j2", template_vars=template_vars, debug=debug + ) + return resp + + def update( + self, + name, + description, + policy_list, + source_zones, + dest_zones, + policy_type, + source_zone_action, + dest_zone_action, + debug, + ): + """Update a firewall rule group. + + Args: + name(str): Name of the firewall rule group + description(str): Description for the firewall rule group + policy_list(list): List of firewall rules to add to firewall group + source_zones(list): List of source zones + dest_zones(list): List of destination zones + policy_type(str): Policy type. Valid values are User/network rule, Network rule, User rule, WAF rule, Any + source_zone_action(str): Specify add to add a new rule to the list. Specify remove to remove a rule from the list. Specify replace to replace the list. Default=add. + dest_zone_action(str): Specify add to add a new rule to the list. Specify remove to remove a rule from the list. Specify replace to replace the list. Default=add. + Returns: + dict: XML response converted to Python dictionary + """ + + # Get the existing rule group + exist_rulegroup = self.get(name=name)["Response"]["FirewallRuleGroup"] + + updated_params = dict(name=name) + + if description: + updated_params["description"] = description + else: + updated_params["description"] = exist_rulegroup["Description"] + + if policy_list: + if isinstance(exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"], list): + updated_params["policy_list"] = ( + policy_list + exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"] + ) + elif isinstance(exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"], str): + policy_list.append(exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"]) + updated_params["policy_list"] = policy_list + else: + if isinstance(exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"], list): + updated_params["policy_list"] = exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"] + elif isinstance(exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"], str): + updated_params["policy_list"] = [exist_rulegroup["SecurityPolicyList"]["SecurityPolicy"]] + + if source_zones: + if source_zone_action == "add": + if exist_rulegroup.get("SourceZones"): + if isinstance(exist_rulegroup["SourceZones"]["Zone"], list): + updated_params["source_zones"] = ( + source_zones + exist_rulegroup["SourceZones"]["Zone"] + ) + elif isinstance(exist_rulegroup["SourceZones"]["Zone"], str): + source_zones.append(exist_rulegroup["SourceZones"]["Zone"]) + updated_params["source_zones"] = source_zones + else: + updated_params["source_zones"] = source_zones + elif source_zone_action == "remove": + for zone in source_zones: + try: + exist_rulegroup["SourceZones"]["Zone"].remove(zone) + except ValueError: + continue + updated_params["source_zones"] = exist_rulegroup["SourceZones"]["Zone"] + elif source_zone_action == "replace": + if "Any" in source_zones: + updated_params["source_zones"] = None + else: + updated_params["source_zones"] = source_zones + else: + raise SophosFirewallInvalidArgument( + "Invalid source_zone_action argument specified!" + ) + else: + if exist_rulegroup.get("SourceZones"): + if isinstance(exist_rulegroup["SourceZones"]["Zone"], list): + updated_params["source_zones"] = exist_rulegroup["SourceZones"]["Zone"] + elif isinstance(exist_rulegroup["SourceZones"]["Zone"], str): + updated_params["source_zones"] = [exist_rulegroup["SourceZones"]["Zone"]] + + if dest_zones: + if dest_zone_action == "add": + if exist_rulegroup.get("DestinationZones"): + if isinstance(exist_rulegroup["DestinationZones"]["Zone"], list): + updated_params["dest_zones"] = ( + dest_zones + exist_rulegroup["DestinationZones"]["Zone"] + ) + elif isinstance(exist_rulegroup["DestinationZones"]["Zone"], str): + dest_zones.append(exist_rulegroup["DestinationZones"]["Zone"]) + updated_params["dest_zones"] = dest_zones + else: + updated_params["dest_zones"] = dest_zones + elif dest_zone_action == "remove": + for zone in dest_zones: + try: + exist_rulegroup["DestinationZones"]["Zone"].remove(zone) + except ValueError: + continue + updated_params["dest_zones"] = exist_rulegroup["DestinationZones"]["Zone"] + elif dest_zone_action == "replace": + if "Any" in dest_zones: + updated_params["dest_zones"] = None + else: + updated_params["dest_zones"] = dest_zones + else: + raise SophosFirewallInvalidArgument( + "Invalid dest_zone_action argument specified!" + ) + else: + if exist_rulegroup.get("DestinationZones"): + if isinstance(exist_rulegroup["DestinationZones"]["Zone"], list): + updated_params["dest_zones"] = exist_rulegroup["DestinationZones"]["Zone"] + elif isinstance(exist_rulegroup["DestinationZones"]["Zone"], str): + updated_params["dest_zones"] = [exist_rulegroup["DestinationZones"]["Zone"]] + + if policy_type: + updated_params["policy_type"] = policy_type + else: + updated_params["policy_type"] = exist_rulegroup["Policytype"] + + resp = self.client.submit_template( + "updatefwrulegroup.j2", template_vars=updated_params, debug=debug + ) + + return resp diff --git a/sophosfirewall_python/templates/createfwrulegroup.j2 b/sophosfirewall_python/templates/createfwrulegroup.j2 new file mode 100644 index 0000000..73245c5 --- /dev/null +++ b/sophosfirewall_python/templates/createfwrulegroup.j2 @@ -0,0 +1,32 @@ + + + {{username}} + {{password}} + + + + {{ name }} + {{ description if description else '' }} + + {% for policy in policy_list %} + {{ policy }} + {% endfor %} + + {% if source_zones %} + + {% for zone in source_zones %} + {{ zone }} + {% endfor %} + + {% endif %} + {% if dest_zones %} + + {% for zone in dest_zones %} + {{ zone }} + {% endfor %} + + {% endif %} + {{ policy_type }} + + + \ No newline at end of file diff --git a/sophosfirewall_python/templates/updatefwrulegroup.j2 b/sophosfirewall_python/templates/updatefwrulegroup.j2 new file mode 100644 index 0000000..73788c0 --- /dev/null +++ b/sophosfirewall_python/templates/updatefwrulegroup.j2 @@ -0,0 +1,34 @@ + + + {{username}} + {{password}} + + + + {{ name }} + {{ description if description else '' }} + + {% for policy in policy_list %} + {{ policy }} + {% endfor %} + + {% if source_zones %} + + {% for zone in source_zones %} + {{ zone }} + {% endfor %} + + {% endif %} + {% if dest_zones %} + + {% for zone in dest_zones %} + {{ zone }} + {% endfor %} + + {% endif %} + {% if policy_type %} + {{ policy_type }} + {% endif %} + + + \ No newline at end of file