def introspect(clients, **workflow_input): """Introspect Baremetal Nodes Run the tripleo.baremetal.v1.introspect Mistral workflow. """ workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient print("Waiting for introspection to finish...") with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.baremetal.v1.introspect', workflow_input={ 'node_uuids': workflow_input['node_uuids'], 'run_validations': workflow_input['run_validations'] }) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: print(payload['message']) if payload['status'] != 'SUCCESS': raise exceptions.IntrospectionError( "Introspection completed with errors:\n%s" % '\n'.join(msg for msg in payload['message'] if msg))
def discover_and_enroll(clients, **workflow_input): """Discover nodes. Run the tripleo.baremetal.v1.discover_and_enroll_nodes Mistral workflow. """ workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.baremetal.v1.discover_and_enroll_nodes', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if payload.get('message'): print(payload['message']) if payload['status'] == 'SUCCESS': registered_nodes = payload['registered_nodes'] for nd in registered_nodes: print('Successfully registered node UUID %s' % nd['uuid']) return registered_nodes else: raise exceptions.RegisterOrUpdateError( 'Exception discovering nodes: {}'.format(payload['message']))
def provide(clients, **workflow_input): """Provide Baremetal Nodes Run the tripleo.baremetal.v1.provide Mistral workflow. """ workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.baremetal.v1.provide', workflow_input={'node_uuids': workflow_input['node_uuids']}) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: print(payload['message']) if payload['status'] != 'SUCCESS': try: message = _format_provide_errors(payload) except Exception: message = 'Failed.' raise exceptions.NodeProvideError( 'Failed to set nodes to available state: {}'.format(message))
def create_raid_configuration(clients, **workflow_input): """Create RAID configuration on nodes. Run the tripleo.baremetal.v1.create_raid_configuration Mistral workflow. """ workflow_client = clients.workflow_engine ooo_client = clients.tripleoclient print('Creating RAID configuration for given nodes, this may take time') with ooo_client.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.baremetal.v1.create_raid_configuration', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: print(payload['message']) if payload['status'] == 'SUCCESS': print('Success') else: raise RuntimeError('Failed to create RAID: {}'.format( payload['message']))
def check_deprecated_parameters(clients, container): """Checks for deprecated parameters in plan and adds warning if present""" workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient workflow_input = {'container': container} with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.plan_management.v1.get_deprecated_parameters', workflow_input=workflow_input) messages = base.wait_for_messages(workflow_client, ws, execution, 120) deprecated_params = [] unused_params = [] invalid_role_specific_params = [] for message in messages: if message['status'] == 'SUCCESS': for param in message.get('deprecated', []): if param.get('user_defined'): deprecated_params.append(param['parameter']) unused_params = message.get('unused', []) invalid_role_specific_params = message.get( 'invalid_role_specific', []) if deprecated_params: deprecated_join = ', '.join( ['{param}'.format(param=param) for param in deprecated_params]) LOG.warning( 'WARNING: Following parameter(s) are deprecated and still ' 'defined. Deprecated parameters will be removed soon!' ' {deprecated_join}'.format(deprecated_join=deprecated_join)) # exclude our known params that may not be used ignore_re = re.compile('|'.join(UNUSED_PARAMETER_EXCLUDES_RE)) unused_params = [p for p in unused_params if not ignore_re.search(p)] if unused_params: unused_join = ', '.join( ['{param}'.format(param=param) for param in unused_params]) LOG.warning( 'WARNING: Following parameter(s) are defined but not ' 'currently used in the deployment plan. These parameters ' 'may be valid but not in use due to the service or ' 'deployment configuration.' ' {unused_join}'.format(unused_join=unused_join)) if invalid_role_specific_params: invalid_join = ', '.join([ '{param}'.format(param=param) for param in invalid_role_specific_params ]) LOG.warning('WARNING: Following parameter(s) are not supported as ' 'role-specific inputs. {invalid_join}'.format( invalid_join=invalid_join))
def test_wait_for_messages_timeout(self): mistral = mock.Mock() websocket = mock.Mock() websocket.wait_for_messages.side_effect = ex.WebSocketTimeout execution = mock.Mock() execution.id = 1 messages = base.wait_for_messages(mistral, websocket, execution) self.assertRaises(ex.WebSocketTimeout, list, messages) self.assertTrue(mistral.executions.get.called) websocket.wait_for_messages.assert_called_with(timeout=None)
def delete_node(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.scale.v1.delete_node', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if payload['status'] != "SUCCESS": raise InvalidConfiguration(payload['message'])
def backup(clients, workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.undercloud_backup.v1.backup', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: assert payload['status'] == "SUCCESS", pprint.pformat(payload) print('Undercloud Backup succeed')
def config_download(log, clients, stack, templates, ssh_user, ssh_key, ssh_network, output_dir, override_ansible_cfg, timeout, verbosity=1, deployment_options={}, in_flight_validations=False): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient if in_flight_validations: skip_tags = '' else: skip_tags = 'opendev-validation' workflow_input = { 'verbosity': verbosity, 'plan_name': stack.stack_name, 'ssh_network': ssh_network, 'config_download_timeout': timeout, 'deployment_options': deployment_options, 'skip_tags': skip_tags } if output_dir: workflow_input.update(dict(work_dir=output_dir)) if override_ansible_cfg: with open(override_ansible_cfg) as cfg: override_ansible_cfg_contents = cfg.read() workflow_input.update( dict(override_ansible_cfg=override_ansible_cfg_contents)) with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.deployment.v1.config_download_deploy', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): print(payload['message']) if payload['status'] == 'SUCCESS': print("Overcloud configuration completed.") else: raise exceptions.DeploymentError("Overcloud configuration failed.")
def _create_update_deployment_plan(clients, workflow, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, workflow, workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution, _WORKFLOW_TIMEOUT): if 'message' in payload: print(payload['message']) return payload
def get_horizon_url(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.deployment.v1.get_horizon_url', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution, 360): assert payload['status'] == "SUCCESS" return payload['horizon_url']
def test_wait_for_messages_success(self): payload_a = {'status': 'ERROR', 'execution': {'id': 2}} payload_b = {'status': 'ERROR', 'execution': {'id': 1}} mistral = mock.Mock() websocket = mock.Mock() websocket.wait_for_messages.return_value = iter([payload_a, payload_b]) execution = mock.Mock() execution.id = 1 messages = list(base.wait_for_messages(mistral, websocket, execution)) self.assertEqual([payload_a, payload_b], messages) self.assertFalse(mistral.executions.get.called) websocket.wait_for_messages.assert_called_with(timeout=None)
def list_validations(clients, workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.validations.v1.list', workflow_input=workflow_input ) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: assert payload['status'] == "SUCCESS", pprint.pformat(payload) return payload['validations']
def get_config(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.package_update.v1.get_config', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): assert payload['status'] == "SUCCESS", pprint.pformat(payload) if payload['status'] == 'SUCCESS': print('Success') else: raise RuntimeError('Minor update failed with: {}'.format(payload))
def deploy(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.deployment.v1.deploy_plan', workflow_input=workflow_input) # The deploy workflow ends once the Heat create/update starts. This # means that is shouldn't take very long. Wait for six minutes for # messages from the workflow. for payload in base.wait_for_messages(workflow_client, ws, execution, 360): assert payload['status'] == "SUCCESS", pprint.pformat(payload)
def list_deployment_plans(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.plan_management.v1.list_plans', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution, _WORKFLOW_TIMEOUT): if payload['status'] != 'SUCCESS': raise exceptions.WorkflowServiceError( 'Exception listing plans: {}'.format(payload['message'])) return payload['plans']
def check_deprecated_parameters(clients, container): """Checks for deprecated parameters in plan and adds warning if present""" workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient workflow_input = {'container': container} with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.plan_management.v1.get_deprecated_parameters', workflow_input=workflow_input) messages = base.wait_for_messages(workflow_client, ws, execution, 120) deprecated_params = [] unused_params = [] invalid_role_specific_params = [] for message in messages: if message['status'] == 'SUCCESS': for param in message.get('deprecated', []): if param.get('user_defined'): deprecated_params.append(param['parameter']) unused_params = message.get('unused', []) invalid_role_specific_params = message.get( 'invalid_role_specific', []) if deprecated_params: print('WARNING: Following parameter(s) are deprecated and still ' 'defined. Deprecated parameters will be removed soon!') print('\n'.join( [' {}'.format(param) for param in deprecated_params])) if unused_params: print('WARNING: Following parameter(s) are defined but not used ' 'in plan. Could be possible that parameter is valid but ' 'currently not used.') print('\n'.join([' {}'.format(param) for param in unused_params])) if invalid_role_specific_params: print('WARNING: Following parameter(s) are not supported as ' 'role-specific inputs.') print('\n'.join([ ' {}'.format(param) for param in invalid_role_specific_params ]))
def run_on_nodes(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket( workflow_input['queue_name']) as ws: execution = base.start_workflow( workflow_client, 'tripleo.deployment.v1.deploy_on_servers', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): assert payload['status'] == "SUCCESS", pprint.pformat(payload) if payload['status'] == "SUCCESS": print('Success') else: raise RuntimeError('run on nodes failed: {}'.format(payload))
def create_overcloudrc(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient execution = base.start_workflow(workflow_client, 'tripleo.deployment.v1.create_overcloudrc', workflow_input=workflow_input) with tripleoclients.messaging_websocket() as ws: for payload in base.wait_for_messages(workflow_client, ws, execution): # the workflow will return the overcloudrc data, an error message # or blank. if payload.get('status') == 'SUCCESS': return payload.get('message') else: raise exceptions.WorkflowServiceError( 'Exception creating overcloudrc: {}'.format( payload.get('message')))
def delete_deployment_plan(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient execution = base.start_workflow( workflow_client, 'tripleo.plan_management.v1.delete_deployment_plan', workflow_input=workflow_input) with tripleoclients.messaging_websocket() as ws: for payload in base.wait_for_messages(workflow_client, ws, execution, _WORKFLOW_TIMEOUT): if 'message' in payload: print(payload['message']) if payload['status'] != 'SUCCESS': raise exceptions.WorkflowServiceError( 'Exception deleting plan: {}'.format(payload['message']))
def update_converge_nodes(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket( workflow_input['queue_name']) as ws: execution = base.start_workflow( workflow_client, 'tripleo.package_update.v1.update_converge_plan', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): assert payload['status'] == "SUCCESS", pprint.pformat(payload) if payload['status'] == 'SUCCESS': print('Success') else: raise RuntimeError('Update converge failed: {}'.format(payload))
def delete_node(clients, timeout, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient if timeout is not None: workflow_input['timeout'] = timeout with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.scale.v1.delete_node', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): status = payload['status'] if status == 'RUNNING': continue if status != 'SUCCESS': raise exceptions.InvalidConfiguration(payload['message'])
def generate_fencing_parameters(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.parameters.v1.generate_fencing_parameters', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution, 600): if payload['status'] != 'SUCCESS': raise exceptions.WorkflowServiceError( 'Exception generating fencing parameters: {}'.format( payload['message'])) if ('fencing_parameters' in payload and (payload.get('status', 'FAILED') == "SUCCESS")): return payload['fencing_parameters']
def ansible_tear_down(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient workflow_input['playbook_name'] = 'scale_playbook.yaml' with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.deployment.v1.config_download_deploy', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): print(payload['message']) if payload['status'] == 'SUCCESS': print("Scale-down configuration completed.") else: raise exceptions.DeploymentError("Scale-down configuration failed.")
def delete_stack(clients, stack): """Deletes the stack named in the workflow_input. :param workflow_client: Workflow client :param stack: Name or ID of stack to delete """ workflow_client = clients.workflow_engine tripleoclient = clients.tripleoclient workflow_input = {'stack': stack} with tripleoclient.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.stack.v1.delete_stack', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if payload['status'] != "SUCCESS": raise InvalidConfiguration(payload['message'])
def update_ansible(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient ansible_queue = workflow_input['ansible_queue_name'] with tripleoclients.messaging_websocket(ansible_queue) as update_ws: execution = base.start_workflow( workflow_client, 'tripleo.package_update.v1.update_nodes', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, update_ws, execution): if payload.get('message'): pprint.pprint(payload['message'].splitlines()) if payload['status'] == 'SUCCESS': print('Success') else: raise RuntimeError('Update failed with: {}'.format(payload))
def fetch_logs(clients, container, server_name, timeout=None, concurrency=None): """Executes fetch log action :param clients: openstack clients :param container: name of the container to put the logs :param server_name: server name to restrict where logs are pulled from :param timeout: timeout for the log fetch operation :param concurrency: max number of concurrent log collection tasks """ workflow_input = { "container": container, "server_name": server_name, } if timeout is not None: workflow_input['timeout'] = timeout if concurrency is not None: workflow_input['concurrency'] = concurrency workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.support.v1.fetch_logs', workflow_input=workflow_input ) messages = base.wait_for_messages(workflow_client, ws, execution, timeout) for message in messages: if message['status'] != 'SUCCESS': raise LogFetchError(message['message']) if message['message']: print('{}'.format(message['message']))
def configure(clients, **workflow_input): """Configure Node boot options. Run the tripleo.baremetal.v1.configure Mistral workflow. """ workflow_client = clients.workflow_engine ooo_client = clients.tripleoclient with ooo_client.messaging_websocket() as ws: execution = base.start_workflow(workflow_client, 'tripleo.baremetal.v1.configure', workflow_input=workflow_input) for payload in base.wait_for_messages(workflow_client, ws, execution): if 'message' in payload: print(payload['message']) if payload['status'] != 'SUCCESS': raise exceptions.NodeConfigurationError( 'Failed to configure nodes: {}'.format(payload['message']))
def get_deployment_failures(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient execution = base.start_workflow( workflow_client, 'tripleo.deployment.v1.get_deployment_failures', workflow_input=workflow_input) with tripleoclients.messaging_websocket() as ws: for payload in base.wait_for_messages(workflow_client, ws, execution, _WORKFLOW_TIMEOUT): if 'message' in payload: print(payload['message']) if payload['status'] == 'SUCCESS': return payload['deployment_failures']['failures'] else: raise exceptions.WorkflowServiceError( 'Exception getting deployment failures: {}'.format( payload.get('message', '')))
def list_available_roles(clients, **workflow_input): workflow_client = clients.workflow_engine tripleoclients = clients.tripleoclient available_roles = [] with tripleoclients.messaging_websocket() as ws: execution = base.start_workflow( workflow_client, 'tripleo.plan_management.v1.list_available_roles', workflow_input=workflow_input ) for payload in base.wait_for_messages(workflow_client, ws, execution): if payload['status'] == 'SUCCESS': available_roles = payload['available_roles'] else: raise exceptions.WorkflowServiceError( 'Error retrieving available roles: {}'.format( payload.get('message'))) return available_roles