14
14
# under the License.
17
from keystoneclient import auth as ks_auth
18
from keystoneclient.auth.identity import v2 as v2_auth
19
from keystoneclient import session as ks_session
20
from novaclient import client as nova_client
17
21
from novaclient import exceptions as nova_exceptions
18
import novaclient.v1_1.client as nclient
19
from novaclient.v1_1.contrib import server_external_events
20
from oslo.config import cfg
22
from oslo_config import cfg
23
from oslo_log import log as logging
24
from oslo_utils import importutils
21
25
from sqlalchemy.orm import attributes as sql_attr
23
27
from neutron.common import constants
24
28
from neutron import context
25
29
from neutron.i18n import _LE, _LI, _LW
26
30
from neutron import manager
27
from neutron.openstack.common import log as logging
28
31
from neutron.openstack.common import uuidutils
35
38
NEUTRON_NOVA_EVENT_STATUS_MAP = {constants.PORT_STATUS_ACTIVE: 'completed',
36
39
constants.PORT_STATUS_ERROR: 'failed',
37
40
constants.PORT_STATUS_DOWN: 'completed'}
41
NOVA_API_VERSION = "2"
44
class DefaultAuthPlugin(v2_auth.Password):
45
"""A wrapper around standard v2 user/pass to handle bypass url.
47
This is only necessary because novaclient doesn't support endpoint_override
50
When this bug is fixed we can pass the endpoint_override to the client
51
instead and remove this class.
54
def __init__(self, **kwargs):
55
self._endpoint_override = kwargs.pop('endpoint_override', None)
56
super(DefaultAuthPlugin, self).__init__(**kwargs)
58
def get_endpoint(self, session, **kwargs):
59
if self._endpoint_override:
60
return self._endpoint_override
62
return super(DefaultAuthPlugin, self).get_endpoint(session, **kwargs)
40
65
class Notifier(object):
42
67
def __init__(self):
43
# TODO(arosen): we need to cache the endpoints and figure out
44
# how to deal with different regions here....
45
if cfg.CONF.nova_admin_tenant_id:
46
bypass_url = "%s/%s" % (cfg.CONF.nova_url,
47
cfg.CONF.nova_admin_tenant_id)
51
self.nclient = nclient.Client(
52
username=cfg.CONF.nova_admin_username,
53
api_key=cfg.CONF.nova_admin_password,
54
project_id=cfg.CONF.nova_admin_tenant_name,
55
tenant_id=cfg.CONF.nova_admin_tenant_id,
56
auth_url=cfg.CONF.nova_admin_auth_url,
57
cacert=cfg.CONF.nova_ca_certificates_file,
58
insecure=cfg.CONF.nova_api_insecure,
59
bypass_url=bypass_url,
60
region_name=cfg.CONF.nova_region_name,
68
# FIXME(jamielennox): A notifier is being created for each Controller
69
# and each Notifier is handling it's own auth. That means that we are
70
# authenticating the exact same thing len(controllers) times. This
71
# should be an easy thing to optimize.
72
auth = ks_auth.load_from_conf_options(cfg.CONF, 'nova')
73
endpoint_override = None
76
LOG.warning(_LW('Authenticating to nova using nova_admin_* options'
77
' is deprecated. This should be done using'
78
' an auth plugin, like password'))
80
if cfg.CONF.nova_admin_tenant_id:
81
endpoint_override = "%s/%s" % (cfg.CONF.nova_url,
82
cfg.CONF.nova_admin_tenant_id)
84
auth = DefaultAuthPlugin(
85
auth_url=cfg.CONF.nova_admin_auth_url,
86
username=cfg.CONF.nova_admin_username,
87
password=cfg.CONF.nova_admin_password,
88
tenant_id=cfg.CONF.nova_admin_tenant_id,
89
tenant_name=cfg.CONF.nova_admin_tenant_name,
90
endpoint_override=endpoint_override)
92
session = ks_session.Session.load_from_conf_options(cfg.CONF,
96
# NOTE(andreykurilin): novaclient.v1_1 was renamed to v2 and there is
97
# no way to import the contrib module directly without referencing v2,
98
# which would only work for novaclient >= 2.21.0.
99
novaclient_cls = nova_client.get_client_class(NOVA_API_VERSION)
100
server_external_events = importutils.import_module(
101
novaclient_cls.__module__.replace(
102
".client", ".contrib.server_external_events"))
104
self.nclient = novaclient_cls(
106
region_name=cfg.CONF.nova.region_name,
61
107
extensions=[server_external_events])
62
108
self.pending_events = []
63
109
self._waiting_to_send = False