def _get_action_6_6(self, action): """ Get the action field for a rule. In SMC 6.6 actions have to be in list format whereas in SMC < 6.6 they were string. :param str,list action: provided action in create constructor :rtype: Action :raises CreateRuleFailed: invalid rule based on rule """ if isinstance(action, Action): rule_action = action else: rule_action = Action() if isinstance(action, str): rule_action.action = [action] else: rule_action.action = action valid_action = False if isinstance(rule_action.action, list): valid_action = all(_action in self._actions for _action in rule_action.action) else: valid_action = rule_action.action in self._actions if not valid_action: raise CreateRuleFailed("Action specified is not valid for this " "rule type; action: {}".format( rule_action.action)) return rule_action
def test_action(self): action = Action() # Defaults self.assertEqual(action.action, 'allow') self.assertEqual(action.scan_detection, 'undefined') action.action = 'discard' self.assertEqual(action.action, 'discard') action.action = 'foo' self.assertEqual(action.action, 'foo') action.deep_inspection = True action.file_filtering = False action.dos_protection = True action.scan_detection = 'on' action.vpn = 'http://1.1.1.1' action.mobile_vpn = True self.assertTrue(action.deep_inspection) self.assertFalse(action.file_filtering) self.assertTrue(action.dos_protection) self.assertEqual(action.scan_detection, 'on') self.assertEqual(action.vpn, 'http://1.1.1.1') self.assertTrue(action.mobile_vpn) self.assertIsNone(action.user_response) self.assertFalse(action.connection_tracking_options.mss_enforced) self.assertEqual(action.connection_tracking_options.timeout, -1) mini, maxi = action.connection_tracking_options.mss_enforced_min_max self.assertEqual(mini, 0) self.assertEqual(maxi, 0) action.connection_tracking_options.state = 'normal' action.connection_tracking_options.timeout = 60 action.connection_tracking_options.mss_enforced_min_max = (1400, 1450) action.connection_tracking_options.mss_enforced = True self.assertEqual(action.connection_tracking_options.state, 'normal') self.assertEqual(action.connection_tracking_options.timeout, 60) mini, maxi = action.connection_tracking_options.mss_enforced_min_max self.assertEqual(mini, 1400) self.assertEqual(maxi, 1450) self.assertTrue(action.connection_tracking_options.mss_enforced) o = action() for k, v in o.items(): self.assertEqual(k, 'action') self.assertDictEqual(v, action.data) action = Action({'foo': 'bar'}) self.assertDictEqual(action.data, {'foo': 'bar'})
def create(self, name, sources=None, destinations=None, services=None, action='allow', is_disabled=False, logical_interfaces=None): """ Create an Ethernet rule :param str name: name of rule :param list sources: list of source href's :param list destinations: list of destination href's :param list services: list of service href's :param list logical_interfaces: logical interfaces by name :param str action: \|allow\|continue\|discard\|refuse\|blacklist :param boolean is_disabled: whether to disable rule or not :raises: :py:class:`smc.api.exceptions.MissingReuqiredInput` when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises: :py:class:`smc.api.exceptions.CreateRuleFailed`: rule creation failure :return: str href: href of new rule """ rule_values = _rule_common(sources, destinations, services) rule_values.update(name=name) rule_values.update(is_disabled=is_disabled) rule_action = Action(actions=self.actions) rule_action.action = action rule_values.update(rule_action()) rule_values.update(_rule_l2_common(logical_interfaces)) return prepared_request(CreateRuleFailed, href=self.href, json=rule_values).create().href
def create(self, name, sources=None, destinations=None, services=None, action='allow', is_disabled=False, vpn_policy=None, **kwargs): """ Create a layer 3 firewall rule :param str name: name of rule :param list source: source/s for rule, in href format :param list destination: destinations, in href format :param list service: service/s, in href format :param str action: allow|continue|discard|refuse|enforce_vpn|apply_vpn|blacklist (default: allow) :param str: vpn_policy: vpn policy name; required for enforce_vpn and apply_vpn actions :raises: :py:class:`smc.api.exceptions.MissingRequiredInput` when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises: :py:class:`smc.api.exceptions.CreateRuleFailed`: rule creation failure :return: str href: href of new rule """ rule_values = _rule_common(sources, destinations, services) rule_values.update(name=name) rule_action = Action(actions=self.actions) rule_action.action = action if rule_action.action in ['apply_vpn', 'enforce_vpn', 'forward_vpn']: if vpn_policy is None: raise MissingRequiredInput('A VPN policy must be specified when ' 'rule action has a VPN action') try: vpn = VPNPolicy(vpn_policy).href rule_action.vpn = vpn except ElementNotFound: raise MissingRequiredInput('Cannot find VPN policy specified: {}, ' .format(vpn_policy)) rule_values.update(rule_action()) log_options = LogOptions() auth_options = AuthenticationOptions() rule_values.update(log_options()) rule_values.update(auth_options()) rule_values.update(is_disabled=is_disabled) return prepared_request(CreateRuleFailed, href=self.href, json=rule_values).create().href
def exec_module(self, **kwargs): state = kwargs.pop('state', 'present') for name, value in kwargs.items(): setattr(self, name, value) changed = False try: # Now that we have valid option settings, we can hit the db if self.policy: policy = FirewallPolicy.get(self.policy) else: policy = FirewallSubPolicy.get(self.sub_policy) if state == 'present': for rule in self.rules: try: validate_rule_syntax(rule) except Exception as e: self.fail(msg=str(e)) self.cache = Cache() for rule in self.rules: # Resolve elements if they exist, calls to SMC could happen here if 'sources' in rule: self.field_resolver(rule.get('sources'), rule_targets) if 'destinations' in rule: self.field_resolver(rule.get('destinations'), rule_targets) if 'services' in rule: self.field_resolver(rule.get('services'), service_targets) if 'vpn_policy' in rule: self.cache._add_entry('vpn', rule.get('vpn_policy')) if 'sub_policy' in rule: self.cache._add_entry('sub_ipv4_fw_policy', rule.get('sub_policy')) if 'authentication_options' in rule: auth = rule['authentication_options'] if auth.get('require_auth'): for method in auth.get('methods'): self.cache._add_entry('authentication_service', method) for accounts in ('users', 'groups'): self.cache._add_user_entries(accounts, auth.get(accounts, [])) if self.cache.missing: self.fail(msg='Missing required elements that are referenced in this ' 'configuration: %s' % self.cache.missing) if self.check_mode: return self.results for rule in self.rules: rule_dict = {} if 'log_options' in rule: log_options = LogOptions() _log = rule['log_options'] for name, value in log_options.items(): if name not in _log: log_options.pop(name) log_options.update(rule.get('log_options', {})) rule_dict.update(log_options=log_options) if 'connection_tracking' in rule: connection_tracking = ConnectionTracking() _ct = rule['connection_tracking'] for name, value in connection_tracking.items(): if name not in _ct: connection_tracking.pop(name) connection_tracking.update(rule.get('connection_tracking',{})) rule_dict.update(connection_tracking=connection_tracking) action = Action() # If no action, set to default based on version if 'action' not in rule: action.action = 'allow' if not is_sixdotsix_compat() else ['allow'] else: action.action = rule.get('action') if 'inspection_options' in rule: _inspection = rule['inspection_options'] for option in inspection_options: if option in _inspection: action[option] = _inspection.get(option) if 'authentication_options' in rule: _auth_options = rule['authentication_options'] auth_options = AuthenticationOptions() if _auth_options.get('require_auth'): auth_options.update(methods=[ self.get_value('authentication_service', m).href for m in _auth_options.get('methods', [])], require_auth=True) auth_options.update(users=[entry.href for entry in self.cache.get_type('user_element')]) rule_dict.update(authentication_options=auth_options) rule_dict.update(action=action) for field in ('sources', 'destinations', 'services'): rule_dict[field] = self.get_values(rule.get(field, None)) rule_dict.update( vpn_policy=self.get_value('vpn', rule.get('vpn_policy')), sub_policy=self.get_value('sub_ipv4_fw_policy', rule.get('sub_policy')), mobile_vpn=rule.get('mobile_vpn', False)) if 'comment' in rule: rule_dict.update(comment=rule.get('comment')) rule_dict.update( name=rule.get('name'), is_disabled=rule.get('is_disabled', False)) if 'tag' not in rule: # If no tag is present, this is a create rule_dict.update( before=rule.get('add_before'), after=rule.get('add_after')) rule = policy.fw_ipv4_access_rules.create(**rule_dict) changed = True self.results['state'].append({ 'rule': rule.name, 'type': rule.typeof, 'action': 'created'}) else: # Modify as rule has 'tag' defined. Fetch the rule first # by it's tag reference, skip if tag not found target_rule = self.rule_by_tag(policy, rule.get('tag')) if not target_rule: continue changes = compare_rules(target_rule, rule_dict) # Changes have already been merged if any if rule.get('add_after', None): rule_at_pos = self.rule_by_tag(policy, rule.get('add_after')) if rule_at_pos: target_rule.move_rule_after(rule_at_pos) changes.append('add_after') elif rule.get('add_before', None): rule_at_pos = self.rule_by_tag(policy, rule.get('add_before')) if rule_at_pos: target_rule.move_rule_before(rule_at_pos) changes.append('add_before') elif changes: target_rule.save() if changes: changed = True self.results['state'].append({ 'rule': target_rule.name, 'type': target_rule.typeof, 'action': 'modified', 'changes': changes}) elif state == 'absent': for rule in self.rules: if 'tag' in rule: target_rule = self.rule_by_tag(policy, rule.get('tag')) if target_rule: target_rule.delete() changed = True self.results['state'].append({ 'rule': target_rule.name, 'type': target_rule.typeof, 'action': 'deleted'}) except SMCException as err: self.fail(msg=str(err), exception=traceback.format_exc()) self.results['changed'] = changed return self.results
def create(self, name, sources=None, destinations=None, services=None, action='allow', is_disabled=False, logical_interfaces=None, add_pos=None, after=None, before=None, comment=None): """ Create an Ethernet rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param str action: \|allow\|continue\|discard\|refuse\|blacklist :param bool is_disabled: whether to disable rule or not :param list logical_interfaces: logical interfaces by name :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :raises MissingReuqiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: newly created rule :rtype: EthernetRule """ rule_values = self.update_targets(sources, destinations, services) rule_values.update(name=name, comment=comment) rule_values.update(is_disabled=is_disabled) if isinstance(action, Action): rule_action = action else: rule_action = Action() rule_action.action = action if not rule_action.action in self._actions: raise CreateRuleFailed('Action specified is not valid for this ' 'rule type; action: {}'.format( rule_action.action)) rule_values.update(action=rule_action.data) rule_values.update(self.update_logical_if(logical_interfaces)) params = None href = self.href if add_pos is not None: href = self.add_at_position(add_pos) else: params = self.add_before_after(before, after) return ElementCreator(self.__class__, exception=CreateRuleFailed, href=href, params=params, json=rule_values)
def create(self, name, sources=None, destinations=None, services=None, action='allow', log_options=None, authentication_options=None, connection_tracking=None, is_disabled=False, vpn_policy=None, mobile_vpn=False, add_pos=None, after=None, before=None, sub_policy=None, comment=None, **kw): """ Create a layer 3 firewall rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param action: allow,continue,discard,refuse,enforce_vpn, apply_vpn,forward_vpn, blacklist (default: allow) :type action: Action or str :param LogOptions log_options: LogOptions object :param ConnectionTracking connection_tracking: custom connection tracking settings :param AuthenticationOptions authentication_options: options for auth if any :param PolicyVPN,str vpn_policy: policy element or str href; required for enforce_vpn, use_vpn and apply_vpn actions :param bool mobile_vpn: if using a vpn action, you can set mobile_vpn to True and omit the vpn_policy setting if you want this VPN to apply to any mobile VPN based on the policy VPN associated with the engine :param str,Element sub_policy: sub policy required when rule has an action of 'jump'. Can be the FirewallSubPolicy element or href. :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :param str comment: optional comment for this rule :raises MissingRequiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: the created ipv4 rule :rtype: IPv4Rule """ rule_values = self.update_targets(sources, destinations, services) rule_values.update(name=name, comment=comment) if isinstance(action, Action): rule_action = action else: rule_action = Action() rule_action.action = action if not rule_action.action in self._actions: raise CreateRuleFailed('Action specified is not valid for this ' 'rule type; action: {}'.format( rule_action.action)) if rule_action.action in ('apply_vpn', 'enforce_vpn', 'forward_vpn'): if vpn_policy is None and not mobile_vpn: raise MissingRequiredInput( 'You must either specify a vpn_policy or set ' 'mobile_vpn when using a rule with a VPN action') if mobile_vpn: rule_action.mobile_vpn = True else: try: vpn = element_resolver(vpn_policy) # VPNPolicy rule_action.vpn = vpn except ElementNotFound: raise MissingRequiredInput( 'Cannot find VPN policy specified: {}, '.format( vpn_policy)) elif rule_action.action == 'jump': try: rule_action.sub_policy = element_resolver(sub_policy) except ElementNotFound: raise MissingRequiredInput( 'Cannot find sub policy specified: {} '.format(sub_policy)) #rule_values.update(action=rule_action.data) log_options = LogOptions() if not log_options else log_options if connection_tracking is not None: rule_action.connection_tracking_options.update( **connection_tracking) auth_options = AuthenticationOptions() if not authentication_options \ else authentication_options rule_values.update(action=rule_action.data, options=log_options.data, authentication_options=auth_options.data, is_disabled=is_disabled) params = None href = self.href if add_pos is not None: href = self.add_at_position(add_pos) elif before or after: params = self.add_before_after(before, after) return ElementCreator(self.__class__, exception=CreateRuleFailed, href=href, params=params, json=rule_values)
def create(self, name, sources=None, destinations=None, services=None, action='allow', log_options=None, is_disabled=False, vpn_policy=None, add_pos=None, after=None, before=None, sub_policy=None, comment=None, **kw): """ Create a layer 3 firewall rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param action: allow,continue,discard,refuse,enforce_vpn, apply_vpn,blacklist (default: allow) :type action: Action or str :param LogOptions log_options: LogOptions object :param str: vpn_policy: vpn policy name; required for enforce_vpn and apply_vpn actions :param str,Element sub_policy: sub policy required when rule has an action of 'jump'. Can be the FirewallSubPolicy element or href. :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :param str comment: optional comment for this rule :raises MissingRequiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: the created ipv4 rule :rtype: IPv4Rule """ rule_values = self.update_targets(sources, destinations, services) rule_values.update(name=name, comment=comment) if isinstance(action, Action): rule_action = action else: rule_action = Action() rule_action.action = action if not rule_action.action in self._actions: raise CreateRuleFailed('Action specified is not valid for this ' 'rule type; action: {}'.format( rule_action.action)) if rule_action.action in ['apply_vpn', 'enforce_vpn', 'forward_vpn']: if vpn_policy is None: raise MissingRequiredInput( 'A VPN policy must be specified when ' 'rule action has a VPN action') try: vpn = PolicyVPN(vpn_policy).href rule_action.vpn = vpn except ElementNotFound: raise MissingRequiredInput( 'Cannot find VPN policy specified: {}, '.format( vpn_policy)) elif rule_action.action in ['jump']: try: rule_action.sub_policy = element_resolver(sub_policy) except ElementNotFound: raise MissingRequiredInput( 'Cannot find sub policy specified: {} '.format(sub_policy)) rule_values.update(action=rule_action.data) if log_options is None: log_options = LogOptions() auth_options = AuthenticationOptions() rule_values.update(options=log_options.data) rule_values.update(authentication_options=auth_options.data) rule_values.update(is_disabled=is_disabled) params = None href = self.href if add_pos is not None: href = self.add_at_position(add_pos) elif before or after: params = self.add_before_after(before, after) return SubElementCreator(self.__class__, CreateRuleFailed, href=href, params=params, json=rule_values)
def create(self, name, sources=None, destinations=None, services=None, action='allow', is_disabled=False, logical_interfaces=None, add_pos=None, after=None, before=None, comment=None): """ Create an Ethernet rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param str action: \|allow\|continue\|discard\|refuse\|blacklist :param bool is_disabled: whether to disable rule or not :param list logical_interfaces: logical interfaces by name :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :raises MissingReuqiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: newly created rule :rtype: EthernetRule """ rule_values = self.update_targets(sources, destinations, services) rule_values.update(name=name, comment=comment) rule_values.update(is_disabled=is_disabled) if isinstance(action, Action): rule_action = action else: rule_action = Action() rule_action.action = action if not rule_action.action in self._actions: raise CreateRuleFailed('Action specified is not valid for this ' 'rule type; action: {}' .format(rule_action.action)) rule_values.update(action=rule_action.data) rule_values.update(self.update_logical_if(logical_interfaces)) params = None href = self.href if add_pos is not None: href = self.add_at_position(add_pos) else: params = self.add_before_after(before, after) return ElementCreator( self.__class__, exception=CreateRuleFailed, href=href, params=params, json=rule_values)
def create(self, name, sources=None, destinations=None, services=None, action='allow', log_options=None, authentication_options=None, connection_tracking=None, is_disabled=False, vpn_policy=None, mobile_vpn=False, add_pos=None, after=None, before=None, sub_policy=None, comment=None, **kw): """ Create a layer 3 firewall rule :param str name: name of rule :param sources: source/s for rule :type sources: list[str, Element] :param destinations: destination/s for rule :type destinations: list[str, Element] :param services: service/s for rule :type services: list[str, Element] :param action: allow,continue,discard,refuse,enforce_vpn, apply_vpn,forward_vpn, blacklist (default: allow) :type action: Action or str :param LogOptions log_options: LogOptions object :param ConnectionTracking connection_tracking: custom connection tracking settings :param AuthenticationOptions authentication_options: options for auth if any :param PolicyVPN,str vpn_policy: policy element or str href; required for enforce_vpn, use_vpn and apply_vpn actions :param bool mobile_vpn: if using a vpn action, you can set mobile_vpn to True and omit the vpn_policy setting if you want this VPN to apply to any mobile VPN based on the policy VPN associated with the engine :param str,Element sub_policy: sub policy required when rule has an action of 'jump'. Can be the FirewallSubPolicy element or href. :param int add_pos: position to insert the rule, starting with position 1. If the position value is greater than the number of rules, the rule is inserted at the bottom. If add_pos is not provided, rule is inserted in position 1. Mutually exclusive with ``after`` and ``before`` params. :param str after: Rule tag to add this rule after. Mutually exclusive with ``add_pos`` and ``before`` params. :param str before: Rule tag to add this rule before. Mutually exclusive with ``add_pos`` and ``after`` params. :param str comment: optional comment for this rule :raises MissingRequiredInput: when options are specified the need additional setting, i.e. use_vpn action requires a vpn policy be specified. :raises CreateRuleFailed: rule creation failure :return: the created ipv4 rule :rtype: IPv4Rule """ rule_values = self.update_targets(sources, destinations, services) rule_values.update(name=name, comment=comment) if isinstance(action, Action): rule_action = action else: rule_action = Action() rule_action.action = action if not rule_action.action in self._actions: raise CreateRuleFailed('Action specified is not valid for this ' 'rule type; action: {}'.format(rule_action.action)) if rule_action.action in ('apply_vpn', 'enforce_vpn', 'forward_vpn'): if vpn_policy is None and not mobile_vpn: raise MissingRequiredInput('You must either specify a vpn_policy or set ' 'mobile_vpn when using a rule with a VPN action') if mobile_vpn: rule_action.mobile_vpn = True else: try: vpn = element_resolver(vpn_policy) # VPNPolicy rule_action.vpn = vpn except ElementNotFound: raise MissingRequiredInput('Cannot find VPN policy specified: {}, ' .format(vpn_policy)) elif rule_action.action == 'jump': try: rule_action.sub_policy = element_resolver(sub_policy) except ElementNotFound: raise MissingRequiredInput('Cannot find sub policy specified: {} ' .format(sub_policy)) #rule_values.update(action=rule_action.data) log_options = LogOptions() if not log_options else log_options if connection_tracking is not None: rule_action.connection_tracking_options.update(**connection_tracking) auth_options = AuthenticationOptions() if not authentication_options \ else authentication_options rule_values.update( action=rule_action.data, options=log_options.data, authentication_options=auth_options.data, is_disabled=is_disabled) params = None href = self.href if add_pos is not None: href = self.add_at_position(add_pos) elif before or after: params = self.add_before_after(before, after) return ElementCreator( self.__class__, exception=CreateRuleFailed, href=href, params=params, json=rule_values)