ZhiQiang Fan 23027228ac Fix message i18n error
Partial-Bug: #1217100

Using tools/check_i18n.py to scan source directory, and fix most of
the errors.

- Message internationalization
- First letter must be capital
- Using comma instead of percent in LOG.xxx

Note: all extension's description are not touched in this patch,
can be fixed after discussing.
Note: all nicira/check_nvp_config.py print messages are not fixed.

Change-Id: I79ef06fd42f6780beb5019c592662536c2a51864
2013-09-08 15:58:12 +08:00

368 lines
15 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2012 Cisco Systems, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# @author: Sumit Naiksatam, Cisco Systems, Inc.
import inspect
import logging
from sqlalchemy import orm
import webob.exc as wexc
from neutron.api.v2 import base
from neutron.common import exceptions as exc
from neutron.db import db_base_plugin_v2
from neutron.db import models_v2
from neutron.openstack.common import importutils
from neutron.plugins.cisco.common import cisco_constants as const
from neutron.plugins.cisco.common import cisco_exceptions as cexc
from neutron.plugins.cisco.common import config
from neutron.plugins.cisco.db import network_db_v2 as cdb
LOG = logging.getLogger(__name__)
class PluginV2(db_base_plugin_v2.NeutronDbPluginV2):
"""Meta-Plugin with v2 API support for multiple sub-plugins."""
supported_extension_aliases = ["Cisco Credential", "Cisco qos"]
_methods_to_delegate = ['create_network',
'delete_network', 'update_network', 'get_network',
'get_networks',
'create_port', 'delete_port',
'update_port', 'get_port', 'get_ports',
'create_subnet',
'delete_subnet', 'update_subnet',
'get_subnet', 'get_subnets', ]
_master = True
CISCO_FAULT_MAP = {
cexc.NetworkSegmentIDNotFound: wexc.HTTPNotFound,
cexc.NoMoreNics: wexc.HTTPBadRequest,
cexc.NetworkVlanBindingAlreadyExists: wexc.HTTPBadRequest,
cexc.VlanIDNotFound: wexc.HTTPNotFound,
cexc.VlanIDNotAvailable: wexc.HTTPNotFound,
cexc.QosNotFound: wexc.HTTPNotFound,
cexc.QosNameAlreadyExists: wexc.HTTPBadRequest,
cexc.CredentialNotFound: wexc.HTTPNotFound,
cexc.CredentialNameNotFound: wexc.HTTPNotFound,
cexc.CredentialAlreadyExists: wexc.HTTPBadRequest,
cexc.NexusComputeHostNotConfigured: wexc.HTTPNotFound,
cexc.NexusConnectFailed: wexc.HTTPServiceUnavailable,
cexc.NexusConfigFailed: wexc.HTTPBadRequest,
cexc.NexusPortBindingNotFound: wexc.HTTPNotFound,
cexc.PortVnicBindingAlreadyExists: wexc.HTTPBadRequest,
cexc.PortVnicNotFound: wexc.HTTPNotFound}
def __init__(self):
"""Load the model class."""
self._model = importutils.import_object(config.CISCO.model_class)
if hasattr(self._model, "MANAGE_STATE") and self._model.MANAGE_STATE:
self._master = False
LOG.debug(_("Model %s manages state"), config.CISCO.model_class)
native_bulk_attr_name = ("_%s__native_bulk_support"
% self._model.__class__.__name__)
self.__native_bulk_support = getattr(self._model,
native_bulk_attr_name, False)
if hasattr(self._model, "supported_extension_aliases"):
self.supported_extension_aliases.extend(
self._model.supported_extension_aliases)
# Extend the fault map
self._extend_fault_map()
LOG.debug(_("Plugin initialization complete"))
def __getattribute__(self, name):
"""Delegate core API calls to the model class.
When the configured model class offers to manage the state of the
logical resources, we delegate the core API calls directly to it.
Note: Bulking calls will be handled by this class, and turned into
non-bulking calls to be considered for delegation.
"""
master = object.__getattribute__(self, "_master")
methods = object.__getattribute__(self, "_methods_to_delegate")
if not master and name in methods:
return getattr(object.__getattribute__(self, "_model"),
name)
else:
return object.__getattribute__(self, name)
def __getattr__(self, name):
"""Delegate calls to the extensions.
This delegates the calls to the extensions explicitly implemented by
the model.
"""
if hasattr(self._model, name):
return getattr(self._model, name)
else:
# Must make sure we re-raise the error that led us here, since
# otherwise getattr() and even hasattr() doesn't work corretly.
raise AttributeError(
_("'%(model)s' object has no attribute '%(name)s'") %
{'model': self._model, 'name': name})
def _extend_fault_map(self):
"""Extend the Neutron Fault Map for Cisco exceptions.
Map exceptions which are specific to the Cisco Plugin
to standard HTTP exceptions.
"""
base.FAULT_MAP.update(self.CISCO_FAULT_MAP)
"""
Core API implementation
"""
def create_network(self, context, network):
"""Create new Virtual Network, and assigns it a symbolic name."""
LOG.debug(_("create_network() called"))
new_network = super(PluginV2, self).create_network(context,
network)
try:
self._invoke_device_plugins(self._func_name(), [context,
new_network])
return new_network
except Exception:
super(PluginV2, self).delete_network(context,
new_network['id'])
raise
def update_network(self, context, id, network):
"""Update network.
Updates the symbolic name belonging to a particular Virtual Network.
"""
LOG.debug(_("update_network() called"))
upd_net_dict = super(PluginV2, self).update_network(context, id,
network)
self._invoke_device_plugins(self._func_name(), [context, id,
upd_net_dict])
return upd_net_dict
def delete_network(self, context, id):
"""Delete network.
Deletes the network with the specified network identifier
belonging to the specified tenant.
"""
LOG.debug(_("delete_network() called"))
#We first need to check if there are any ports on this network
with context.session.begin():
network = self._get_network(context, id)
filter = {'network_id': [id]}
ports = self.get_ports(context, filters=filter)
# check if there are any tenant owned ports in-use
prefix = db_base_plugin_v2.AGENT_OWNER_PREFIX
only_svc = all(p['device_owner'].startswith(prefix) for p in ports)
if not only_svc:
raise exc.NetworkInUse(net_id=id)
context.session.close()
#Network does not have any ports, we can proceed to delete
network = self._get_network(context, id)
kwargs = {const.NETWORK: network,
const.BASE_PLUGIN_REF: self}
self._invoke_device_plugins(self._func_name(), [context, id,
kwargs])
return super(PluginV2, self).delete_network(context, id)
def get_network(self, context, id, fields=None):
"""Get a particular network."""
LOG.debug(_("get_network() called"))
return super(PluginV2, self).get_network(context, id, fields)
def get_networks(self, context, filters=None, fields=None):
"""Get all networks."""
LOG.debug(_("get_networks() called"))
return super(PluginV2, self).get_networks(context, filters, fields)
def create_port(self, context, port):
"""Create a port on the specified Virtual Network."""
LOG.debug(_("create_port() called"))
new_port = super(PluginV2, self).create_port(context, port)
try:
self._invoke_device_plugins(self._func_name(), [context, new_port])
return new_port
except Exception:
super(PluginV2, self).delete_port(context, new_port['id'])
raise
def delete_port(self, context, id):
LOG.debug(_("delete_port() called"))
port = self._get_port(context, id)
"""Delete port.
TODO (Sumit): Disabling this check for now, check later
Allow deleting a port only if the administrative state is down,
and its operation status is also down
#if port['admin_state_up'] or port['status'] == 'ACTIVE':
# raise exc.PortInUse(port_id=id, net_id=port['network_id'],
# att_id=port['device_id'])
"""
kwargs = {const.PORT: port}
# TODO(Sumit): Might first need to check here if port is active
self._invoke_device_plugins(self._func_name(), [context, id,
kwargs])
return super(PluginV2, self).delete_port(context, id)
def update_port(self, context, id, port):
"""Update the state of a port and return the updated port."""
LOG.debug(_("update_port() called"))
self._invoke_device_plugins(self._func_name(), [context, id,
port])
return super(PluginV2, self).update_port(context, id, port)
def create_subnet(self, context, subnet):
"""Create subnet.
Create a subnet, which represents a range of IP addresses
that can be allocated to devices.
"""
LOG.debug(_("create_subnet() called"))
new_subnet = super(PluginV2, self).create_subnet(context, subnet)
try:
self._invoke_device_plugins(self._func_name(), [context,
new_subnet])
return new_subnet
except Exception:
super(PluginV2, self).delete_subnet(context, new_subnet['id'])
raise
def update_subnet(self, context, id, subnet):
"""Updates the state of a subnet and returns the updated subnet."""
LOG.debug(_("update_subnet() called"))
self._invoke_device_plugins(self._func_name(), [context, id,
subnet])
return super(PluginV2, self).update_subnet(context, id, subnet)
def delete_subnet(self, context, id):
LOG.debug(_("delete_subnet() called"))
with context.session.begin():
subnet = self._get_subnet(context, id)
# Check if ports are using this subnet
allocated_qry = context.session.query(models_v2.IPAllocation)
allocated_qry = allocated_qry.options(orm.joinedload('ports'))
allocated = allocated_qry.filter_by(subnet_id=id)
prefix = db_base_plugin_v2.AGENT_OWNER_PREFIX
if not all(not a.port_id or a.ports.device_owner.startswith(prefix)
for a in allocated):
raise exc.SubnetInUse(subnet_id=id)
context.session.close()
kwargs = {const.SUBNET: subnet}
self._invoke_device_plugins(self._func_name(), [context, id,
kwargs])
return super(PluginV2, self).delete_subnet(context, id)
"""
Extension API implementation
"""
def get_all_qoss(self, tenant_id):
"""Get all QoS levels."""
LOG.debug(_("get_all_qoss() called"))
qoslist = cdb.get_all_qoss(tenant_id)
return qoslist
def get_qos_details(self, tenant_id, qos_id):
"""Get QoS Details."""
LOG.debug(_("get_qos_details() called"))
return cdb.get_qos(tenant_id, qos_id)
def create_qos(self, tenant_id, qos_name, qos_desc):
"""Create a QoS level."""
LOG.debug(_("create_qos() called"))
qos = cdb.add_qos(tenant_id, qos_name, str(qos_desc))
return qos
def delete_qos(self, tenant_id, qos_id):
"""Delete a QoS level."""
LOG.debug(_("delete_qos() called"))
return cdb.remove_qos(tenant_id, qos_id)
def rename_qos(self, tenant_id, qos_id, new_name):
"""Rename QoS level."""
LOG.debug(_("rename_qos() called"))
return cdb.update_qos(tenant_id, qos_id, new_name)
def get_all_credentials(self):
"""Get all credentials."""
LOG.debug(_("get_all_credentials() called"))
credential_list = cdb.get_all_credentials()
return credential_list
def get_credential_details(self, credential_id):
"""Get a particular credential."""
LOG.debug(_("get_credential_details() called"))
try:
credential = cdb.get_credential(credential_id)
except exc.NotFound:
raise cexc.CredentialNotFound(credential_id=credential_id)
return credential
def rename_credential(self, credential_id, new_name):
"""Rename the particular credential resource."""
LOG.debug(_("rename_credential() called"))
try:
credential = cdb.get_credential(credential_id)
except exc.NotFound:
raise cexc.CredentialNotFound(credential_id=credential_id)
credential = cdb.update_credential(credential_id, new_name)
return credential
def schedule_host(self, tenant_id, instance_id, instance_desc):
"""Provides the hostname on which a dynamic vnic is reserved."""
LOG.debug(_("schedule_host() called"))
host_list = self._invoke_device_plugins(self._func_name(),
[tenant_id,
instance_id,
instance_desc])
return host_list
def associate_port(self, tenant_id, instance_id, instance_desc):
"""Associate port.
Get the portprofile name and the device name for the dynamic vnic.
"""
LOG.debug(_("associate_port() called"))
return self._invoke_device_plugins(self._func_name(), [tenant_id,
instance_id,
instance_desc])
def detach_port(self, tenant_id, instance_id, instance_desc):
"""Remove the association of the VIF with the dynamic vnic."""
LOG.debug(_("detach_port() called"))
return self._invoke_device_plugins(self._func_name(), [tenant_id,
instance_id,
instance_desc])
"""
Private functions
"""
def _invoke_device_plugins(self, function_name, args):
"""Device-specific calls.
Including core API and extensions are delegated to the model.
"""
if hasattr(self._model, function_name):
return getattr(self._model, function_name)(*args)
def _func_name(self, offset=0):
"""Getting the name of the calling funciton."""
return inspect.stack()[1 + offset][3]