'Update ports from network_requests.
Updates the pre-existing ports and the ones created in
``_create_ports_for_instance`` with ``device_id``, ``device_owner``,
optionally ``mac_address`` and ``dhcp_opts``, and, depending on the
loaded extensions, ``rxtx_factor``, ``binding:host_id``, ``dns_name``.
:param context: The request context.
:param instance: nova.objects.instance.Instance object.
:param neutron: client using user context
:param admin_client: client using admin context
:param requests_and_created_ports: [(NetworkRequest, created_port_id)]
:param nets: a dict of network_id to networks returned from neutron
:param bind_host_id: a string for port[\'binding:host_id\']
:param dhcp_opts: a list dicts that contain dhcp option name and value
e.g. [{\'opt_name\': \'tftp-server\', \'opt_value\': \'1.2.3.4\'}]
:param available_macs: a list of available mac addresses'

def _update_ports_for_instance(self, context, instance, neutron, admin_client, requests_and_created_ports, nets, bind_host_id, dhcp_opts, available_macs):

    port_client = (neutron if (not self._has_port_binding_extension(context, refresh_cache=True, neutron=neutron)) else admin_client)
    preexisting_port_ids = []
    created_port_ids = []
    ports_in_requested_order = []
    nets_in_requested_order = []
    created_vifs = []
    for (request, created_port_id) in requests_and_created_ports:
        vifobj = objects.VirtualInterface(context)
        vifobj.instance_uuid = instance.uuid
        vifobj.tag = (request.tag if ('tag' in request) else None)
        network = nets.get(request.network_id)
        if (not network):
            continue
        nets_in_requested_order.append(network)
        zone = ('compute:%s' % instance.availability_zone)
        port_req_body = {'port': {'device_id': instance.uuid, 'device_owner': zone}}
        try:
            self._populate_neutron_extension_values(context, instance, request.pci_request_id, port_req_body, network=network, neutron=neutron, bind_host_id=bind_host_id)
            self._populate_pci_mac_address(instance, request.pci_request_id, port_req_body)
            self._populate_mac_address(instance, port_req_body, available_macs)
            if (dhcp_opts is not None):
                port_req_body['port']['extra_dhcp_opts'] = dhcp_opts
            if created_port_id:
                port_id = created_port_id
                created_port_ids.append(port_id)
            else:
                port_id = request.port_id
            ports_in_requested_order.append(port_id)
            updated_port = self._update_port(port_client, instance, port_id, port_req_body)
            vifobj.address = ('%s/%s' % (updated_port['mac_address'], updated_port['id']))
            vifobj.uuid = port_id
            vifobj.create()
            created_vifs.append(vifobj)
            if (not created_port_id):
                preexisting_port_ids.append(port_id)
            self._update_port_dns_name(context, instance, network, ports_in_requested_order[(-1)], neutron)
        except Exception:
            with excutils.save_and_reraise_exception():
                self._unbind_ports(context, preexisting_port_ids, neutron, port_client)
                self._delete_ports(neutron, instance, created_port_ids)
                for vif in created_vifs:
                    vif.destroy()
    return (nets_in_requested_order, ports_in_requested_order, preexisting_port_ids, created_port_ids)
