diff --git a/src/cloudimagedirectory/transform/transform.py b/src/cloudimagedirectory/transform/transform.py index 88722478..3954d270 100644 --- a/src/cloudimagedirectory/transform/transform.py +++ b/src/cloudimagedirectory/transform/transform.py @@ -523,3 +523,44 @@ def run(self, data: type[Transformer]) -> list: # NOTE: Add /list suffix to prevent collision with "provider" folder. results.append(connection.DataEntry(f"v2/os/{os}/provider/list", provider_map)) return results + + +class TransformerV2ListVersionByProvider(Transformer): + """Generate a list for all available versions for a specific provider.""" + + @no_type_check + def run(self, data: type[Transformer]) -> list: + # NOTE: check that its the v2 data entries. + entries = [x for x in data if x.is_API("v2")] + + results = [] + versions = {} + + for e in entries: + entry = copy.deepcopy(e) + filename = entry.filename.split("/") + os = filename[2] + provider = filename[4] + version = filename[6] + + if os not in versions: + versions[os] = {provider: {}} + + if provider not in versions[os]: + versions[os][provider] = {version: 1} + continue + + if version not in versions[os][provider]: + versions[os][provider][version] = 1 + continue + + # NOTE: Counter of how many images are available in this explicit provider. + versions[os][provider][version] += 1 + + for os, version_map in versions.items(): + for provider in version_map: + # NOTE: Add /list suffix to prevent collision with "version" folder. + results.append( + connection.DataEntry(f"v2/os/{os}/provider/{provider}/version/list", version_map[provider]) + ) + return results diff --git a/src/cloudimagedirectory/transformer.py b/src/cloudimagedirectory/transformer.py index 0d37a612..2766cbd9 100644 --- a/src/cloudimagedirectory/transformer.py +++ b/src/cloudimagedirectory/transformer.py @@ -99,6 +99,7 @@ def run(origin_path: str, destination_path: str, arg_files: str, filter_until: s transform.TransformerV2All, transform.TransformerV2ListOS, transform.TransformerV2ListProviderByOS, + transform.TransformerV2ListVersionByProvider, ], ) print("run pipeline v2") diff --git a/tests/transformer/test_list_version.py b/tests/transformer/test_list_version.py new file mode 100644 index 00000000..66ad86da --- /dev/null +++ b/tests/transformer/test_list_version.py @@ -0,0 +1,86 @@ +"""Test for the list version endpoint.""" +import filecmp +import os + +from cloudimagedirectory import transformer + + +def test_V2ListVersion(runner, tmp_path): + """Run transformer end to end and generate a list with all available + versions for the specific provider.""" + result = runner.invoke( + transformer.run, + [ + "-f", + "tests/transformer/testdata/input/raw/google/all.json,tests/transformer/testdata/input/raw/aws/af-south-1.json,tests/transformer/testdata/input/raw/azure/eastus.json", + "-op=.", + f"-dp={tmp_path}", + "--filter.until=none", + ], + ) + + assert result.exit_code == 0, f"expected no error, but got code {result.exit_code} and output:\n{result.output}" + + # Get current directory + pwd = os.getcwd() + + # Check image data by comparing the expected file and the output file byte by byte. + assert filecmp.cmp( + f"{pwd}/tests/transformer/testdata/expected/v2/os/rhel/provider/google/version/list", + f"{tmp_path}/v2/os/rhel/provider/google/version/list", + ) + + +def test_transformerV2ListVersion(tmpdir): + """Test list version run method.""" + temporary_directory = tmpdir.mkdir("test") + connection = transformer.connection.ConnectionFS(temporary_directory, []) + runner = transformer.transform.TransformerV2ListVersionByProvider(connection) + chunk_size = 2 + runner.chunk_size = chunk_size + data = [ + transformer.connection.DataEntry( + "v2/os/rhel/provider/google/version/9/region/global/image/9054fbe0b622c638224d50d20824d2ff6782e308", + { + "date": "2023-03-06T12:57:17.827-08:00", + "name": "test2", + "arch": "ARM64", + "region": "global", + }, + ), + transformer.connection.DataEntry( + "v2/os/rhel/provider/google/version/8/region/global/image/dba7673010f19a94af4345453005933fd511bea9", + { + "date": "2019-01-01", + "name": "test1", + "arch": "arch1", + "region": "global", + }, + ), + transformer.connection.DataEntry( + "v2/os/rhel/provider/aws/version/8/region/ap-south-2/image/9054fbe0b622c638224d50d20824d2ff6782e308", + { + "date": "2020-01-01", + "name": "test2", + "arch": "arch2", + "region": "ap-south-2", + }, + ), + transformer.connection.DataEntry( + "v2/os/unkown/provider/aws/version/7/region/some-region-1/image/9054fbe0b622c638224d50d20824d2ff6782e308", + { + "date": "2020-01-01", + "name": "test2", + "arch": "arch2", + "region": "region-1", + }, + ), + ] + results = runner.run(data) + expected = transformer.connection.DataEntry( + "v2/os/rhel/provider/google/version/list", + {"8": 1, "9": 1}, + ) + + assert expected.filename == results[0].filename + assert expected.content == results[0].content diff --git a/tests/transformer/testdata/expected/v2/os/rhel/provider/google/version/list b/tests/transformer/testdata/expected/v2/os/rhel/provider/google/version/list new file mode 100644 index 00000000..7adc243a --- /dev/null +++ b/tests/transformer/testdata/expected/v2/os/rhel/provider/google/version/list @@ -0,0 +1 @@ +{"7": 1}