def test_manage_servers_with_network_exception(self, get_manageable_mock, manage_mock, umanage_mock, server_create_mock, rollback_quota_mock): get_manageable_mock.side_effect = None manage_mock.side_effect = exception.NetworkError() server_create_mock.side_effect = None server = obj_utils.get_test_server( self.context, status=None, node_uuid=None, power_state=states.NOSTATE, availability_zone=None, image_uuid=None) node_uuid = 'aacdbd78-d670-409e-95aa-ecfcfb94fee2' self.assertRaises(exception.NetworkError, self.service.manage_server, self.context, server, node_uuid) get_manageable_mock.assert_called_once_with(node_uuid) manage_mock.assert_called_once() umanage_mock.assert_not_called() server_create_mock.assert_not_called() rollback_quota_mock.assert_called_once_with(self.context, -1)
def _build_networks(self, context, server, requested_networks): # TODO(zhenguo): This seems not needed as our scheduler has already # guaranteed this. ports = self.manager.driver.get_ports_from_node(server.node_uuid) if len(requested_networks) > len(ports): raise exception.InterfacePlugException( _("Ironic node: %(id)s virtual to physical interface count" " mismatch" " (Vif count: %(vif_count)d, Pif count: %(pif_count)d)") % { 'id': server.node_uuid, 'vif_count': len(requested_networks), 'pif_count': len(ports) }) nics_obj = objects.ServerNics(context) for vif in requested_networks: try: if vif.get('net_id'): port = self.manager.network_api.create_port( context, vif['net_id'], server.uuid) port_dict = port['port'] elif vif.get('port_id'): port_dict = self.manager.network_api.show_port( context, vif.get('port_id')) nic_dict = { 'port_id': port_dict['id'], 'network_id': port_dict['network_id'], 'mac_address': port_dict['mac_address'], 'fixed_ips': port_dict['fixed_ips'], 'server_uuid': server.uuid } server_nic = objects.ServerNic(context, **nic_dict) nics_obj.objects.append(server_nic) self.manager.driver.plug_vif(server.node_uuid, port_dict['id']) # Get updated VIF info port_dict = self.manager.network_api.show_port( context, port_dict.get('id')) # Update the real physical mac address from ironic. server_nic.mac_address = port_dict['mac_address'] except Exception as e: # Set nics here, so we can clean up the # created networks during reverting. server.nics = nics_obj LOG.error( "Server %(server)s: create or get network " "failed. The reason is %(reason)s", { "server": server.uuid, "reason": e }) raise exception.NetworkError( _("Build network for server failed.")) return nics_obj
def _show_port(self, client, port_id): """Return the port for the client given the port id.""" try: result = client.show_port(port_id) return result.get('port') except neutron_exceptions.PortNotFoundClient: raise exception.PortNotFound(port_id=port_id) except neutron_exceptions.Unauthorized: raise exception.Forbidden() except neutron_exceptions.NeutronClientException as e: msg = (_("Failed to access port %(port_id)s: %(reason)s") % { 'port_id': port_id, 'reason': e }) raise exception.NetworkError(msg)
def create_port(self, context, network_uuid, server_uuid): """Create neutron port.""" client = get_client(context.auth_token) body = { 'port': { 'network_id': network_uuid, 'device_id': server_uuid, } } try: port = client.create_port(body) except neutron_exceptions.NeutronClientException as e: msg = (_("Could not create neutron port on network %(net)s for " "server %(server)s. %(exc)s"), { 'net': network_uuid, 'server': server_uuid, 'exc': e }) LOG.exception(msg) raise exception.NetworkError(msg) return port
def _build_networks(self, context, server, requested_networks): ports = self.manager.driver.get_portgroups_and_ports(server.node_uuid) if len(requested_networks) > len(ports): raise exception.InterfacePlugException( _("Ironic node: %(id)s virtual to physical interface count" " mismatch" " (Vif count: %(vif_count)d, Pif count: %(pif_count)d)") % { 'id': server.node_uuid, 'vif_count': len(requested_networks), 'pif_count': len(ports) }) nics_obj = objects.ServerNics(context) for vif in requested_networks: try: if vif.get('net_id'): port = self.manager.network_api.create_port( context, vif['net_id'], server.uuid) preserve_on_delete = False elif vif.get('port_id'): port = self.manager.network_api.show_port( context, vif.get('port_id')) self.manager.network_api.check_port_availability(port) self.manager.network_api.bind_port(context, port['id'], server) preserve_on_delete = True nic_dict = { 'port_id': port['id'], 'network_id': port['network_id'], 'mac_address': port['mac_address'], 'fixed_ips': port['fixed_ips'], 'preserve_on_delete': preserve_on_delete, 'server_uuid': server.uuid } server_nic = objects.ServerNic(context, **nic_dict) nics_obj.objects.append(server_nic) self.manager.driver.plug_vif(server.node_uuid, port['id']) # Get updated VIF info port_dict = self.manager.network_api.show_port( context, port.get('id')) # Update the real physical mac address from ironic. server_nic.mac_address = port_dict['mac_address'] except Exception as e: # Set nics here, so we can clean up the # created networks during reverting. server.nics = nics_obj LOG.error( "Server %(server)s: create or get network " "failed. The reason is %(reason)s", { "server": server.uuid, "reason": e }) raise exception.NetworkError( _("Build network for server failed.")) return nics_obj
def _manage_server(self, context, server, node): # Create the rp resource_class = sched_utils.ensure_resource_class_name( node['resource_class']) inventory = self.driver.get_node_inventory(node) inventory_data = {resource_class: inventory} # TODO(liusheng) need to ensure the inventory being rollback if # putting allocations failed. self.scheduler_client.set_inventory_for_provider( node['uuid'], node['name'] or node['uuid'], inventory_data, resource_class) # Allocate the resource self.scheduler_client.reportclient.put_allocations( node['uuid'], server.uuid, {resource_class: 1}, server.project_id, server.user_id) LOG.info( "Starting to manage bare metal node %(node_uuid)s for " "server %(uuid)s", { "node_uuid": node['uuid'], "uuid": server.uuid }) nics_obj = objects.ServerNics(context) # Check networks all_ports = node['ports'] + node['portgroups'] for vif in all_ports: neutron_port_id = vif['neutron_port_id'] if neutron_port_id is not None: port_dict = self.network_api.show_port(context, neutron_port_id) nic_dict = { 'port_id': port_dict['id'], 'network_id': port_dict['network_id'], 'mac_address': port_dict['mac_address'], 'fixed_ips': port_dict['fixed_ips'], 'preserve_on_delete': False, 'server_uuid': server.uuid } # Check if the neutron port's mac address matches the port # address of bare metal nics. if nic_dict['mac_address'] != vif['address']: msg = (_("The address of neutron port %(port_id)s is " "%(address)s, but the nic address of bare metal " "node %(node_uuid)s is %(nic_address)s.") % { "port_id": nic_dict['port_id'], "address": nic_dict['mac_address'], "node_uuid": node['uuid'], "nic_address": vif['address'] }) raise exception.NetworkError(msg) self.network_api.bind_port(context, neutron_port_id, server) server_nic = objects.ServerNic(context, **nic_dict) nics_obj.objects.append(server_nic) # Manage the bare metal node self.driver.manage(server, node['uuid']) image_uuid = node.get('image_source') if not uuidutils.is_uuid_like(image_uuid): image_uuid = None # Set the server information server.image_uuid = image_uuid server.node_uuid = node['uuid'] server.node = node['name'] server.nics = nics_obj server.power_state = node['power_state'] server.launched_at = timeutils.utcnow() server.status = states.ACTIVE server.system_metadata = {"managed_server": "True"} if server.power_state == states.POWER_OFF: server.status = states.STOPPED