def _nested_output(obj): ''' Serialize obj and format for output. ''' nested.__opts__ = __opts__ ret = nested.output(obj).rstrip() return ret
def _nested_output(obj): ''' Serialize obj and format for output ''' # Explicit late import to avoid circular import from salt.output import nested nested.__opts__ = {} ret = nested.output(obj).rstrip() return ret
def test_output_with_indent(self): # Everything must be indented by exactly two spaces # (using nested_indent=2 sent to nested.output as kwarg) expected_output_str = ( ' \x1b[0;36m----------\x1b[0;0m\n \x1b[0;36mlocal\x1b[0;0m:\n \x1b[0;36m----------\x1b[0;0m\n' ' \x1b[0;36margs\x1b[0;0m:\n \x1b[0;1;33m- 1\x1b[0;0m\n \x1b[0;32m- two\x1b[0;0m\n' ' \x1b[0;1;33m- 3.1\x1b[0;0m\n \x1b[0;36mkwargs\x1b[0;0m:\n' ' \x1b[0;36m----------\x1b[0;0m\n \x1b[0;36m__pub_fun\x1b[0;0m:\n' ' \x1b[0;32mtest.arg\x1b[0;0m\n \x1b[0;36m__pub_jid\x1b[0;0m:\n' ' \x1b[0;32m20171207105927331329\x1b[0;0m\n \x1b[0;36m__pub_pid\x1b[0;0m:\n' ' \x1b[0;1;33m25938\x1b[0;0m\n \x1b[0;36m__pub_tgt\x1b[0;0m:\n' ' \x1b[0;32msalt-call\x1b[0;0m\n \x1b[0;36mtxt\x1b[0;0m:\n' ' \x1b[0;32mhello\x1b[0;0m\n \x1b[0;36mwow\x1b[0;0m:\n' ' \x1b[0;36m----------\x1b[0;0m\n \x1b[0;36ma\x1b[0;0m:\n' ' \x1b[0;1;33m1\x1b[0;0m\n \x1b[0;36mb\x1b[0;0m:\n' ' \x1b[0;32mhello\x1b[0;0m') ret = nested.output(self.data, nested_indent=2) self.assertEqual(ret, expected_output_str)
def test_output_with_colors(self): # Should look exactly like that, with the default color scheme: # # local: # ---------- # args: # - 1 # - two # - 3.1 # kwargs: # ---------- # __pub_fun: # test.arg # __pub_jid: # 20171207105927331329 # __pub_pid: # 25938 # __pub_tgt: # salt-call # txt: # hello # wow: # ---------- # a: # 1 # b: # hello expected_output_str = ( "\x1b[0;36mlocal\x1b[0;0m:\n \x1b[0;36m----------\x1b[0;0m\n " " \x1b[0;36margs\x1b[0;0m:\n \x1b[0;1;33m- 1\x1b[0;0m\n " " \x1b[0;32m- two\x1b[0;0m\n \x1b[0;1;33m- 3.1\x1b[0;0m\n " " \x1b[0;36mkwargs\x1b[0;0m:\n \x1b[0;36m----------\x1b[0;0m\n " " \x1b[0;36m__pub_fun\x1b[0;0m:\n \x1b[0;32mtest.arg\x1b[0;0m\n" " \x1b[0;36m__pub_jid\x1b[0;0m:\n " " \x1b[0;32m20171207105927331329\x1b[0;0m\n " " \x1b[0;36m__pub_pid\x1b[0;0m:\n \x1b[0;1;33m25938\x1b[0;0m\n " " \x1b[0;36m__pub_tgt\x1b[0;0m:\n " " \x1b[0;32msalt-call\x1b[0;0m\n \x1b[0;36mtxt\x1b[0;0m:\n " " \x1b[0;32mhello\x1b[0;0m\n \x1b[0;36mwow\x1b[0;0m:\n " " \x1b[0;36m----------\x1b[0;0m\n \x1b[0;36ma\x1b[0;0m:\n " " \x1b[0;1;33m1\x1b[0;0m\n \x1b[0;36mb\x1b[0;0m:\n " " \x1b[0;32mhello\x1b[0;0m") ret = nested.output(self.data) self.assertEqual(ret, expected_output_str)
def test_output_with_retcode(self): # Non-zero retcode should change the colors # Same output format as above, just different colors expected_output_str = ( '\x1b[0;31mlocal\x1b[0;0m:\n \x1b[0;31m----------\x1b[0;0m\n \x1b[0;31margs\x1b[0;0m:\n' ' \x1b[0;1;33m- 1\x1b[0;0m\n \x1b[0;32m- two\x1b[0;0m\n \x1b[0;1;33m- 3.1\x1b[0;0m\n' ' \x1b[0;31mkwargs\x1b[0;0m:\n \x1b[0;31m----------\x1b[0;0m\n' ' \x1b[0;31m__pub_fun\x1b[0;0m:\n \x1b[0;32mtest.arg\x1b[0;0m\n' ' \x1b[0;31m__pub_jid\x1b[0;0m:\n \x1b[0;32m20171207105927331329\x1b[0;0m\n' ' \x1b[0;31m__pub_pid\x1b[0;0m:\n \x1b[0;1;33m25938\x1b[0;0m\n' ' \x1b[0;31m__pub_tgt\x1b[0;0m:\n \x1b[0;32msalt-call\x1b[0;0m\n' ' \x1b[0;31mtxt\x1b[0;0m:\n \x1b[0;32mhello\x1b[0;0m\n \x1b[0;31mwow\x1b[0;0m:\n' ' \x1b[0;31m----------\x1b[0;0m\n \x1b[0;31ma\x1b[0;0m:\n' ' \x1b[0;1;33m1\x1b[0;0m\n \x1b[0;31mb\x1b[0;0m:\n' ' \x1b[0;32mhello\x1b[0;0m') # You can notice that in test_output_with_colors the color code is \x1b[0;36m, i.e., GREEN, # while here the color code is \x1b[0;31m, i.e., RED (failure) ret = nested.output(self.data, _retcode=1) self.assertEqual(ret, expected_output_str)
def _present(name, block_icmp=None, prune_block_icmp=False, default=None, masquerade=False, ports=None, prune_ports=False, port_fwd=None, prune_port_fwd=False, services=None, # TODO: prune_services=False in future release # prune_services=False, prune_services=None, interfaces=None, prune_interfaces=False, sources=None, prune_sources=False, rich_rules=None, prune_rich_rules=False): ''' Ensure a zone has specific attributes. ''' ret = {'name': name, 'result': False, 'changes': {}, 'comment': ''} try: zones = __salt__['firewalld.get_zones'](permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if name not in zones: if not __opts__['test']: try: __salt__['firewalld.new_zone'](name) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret ret['changes'].update({name: {'old': zones, 'new': name}}) if block_icmp or prune_block_icmp: block_icmp = block_icmp or [] new_icmp_types = [] old_icmp_types = [] try: _current_icmp_blocks = __salt__['firewalld.list_icmp_block'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if block_icmp: try: _valid_icmp_types = __salt__['firewalld.get_icmp_types']( permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret # log errors for invalid ICMP types in block_icmp input for icmp_type in set(block_icmp) - set(_valid_icmp_types): log.error('%s is an invalid ICMP type', icmp_type) block_icmp.remove(icmp_type) new_icmp_types = set(block_icmp) - set(_current_icmp_blocks) for icmp_type in new_icmp_types: if not __opts__['test']: try: __salt__['firewalld.block_icmp'](name, icmp_type, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_block_icmp: old_icmp_types = set(_current_icmp_blocks) - set(block_icmp) for icmp_type in old_icmp_types: # no need to check against _valid_icmp_types here, because all # elements in old_icmp_types are guaranteed to be in # _current_icmp_blocks, whose elements are inherently valid if not __opts__['test']: try: __salt__['firewalld.allow_icmp'](name, icmp_type, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_icmp_types or old_icmp_types: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_block_icmp: block_icmp = list(new_icmp_types | set(_current_icmp_blocks)) ret['changes'].update({'icmp_types': {'old': _current_icmp_blocks, 'new': block_icmp}}) # that's the only parameter that can't be permanent or runtime, it's # directly both if default: try: default_zone = __salt__['firewalld.default_zone']() except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if name != default_zone: if not __opts__['test']: try: __salt__['firewalld.set_default_zone'](name) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret ret['changes'].update({'default': {'old': default_zone, 'new': name}}) try: masquerade_ret = __salt__['firewalld.get_masquerade'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if masquerade and not masquerade_ret: if not __opts__['test']: try: __salt__['firewalld.add_masquerade'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret ret['changes'].update({'masquerade': {'old': '', 'new': 'Masquerading successfully set.'}}) elif not masquerade and masquerade_ret: if not __opts__['test']: try: __salt__['firewalld.remove_masquerade'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret ret['changes'].update({'masquerade': {'old': '', 'new': 'Masquerading successfully ' 'disabled.'}}) if ports or prune_ports: ports = ports or [] try: _current_ports = __salt__['firewalld.list_ports'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret new_ports = set(ports) - set(_current_ports) old_ports = [] for port in new_ports: if not __opts__['test']: try: __salt__['firewalld.add_port'](name, port, permanent=True, force_masquerade=False) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_ports: old_ports = set(_current_ports) - set(ports) for port in old_ports: if not __opts__['test']: try: __salt__['firewalld.remove_port'](name, port, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_ports or old_ports: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_ports: ports = list(new_ports | set(_current_ports)) ret['changes'].update({'ports': {'old': _current_ports, 'new': ports}}) if port_fwd or prune_port_fwd: port_fwd = port_fwd or [] try: _current_port_fwd = __salt__['firewalld.list_port_fwd'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret port_fwd = [_parse_forward(fwd) for fwd in port_fwd] _current_port_fwd = [ ForwardingMapping( srcport=fwd['Source port'], destport=fwd['Destination port'], protocol=fwd['Protocol'], destaddr=fwd['Destination address'] ) for fwd in _current_port_fwd] new_port_fwd = set(port_fwd) - set(_current_port_fwd) old_port_fwd = [] for fwd in new_port_fwd: if not __opts__['test']: try: __salt__['firewalld.add_port_fwd'](name, fwd.srcport, fwd.destport, fwd.protocol, fwd.destaddr, permanent=True, force_masquerade=False) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_port_fwd: old_port_fwd = set(_current_port_fwd) - set(port_fwd) for fwd in old_port_fwd: if not __opts__['test']: try: __salt__['firewalld.remove_port_fwd'](name, fwd.srcport, fwd.destport, fwd.protocol, fwd.destaddr, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_port_fwd or old_port_fwd: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_port_fwd: port_fwd = list(new_port_fwd | set(_current_port_fwd)) ret['changes'].update({'port_fwd': {'old': [fwd.todict() for fwd in _current_port_fwd], 'new': [fwd.todict() for fwd in port_fwd]}}) if services or prune_services: services = services or [] try: _current_services = __salt__['firewalld.list_services'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret new_services = set(services) - set(_current_services) old_services = [] for new_service in new_services: if not __opts__['test']: try: __salt__['firewalld.add_service'](new_service, name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_services: old_services = set(_current_services) - set(services) for old_service in old_services: if not __opts__['test']: try: __salt__['firewalld.remove_service'](old_service, name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_services or old_services: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_services: services = list(new_services | set(_current_services)) ret['changes'].update({'services': {'old': _current_services, 'new': services}}) if interfaces or prune_interfaces: interfaces = interfaces or [] try: _current_interfaces = __salt__['firewalld.get_interfaces'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret new_interfaces = set(interfaces) - set(_current_interfaces) old_interfaces = [] for interface in new_interfaces: if not __opts__['test']: try: __salt__['firewalld.change_interface'](name, interface, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_interfaces: old_interfaces = set(_current_interfaces) - set(interfaces) for interface in old_interfaces: if not __opts__['test']: try: __salt__['firewalld.remove_interface'](name, interface, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_interfaces or old_interfaces: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_interfaces: interfaces = list(new_interfaces | set(_current_interfaces)) ret['changes'].update({'interfaces': {'old': _current_interfaces, 'new': interfaces}}) if sources or prune_sources: sources = sources or [] try: _current_sources = __salt__['firewalld.get_sources'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret new_sources = set(sources) - set(_current_sources) old_sources = [] for source in new_sources: if not __opts__['test']: try: __salt__['firewalld.add_source'](name, source, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_sources: old_sources = set(_current_sources) - set(sources) for source in old_sources: if not __opts__['test']: try: __salt__['firewalld.remove_source'](name, source, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_sources or old_sources: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_sources: sources = list(new_sources | set(_current_sources)) ret['changes'].update({'sources': {'old': _current_sources, 'new': sources}}) if rich_rules or prune_rich_rules: rich_rules = rich_rules or [] try: _current_rich_rules = __salt__['firewalld.get_rich_rules'](name, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret new_rich_rules = set(rich_rules) - set(_current_rich_rules) old_rich_rules = [] for rich_rule in new_rich_rules: if not __opts__['test']: try: __salt__['firewalld.add_rich_rule'](name, rich_rule, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if prune_rich_rules: old_rich_rules = set(_current_rich_rules) - set(rich_rules) for rich_rule in old_rich_rules: if not __opts__['test']: try: __salt__['firewalld.remove_rich_rule'](name, rich_rule, permanent=True) except CommandExecutionError as err: ret['comment'] = 'Error: {0}'.format(err) return ret if new_rich_rules or old_rich_rules: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_rich_rules: rich_rules = list(new_rich_rules | set(_current_rich_rules)) ret['changes'].update({'rich_rules': {'old': _current_rich_rules, 'new': rich_rules}}) # No changes if ret['changes'] == {}: ret['result'] = True ret['comment'] = '\'{0}\' is already in the desired state.'.format(name) return ret # test=True and changes predicted if __opts__['test']: ret['result'] = None # build comment string nested.__opts__ = __opts__ comment = [] comment.append('Configuration for \'{0}\' will change:'.format(name)) comment.append(nested.output(ret['changes']).rstrip()) ret['comment'] = '\n'.join(comment) ret['changes'] = {} return ret # Changes were made successfully ret['result'] = True ret['comment'] = '\'{0}\' was configured.'.format(name) return ret
def _present( name, block_icmp=None, prune_block_icmp=False, default=None, masquerade=False, ports=None, prune_ports=False, port_fwd=None, prune_port_fwd=False, services=None, # TODO: prune_services=False in future release # prune_services=False, prune_services=None, interfaces=None, prune_interfaces=False, sources=None, prune_sources=False, rich_rules=None, prune_rich_rules=False, ): """ Ensure a zone has specific attributes. """ ret = {"name": name, "result": False, "changes": {}, "comment": ""} try: zones = __salt__["firewalld.get_zones"](permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if name not in zones: if not __opts__["test"]: try: __salt__["firewalld.new_zone"](name) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret ret["changes"].update({name: {"old": zones, "new": name}}) if block_icmp or prune_block_icmp: block_icmp = block_icmp or [] new_icmp_types = [] old_icmp_types = [] try: _current_icmp_blocks = __salt__["firewalld.list_icmp_block"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if block_icmp: try: _valid_icmp_types = __salt__["firewalld.get_icmp_types"]( permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret # log errors for invalid ICMP types in block_icmp input for icmp_type in set(block_icmp) - set(_valid_icmp_types): log.error("%s is an invalid ICMP type", icmp_type) block_icmp.remove(icmp_type) new_icmp_types = set(block_icmp) - set(_current_icmp_blocks) for icmp_type in new_icmp_types: if not __opts__["test"]: try: __salt__["firewalld.block_icmp"](name, icmp_type, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_block_icmp: old_icmp_types = set(_current_icmp_blocks) - set(block_icmp) for icmp_type in old_icmp_types: # no need to check against _valid_icmp_types here, because all # elements in old_icmp_types are guaranteed to be in # _current_icmp_blocks, whose elements are inherently valid if not __opts__["test"]: try: __salt__["firewalld.allow_icmp"](name, icmp_type, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_icmp_types or old_icmp_types: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_block_icmp: block_icmp = list(new_icmp_types | set(_current_icmp_blocks)) ret["changes"].update({ "icmp_types": { "old": _current_icmp_blocks, "new": block_icmp } }) # that's the only parameter that can't be permanent or runtime, it's # directly both if default: try: default_zone = __salt__["firewalld.default_zone"]() except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if name != default_zone: if not __opts__["test"]: try: __salt__["firewalld.set_default_zone"](name) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret ret["changes"].update( {"default": { "old": default_zone, "new": name }}) try: masquerade_ret = __salt__["firewalld.get_masquerade"](name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if masquerade and not masquerade_ret: if not __opts__["test"]: try: __salt__["firewalld.add_masquerade"](name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret ret["changes"].update({ "masquerade": { "old": "", "new": "Masquerading successfully set." } }) elif not masquerade and masquerade_ret: if not __opts__["test"]: try: __salt__["firewalld.remove_masquerade"](name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret ret["changes"].update({ "masquerade": { "old": "", "new": "Masquerading successfully " "disabled." } }) if ports or prune_ports: ports = ports or [] try: _current_ports = __salt__["firewalld.list_ports"](name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret new_ports = set(ports) - set(_current_ports) old_ports = [] for port in new_ports: if not __opts__["test"]: try: __salt__["firewalld.add_port"](name, port, permanent=True, force_masquerade=False) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_ports: old_ports = set(_current_ports) - set(ports) for port in old_ports: if not __opts__["test"]: try: __salt__["firewalld.remove_port"](name, port, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_ports or old_ports: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_ports: ports = list(new_ports | set(_current_ports)) ret["changes"].update( {"ports": { "old": _current_ports, "new": ports }}) if port_fwd or prune_port_fwd: port_fwd = port_fwd or [] try: _current_port_fwd = __salt__["firewalld.list_port_fwd"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret port_fwd = [_parse_forward(fwd) for fwd in port_fwd] _current_port_fwd = [ ForwardingMapping( srcport=fwd["Source port"], destport=fwd["Destination port"], protocol=fwd["Protocol"], destaddr=fwd["Destination address"], ) for fwd in _current_port_fwd ] new_port_fwd = set(port_fwd) - set(_current_port_fwd) old_port_fwd = [] for fwd in new_port_fwd: if not __opts__["test"]: try: __salt__["firewalld.add_port_fwd"]( name, fwd.srcport, fwd.destport, fwd.protocol, fwd.destaddr, permanent=True, force_masquerade=False, ) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_port_fwd: old_port_fwd = set(_current_port_fwd) - set(port_fwd) for fwd in old_port_fwd: if not __opts__["test"]: try: __salt__["firewalld.remove_port_fwd"]( name, fwd.srcport, fwd.destport, fwd.protocol, fwd.destaddr, permanent=True, ) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_port_fwd or old_port_fwd: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_port_fwd: port_fwd = list(new_port_fwd | set(_current_port_fwd)) ret["changes"].update({ "port_fwd": { "old": [fwd.todict() for fwd in _current_port_fwd], "new": [fwd.todict() for fwd in port_fwd], } }) if services or prune_services: services = services or [] try: _current_services = __salt__["firewalld.list_services"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret new_services = set(services) - set(_current_services) old_services = [] for new_service in new_services: if not __opts__["test"]: try: __salt__["firewalld.add_service"](new_service, name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_services: old_services = set(_current_services) - set(services) for old_service in old_services: if not __opts__["test"]: try: __salt__["firewalld.remove_service"](old_service, name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_services or old_services: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_services: services = list(new_services | set(_current_services)) ret["changes"].update( {"services": { "old": _current_services, "new": services }}) if interfaces or prune_interfaces: interfaces = interfaces or [] try: _current_interfaces = __salt__["firewalld.get_interfaces"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret new_interfaces = set(interfaces) - set(_current_interfaces) old_interfaces = [] for interface in new_interfaces: if not __opts__["test"]: try: __salt__["firewalld.add_interface"](name, interface, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_interfaces: old_interfaces = set(_current_interfaces) - set(interfaces) for interface in old_interfaces: if not __opts__["test"]: try: __salt__["firewalld.remove_interface"](name, interface, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_interfaces or old_interfaces: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_interfaces: interfaces = list(new_interfaces | set(_current_interfaces)) ret["changes"].update({ "interfaces": { "old": _current_interfaces, "new": interfaces } }) if sources or prune_sources: sources = sources or [] try: _current_sources = __salt__["firewalld.get_sources"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret new_sources = set(sources) - set(_current_sources) old_sources = [] for source in new_sources: if not __opts__["test"]: try: __salt__["firewalld.add_source"](name, source, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_sources: old_sources = set(_current_sources) - set(sources) for source in old_sources: if not __opts__["test"]: try: __salt__["firewalld.remove_source"](name, source, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_sources or old_sources: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_sources: sources = list(new_sources | set(_current_sources)) ret["changes"].update( {"sources": { "old": _current_sources, "new": sources }}) if rich_rules or prune_rich_rules: rich_rules = rich_rules or [] try: _current_rich_rules = __salt__["firewalld.get_rich_rules"]( name, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret new_rich_rules = set(rich_rules) - set(_current_rich_rules) old_rich_rules = [] for rich_rule in new_rich_rules: if not __opts__["test"]: try: __salt__["firewalld.add_rich_rule"](name, rich_rule, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if prune_rich_rules: old_rich_rules = set(_current_rich_rules) - set(rich_rules) for rich_rule in old_rich_rules: if not __opts__["test"]: try: __salt__["firewalld.remove_rich_rule"](name, rich_rule, permanent=True) except CommandExecutionError as err: ret["comment"] = "Error: {}".format(err) return ret if new_rich_rules or old_rich_rules: # If we're not pruning, include current items in new output so it's clear # that they're still present if not prune_rich_rules: rich_rules = list(new_rich_rules | set(_current_rich_rules)) ret["changes"].update({ "rich_rules": { "old": _current_rich_rules, "new": rich_rules } }) # No changes if ret["changes"] == {}: ret["result"] = True ret["comment"] = "'{}' is already in the desired state.".format(name) return ret # test=True and changes predicted if __opts__["test"]: ret["result"] = None # build comment string nested.__opts__ = __opts__ comment = [] comment.append("Configuration for '{}' will change:".format(name)) comment.append(nested.output(ret["changes"]).rstrip()) ret["comment"] = "\n".join(comment) ret["changes"] = {} return ret # Changes were made successfully ret["result"] = True ret["comment"] = "'{}' was configured.".format(name) return ret