diff --git a/src/bin/shipyard_airflow/shipyard_airflow/plugins/drydock_verify_nodes.py b/src/bin/shipyard_airflow/shipyard_airflow/plugins/drydock_verify_nodes.py index 212888be..36c4f10c 100644 --- a/src/bin/shipyard_airflow/shipyard_airflow/plugins/drydock_verify_nodes.py +++ b/src/bin/shipyard_airflow/shipyard_airflow/plugins/drydock_verify_nodes.py @@ -23,37 +23,57 @@ except ImportError: DrydockBaseOperator LOG = logging.getLogger(__name__) +safeguard_message_header = ( + "No nodes were found by Drydock. Safeguard triggered to prevent " + "continued deployment of nodes.") +safeguard_message_body = ( + "This condition can occur if update_site is invoked before a deploy_site " + "has previously deployed nodes in this site. If nodes are expected to be " + "present (previously deployed), this is a serious condition and should " + "be investigated. This behavior can be bypassed by setting " + "continue-on-fail to true.") +safeguard_bypassed_message = ( + "Nodes do not exist, but continue-on-fail is True. Safeguard bypassed by " + "invocation options.") class DrydockVerifyNodesExistOperator(DrydockBaseOperator): - """Drydock Verify nodes exist Operator - This operator will trigger drydock to verify node for - site update - + Check that ANY nodes exist. + One use of this is to prevent an update_site from redeploying servers if + the underlying datastores have lost their data. Doing this prevents + destruction of potentially running workloads. """ def do_execute(self): - - LOG.info('verify_nodes_exit was invoked.') + LOG.info("Verifying that nodes exist before proceeding.") node_list = self.get_nodes() - continue_on_fail = self.action_info['parameters'].get( - 'continue-on-fail', 'false') - LOG.debug('node list is : {}'.format(node_list)) - LOG.debug('continue on fail is: {}'.format(continue_on_fail)) + if not node_list: + if self.continue_on_fail(): + LOG.info(safeguard_bypassed_message) + else: + LOG.error(safeguard_message_header) + LOG.error(safeguard_message_body) + raise AirflowException(safeguard_message_header) + else: + LOG.info("Drydock reports nodes: %s", node_list) - if not node_list and str(continue_on_fail).lower() != 'true': - msg = 'No nodes were found in MaaS, ' \ - 'and continue_on_fail is {} ' \ - '-> Fail Drydock prepare and ' \ - 'deply nodes.'.format(continue_on_fail) - LOG.error(msg) - raise AirflowException(msg) + def continue_on_fail(self): + """Retrieve the continue_on_fail boolean value + + Fetch the continue-on-fail value from the action_info parameters and + translate it into a boolean value. + """ + continue_on_fail_str = str(self.action_info['parameters'].get( + 'continue-on-fail', 'false')) + continue_on_fail = continue_on_fail_str.lower() == 'true' + LOG.debug("continue-on-fail value is: %s, evaluates to: %s", + continue_on_fail_str, continue_on_fail) + return continue_on_fail class DrydockVerifyNodesExistOperatorPlugin(AirflowPlugin): - """Creates DrydockVerifyNodesExistOperatorPlugin in Airflow.""" name = 'drydock_verify_nodes_exist_operator'