Move clients into class constructor

Currently we reference the various clients in several functions, so it's
cleaner if we just define them in the constructor vs passing them around
between functions etc.  In particular the swift client will be needed
in several functions if we're to break up the plan-update logic related
to handling environments effectively, so we may as well move all clients
for consistency (when more validations are done via mistral we can probably
remove some of these altogether e.g ref the validations-in-workflows
blueprint).

Change-Id: I8e3ca726ec6d873529127c2326f1b65dbb2bc22e
Partial-Bug: #1635409
This commit is contained in:
Steven Hardy 2017-03-24 12:25:41 +00:00
parent 04e2ea09e8
commit 040e997867
2 changed files with 49 additions and 66 deletions

View File

@ -52,7 +52,8 @@ class TestDeployValidators(fakes.TestDeployOvercloud):
# get a FakeNode by its UUID, replaces bm_client.node.get # get a FakeNode by its UUID, replaces bm_client.node.get
self.cmd._check_ironic_boot_configuration(bm_client) self.cmd.baremetal_client = bm_client
self.cmd._check_ironic_boot_configuration()
mock_maint_nodes.assert_called_once_with(detail=True, mock_maint_nodes.assert_called_once_with(detail=True,
maintenance=False) maintenance=False)

View File

@ -57,8 +57,16 @@ class DeployOvercloud(command.Command):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self._password_cache = None self._password_cache = None
super(DeployOvercloud, self).__init__(*args, **kwargs) super(DeployOvercloud, self).__init__(*args, **kwargs)
self.clients = self.app.client_manager
self.object_client = self.clients.tripleoclient.object_store
self.workflow_client = self.clients.workflow_engine
self.network_client = self.clients.network
self.orchestration_client = self.clients.orchestration
self.compute_client = self.clients.compute
self.baremetal_client = self.clients.baremetal
self.image_client = self.clients.image
def _update_parameters(self, args, network_client, stack): def _update_parameters(self, args, stack):
parameters = {} parameters = {}
stack_is_new = stack is None stack_is_new = stack is None
@ -197,9 +205,6 @@ class DeployOvercloud(command.Command):
run_validations, ws_client): run_validations, ws_client):
"""Verify the Baremetal nodes are available and do a stack update""" """Verify the Baremetal nodes are available and do a stack update"""
clients = self.app.client_manager
workflow_client = clients.workflow_engine
if stack: if stack:
update.add_breakpoints_cleanup_into_env(env) update.add_breakpoints_cleanup_into_env(env)
@ -212,10 +217,8 @@ class DeployOvercloud(command.Command):
# heatclient template_utils needs a function that can # heatclient template_utils needs a function that can
# retrieve objects from a container by name/path # retrieve objects from a container by name/path
objectclient = clients.tripleoclient.object_store
def do_object_request(method='GET', object_path=None): def do_object_request(method='GET', object_path=None):
obj = objectclient.get_object(stack_name, object_path) obj = self.object_client.get_object(stack_name, object_path)
return obj and obj[1] return obj and obj[1]
template_files, template = template_utils.get_template_contents( template_files, template = template_utils.get_template_contents(
@ -232,17 +235,14 @@ class DeployOvercloud(command.Command):
'environments when using multiple controllers ' 'environments when using multiple controllers '
'(with HA).') '(with HA).')
clients = self.app.client_manager
moved_files = self._upload_missing_files( moved_files = self._upload_missing_files(
stack_name, objectclient, files, tht_root) stack_name, files, tht_root)
self._process_and_upload_environment( self._process_and_upload_environment(
stack_name, objectclient, env, moved_files, tht_root, stack_name, env, moved_files, tht_root)
workflow_client)
if not update_plan_only: if not update_plan_only:
deployment.deploy_and_wait(self.log, clients, stack, stack_name, deployment.deploy_and_wait(self.log, self.clients, stack,
self.app_args.verbose_level, stack_name, self.app_args.verbose_level,
timeout=timeout, timeout=timeout,
run_validations=run_validations, run_validations=run_validations,
ws_client=ws_client) ws_client=ws_client)
@ -261,8 +261,8 @@ class DeployOvercloud(command.Command):
environments.append(f) environments.append(f)
return environments return environments
def _process_and_upload_environment(self, container_name, swift_client, def _process_and_upload_environment(self, container_name,
env, moved_files, tht_root, mistral): env, moved_files, tht_root):
"""Process the environment and upload to Swift """Process the environment and upload to Swift
The environment at this point should be the result of the merged The environment at this point should be the result of the merged
@ -295,7 +295,8 @@ class DeployOvercloud(command.Command):
if 'parameter_defaults' in env: if 'parameter_defaults' in env:
params = env.pop('parameter_defaults') params = env.pop('parameter_defaults')
workflow_params.update_parameters( workflow_params.update_parameters(
mistral, container=container_name, parameters=params) self.workflow_client, container=container_name,
parameters=params)
contents = yaml.safe_dump(env) contents = yaml.safe_dump(env)
@ -304,19 +305,18 @@ class DeployOvercloud(command.Command):
# custom environments passed to the deploy command. # custom environments passed to the deploy command.
# See bug: https://bugs.launchpad.net/tripleo/+bug/1623431 # See bug: https://bugs.launchpad.net/tripleo/+bug/1623431
swift_path = "user-environment.yaml" swift_path = "user-environment.yaml"
swift_client.put_object(container_name, swift_path, contents) self.object_client.put_object(container_name, swift_path, contents)
mistral_env = mistral.environments.get(container_name) mistral_env = self.workflow_client.environments.get(container_name)
user_env = {'path': swift_path} user_env = {'path': swift_path}
if user_env not in mistral_env.variables['environments']: if user_env not in mistral_env.variables['environments']:
mistral_env.variables['environments'].append(user_env) mistral_env.variables['environments'].append(user_env)
mistral.environments.update( self.workflow_client.environments.update(
name=container_name, name=container_name,
variables=mistral_env.variables variables=mistral_env.variables
) )
def _upload_missing_files(self, container_name, swift_client, files_dict, def _upload_missing_files(self, container_name, files_dict, tht_root):
tht_root):
"""Find the files referenced in custom environments and upload them """Find the files referenced in custom environments and upload them
Heat environments can be passed to be included in the deployment, these Heat environments can be passed to be included in the deployment, these
@ -351,15 +351,13 @@ class DeployOvercloud(command.Command):
file_relocation, os.path.dirname(reloc_path)) file_relocation, os.path.dirname(reloc_path))
contents = utils.replace_links_in_template_contents( contents = utils.replace_links_in_template_contents(
files_dict[orig_path], link_replacement) files_dict[orig_path], link_replacement)
swift_client.put_object(container_name, reloc_path, contents) self.object_client.put_object(container_name, reloc_path, contents)
return file_relocation return file_relocation
def _download_missing_files_from_plan(self, tht_dir, plan_name): def _download_missing_files_from_plan(self, tht_dir, plan_name):
# get and download missing files into tmp directory # get and download missing files into tmp directory
clients = self.app.client_manager plan_list = self.object_client.get_container(plan_name)
objectclient = clients.tripleoclient.object_store
plan_list = objectclient.get_container(plan_name)
plan_filenames = [f['name'] for f in plan_list[1]] plan_filenames = [f['name'] for f in plan_list[1]]
for pf in plan_filenames: for pf in plan_filenames:
file_path = os.path.join(tht_dir, pf) file_path = os.path.join(tht_dir, pf)
@ -369,7 +367,7 @@ class DeployOvercloud(command.Command):
if not os.path.exists(os.path.dirname(file_path)): if not os.path.exists(os.path.dirname(file_path)):
os.makedirs(os.path.dirname(file_path)) os.makedirs(os.path.dirname(file_path))
with open(file_path, 'w') as f: with open(file_path, 'w') as f:
f.write(objectclient.get_object(plan_name, pf)[1]) f.write(self.object_client.get_object(plan_name, pf)[1])
def _deploy_tripleo_heat_templates_tmpdir(self, stack, parsed_args): def _deploy_tripleo_heat_templates_tmpdir(self, stack, parsed_args):
# copy tht_root to temporary directory because we need to # copy tht_root to temporary directory because we need to
@ -393,14 +391,9 @@ class DeployOvercloud(command.Command):
def _deploy_tripleo_heat_templates(self, stack, parsed_args, def _deploy_tripleo_heat_templates(self, stack, parsed_args,
tht_root, user_tht_root): tht_root, user_tht_root):
"""Deploy the fixed templates in TripleO Heat Templates""" """Deploy the fixed templates in TripleO Heat Templates"""
clients = self.app.client_manager parameters = self._update_parameters(parsed_args, stack)
network_client = clients.network
workflow_client = clients.workflow_engine
parameters = self._update_parameters( plans = plan_management.list_deployment_plans(self.workflow_client)
parsed_args, network_client, stack)
plans = plan_management.list_deployment_plans(workflow_client)
generate_passwords = not parsed_args.disable_password_generation generate_passwords = not parsed_args.disable_password_generation
# TODO(d0ugal): We need to put a more robust strategy in place here to # TODO(d0ugal): We need to put a more robust strategy in place here to
@ -409,12 +402,12 @@ class DeployOvercloud(command.Command):
# Upload the new plan templates to swift to replace the existing # Upload the new plan templates to swift to replace the existing
# templates. # templates.
plan_management.update_plan_from_templates( plan_management.update_plan_from_templates(
clients, parsed_args.stack, tht_root, parsed_args.roles_file, self.clients, parsed_args.stack, tht_root,
generate_passwords) parsed_args.roles_file, generate_passwords)
else: else:
plan_management.create_plan_from_templates( plan_management.create_plan_from_templates(
clients, parsed_args.stack, tht_root, parsed_args.roles_file, self.clients, parsed_args.stack, tht_root,
generate_passwords) parsed_args.roles_file, generate_passwords)
# Get any missing (e.g j2 rendered) files from the plan to tht_root # Get any missing (e.g j2 rendered) files from the plan to tht_root
self._download_missing_files_from_plan( self._download_missing_files_from_plan(
@ -436,8 +429,7 @@ class DeployOvercloud(command.Command):
env['event_sinks'] = [ env['event_sinks'] = [
{'type': 'zaqar-queue', 'target': event_queue, {'type': 'zaqar-queue', 'target': event_queue,
'ttl': parsed_args.timeout * 60}] 'ttl': parsed_args.timeout * 60}]
clients = self.app.client_manager ws_client = self.clients.tripleoclient.messaging_websocket(event_queue)
ws_client = clients.tripleoclient.messaging_websocket(event_queue)
if parsed_args.rhel_reg: if parsed_args.rhel_reg:
reg_env_files, reg_env = self._create_registration_env(parsed_args) reg_env_files, reg_env = self._create_registration_env(parsed_args)
@ -480,7 +472,7 @@ class DeployOvercloud(command.Command):
# steps that are now deprecated. It should be removed when they are. # steps that are now deprecated. It should be removed when they are.
if self._password_cache is None: if self._password_cache is None:
self._password_cache = workflow_params.get_overcloud_passwords( self._password_cache = workflow_params.get_overcloud_passwords(
self.app.client_manager, self.clients,
container=stack_name, container=stack_name,
queue_name=str(uuid.uuid4())) queue_name=str(uuid.uuid4()))
@ -721,33 +713,29 @@ class DeployOvercloud(command.Command):
self.predeploy_warnings = 0 self.predeploy_warnings = 0
self.log.debug("Starting _pre_verify_capabilities") self.log.debug("Starting _pre_verify_capabilities")
bm_client = self.app.client_manager.baremetal
self._check_boot_images() self._check_boot_images()
flavors = self._collect_flavors(parsed_args) flavors = self._collect_flavors(parsed_args)
self._check_ironic_boot_configuration(bm_client) self._check_ironic_boot_configuration()
errors, warnings = utils.assign_and_verify_profiles( errors, warnings = utils.assign_and_verify_profiles(
bm_client, flavors, self.baremetal_client, flavors,
assign_profiles=False, assign_profiles=False,
dry_run=parsed_args.dry_run dry_run=parsed_args.dry_run
) )
self.predeploy_errors += errors self.predeploy_errors += errors
self.predeploy_warnings += warnings self.predeploy_warnings += warnings
compute_client = self.app.client_manager.compute
self.log.debug("Checking hypervisor stats") self.log.debug("Checking hypervisor stats")
if utils.check_hypervisor_stats(compute_client) is None: if utils.check_hypervisor_stats(self.compute_client) is None:
self.log.error("Expected hypervisor stats not met") self.log.error("Expected hypervisor stats not met")
self.predeploy_errors += 1 self.predeploy_errors += 1
self.log.debug("Checking nodes count") self.log.debug("Checking nodes count")
default_role_counts = self._get_default_role_counts(parsed_args) default_role_counts = self._get_default_role_counts(parsed_args)
enough_nodes, count, ironic_nodes_count = utils.check_nodes_count( enough_nodes, count, ironic_nodes_count = utils.check_nodes_count(
bm_client, self.baremetal_client,
stack, stack,
parameters, parameters,
default_role_counts default_role_counts
@ -767,11 +755,10 @@ class DeployOvercloud(command.Command):
if self.__kernel_id is not None and self.__ramdisk_id is not None: if self.__kernel_id is not None and self.__ramdisk_id is not None:
return self.__kernel_id, self.__ramdisk_id return self.__kernel_id, self.__ramdisk_id
image_client = self.app.client_manager.image
kernel_id, ramdisk_id = None, None kernel_id, ramdisk_id = None, None
try: try:
kernel_id = osc_utils.find_resource( kernel_id = osc_utils.find_resource(
image_client.images, 'bm-deploy-kernel').id self.image_client.images, 'bm-deploy-kernel').id
except AttributeError: except AttributeError:
self.log.exception("Please make sure there is only one image " self.log.exception("Please make sure there is only one image "
"named 'bm-deploy-kernel' in glance.") "named 'bm-deploy-kernel' in glance.")
@ -782,7 +769,7 @@ class DeployOvercloud(command.Command):
try: try:
ramdisk_id = osc_utils.find_resource( ramdisk_id = osc_utils.find_resource(
image_client.images, 'bm-deploy-ramdisk').id self.image_client.images, 'bm-deploy-ramdisk').id
except AttributeError: except AttributeError:
self.log.exception("Please make sure there is only one image " self.log.exception("Please make sure there is only one image "
"named 'bm-deploy-ramdisk' in glance.") "named 'bm-deploy-ramdisk' in glance.")
@ -817,9 +804,7 @@ class DeployOvercloud(command.Command):
:returns: dictionary flavor name -> (flavor object, scale) :returns: dictionary flavor name -> (flavor object, scale)
""" """
compute_client = self.app.client_manager.compute flavors = {f.name: f for f in self.compute_client.flavors.list()}
flavors = {f.name: f for f in compute_client.flavors.list()}
result = {} result = {}
message = "Provided --{}-flavor, '{}', does not exist" message = "Provided --{}-flavor, '{}', does not exist"
@ -862,8 +847,9 @@ class DeployOvercloud(command.Command):
return result return result
def _check_ironic_boot_configuration(self, bm_client): def _check_ironic_boot_configuration(self):
for node in bm_client.node.list(detail=True, maintenance=False): for node in self.baremetal_client.node.list(detail=True,
maintenance=False):
self.log.debug("Checking config for Node {0}".format(node.uuid)) self.log.debug("Checking config for Node {0}".format(node.uuid))
self._check_node_boot_configuration(node) self._check_node_boot_configuration(node)
@ -1071,18 +1057,14 @@ class DeployOvercloud(command.Command):
self._validate_args(parsed_args) self._validate_args(parsed_args)
clients = self.app.client_manager stack = utils.get_stack(self.orchestration_client, parsed_args.stack)
orchestration_client = clients.orchestration
stack = utils.get_stack(orchestration_client, parsed_args.stack)
if stack and stack.stack_status == 'IN_PROGRESS': if stack and stack.stack_status == 'IN_PROGRESS':
raise exceptions.StackInProgress( raise exceptions.StackInProgress(
"Unable to deploy as the stack '{}' status is '{}'".format( "Unable to deploy as the stack '{}' status is '{}'".format(
stack.stack_name, stack.stack_status)) stack.stack_name, stack.stack_status))
parameters = self._update_parameters( parameters = self._update_parameters(parsed_args, stack)
parsed_args, clients.network, stack)
if not parsed_args.disable_validations: if not parsed_args.disable_validations:
errors, warnings = self._predeploy_verify_capabilities( errors, warnings = self._predeploy_verify_capabilities(
@ -1140,7 +1122,7 @@ class DeployOvercloud(command.Command):
# Get a new copy of the stack after stack update/create. If it was # Get a new copy of the stack after stack update/create. If it was
# a create then the previous stack object would be None. # a create then the previous stack object would be None.
stack = utils.get_stack(orchestration_client, parsed_args.stack) stack = utils.get_stack(self.orchestration_client, parsed_args.stack)
if parsed_args.update_plan_only: if parsed_args.update_plan_only:
# If we are only updating the plan, then we either wont have a # If we are only updating the plan, then we either wont have a
@ -1152,7 +1134,7 @@ class DeployOvercloud(command.Command):
stack.get() stack.get()
overcloudrcs = deployment.overcloudrc( overcloudrcs = deployment.overcloudrc(
clients.workflow_engine, container=stack.stack_name, self.workflow_client, container=stack.stack_name,
no_proxy=parsed_args.no_proxy) no_proxy=parsed_args.no_proxy)
utils.write_overcloudrc(stack.stack_name, overcloudrcs) utils.write_overcloudrc(stack.stack_name, overcloudrcs)