Skip to content

Commit

Permalink
Merge pull request #2211 from craddm/config-upload-errors
Browse files Browse the repository at this point in the history
Catch config upload validation errors
  • Loading branch information
JimMadge authored Oct 8, 2024
2 parents f275f5d + 934ec49 commit 567d30e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 4 deletions.
6 changes: 5 additions & 1 deletion data_safe_haven/commands/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,11 @@ def upload(
else:
logger.critical(f"Configuration file '{file}' not found.")
raise typer.Exit(1)
config = SREConfig.from_yaml(config_yaml)
try:
config = SREConfig.from_yaml(config_yaml)
except DataSafeHavenTypeError as exc:
logger.error("Check for missing or incorrect fields in the configuration.")
raise typer.Exit(1) from exc

# Present diff to user
if (not force) and SREConfig.remote_exists(context, filename=config.filename):
Expand Down
2 changes: 1 addition & 1 deletion data_safe_haven/serialisers/yaml_serialisable_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def from_yaml(cls: type[T], settings_yaml: str) -> T:
)
for error in exc.errors():
logger.error(
f"[red]{'.'.join(map(str, error.get('loc', [])))}: {error.get('input', '')}[/] - {error.get('msg', '')}"
f"{error.get('msg', '')}: [red]{'.'.join(map(str, error.get('loc', [])))}.[/] Original input: [red]{error.get('input', '')}[/]"
)
msg = f"{cls.config_type} configuration is invalid."
raise DataSafeHavenTypeError(msg) from exc
Expand Down
13 changes: 13 additions & 0 deletions tests/commands/test_config_sre.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,16 @@ def test_upload_invalid_config_force(
context.storage_account_name,
context.storage_container_name,
)

def test_upload_missing_field(
self, runner, tmp_path, sre_config_yaml_missing_field
):
config_file_path = tmp_path / "config.yaml"
with open(config_file_path, "w") as f:
f.write(sre_config_yaml_missing_field)

result = runner.invoke(config_command_group, ["upload", str(config_file_path)])

assert result.exit_code == 1
assert "validation errors" in result.stdout
assert "Check for missing" in result.stdout
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,12 @@ def sre_config_yaml(request):
return yaml.dump(yaml.safe_load(content))


@fixture
def sre_config_yaml_missing_field(sre_config_yaml):
content = sre_config_yaml.replace("admin_email_address: [email protected]", "")
return yaml.dump(yaml.safe_load(content))


@fixture
def sre_project_manager(
context_no_secrets,
Expand Down
13 changes: 11 additions & 2 deletions tests/serialisers/test_yaml_serialisable_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,24 @@ def test_from_yaml_not_dict(self):
):
ExampleYAMLSerialisableModel.from_yaml(yaml)

def test_from_yaml_validation_error(self):
def test_from_yaml_validation_errors(self, caplog):
yaml = "\n".join(
["string: 'abc'", "integer: 'not an integer'", "list_of_integers: [-1,0,1]"]
[
"string: 'abc'",
"integer: 'not an integer'",
"list_of_integers: [-1,0,z,1]",
]
)
with raises(
DataSafeHavenTypeError,
match="Example configuration is invalid.",
):
ExampleYAMLSerialisableModel.from_yaml(yaml)
assert "Input should be a valid integer" in caplog.text
assert "Original input: not an integer" in caplog.text
assert "unable to parse string as an integer" in caplog.text
assert "list_of_integers.2" in caplog.text
assert "Original input: z" in caplog.text

def test_to_filepath(self, tmp_path, example_config_class):
filepath = tmp_path / "test.yaml"
Expand Down

0 comments on commit 567d30e

Please sign in to comment.