tricircle/novaproxy/nova/compute/clients.py

247 lines
7.4 KiB
Python

# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# 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.
from oslo.config import cfg
from nova.openstack.common import importutils
from nova.openstack.common import log as logging
logger = logging.getLogger(__name__)
from nova.compute import compute_keystoneclient as hkc
from novaclient import client as novaclient
from novaclient import shell as novashell
try:
from swiftclient import client as swiftclient
except ImportError:
swiftclient = None
logger.info('swiftclient not available')
try:
from neutronclient.v2_0 import client as neutronclient
except ImportError:
neutronclient = None
logger.info('neutronclient not available')
try:
from cinderclient import client as cinderclient
except ImportError:
cinderclient = None
logger.info('cinderclient not available')
try:
from ceilometerclient.v2 import client as ceilometerclient
except ImportError:
ceilometerclient = None
logger.info('ceilometerclient not available')
cloud_opts = [
cfg.StrOpt('cloud_backend',
default=None,
help="Cloud module to use as a backend. Defaults to OpenStack.")
]
cfg.CONF.register_opts(cloud_opts)
class OpenStackClients(object):
'''
Convenience class to create and cache client instances.
'''
def __init__(self, context):
self.context = context
self._nova = {}
self._keystone = None
self._swift = None
self._neutron = None
self._cinder = None
self._ceilometer = None
@property
def auth_token(self):
# if there is no auth token in the context
# attempt to get one using the context username and password
return self.context.auth_token or self.keystone().auth_token
def keystone(self):
if self._keystone:
return self._keystone
self._keystone = hkc.KeystoneClient(self.context)
return self._keystone
def url_for(self, **kwargs):
return self.keystone().url_for(**kwargs)
def nova(self, service_type='compute'):
if service_type in self._nova:
return self._nova[service_type]
con = self.context
if self.auth_token is None:
logger.error("Nova connection failed, no auth_token!")
return None
computeshell = novashell.OpenStackComputeShell()
extensions = computeshell._discover_extensions("1.1")
args = {
'project_id': con.tenant_id,
'auth_url': con.auth_url,
'service_type': service_type,
'username': None,
'api_key': None,
'extensions': extensions
}
if con.password is not None:
if self.context.region_name is None:
management_url = self.url_for(service_type=service_type)
else:
management_url = self.url_for(
service_type=service_type,
attr='region',
filter_value=self.context.region_name)
else:
management_url = con.nova_url + '/' + con.tenant_id
client = novaclient.Client(2, **args)
client.client.auth_token = self.auth_token
client.client.management_url = management_url
self._nova[service_type] = client
return client
def swift(self):
if swiftclient is None:
return None
if self._swift:
return self._swift
con = self.context
if self.auth_token is None:
logger.error("Swift connection failed, no auth_token!")
return None
args = {
'auth_version': '2.0',
'tenant_name': con.tenant_id,
'user': con.username,
'key': None,
'authurl': None,
'preauthtoken': self.auth_token,
'preauthurl': self.url_for(service_type='object-store')
}
self._swift = swiftclient.Connection(**args)
return self._swift
def neutron(self):
if neutronclient is None:
return None
if self._neutron:
return self._neutron
con = self.context
if self.auth_token is None:
logger.error("Neutron connection failed, no auth_token!")
return None
if con.password is not None:
if self.context.region_name is None:
management_url = self.url_for(service_type='network')
else:
management_url = self.url_for(
service_type='network',
attr='region',
filter_value=self.context.region_name)
else:
management_url = con.neutron_url
args = {
'auth_url': con.auth_url,
'service_type': 'network',
'token': self.auth_token,
'endpoint_url': management_url
}
self._neutron = neutronclient.Client(**args)
return self._neutron
def cinder(self):
if cinderclient is None:
return self.nova('volume')
if self._cinder:
return self._cinder
con = self.context
if self.auth_token is None:
logger.error("Cinder connection failed, no auth_token!")
return None
args = {
'service_type': 'volume',
'auth_url': con.auth_url,
'project_id': con.tenant_id,
'username': None,
'api_key': None
}
self._cinder = cinderclient.Client('1', **args)
if con.password is not None:
if self.context.region_name is None:
management_url = self.url_for(service_type='volume')
else:
management_url = self.url_for(
service_type='volume',
attr='region',
filter_value=self.context.region_name)
else:
management_url = con.cinder_url + '/' + con.tenant_id
self._cinder.client.auth_token = self.auth_token
self._cinder.client.management_url = management_url
return self._cinder
def ceilometer(self):
if ceilometerclient is None:
return None
if self._ceilometer:
return self._ceilometer
if self.auth_token is None:
logger.error("Ceilometer connection failed, no auth_token!")
return None
con = self.context
args = {
'auth_url': con.auth_url,
'service_type': 'metering',
'project_id': con.tenant_id,
'token': lambda: self.auth_token,
'endpoint': self.url_for(service_type='metering'),
}
client = ceilometerclient.Client(**args)
self._ceilometer = client
return self._ceilometer
if cfg.CONF.cloud_backend:
cloud_backend_module = importutils.import_module(cfg.CONF.cloud_backend)
Clients = cloud_backend_module.Clients
else:
Clients = OpenStackClients
logger.debug('Using backend %s' % Clients)