Merge "Create keypairs in other regions using context."

This commit is contained in:
Jenkins 2017-06-08 11:18:24 +00:00 committed by Gerrit Code Review
commit 26ee37310e
12 changed files with 176 additions and 189 deletions

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
from oslo_config import cfg
from oslo_log import log as logging from oslo_log import log as logging
from oslo_utils import uuidutils from oslo_utils import uuidutils
@ -24,14 +23,13 @@ from pecan import request
from kingbird.api.controllers import restcomm from kingbird.api.controllers import restcomm
from kingbird.common import consts from kingbird.common import consts
from kingbird.common.endpoint_cache import EndpointCache
from kingbird.common import exceptions from kingbird.common import exceptions
from kingbird.common.i18n import _ from kingbird.common.i18n import _
from kingbird.db.sqlalchemy import api as db_api from kingbird.db.sqlalchemy import api as db_api
from kingbird.drivers.openstack import sdk from kingbird.drivers.openstack.nova_v2 import NovaClient
from kingbird.rpc import client as rpc_client from kingbird.rpc import client as rpc_client
CONF = cfg.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -57,6 +55,13 @@ class ResourceSyncController(object):
@index.when(method='GET', template='json') @index.when(method='GET', template='json')
def get(self, project, action=None): def get(self, project, action=None):
"""Get details about Sync Job.
:param project: It's UUID of the project.
:param action: Optional. If provided, it can be
'active' to get the list of active jobs.
'job-id' to get the details of a job.
"""
context = restcomm.extract_context_from_environ() context = restcomm.extract_context_from_environ()
if not uuidutils.is_uuid_like(project) or project != context.project: if not uuidutils.is_uuid_like(project) or project != context.project:
pecan.abort(400, _('Invalid request URL')) pecan.abort(400, _('Invalid request URL'))
@ -75,32 +80,38 @@ class ResourceSyncController(object):
@index.when(method='POST', template='json') @index.when(method='POST', template='json')
def post(self, project): def post(self, project):
"""Sync resources present in one region to another region.
:param project: It's UUID of the project.
"""
context = restcomm.extract_context_from_environ() context = restcomm.extract_context_from_environ()
if not uuidutils.is_uuid_like(project) or project != context.project: if not uuidutils.is_uuid_like(project) or project != context.project:
pecan.abort(400, _('Invalid request URL')) pecan.abort(400, _('Invalid request URL'))
if not request.body:
pecan.abort(400, _('Body required'))
payload = eval(request.body) payload = eval(request.body)
if not payload:
pecan.abort(400, _('Body required'))
payload = payload.get('resource_set') payload = payload.get('resource_set')
if not payload: if not payload:
pecan.abort(400, _('resource_set required')) pecan.abort(400, _('resource_set required'))
resource_type = payload.get('resource_type')
target_regions = payload.get('target') target_regions = payload.get('target')
if not target_regions or not isinstance(target_regions, list): if not target_regions or not isinstance(target_regions, list):
pecan.abort(400, _('Target regions required')) pecan.abort(400, _('Target regions required'))
source_region = payload.get('source') source_region = payload.get('source')
if not source_region or not isinstance(source_region, str): if not source_region or not isinstance(source_region, str):
pecan.abort(400, _('Source region required')) pecan.abort(400, _('Source region required'))
if payload.get('resource_type') == consts.KEYPAIR: source_resources = payload.get('resources')
user_id = context.user if not source_resources:
source_keys = payload.get('resources') pecan.abort(400, _('Source resources required'))
if not source_keys: if resource_type == consts.KEYPAIR:
pecan.abort(400, _('Source keypairs required')) session = EndpointCache().get_session_from_token(
context.auth_token, context.project)
# Create Source Region object # Create Source Region object
source_os_client = sdk.OpenStackDriver(source_region) source_nova_client = NovaClient(source_region, session)
# Check for keypairs in Source Region # Check for keypairs in Source Region
for source_keypair in source_keys: for source_keypair in source_resources:
source_keypair = source_os_client.get_keypairs(user_id, source_keypair = source_nova_client.\
source_keypair) get_keypairs(source_keypair)
if not source_keypair: if not source_keypair:
pecan.abort(404) pecan.abort(404)
job_id = uuidutils.generate_uuid() job_id = uuidutils.generate_uuid()
@ -111,20 +122,25 @@ class ResourceSyncController(object):
pecan.abort(404, _('Job not found')) pecan.abort(404, _('Job not found'))
# Insert into the child table # Insert into the child table
for region in target_regions: for region in target_regions:
for keypair in source_keys: for keypair in source_resources:
try: try:
db_api.resource_sync_create(context, result, db_api.resource_sync_create(context, result,
region, source_region, region, source_region,
keypair, consts.KEYPAIR) keypair, consts.KEYPAIR)
except exceptions.JobNotFound: except exceptions.JobNotFound:
pecan.abort(404, _('Job not found')) pecan.abort(404, _('Job not found'))
return self._keypair_sync(job_id, user_id, payload, context, return self._keypair_sync(job_id, payload, context, result)
result)
else: else:
pecan.abort(400, _('Bad resource_type')) pecan.abort(400, _('Bad resource_type'))
@index.when(method='delete', template='json') @index.when(method='delete', template='json')
def delete(self, project, job_id): def delete(self, project, job_id):
"""Delete the database entries of a given job_id.
:param project: It's UUID of the project.
:param job_id: ID of the job for which the database entries
have to be deleted.
"""
context = restcomm.extract_context_from_environ() context = restcomm.extract_context_from_environ()
if not uuidutils.is_uuid_like(project) or project != context.project: if not uuidutils.is_uuid_like(project) or project != context.project:
pecan.abort(400, _('Invalid request URL')) pecan.abort(400, _('Invalid request URL'))
@ -144,9 +160,16 @@ class ResourceSyncController(object):
else: else:
pecan.abort(400, _('Bad request')) pecan.abort(400, _('Bad request'))
def _keypair_sync(self, job_id, user_id, payload, context, result): def _keypair_sync(self, job_id, payload, context, result):
self.rpc_client.keypair_sync_for_user(context, job_id, payload, """Make an rpc call to kb-engine.
user_id)
:param job_id: ID of the job to update values in database based on
the job_id.
:param payload: payload object.
:param context: context of the request.
:param result: Result object to return an output.
"""
self.rpc_client.keypair_sync_for_user(context, job_id, payload)
return {'job_status': {'id': result.id, 'status': result.sync_status, return {'job_status': {'id': result.id, 'status': result.sync_status,
'created_at': result.created_at}} 'created_at': result.created_at}}

View File

@ -15,9 +15,10 @@
import collections import collections
from keystoneclient.auth.identity import v3 as auth_identity from keystoneauth1.identity import v3 as auth_identity
from keystoneauth1 import loading
from keystoneauth1 import session
from keystoneclient.auth import token_endpoint from keystoneclient.auth import token_endpoint
from keystoneclient import session
from keystoneclient.v3 import client as keystone_client from keystoneclient.v3 import client as keystone_client
from oslo_config import cfg from oslo_config import cfg
@ -88,7 +89,7 @@ class EndpointCache(object):
service] = endpoint_map[region][service] service] = endpoint_map[region][service]
def get_endpoint(self, region, service): def get_endpoint(self, region, service):
"""Get service endpoint url """Get service endpoint url.
:param region: region the service belongs to :param region: region the service belongs to
:param service: service type :param service: service type
@ -97,15 +98,29 @@ class EndpointCache(object):
return self._get_endpoint(region, service, True) return self._get_endpoint(region, service, True)
def update_endpoints(self): def update_endpoints(self):
"""Update endpoint cache from Keystone """Update endpoint cache from Keystone.
:return: None :return: None
""" """
self._update_endpoints() self._update_endpoints()
def get_all_regions(self): def get_all_regions(self):
"""Get region list """Get region list.
return: List of regions return: List of regions
""" """
return self.endpoint_map.keys() return self.endpoint_map.keys()
def get_session_from_token(self, token, project_id):
"""Get session based on token to communicate with openstack services.
:param token: token with which the request is triggered.
:param project_id: UUID of the project.
:return: session object.
"""
loader = loading.get_plugin_loader('token')
auth = loader.load_from_options(auth_url=cfg.CONF.cache.auth_uri,
token=token, project_id=project_id)
sess = session.Session(auth=auth)
return sess

View File

@ -26,21 +26,23 @@ API_VERSION = '2.37'
class NovaClient(base.DriverBase): class NovaClient(base.DriverBase):
'''Nova V2.37 driver.''' """Nova V2.37 driver."""
def __init__(self, region, disabled_quotas, session):
def __init__(self, region, session, disabled_quotas=None):
try: try:
self.nova_client = client.Client(API_VERSION, self.nova_client = client.Client(API_VERSION,
session=session, session=session,
region_name=region) region_name=region)
self.enabled_quotas = list(set(consts.NOVA_QUOTA_FIELDS) - if disabled_quotas:
set(disabled_quotas)) self.enabled_quotas = list(set(consts.NOVA_QUOTA_FIELDS) -
self.no_neutron = True if 'floatingips' in self.enabled_quotas \ set(disabled_quotas))
or 'fixedips' in self.enabled_quotas else False self.no_neutron = True if 'floatingips' in self.enabled_quotas \
or 'fixedips' in self.enabled_quotas else False
except exceptions.ServiceUnavailable: except exceptions.ServiceUnavailable:
raise raise
def get_resource_usages(self, project_id): def get_resource_usages(self, project_id):
"""Collect resource usages for a given project """Collect resource usages for a given project.
:params: project_id :params: project_id
:return: dictionary of corresponding resources with its usage :return: dictionary of corresponding resources with its usage
@ -69,7 +71,7 @@ class NovaClient(base.DriverBase):
raise raise
def update_quota_limits(self, project_id, **new_quota): def update_quota_limits(self, project_id, **new_quota):
"""Update quota limits for a given project """Update quota limits for a given project.
:params: project_id, dictionary with the quota limits to update :params: project_id, dictionary with the quota limits to update
:return: Nothing :return: Nothing
@ -88,7 +90,7 @@ class NovaClient(base.DriverBase):
raise raise
def delete_quota_limits(self, project_id): def delete_quota_limits(self, project_id):
"""Delete/Reset quota limits for a given project """Delete/Reset quota limits for a given project.
:params: project_id :params: project_id
:return: Nothing :return: Nothing
@ -98,14 +100,14 @@ class NovaClient(base.DriverBase):
except exceptions.InternalError: except exceptions.InternalError:
raise raise
def get_keypairs(self, user_id, res_id): def get_keypairs(self, res_id):
"""Display keypair of the specified User """Display keypair of the specified User.
:params: user_id and resource_identifier :params: resource_identifier
:return: Keypair :return: Keypair
""" """
try: try:
keypair = self.nova_client.keypairs.get(res_id, user_id) keypair = self.nova_client.keypairs.get(res_id)
LOG.info("Source Keypair: %s", keypair.name) LOG.info("Source Keypair: %s", keypair.name)
return keypair return keypair
@ -113,15 +115,15 @@ class NovaClient(base.DriverBase):
LOG.error('Exception Occurred: %s', exception.message) LOG.error('Exception Occurred: %s', exception.message)
pass pass
def create_keypairs(self, force, keypair, user_id): def create_keypairs(self, force, keypair):
"""Create keypair for the specified User """Create keypair for the specified User.
:params: user_id, keypair, force :params: keypair, force
:return: Creates a Keypair :return: Creates a Keypair
""" """
if force: if force:
try: try:
self.nova_client.keypairs.delete(keypair, user_id) self.nova_client.keypairs.delete(keypair)
LOG.info("Deleted Keypair: %s", keypair.name) LOG.info("Deleted Keypair: %s", keypair.name)
except Exception as exception: except Exception as exception:
LOG.error('Exception Occurred: %s', exception.message) LOG.error('Exception Occurred: %s', exception.message)
@ -129,5 +131,4 @@ class NovaClient(base.DriverBase):
LOG.info("Created Keypair: %s", keypair.name) LOG.info("Created Keypair: %s", keypair.name)
return self.nova_client.keypairs. \ return self.nova_client.keypairs. \
create(keypair.name, create(keypair.name,
user_id=user_id,
public_key=keypair.public_key) public_key=keypair.public_key)

View File

@ -66,8 +66,8 @@ class OpenStackDriver(object):
self.disabled_quotas, self.disabled_quotas,
self.keystone_client.session) self.keystone_client.session)
self.nova_client = NovaClient(region_name, self.nova_client = NovaClient(region_name,
self.disabled_quotas, self.keystone_client.session,
self.keystone_client.session) self.disabled_quotas)
self.cinder_client = CinderClient(region_name, self.cinder_client = CinderClient(region_name,
self.disabled_quotas, self.disabled_quotas,
self.keystone_client.session) self.keystone_client.session)
@ -182,9 +182,3 @@ class OpenStackDriver(object):
return False return False
else: else:
return True return True
def get_keypairs(self, user_id, resource_identifier):
return self.nova_client.get_keypairs(user_id, resource_identifier)
def create_keypairs(self, force, keypair, user_id):
return self.nova_client.create_keypairs(force, keypair, user_id)

View File

@ -154,9 +154,9 @@ class EngineService(service.Service):
self.qm.quota_sync_for_project(project_id) self.qm.quota_sync_for_project(project_id)
@request_context @request_context
def keypair_sync_for_user(self, ctxt, user_id, job_id, payload): def keypair_sync_for_user(self, ctxt, job_id, payload):
# Keypair Sync for a user, will be triggered by KB-API # Keypair Sync for a user, will be triggered by KB-API
self.sm.keypair_sync_for_user(user_id, job_id, payload) self.sm.keypair_sync_for_user(ctxt, job_id, payload)
def _stop_rpc_server(self): def _stop_rpc_server(self):
# Stop RPC connection to prevent new requests # Stop RPC connection to prevent new requests

View File

@ -1,4 +1,4 @@
# Copyright 2017 Ericsson AB # Copyright 2017 Ericsson AB.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@ -18,43 +18,42 @@ import threading
from oslo_log import log as logging from oslo_log import log as logging
from kingbird.common import consts from kingbird.common import consts
from kingbird.common import context from kingbird.common.endpoint_cache import EndpointCache
from kingbird.common import exceptions from kingbird.common import exceptions
from kingbird.common import manager
from kingbird.db.sqlalchemy import api as db_api from kingbird.db.sqlalchemy import api as db_api
from kingbird.drivers.openstack import sdk from kingbird.drivers.openstack.nova_v2 import NovaClient
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
class SyncManager(manager.Manager): class SyncManager(object):
"""Manages tasks related to resource management""" """Manages tasks related to resource management"""
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(SyncManager, self).__init__(service_name="sync_manager", super(SyncManager, self).__init__()
*args, **kwargs)
self.context = context.get_admin_context()
def _create_keypairs_in_region(self, job_id, force, target_regions, def _create_keypairs_in_region(self, job_id, force, target_regions,
source_keypair, user_id): source_keypair, session, context):
regions_thread = list() regions_thread = list()
for region in target_regions: for region in target_regions:
thread = threading.Thread(target=self._create_keypairs, thread = threading.Thread(target=self._create_keypairs,
args=(job_id, force, region, args=(job_id, force, region,
source_keypair, user_id,)) source_keypair, session,
context))
regions_thread.append(thread) regions_thread.append(thread)
thread.start() thread.start()
for region_thread in regions_thread: for region_thread in regions_thread:
region_thread.join() region_thread.join()
def _create_keypairs(self, job_id, force, region, source_keypair, user_id): def _create_keypairs(self, job_id, force, region, source_keypair,
os_client = sdk.OpenStackDriver(region) session, context):
target_nova_client = NovaClient(region, session)
try: try:
os_client.create_keypairs(force, source_keypair, user_id) target_nova_client.create_keypairs(force, source_keypair)
LOG.info('keypair %(keypair)s created in %(region)s' LOG.info('keypair %(keypair)s created in %(region)s'
% {'keypair': source_keypair.name, 'region': region}) % {'keypair': source_keypair.name, 'region': region})
try: try:
db_api.resource_sync_update(self.context, job_id, region, db_api.resource_sync_update(context, job_id, region,
source_keypair.name, source_keypair.name,
consts.JOB_SUCCESS) consts.JOB_SUCCESS)
except exceptions.JobNotFound(): except exceptions.JobNotFound():
@ -63,27 +62,29 @@ class SyncManager(manager.Manager):
LOG.error('Exception Occurred: %(msg)s in %(region)s' LOG.error('Exception Occurred: %(msg)s in %(region)s'
% {'msg': exc.message, 'region': region}) % {'msg': exc.message, 'region': region})
try: try:
db_api.resource_sync_update(self.context, job_id, region, db_api.resource_sync_update(context, job_id, region,
source_keypair.name, source_keypair.name,
consts.JOB_FAILURE) consts.JOB_FAILURE)
except exceptions.JobNotFound(): except exceptions.JobNotFound():
raise raise
pass pass
def keypair_sync_for_user(self, user_id, job_id, payload): def keypair_sync_for_user(self, context, job_id, payload):
LOG.info("Keypair sync Called for user: %s",
user_id)
keypairs_thread = list() keypairs_thread = list()
target_regions = payload['target'] target_regions = payload['target']
force = eval(str(payload.get('force', False))) force = eval(str(payload.get('force', False)))
resource_ids = payload.get('resources') resource_ids = payload.get('resources')
source_os_client = sdk.OpenStackDriver(payload['source']) source_region = payload['source']
session = EndpointCache().get_session_from_token(
context.auth_token, context.project)
# Create Source Region object
source_nova_client = NovaClient(source_region, session)
for keypair in resource_ids: for keypair in resource_ids:
source_keypair = source_os_client.get_keypairs(user_id, source_keypair = source_nova_client.get_keypairs(keypair)
keypair)
thread = threading.Thread(target=self._create_keypairs_in_region, thread = threading.Thread(target=self._create_keypairs_in_region,
args=(job_id, force, target_regions, args=(job_id, force, target_regions,
source_keypair, user_id,)) source_keypair, session,
context,))
keypairs_thread.append(thread) keypairs_thread.append(thread)
thread.start() thread.start()
for keypair_thread in keypairs_thread: for keypair_thread in keypairs_thread:
@ -92,13 +93,13 @@ class SyncManager(manager.Manager):
# Update the parent_db after the sync # Update the parent_db after the sync
try: try:
resource_sync_details = db_api.\ resource_sync_details = db_api.\
resource_sync_status(self.context, job_id) resource_sync_status(context, job_id)
except exceptions.JobNotFound: except exceptions.JobNotFound:
raise raise
result = consts.JOB_SUCCESS result = consts.JOB_SUCCESS
if consts.JOB_FAILURE in resource_sync_details: if consts.JOB_FAILURE in resource_sync_details:
result = consts.JOB_FAILURE result = consts.JOB_FAILURE
try: try:
db_api.sync_job_update(self.context, job_id, result) db_api.sync_job_update(context, job_id, result)
except exceptions.JobNotFound: except exceptions.JobNotFound:
raise raise

View File

@ -69,8 +69,8 @@ class EngineClient(object):
return self.cast(ctxt, self.make_msg('quota_sync_for_project', return self.cast(ctxt, self.make_msg('quota_sync_for_project',
project_id=project_id)) project_id=project_id))
def keypair_sync_for_user(self, ctxt, job_id, payload, user_id): def keypair_sync_for_user(self, ctxt, job_id, payload):
return self.cast( return self.cast(
ctxt, ctxt,
self.make_msg('keypair_sync_for_user', self.make_msg('keypair_sync_for_user', job_id=job_id,
user_id=user_id, job_id=job_id, payload=payload)) payload=payload))

View File

@ -60,9 +60,11 @@ class TestResourceManager(testroot.KBApiTest):
self.ctx = utils.dummy_context() self.ctx = utils.dummy_context()
@mock.patch.object(rpc_client, 'EngineClient') @mock.patch.object(rpc_client, 'EngineClient')
@mock.patch.object(sync_manager, 'sdk') @mock.patch.object(sync_manager, 'NovaClient')
@mock.patch.object(sync_manager, 'EndpointCache')
@mock.patch.object(sync_manager, 'db_api') @mock.patch.object(sync_manager, 'db_api')
def test_post_keypair_sync(self, mock_db_api, mock_sdk, mock_rpc_client): def test_post_keypair_sync(self, mock_db_api, mock_endpoint_cache,
mock_nova, mock_rpc_client):
time_now = timeutils.utcnow() time_now = timeutils.utcnow()
data = {"resource_set": {"resources": [SOURCE_KEYPAIR], data = {"resource_set": {"resources": [SOURCE_KEYPAIR],
"resource_type": "keypair", "resource_type": "keypair",
@ -71,13 +73,15 @@ class TestResourceManager(testroot.KBApiTest):
"target": [FAKE_TARGET_REGION]}} "target": [FAKE_TARGET_REGION]}}
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
sync_job_result = SyncJob(FAKE_JOB, consts.JOB_PROGRESS, time_now) sync_job_result = SyncJob(FAKE_JOB, consts.JOB_PROGRESS, time_now)
mock_sdk.OpenStackDriver().get_keypairs.return_value = fake_key mock_endpoint_cache().get_session_from_token.\
return_value = 'fake_session'
mock_nova().get_keypairs.return_value = fake_key
mock_db_api.sync_job_create.return_value = sync_job_result mock_db_api.sync_job_create.return_value = sync_job_result
response = self.app.post_json(FAKE_URL, response = self.app.post_json(FAKE_URL,
headers=FAKE_HEADERS, headers=FAKE_HEADERS,
params=data) params=data)
self.assertEqual(1, self.assertEqual(1,
mock_sdk.OpenStackDriver().get_keypairs.call_count) mock_nova().get_keypairs.call_count)
self.assertEqual(1, self.assertEqual(1,
mock_db_api.resource_sync_create.call_count) mock_db_api.resource_sync_create.call_count)
self.assertEqual(1, self.assertEqual(1,
@ -148,14 +152,18 @@ class TestResourceManager(testroot.KBApiTest):
headers=FAKE_HEADERS, params=data) headers=FAKE_HEADERS, params=data)
@mock.patch.object(rpc_client, 'EngineClient') @mock.patch.object(rpc_client, 'EngineClient')
@mock.patch.object(sync_manager, 'sdk') @mock.patch.object(sync_manager, 'EndpointCache')
def test_post_no_keypairs_in_region(self, mock_sdk, mock_rpc_client): @mock.patch.object(sync_manager, 'NovaClient')
def test_post_no_keypairs_in_region(self, mock_nova, mock_endpoint_cache,
mock_rpc_client):
data = {"resource_set": {"resources": [SOURCE_KEYPAIR], data = {"resource_set": {"resources": [SOURCE_KEYPAIR],
"resource_type": "keypair", "resource_type": "keypair",
"force": "True", "force": "True",
"source": FAKE_SOURCE_REGION, "source": FAKE_SOURCE_REGION,
"target": [FAKE_TARGET_REGION]}} "target": [FAKE_TARGET_REGION]}}
mock_sdk.OpenStackDriver().get_keypairs.return_value = None mock_endpoint_cache().get_session_from_token.\
return_value = 'fake_session'
mock_nova().get_keypairs.return_value = None
self.assertRaisesRegexp(webtest.app.AppError, "404 *", self.assertRaisesRegexp(webtest.app.AppError, "404 *",
self.app.post_json, FAKE_URL, self.app.post_json, FAKE_URL,
headers=FAKE_HEADERS, params=data) headers=FAKE_HEADERS, params=data)

View File

@ -70,8 +70,8 @@ class TestNovaClient(base.KingbirdTestCase):
self.user = 'fake_user' self.user = 'fake_user'
def test_init(self): def test_init(self):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
self.assertIsNotNone(nv_client) self.assertIsNotNone(nv_client)
expected_quotas = list(set(consts.NOVA_QUOTA_FIELDS) - expected_quotas = list(set(consts.NOVA_QUOTA_FIELDS) -
set(DISABLED_QUOTAS)) set(DISABLED_QUOTAS))
@ -84,8 +84,8 @@ class TestNovaClient(base.KingbirdTestCase):
mock_novaclient.Client().keypairs.list.return_value = FAKE_KEYPAIRS mock_novaclient.Client().keypairs.list.return_value = FAKE_KEYPAIRS
mock_novaclient.Client().limits.get().to_dict.return_value = \ mock_novaclient.Client().limits.get().to_dict.return_value = \
FAKE_LIMITS FAKE_LIMITS
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
total_nova_usage = nv_client.get_resource_usages(self.project) total_nova_usage = nv_client.get_resource_usages(self.project)
self.assertEqual(total_nova_usage['ram'], 512 * 2) self.assertEqual(total_nova_usage['ram'], 512 * 2)
self.assertEqual(total_nova_usage['cores'], 2) self.assertEqual(total_nova_usage['cores'], 2)
@ -94,8 +94,8 @@ class TestNovaClient(base.KingbirdTestCase):
@mock.patch.object(nova_v2, 'client') @mock.patch.object(nova_v2, 'client')
def test_update_quota_limits(self, mock_novaclient): def test_update_quota_limits(self, mock_novaclient):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
new_quota = {'ram': 100, 'cores': 50} new_quota = {'ram': 100, 'cores': 50}
nv_client.update_quota_limits(self.project, **new_quota) nv_client.update_quota_limits(self.project, **new_quota)
mock_novaclient.Client().quotas.update.assert_called_once_with( mock_novaclient.Client().quotas.update.assert_called_once_with(
@ -103,8 +103,8 @@ class TestNovaClient(base.KingbirdTestCase):
@mock.patch.object(nova_v2, 'client') @mock.patch.object(nova_v2, 'client')
def test_delete_quota_limits(self, mock_novaclient): def test_delete_quota_limits(self, mock_novaclient):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
new_quota = {'ram': 100, 'cores': 50} new_quota = {'ram': 100, 'cores': 50}
nv_client.update_quota_limits(self.project, **new_quota) nv_client.update_quota_limits(self.project, **new_quota)
@ -116,33 +116,33 @@ class TestNovaClient(base.KingbirdTestCase):
@mock.patch.object(nova_v2, 'client') @mock.patch.object(nova_v2, 'client')
def test_get_keypairs(self, mock_novaclient): def test_get_keypairs(self, mock_novaclient):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
nv_client.get_keypairs(self.user, FAKE_RESOURCE_ID) nv_client.get_keypairs(FAKE_RESOURCE_ID)
mock_novaclient.Client().keypairs.get.return_value = 'key1' mock_novaclient.Client().keypairs.get.return_value = 'key1'
mock_novaclient.Client().keypairs.get.\ mock_novaclient.Client().keypairs.get.\
assert_called_once_with(FAKE_RESOURCE_ID, self.user) assert_called_once_with(FAKE_RESOURCE_ID)
@mock.patch.object(nova_v2, 'client') @mock.patch.object(nova_v2, 'client')
def test_create_keypairs_with_force_false(self, mock_novaclient): def test_create_keypairs_with_force_false(self, mock_novaclient):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
nv_client.create_keypairs(DEFAULT_FORCE, fake_key, self.user) nv_client.create_keypairs(DEFAULT_FORCE, fake_key)
self.assertEqual(0, self.assertEqual(0,
mock_novaclient.Client().keypairs.delete.call_count) mock_novaclient.Client().keypairs.delete.call_count)
mock_novaclient.Client().keypairs.create.\ mock_novaclient.Client().keypairs.create.\
assert_called_once_with(fake_key.name, user_id=self.user, assert_called_once_with(fake_key.name,
public_key=fake_key.public_key) public_key=fake_key.public_key)
@mock.patch.object(nova_v2, 'client') @mock.patch.object(nova_v2, 'client')
def test_create_keypairs_with_force_true(self, mock_novaclient): def test_create_keypairs_with_force_true(self, mock_novaclient):
nv_client = nova_v2.NovaClient('fake_region', DISABLED_QUOTAS, nv_client = nova_v2.NovaClient('fake_region', self.session,
self.session) DISABLED_QUOTAS)
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
nv_client.create_keypairs(True, fake_key, self.user) nv_client.create_keypairs(True, fake_key)
mock_novaclient.Client().keypairs.delete.\ mock_novaclient.Client().keypairs.delete.\
assert_called_once_with(fake_key, self.user) assert_called_once_with(fake_key)
mock_novaclient.Client().keypairs.create.\ mock_novaclient.Client().keypairs.create.\
assert_called_once_with(fake_key.name, user_id=self.user, assert_called_once_with(fake_key.name,
public_key=fake_key.public_key) public_key=fake_key.public_key)

View File

@ -303,53 +303,3 @@ class TestOpenStackDriver(base.KingbirdTestCase):
os_driver = sdk.OpenStackDriver() os_driver = sdk.OpenStackDriver()
expected = os_driver._is_token_valid() expected = os_driver._is_token_valid()
self.assertEqual(expected, False) self.assertEqual(expected, False)
@mock.patch.object(sdk.OpenStackDriver, 'os_clients_dict')
@mock.patch.object(sdk, 'KeystoneClient')
@mock.patch.object(sdk, 'NovaClient')
@mock.patch.object(sdk, 'NeutronClient')
@mock.patch.object(sdk, 'CinderClient')
def test_get_keypairs(self, mock_cinder_client,
mock_network_client,
mock_nova_client, mock_keystone_client,
mock_os_client):
os_driver = sdk.OpenStackDriver()
os_driver.get_keypairs(FAKE_USER_ID, FAKE_RESOURCE_ID)
mock_nova_client().get_keypairs.\
assert_called_once_with(FAKE_USER_ID, FAKE_RESOURCE_ID)
@mock.patch.object(sdk.OpenStackDriver, 'os_clients_dict')
@mock.patch.object(sdk, 'KeystoneClient')
@mock.patch.object(sdk, 'NovaClient')
@mock.patch.object(sdk, 'NeutronClient')
@mock.patch.object(sdk, 'CinderClient')
def test_create_keypairs_with_force_false(self, mock_cinder_client,
mock_network_client,
mock_nova_client,
mock_keystone_client,
mock_os_client):
os_driver = sdk.OpenStackDriver()
fake_key = FakeKeypair('fake_name', 'fake-rsa')
os_driver.create_keypairs(False, fake_key,
FAKE_USER_ID)
mock_nova_client().create_keypairs.\
assert_called_once_with(False, fake_key,
FAKE_USER_ID)
@mock.patch.object(sdk.OpenStackDriver, 'os_clients_dict')
@mock.patch.object(sdk, 'KeystoneClient')
@mock.patch.object(sdk, 'NovaClient')
@mock.patch.object(sdk, 'NeutronClient')
@mock.patch.object(sdk, 'CinderClient')
def test_create_keypairs_with_force_true(self, mock_cinder_client,
mock_network_client,
mock_nova_client,
mock_keystone_client,
mock_os_client):
os_driver = sdk.OpenStackDriver()
fake_key = FakeKeypair('fake_name', 'fake-rsa')
os_driver.create_keypairs(True, fake_key,
FAKE_USER_ID)
mock_nova_client().create_keypairs.\
assert_called_once_with(True, fake_key,
FAKE_USER_ID)

View File

@ -115,7 +115,6 @@ class TestEngineService(base.KingbirdTestCase):
self.service_obj.init_tgm() self.service_obj.init_tgm()
self.service_obj.init_sm() self.service_obj.init_sm()
self.service_obj.keypair_sync_for_user( self.service_obj.keypair_sync_for_user(
self.context, self.user_id, self.context, self.job_id, self.payload,)
self.job_id, self.payload,)
mock_sync_manager().keypair_sync_for_user.\ mock_sync_manager().keypair_sync_for_user.\
assert_called_once_with(self.user_id, self.job_id, self.payload) assert_called_once_with(self.context, self.job_id, self.payload)

View File

@ -37,58 +37,54 @@ class TestSyncManager(base.KingbirdTestCase):
super(TestSyncManager, self).setUp() super(TestSyncManager, self).setUp()
self.ctxt = utils.dummy_context() self.ctxt = utils.dummy_context()
@mock.patch.object(sync_manager, 'context') @mock.patch.object(sync_manager, 'NovaClient')
def test_init(self, mock_context): @mock.patch.object(sync_manager, 'EndpointCache')
mock_context.get_admin_context.return_value = self.ctxt
sm = sync_manager.SyncManager()
self.assertIsNotNone(sm)
self.assertEqual('sync_manager', sm.service_name)
self.assertEqual('localhost', sm.host)
self.assertEqual(self.ctxt, sm.context)
@mock.patch.object(sync_manager, 'sdk')
@mock.patch.object(sync_manager.SyncManager, '_create_keypairs') @mock.patch.object(sync_manager.SyncManager, '_create_keypairs')
@mock.patch.object(sync_manager, 'db_api') @mock.patch.object(sync_manager, 'db_api')
def test_keypair_sync_force_false(self, mock_db_api, mock_create_keypair, def test_keypair_sync_force_false(self, mock_db_api, mock_create_keypair,
mock_sdk): mock_endpoint_cache, mock_nova):
payload = {} payload = dict()
payload['target'] = [FAKE_TARGET_REGION] payload['target'] = [FAKE_TARGET_REGION]
payload['force'] = DEFAULT_FORCE payload['force'] = DEFAULT_FORCE
payload['source'] = FAKE_SOURCE_REGION payload['source'] = FAKE_SOURCE_REGION
payload['resources'] = [SOURCE_KEYPAIR] payload['resources'] = [SOURCE_KEYPAIR]
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
mock_sdk.OpenStackDriver().get_keypairs.return_value = fake_key mock_endpoint_cache().get_session_from_token.\
return_value = 'fake_session'
mock_nova().get_keypairs.return_value = fake_key
sm = sync_manager.SyncManager() sm = sync_manager.SyncManager()
sm.keypair_sync_for_user(FAKE_USER_ID, FAKE_JOB_ID, payload) sm.keypair_sync_for_user(self.ctxt, FAKE_JOB_ID, payload)
mock_create_keypair.assert_called_once_with( mock_create_keypair.assert_called_once_with(
FAKE_JOB_ID, payload['force'], payload['target'][0], fake_key, FAKE_JOB_ID, payload['force'], payload['target'][0], fake_key,
FAKE_USER_ID) 'fake_session', self.ctxt)
@mock.patch.object(sync_manager, 'sdk') @mock.patch.object(sync_manager, 'NovaClient')
@mock.patch.object(sync_manager, 'EndpointCache')
@mock.patch.object(sync_manager.SyncManager, '_create_keypairs') @mock.patch.object(sync_manager.SyncManager, '_create_keypairs')
@mock.patch.object(sync_manager, 'db_api') @mock.patch.object(sync_manager, 'db_api')
def test_keypair_sync_force_true(self, mock_db_api, mock_create_keypair, def test_keypair_sync_force_true(self, mock_db_api, mock_create_keypair,
mock_sdk): mock_endpoint_cache, mock_nova):
payload = dict() payload = dict()
payload['target'] = [FAKE_TARGET_REGION] payload['target'] = [FAKE_TARGET_REGION]
payload['force'] = True payload['force'] = True
payload['source'] = FAKE_SOURCE_REGION payload['source'] = FAKE_SOURCE_REGION
payload['resources'] = [SOURCE_KEYPAIR] payload['resources'] = [SOURCE_KEYPAIR]
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
mock_sdk.OpenStackDriver().get_keypairs.return_value = fake_key mock_endpoint_cache().get_session_from_token.\
return_value = 'fake_session'
mock_nova().get_keypairs.return_value = fake_key
sm = sync_manager.SyncManager() sm = sync_manager.SyncManager()
sm.keypair_sync_for_user(FAKE_USER_ID, FAKE_JOB_ID, payload) sm.keypair_sync_for_user(self.ctxt, FAKE_JOB_ID, payload)
mock_create_keypair.assert_called_once_with( mock_create_keypair.assert_called_once_with(
FAKE_JOB_ID, payload['force'], FAKE_TARGET_REGION, fake_key, FAKE_JOB_ID, payload['force'], payload['target'][0], fake_key,
FAKE_USER_ID) 'fake_session', self.ctxt)
@mock.patch.object(sync_manager, 'sdk') @mock.patch.object(sync_manager, 'NovaClient')
@mock.patch.object(sync_manager, 'db_api') @mock.patch.object(sync_manager, 'db_api')
def test_create_keypair(self, mock_db_api, mock_sdk): def test_create_keypair(self, mock_db_api, mock_nova):
fake_key = FakeKeypair('fake_name', 'fake-rsa') fake_key = FakeKeypair('fake_name', 'fake-rsa')
sm = sync_manager.SyncManager() sm = sync_manager.SyncManager()
sm._create_keypairs(FAKE_JOB_ID, DEFAULT_FORCE, FAKE_TARGET_REGION, sm._create_keypairs(FAKE_JOB_ID, DEFAULT_FORCE, FAKE_TARGET_REGION,
fake_key, FAKE_USER_ID) fake_key, 'fake_session', self.ctxt)
mock_sdk.OpenStackDriver().create_keypairs.\ mock_nova().create_keypairs.\
assert_called_once_with(DEFAULT_FORCE, fake_key, FAKE_USER_ID) assert_called_once_with(DEFAULT_FORCE, fake_key)