diff --git a/ironic/conductor/utils.py b/ironic/conductor/utils.py index 9ee4a5145f..26c590f4d5 100644 --- a/ironic/conductor/utils.py +++ b/ironic/conductor/utils.py @@ -279,20 +279,19 @@ def node_power_action(task, new_state, timeout=None): # Set the target_power_state and clear any last_error, if we're # starting a new operation. This will expose to other processes # and clients that work is in progress. - if node['target_power_state'] != target_state: - node['target_power_state'] = target_state - node['last_error'] = None - driver_internal_info = node.driver_internal_info - driver_internal_info['last_power_state_change'] = str( - timeutils.utcnow().isoformat()) - node.driver_internal_info = driver_internal_info - # NOTE(dtantsur): wipe token on shutting down, otherwise a reboot in - # fast-track (or an accidentally booted agent) will cause subsequent - # actions to fail. - if target_state in (states.POWER_OFF, states.SOFT_POWER_OFF, - states.REBOOT, states.SOFT_REBOOT): - wipe_internal_info_on_power_off(node) - node.save() + node['target_power_state'] = target_state + node['last_error'] = None + driver_internal_info = node.driver_internal_info + driver_internal_info['last_power_state_change'] = str( + timeutils.utcnow().isoformat()) + node.driver_internal_info = driver_internal_info + # NOTE(dtantsur): wipe token on shutting down, otherwise a reboot in + # fast-track (or an accidentally booted agent) will cause subsequent + # actions to fail. + if target_state in (states.POWER_OFF, states.SOFT_POWER_OFF, + states.REBOOT, states.SOFT_REBOOT): + wipe_internal_info_on_power_off(node) + node.save() # take power action try: @@ -456,6 +455,8 @@ def cleaning_error_handler(task, msg, tear_down_cleaning=True, def wipe_internal_info_on_power_off(node): """Wipe information that should not survive reboot/power off.""" driver_internal_info = node.driver_internal_info + # DHCP may result in a new IP next time. + driver_internal_info.pop('agent_url', None) if not is_agent_token_pregenerated(node): # Wipe the token if it's not pre-generated, otherwise we'll refuse to # generate it again for the newly booted agent. diff --git a/ironic/tests/unit/conductor/test_utils.py b/ironic/tests/unit/conductor/test_utils.py index ebb1597d60..9f917142fe 100644 --- a/ironic/tests/unit/conductor/test_utils.py +++ b/ironic/tests/unit/conductor/test_utils.py @@ -389,6 +389,7 @@ class NodePowerActionTestCase(db_base.DbTestCase): self.assertEqual(states.POWER_OFF, node['power_state']) self.assertEqual(states.NOSTATE, node['target_power_state']) self.assertIsNone(node['last_error']) + self.assertNotIn('agent_secret_token', node['driver_internal_info']) @mock.patch.object(conductor_utils, 'LOG', autospec=True) @mock.patch.object(fake.FakePower, 'set_power_state', autospec=True) diff --git a/releasenotes/notes/power-off-token-0403e8a054f31125.yaml b/releasenotes/notes/power-off-token-0403e8a054f31125.yaml new file mode 100644 index 0000000000..8ae2ffb8e7 --- /dev/null +++ b/releasenotes/notes/power-off-token-0403e8a054f31125.yaml @@ -0,0 +1,5 @@ +--- +fixes: + - | + Fixes wiping the agent secret token on manual power off or reboot. Also + makes sure to remove the agent URL since it may potentially change.