diff --git a/sunbeam-python/sunbeam/steps/openstack.py b/sunbeam-python/sunbeam/steps/openstack.py index 59dad008d..dbea89dd0 100644 --- a/sunbeam-python/sunbeam/steps/openstack.py +++ b/sunbeam-python/sunbeam/steps/openstack.py @@ -1215,7 +1215,10 @@ def prompt( show_hint=show_hint, ) - self.variables["configure"] = configure_endpoint_bank.configure.ask() + if self.manifest is None and not self.accept_defaults: + self.variables["configure"] = configure_endpoint_bank.configure.ask() + else: + self.variables["configure"] = preseed.get("configure", False) if not self.variables["configure"]: # Clear all endpoint data when user chooses not to configure endpoints diff --git a/sunbeam-python/tests/unit/sunbeam/steps/test_openstack.py b/sunbeam-python/tests/unit/sunbeam/steps/test_openstack.py index ad25254fa..b334aa1eb 100644 --- a/sunbeam-python/tests/unit/sunbeam/steps/test_openstack.py +++ b/sunbeam-python/tests/unit/sunbeam/steps/test_openstack.py @@ -34,6 +34,7 @@ OPENSTACK_MODEL_CONFIG_KEY, RABBITMQ_STORAGE_KEY, DeployControlPlaneStep, + EndpointsConfigurationStep, OpenStackPatchLoadBalancerServicesIPPoolStep, OpenStackPatchLoadBalancerServicesIPStep, ReapplyOpenStackTerraformPlanStep, @@ -1968,3 +1969,88 @@ def test_charm_not_in_manifest(self, manifest_read_config, snap): ) assert result == [] + + +class TestEndpointsConfigurationStepPrompt: + """Tests for the endpoints promp-skip fix.""" + + def _make_step(self, manifest=None, accept_defaults=False, client=None): + client = client or Mock() + step = EndpointsConfigurationStep( + client=client, + manifest=manifest, + accept_defaults=accept_defaults, + ) + return step + + @patch("sunbeam.steps.openstack.INGRESS_ENDPOINT_TYPES", []) + @patch("sunbeam.steps.openstack.load_answers") + @patch("sunbeam.steps.openstack.QuestionBank") + def test_no_manifest_no_accept_defaults_prompts_interactively( + self, mock_question_bank, mock_load_answers + ): + """With no manifest and no --accept-defaults, should prompt.""" + mock_load_answers.return_value = {} + mock_bank_instance = mock_question_bank.return_value + mock_bank_instance.configure.ask.return_value = True + + step = self._make_step(manifest=None, accept_defaults=False) + step.prompt(console=None) + + mock_bank_instance.configure.ask.assert_called_once() + assert step.variables["configure"] is True + + @patch("sunbeam.steps.openstack.INGRESS_ENDPOINT_TYPES", []) + @patch("sunbeam.steps.openstack.load_answers") + @patch("sunbeam.steps.openstack.QuestionBank") + def test_manifest_without_endpoints_does_not_prompt( + self, mock_question_bank, mock_load_answers + ): + """Manifest provided and no core.config.endpoints, should not prompt.""" + mock_load_answers.return_value = {} + mock_bank_instance = mock_question_bank.return_value + + manifest = Mock() + manifest.core.config.endpoints = None + + step = self._make_step(manifest=manifest, accept_defaults=False) + step.prompt(console=None) + + mock_bank_instance.configure.ask.assert_not_called() + assert step.variables["configure"] is False + + @patch("sunbeam.steps.openstack.INGRESS_ENDPOINT_TYPES", []) + @patch("sunbeam.steps.openstack.load_answers") + @patch("sunbeam.steps.openstack.QuestionBank") + def test_manifest_with_endpoints_does_not_prompt_uses_value( + self, mock_question_bank, mock_load_answers + ): + """Manifest provided with core.config.endpoints, should not prompt.""" + mock_load_answers.return_value = {} + mock_bank_instance = mock_question_bank.return_value + + manifest = Mock() + manifest.core.config.endpoints.model_dump.return_value = { + "configure": True, + } + + step = self._make_step(manifest=manifest, accept_defaults=False) + step.prompt(console=None) + + mock_bank_instance.configure.ask.assert_not_called() + assert step.variables["configure"] is True + + @patch("sunbeam.steps.openstack.load_answers") + @patch("sunbeam.steps.openstack.QuestionBank") + def test_accept_defaults_does_not_prompt_even_without_manifest( + self, mock_question_bank, mock_load_answers + ): + """--accept-defaults set: should not prompt, regardless of the manifest.""" + mock_load_answers.return_value = {} + mock_bank_instance = mock_question_bank.return_value + + step = self._make_step(manifest=None, accept_defaults=True) + step.prompt(console=None) + + mock_bank_instance.configure.ask.assert_not_called() + assert step.variables["configure"] is False