Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
Extend Azure image details
Browse files Browse the repository at this point in the history
  • Loading branch information
F-X64 committed Nov 14, 2022
1 parent 10c6ce9 commit 8e921a7
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 5 deletions.
44 changes: 44 additions & 0 deletions src/rhelocator/update_images/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,38 @@ def get_image_versions(
return images


def get_image_details(
location: str, publisher: str, offer: str, sku: str, version: str
) -> dict[str, dict[str, str]]:
"""Get details about a specific image.
Args:
location: String containing a valid Azure location, such as eastus
publisher: String containing an Azure publisher, such as redhat
offer: String container an offer name
sku: String containing a SKU name
version: String containing a valid image SKU version
Returns:
Dictionary of image details
"""

access_token = get_access_token()
headers = {"Authorization": f"Bearer {access_token}"}
params = {"api-version": "2022-08-01"}

url = (
f"https://management.azure.com/subscriptions/{config.AZURE_SUBSCRIPTION_ID}/"
f"providers/Microsoft.Compute/locations/{location}/publishers/"
f"{publisher}/artifacttypes/vmimage/offers/{offer}/skus/{sku}/"
f"versions/{version}"
)

resp = requests.get(url, params=params, headers=headers, timeout=10)
data: dict[str, dict[str, str]] = resp.json()
return data


def get_images() -> list[dict[str, str]]:
"""Get a list of Azure RHEL images.
Expand All @@ -175,13 +207,25 @@ def get_images() -> list[dict[str, str]]:
# Loop through the image versions and add on this image version to the
# list in Azure's `az vm image list` format.
for image_version in image_versions:
image_details = get_image_details(
config.AZURE_DEFAULT_LOCATION,
publisher,
offer,
sku,
image_version,
)
result = {
"architecture": image_details["properties"]["architecture"],
"hyperVGeneration": image_details["properties"][
"hyperVGeneration"
],
"offer": offer,
"publisher": publisher,
"sku": sku,
"urn": f"{publisher}:{offer}:{sku}:{image_version}",
"version": image_version,
}

results.append(result)

return results
15 changes: 15 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,13 @@
"9.0.2022090601",
]

MOCKED_AZURE_IMAGE_DETAILS = {
"properties": {
"architecture": "x64",
"hyperVGeneration": "V2",
}
}


def pytest_configure(config: any) -> None:
config.addinivalue_line("markers", "e2e: mark as end-to-end test.")
Expand Down Expand Up @@ -78,6 +85,14 @@ def mock_azure_image_versions_latest(mocker):
return mock


@pytest.fixture
def mock_azure_image_details(mocker):
"""Provide an offline result got get_azure_image_details."""
mock = mocker.patch("rhelocator.update_images.azure.get_image_details")
mock.return_value = MOCKED_AZURE_IMAGE_DETAILS
return mock


@pytest.fixture
def mock_gcp_images(mocker):
"""Provide an offline result for calls to get_google_images."""
Expand Down
24 changes: 21 additions & 3 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,21 +98,39 @@ def test_azure_images_live(runner):
assert isinstance(parsed, list)

for image in parsed:
expected_keys = ["offer", "publisher", "sku", "urn", "version"]
expected_keys = [
"architecture",
"hyperVGeneration",
"offer",
"publisher",
"sku",
"urn",
"version",
]
assert list(image.keys()) == expected_keys

assert result.exit_code == 0


def test_azure_images_offline(mock_azure_image_versions, runner):
def test_azure_images_offline(
mock_azure_image_versions, mock_azure_image_details, runner
):
"""Run a live test against the Azure API to get images via CLI."""
result = runner.invoke(cli.azure_images)
parsed = json.loads(result.output)

assert isinstance(parsed, list)

for image in parsed:
expected_keys = ["offer", "publisher", "sku", "urn", "version"]
expected_keys = [
"architecture",
"hyperVGeneration",
"offer",
"publisher",
"sku",
"urn",
"version",
]
assert list(image.keys()) == expected_keys

assert result.exit_code == 0
Expand Down
43 changes: 41 additions & 2 deletions tests/update_images/test_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,53 @@ def test_get_image_versions(mock_get):
assert image_versions == [x["name"] for x in image_versions_response]


def test_get_latest_images(mock_azure_image_versions_latest):
@patch("rhelocator.update_images.azure.requests.get")
def test_get_image_details(mock_get):
"""Test retrieving Azure image details."""
image_details_response = {
"id": "a very long ID",
"location": "westus",
"name": "7.9.2022032206",
"properties": {
"architecture": "x64",
"automaticOSUpgradeProperties": {"automaticOSUpgradeSupported": False},
"dataDiskImages": [],
"disallowed": {"vmDiskType": "Unmanaged"},
"features": [{"name": "IsAcceleratedNetworkSupported", "value": "True"}],
"hyperVGeneration": "V2",
"imageDeprecationStatus": {"imageState": "Active"},
"osDiskImage": {"operatingSystem": "Linux", "sizeInGb": 64},
"replicaCount": 10,
"replicaType": "Managed",
},
}

mock_get.return_value = Mock(ok=True)
mock_get.return_value.json.return_value = image_details_response

image_details = azure.get_image_details(
"eastus", "publisher", "offer", "sku", "version"
)
assert (
image_details["properties"]["architecture"]
== image_details_response["properties"]["architecture"]
)
assert (
image_details["properties"]["hyperVGeneration"]
== image_details_response["properties"]["hyperVGeneration"]
)


def test_get_latest_images(mock_azure_image_versions_latest, mock_azure_image_details):
"""Test retrieving Azure images."""
images = azure.get_images()

assert isinstance(images, list)

# Make sure we have the right keys that match Azure's specification.
assert sorted(images[0].keys()) == [
"architecture",
"hyperVGeneration",
"offer",
"publisher",
"sku",
Expand All @@ -190,7 +229,7 @@ def test_get_latest_images(mock_azure_image_versions_latest):
assert len({x["sku"] for x in images}) == len(images)


def test_get_all_images(mock_azure_image_versions):
def test_get_all_images(mock_azure_image_versions, mock_azure_image_details):
"""Test retrieving Azure images when we want all of the image versions."""
# Fake an image tree with one SKU that doesn't use 'latest'.
config.AZURE_RHEL_IMAGE_TREE = {"redhat": {"RHEL": {"7lvm-gen2": ""}}}
Expand Down

0 comments on commit 8e921a7

Please sign in to comment.