def test_01_setup(self, dev, state_map): state = state_map.setdefault(dev) state.err = True state.fail_func = pytest.skip state.parent = dev state.tmpl = None state.name = None state.obj = None state.targets = [testlib.random_name() for x in range(2)] if self.FUNC is None: pytest.skip('{0}.FUNC must be defined'.format( self.__class__.__name__)) elif self.CLASS is None: pytest.skip('{0}.CLASS must be defined'.format( self.__class__.__name__)) elif self.PARAM is None: pytest.skip('{0}.PARAM must be defined'.format( self.__class__.__name__)) if isinstance(state.parent, Panorama): tmpl = Template(testlib.random_name()) state.parent.add(tmpl) v = Vsys('vsys2') tmpl.add(v) state.parent = v tmpl.create() state.tmpl = tmpl else: vsys_list = [ x.name for x in Vsys.refreshall(dev, add=False, name_only=True) ] if 'vsys2' not in vsys_list: pytest.skip('Firewall needs vsys2 to exist') cls_args = {} eth_args = {'mode': 'layer3'} if self.CLASS == Vlan: eth_args['mode'] = 'layer2' elif self.CLASS == Zone: cls_args['mode'] = 'layer3' state.name = testlib.get_available_interfaces(state.parent)[0] state.obj = EthernetInterface(state.name, **eth_args) state.parent.add(state.obj) if state.tmpl is None: dev.vsys = 'vsys2' instances = [ self.CLASS(state.targets[x], **cls_args) for x in range(2) ] for x in instances: state.parent.add(x) x.create() state.err = False
def main(): helper = get_connection( vsys_importable=True, template=True, with_classic_provider_spec=True, with_state=True, min_pandevice_version=(0, 8, 0), argument_spec=dict( name=dict(required=True), tag=dict(required=True, type='int'), ip=dict(type='list'), ipv6_enabled=dict(type='bool'), management_profile=dict(), mtu=dict(type='int'), adjust_tcp_mss=dict(type='bool'), netflow_profile=dict(), comment=dict(), ipv4_mss_adjust=dict(type='int'), ipv6_mss_adjust=dict(type='int'), enable_dhcp=dict(type='bool', default=True), create_default_route=dict(type='bool', default=False), dhcp_default_route_metric=dict(type='int'), zone_name=dict(), vr_name=dict(default='default'), ), ) module = AnsibleModule( argument_spec=helper.argument_spec, supports_check_mode=True, required_one_of=helper.required_one_of, ) # Verify libs are present, get the parent object. parent = helper.get_pandevice_parent(module) # Get the object params. spec = { 'name': module.params['name'], 'tag': module.params['tag'], 'ip': module.params['ip'], 'ipv6_enabled': module.params['ipv6_enabled'], 'management_profile': module.params['management_profile'], 'mtu': module.params['mtu'], 'adjust_tcp_mss': module.params['adjust_tcp_mss'], 'netflow_profile': module.params['netflow_profile'], 'comment': module.params['comment'], 'ipv4_mss_adjust': module.params['ipv4_mss_adjust'], 'ipv6_mss_adjust': module.params['ipv6_mss_adjust'], 'enable_dhcp': True if module.params['enable_dhcp'] else None, # 'create_dhcp_default_route': set below 'dhcp_default_route_metric': module.params['dhcp_default_route_metric'], } if module.params['create_default_route']: spec['create_dhcp_default_route'] = True elif spec['enable_dhcp']: spec['create_dhcp_default_route'] = False else: spec['create_dhcp_default_route'] = None # Get other info. state = module.params['state'] zone_name = module.params['zone_name'] vr_name = module.params['vr_name'] vsys = module.params['vsys'] # Sanity check. if '.' not in spec['name']: module.fail_json(msg='Interface name does not have "." in it') # check on EthernetInterface or AggregateInterface parent_iname = spec['name'].split('.')[0] # Retrieve the current config. if parent_iname.startswith('ae'): parent_eth = AggregateInterface(parent_iname) else: parent_eth = EthernetInterface(parent_iname) parent.add(parent_eth) try: parent_eth.refresh() except PanDeviceError as e: module.fail_json(msg='Failed refresh: {0}'.format(e)) if parent_eth.mode != 'layer3': module.fail_json(msg='{0} mode is {1}, not layer3'.format(parent_eth.name, parent_eth.mode)) interfaces = parent_eth.findall(Layer3Subinterface) # Build the object based on the user spec. eth = Layer3Subinterface(**spec) parent_eth.add(eth) # Which action should we take on the interface? changed = False reference_params = { 'refresh': True, 'update': not module.check_mode, 'return_type': 'bool', } if state == 'present': for item in interfaces: if item.name != eth.name: continue # Interfaces have children, so don't compare them. if not item.equal(eth, compare_children=False): changed = True eth.extend(item.children) if not module.check_mode: try: eth.apply() except PanDeviceError as e: module.fail_json(msg='Failed apply: {0}'.format(e)) break else: changed = True if not module.check_mode: try: eth.create() except PanDeviceError as e: module.fail_json(msg='Failed create: {0}'.format(e)) # Set references. try: changed |= eth.set_vsys(vsys, **reference_params) changed |= eth.set_zone(zone_name, mode=parent_eth.mode, **reference_params) changed |= eth.set_virtual_router(vr_name, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) elif state == 'absent': # Remove references. try: changed |= eth.set_virtual_router(None, **reference_params) changed |= eth.set_zone(None, mode=parent_eth.mode, **reference_params) changed |= eth.set_vsys(None, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) # Remove the interface. if eth.name in [x.name for x in interfaces]: changed = True if not module.check_mode: try: eth.delete() except PanDeviceError as e: module.fail_json(msg='Failed delete: {0}'.format(e)) # Done! module.exit_json(changed=changed, msg='Done')
def main(): helper = get_connection( vsys_importable=True, template=True, with_classic_provider_spec=True, with_state=True, min_pandevice_version=(0, 8, 0), argument_spec=dict( if_name=dict(required=True), mode=dict( default='layer3', choices=[ 'layer3', 'layer2', 'virtual-wire', 'tap', 'ha', 'decrypt-mirror', 'aggregate-group', ], ), ip=dict(type='list'), ipv6_enabled=dict(type='bool'), management_profile=dict(), mtu=dict(type='int'), adjust_tcp_mss=dict(type='bool'), netflow_profile=dict(), lldp_enabled=dict(), lldp_profile=dict(), netflow_profile_l2=dict(), link_speed=dict(choices=['auto', '10', '100', '1000']), link_duplex=dict(choices=['auto', 'full', 'half']), link_state=dict(choices=['auto', 'up', 'down']), aggregate_group=dict(), comment=dict(), ipv4_mss_adjust=dict(type='int'), ipv6_mss_adjust=dict(type='int'), enable_dhcp=dict(type='bool', default=True), create_default_route=dict(type='bool', default=False), dhcp_default_route_metric=dict(type='int'), zone_name=dict(), vr_name=dict(default='default'), vlan_name=dict(), commit=dict(type='bool', default=True), # TODO(gfreeman) - remove this in 2.12. vsys_dg=dict(), # TODO(gfreeman) - remove in the next release. operation=dict(), ), ) module = AnsibleModule( argument_spec=helper.argument_spec, supports_check_mode=True, required_one_of=helper.required_one_of, ) # TODO(gfreeman) - remove in the next release. if module.params['operation'] is not None: module.fail_json(msg='Operation has been removed; use "state"') # Get the object params. spec = { 'name': module.params['if_name'], 'mode': module.params['mode'], 'ip': module.params['ip'], 'ipv6_enabled': module.params['ipv6_enabled'], 'management_profile': module.params['management_profile'], 'mtu': module.params['mtu'], 'adjust_tcp_mss': module.params['adjust_tcp_mss'], 'netflow_profile': module.params['netflow_profile'], 'lldp_enabled': module.params['lldp_enabled'], 'lldp_profile': module.params['lldp_profile'], 'netflow_profile_l2': module.params['netflow_profile_l2'], 'link_speed': module.params['link_speed'], 'link_duplex': module.params['link_duplex'], 'link_state': module.params['link_state'], 'aggregate_group': module.params['aggregate_group'], 'comment': module.params['comment'], 'ipv4_mss_adjust': module.params['ipv4_mss_adjust'], 'ipv6_mss_adjust': module.params['ipv6_mss_adjust'], 'enable_dhcp': True if module.params['enable_dhcp'] else None, 'create_dhcp_default_route': True if module.params['create_default_route'] else None, 'dhcp_default_route_metric': module.params['dhcp_default_route_metric'], } # Get other info. state = module.params['state'] zone_name = module.params['zone_name'] vlan_name = module.params['vlan_name'] vr_name = module.params['vr_name'] if module.params['vr_name'] else None vsys = module.params['vsys'] vsys_dg = module.params['vsys_dg'] # TODO(gfreeman) - Remove vsys_dg in 2.12, as well as this code chunk. # In the mean time, we'll need to do this special handling. if vsys_dg is not None: module.deprecate('Param "vsys_dg" is deprecated, use "vsys"', '2.12') if vsys is None: vsys = vsys_dg else: msg = [ 'Params "vsys" and "vsys_dg" both given', 'Specify one or the other, not both.', ] module.fail_json(msg='. '.join(msg)) elif vsys is None: # TODO(gfreeman) - v2.12, just set the default for vsys to 'vsys1'. vsys = 'vsys1' module.params['vsys'] = vsys # Verify libs are present, get the parent object. parent = helper.get_pandevice_parent(module) # Retrieve the current config. try: interfaces = EthernetInterface.refreshall(parent, add=False, matching_vsys=False) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Build the object based on the user spec. eth = EthernetInterface(**spec) parent.add(eth) # Which action should we take on the interface? changed = False reference_params = { 'refresh': True, 'update': not module.check_mode, 'return_type': 'bool', } if state == 'present': for item in interfaces: if item.name != eth.name: continue # Interfaces have children, so don't compare them. if not item.equal(eth, compare_children=False): changed = True eth.extend(item.children) if not module.check_mode: try: eth.apply() except PanDeviceError as e: module.fail_json(msg='Failed apply: {0}'.format(e)) break else: changed = True if not module.check_mode: try: eth.create() except PanDeviceError as e: module.fail_json(msg='Failed create: {0}'.format(e)) # Set references. try: changed |= eth.set_vsys(vsys, **reference_params) changed |= eth.set_zone(zone_name, mode=eth.mode, **reference_params) changed |= eth.set_vlan(vlan_name, **reference_params) changed |= eth.set_virtual_router(vr_name, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) elif state == 'absent': # Remove references. try: changed |= eth.set_virtual_router(None, **reference_params) changed |= eth.set_vlan(None, **reference_params) changed |= eth.set_zone(None, mode=eth.mode, **reference_params) changed |= eth.set_vsys(None, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) # Remove the interface. if eth.name in [x.name for x in interfaces]: changed = True if not module.check_mode: try: eth.delete() except PanDeviceError as e: module.fail_json(msg='Failed delete: {0}'.format(e)) # Commit if we were asked to do so. if changed and module.params['commit']: helper.commit(module) # Done! module.exit_json(changed=changed, msg='Done')
def main(): argument_spec = dict( ip_address=dict(required=True), password=dict(no_log=True), username=dict(default='admin'), api_key=dict(no_log=True), operation=dict(default='add', choices=['add', 'update', 'delete']), state=dict(choices=['present', 'absent']), if_name=dict(required=True), mode=dict(default='layer3', choices=[ 'layer3', 'layer2', 'virtual-wire', 'tap', 'ha', 'decrypt-mirror', 'aggregate-group' ]), ip=dict(type='list'), ipv6_enabled=dict(), management_profile=dict(), mtu=dict(), adjust_tcp_mss=dict(), netflow_profile=dict(), lldp_enabled=dict(), lldp_profile=dict(), netflow_profile_l2=dict(), link_speed=dict(), link_duplex=dict(), link_state=dict(), aggregate_group=dict(), comment=dict(), ipv4_mss_adjust=dict(), ipv6_mss_adjust=dict(), enable_dhcp=dict(type='bool', default=True), create_default_route=dict(type='bool', default=False), dhcp_default_route_metric=dict(), zone_name=dict(required=True), vr_name=dict(default='default'), vsys_dg=dict(default='vsys1'), commit=dict(type='bool', default=True), ) module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=False, required_one_of=[['api_key', 'password']]) if not HAS_LIB: module.fail_json(msg='Missing required libraries.') # Get the firewall / panorama auth. auth = [ module.params[x] for x in ('ip_address', 'username', 'password', 'api_key') ] # Get the object params. spec = { 'name': module.params['if_name'], 'mode': module.params['mode'], 'ip': module.params['ip'], 'ipv6_enabled': module.params['ipv6_enabled'], 'management_profile': module.params['management_profile'], 'mtu': module.params['mtu'], 'adjust_tcp_mss': module.params['adjust_tcp_mss'], 'netflow_profile': module.params['netflow_profile'], 'lldp_enabled': module.params['lldp_enabled'], 'lldp_profile': module.params['lldp_profile'], 'netflow_profile_l2': module.params['netflow_profile_l2'], 'link_speed': module.params['link_speed'], 'link_duplex': module.params['link_duplex'], 'link_state': module.params['link_state'], 'aggregate_group': module.params['aggregate_group'], 'comment': module.params['comment'], 'ipv4_mss_adjust': module.params['ipv4_mss_adjust'], 'ipv6_mss_adjust': module.params['ipv6_mss_adjust'], 'enable_dhcp': module.params['enable_dhcp'] or False, 'create_dhcp_default_route': module.params['create_default_route'] or False, 'dhcp_default_route_metric': module.params['dhcp_default_route_metric'], } # Get other info. operation = module.params['operation'] state = module.params['state'] zone_name = module.params['zone_name'] vr_name = module.params['vr_name'] vsys_dg = module.params['vsys_dg'] commit = module.params['commit'] # Open the connection to the PANOS device. con = PanDevice.create_from_device(*auth) # Set vsys if firewall, device group if panorama. if hasattr(con, 'refresh_devices'): # Panorama # Normally we want to set the device group here, but there are no # interfaces on Panorama. So if we're given a Panorama device, then # error out. ''' groups = panorama.DeviceGroup.refreshall(con, add=False) for parent in groups: if parent.name == vsys_dg: con.add(parent) break else: module.fail_json(msg="'{0}' device group is not present".format(vsys_dg)) ''' module.fail_json(msg="Ethernet interfaces don't exist on Panorama") else: # Firewall # Normally we should set the vsys here, but since interfaces are # vsys importables, we'll use organize_into_vsys() to help find and # cleanup when the interface is imported into an undesired vsys. # con.vsys = vsys_dg pass # Retrieve the current config. try: interfaces = EthernetInterface.refreshall(con, add=False, name_only=True) zones = Zone.refreshall(con) routers = VirtualRouter.refreshall(con) vsys_list = Vsys.refreshall(con) except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Build the object based on the user spec. eth = EthernetInterface(**spec) con.add(eth) # Which action should we take on the interface? changed = False if state == 'present': if eth.name in [x.name for x in interfaces]: i = EthernetInterface(eth.name) con.add(i) try: i.refresh() except PanDeviceError as e: module.fail_json(msg='Failed "present" refresh: {0}'.format(e)) if not i.equal(eth, compare_children=False): eth.extend(i.children) try: eth.apply() changed = True except PanDeviceError as e: module.fail_json( msg='Failed "present" apply: {0}'.format(e)) else: try: eth.create() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "present" create: {0}'.format(e)) try: changed |= set_zone(con, eth, zone_name, zones) changed |= set_virtual_router(con, eth, vr_name, routers) except PanDeviceError as e: module.fail_json(msg='Failed zone/vr assignment: {0}'.format(e)) elif state == 'absent': try: changed |= set_zone(con, eth, None, zones) changed |= set_virtual_router(con, eth, None, routers) except PanDeviceError as e: module.fail_json( msg='Failed "absent" zone/vr cleanup: {0}'.format(e)) changed = True if eth.name in [x.name for x in interfaces]: try: eth.delete() changed = True except PanDeviceError as e: module.fail_json(msg='Failed "absent" delete: {0}'.format(e)) elif operation == 'delete': if eth.name not in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} does not exist, and thus cannot be deleted'. format(eth.name)) try: con.organize_into_vsys() set_zone(con, eth, None, zones) set_virtual_router(con, eth, None, routers) eth.delete() changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'add': if eth.name in [x.name for x in interfaces]: module.fail_json( msg='Interface {0} is already present; use operation "update"'. format(eth.name)) con.vsys = vsys_dg # Create the interface. try: eth.create() set_zone(con, eth, zone_name, zones) set_virtual_router(con, eth, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) elif operation == 'update': if eth.name not in [x.name for x in interfaces]: module.fail_json( msg= 'Interface {0} is not present; use operation "add" to create it' .format(eth.name)) # If the interface is in the wrong vsys, remove it from the old vsys. try: con.organize_into_vsys() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) if eth.vsys != vsys_dg: try: eth.delete_import() except PanDeviceError: e = get_exception() module.fail_json(msg=e.message) # Move the ethernet object to the correct vsys. for vsys in vsys_list: if vsys.name == vsys_dg: vsys.add(eth) break else: module.fail_json(msg='Vsys {0} does not exist'.format(vsys)) # Update the interface. try: eth.apply() set_zone(con, eth, zone_name, zones) set_virtual_router(con, eth, vr_name, routers) changed = True except (PanDeviceError, ValueError): e = get_exception() module.fail_json(msg=e.message) else: module.fail_json(msg="Unsupported operation '{0}'".format(operation)) # Commit if we were asked to do so. if changed and commit: try: con.commit(sync=True, exception=True) except PanDeviceError: e = get_exception() module.fail_json(msg='Performed {0} but commit failed: {1}'.format( operation, e.message)) # Done! module.exit_json(changed=changed, msg='okey dokey')
def main(): helper = get_connection( vsys_importable=True, template=True, with_classic_provider_spec=True, with_state=True, min_pandevice_version=(0, 8, 0), argument_spec=dict( name=dict(required=True), tag=dict(required=True, type='int'), lldp_enabled=dict(type='bool'), lldp_profile=dict(), netflow_profile=dict(), comment=dict(), zone_name=dict(), vlan_name=dict(), ), ) module = AnsibleModule( argument_spec=helper.argument_spec, supports_check_mode=True, required_one_of=helper.required_one_of, ) # Verify libs are present, get the parent object. parent = helper.get_pandevice_parent(module) # Get the object params. spec = { 'name': module.params['name'], 'tag': module.params['tag'], 'lldp_enabled': module.params['lldp_enabled'], 'lldp_profile': module.params['lldp_profile'], 'netflow_profile_l2': module.params['netflow_profile'], 'comment': module.params['comment'], } # Get other info. state = module.params['state'] zone_name = module.params['zone_name'] vlan_name = module.params['vlan_name'] vsys = module.params['vsys'] # Sanity check. if '.' not in spec['name']: module.fail_json(msg='Interface name does not have "." in it') # Retrieve the current config. parent_eth = EthernetInterface(spec['name'].split('.')[0]) parent.add(parent_eth) try: parent_eth.refresh() except PanDeviceError as e: module.fail_json(msg='Failed refresh: {0}'.format(e)) if parent_eth.mode != 'layer2': module.fail_json(msg='{0} mode is {1}, not layer2'.format( parent_eth.name, parent_eth.mode)) interfaces = parent_eth.findall(Layer2Subinterface) # Build the object based on the user spec. eth = Layer2Subinterface(**spec) parent_eth.add(eth) # Which action should we take on the interface? changed = False reference_params = { 'refresh': True, 'update': not module.check_mode, 'return_type': 'bool', } if state == 'present': for item in interfaces: if item.name != eth.name: continue # Interfaces have children, so don't compare them. if not item.equal(eth, compare_children=False): changed = True eth.extend(item.children) if not module.check_mode: try: eth.apply() except PanDeviceError as e: module.fail_json(msg='Failed apply: {0}'.format(e)) break else: changed = True if not module.check_mode: try: eth.create() except PanDeviceError as e: module.fail_json(msg='Failed create: {0}'.format(e)) # Set references. try: changed |= eth.set_vsys(vsys, **reference_params) changed |= eth.set_zone(zone_name, mode=parent_eth.mode, **reference_params) changed |= eth.set_vlan(vlan_name, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) elif state == 'absent': # Remove references. try: changed |= eth.set_vlan(None, **reference_params) changed |= eth.set_zone(None, mode=parent_eth.mode, **reference_params) changed |= eth.set_vsys(None, **reference_params) except PanDeviceError as e: module.fail_json(msg='Failed setref: {0}'.format(e)) # Remove the interface. if eth.name in [x.name for x in interfaces]: changed = True if not module.check_mode: try: eth.delete() except PanDeviceError as e: module.fail_json(msg='Failed delete: {0}'.format(e)) # Done! module.exit_json(changed=changed, msg='Done')
def configure_network(device): eth1 = EthernetInterface(name='ethernet1/1', mode='layer3', ip=('192.168.55.20/24', )) eth2 = EthernetInterface(name='ethernet1/2', mode='layer3', ip=('192.168.45.20/24', )) eth3 = EthernetInterface(name='ethernet1/3', mode='layer3', ip=('192.168.35.20/24', )) device.add(eth1) device.add(eth2) device.add(eth3) eth1.create() eth2.create() eth3.create() untrust = Zone(name='untrust', mode='layer3', interface=['ethernet1/1']) web = Zone(name='web', mode='layer3', interface=['ethernet1/2']) db = Zone(name='db', mode='layer3', interface=['ethernet1/3']) device.add(untrust) device.add(web) device.add(db) untrust.create() web.create() db.create() vr_default = VirtualRouter( name='default', interface=['ethernet1/1', 'ethernet1/2', 'ethernet1/3']) device.add(vr_default) vr_default.create() default_route = StaticRoute(name='default', destination='0.0.0.0/0', nexthop='192.168.55.2') vr_default.add(default_route) default_route.create()
def main(): helper = get_connection( template=True, with_classic_provider_spec=True, with_state=True, min_pandevice_version=(0, 14, 0), argument_spec=dict( iface_name=dict(required=True), address=dict(required=True), enable_on_interface=dict(type='bool', default=True), prefix=dict(type='bool'), anycast=dict(type='bool'), advertise_enabled=dict(type='bool'), valid_lifetime=dict(type='int', default=2592000), preferred_lifetime=dict(type='int', default=604800), onlink_flag=dict(type='bool', default=True), auto_config_flag=dict(type='bool', default=True), ), ) module = AnsibleModule( argument_spec=helper.argument_spec, supports_check_mode=True, required_one_of=helper.required_one_of, ) # Verify libs are present, get the parent object. parent = helper.get_pandevice_parent(module) # Get the object params. spec = { 'address': module.params['address'], 'enable_on_interface': module.params['enable_on_interface'], 'prefix': module.params['prefix'], 'anycast': module.params['anycast'], 'advertise_enabled': module.params['advertise_enabled'], 'valid_lifetime': module.params['valid_lifetime'], 'preferred_lifetime': module.params['preferred_lifetime'], 'onlink_flag': module.params['onlink_flag'], 'auto_config_flag': module.params['auto_config_flag'], } # Get other info. iname = module.params['iface_name'] # Determine parent interface. eth = None part = iname if iname.startswith('ethernet') or iname.startswith('ae'): part = iname.split('.')[0] if iname.startswith('ethernet'): eth = EthernetInterface(part) else: eth = AggregateInterface(part) else: if iname.startswith('loopback'): eth = LoopbackInterface(iname) elif iname.startswith('tunnel'): eth = TunnelInterface(iname) elif iname.startswith('vlan'): eth = VlanInterface(iname) else: module.fail_json(msg='Unknown interface style: {0}'.format(iface)) parent.add(eth) try: eth.refresh() except PanDeviceError as e: module.fail_json(msg='Failed refresh: {0}'.format(e)) if iname != part: for child in eth.children: if child.uid == iname: eth = child break else: module.fail_json(msg='Could not find parent interface') listing = eth.findall(IPv6Address) # Build the object based on the user spec. obj = IPv6Address(**spec) eth.add(obj) # Apply the state changed, diff = helper.apply_state(obj, listing, module) # Done. module.exit_json(changed=changed, diff=diff)