Skip to content

Commit

Permalink
Adds Azure support to delete command.
Browse files Browse the repository at this point in the history
  • Loading branch information
jajreidy committed Oct 9, 2024
1 parent fc363ae commit deda351
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/pubtools/_marketplacesvm/cloud_providers/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@ def _delete_push_images(self, push_item: AmiPushItem, **kwargs) -> Tuple[AmiPush
}
self._delete(region, **delete_meta_kwargs)

return AmiPushItem
return push_item


register_provider(
Expand Down
5 changes: 3 additions & 2 deletions src/pubtools/_marketplacesvm/cloud_providers/ms_azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -353,8 +353,9 @@ def _delete_push_images(self, push_item, **kwargs):
Returns:
A VHDPushItem
"""
# TODO: Add delete functionality to Azure
LOG.info("Deleting of Azure images from a push is not implemented yet")
name = self._name_from_push_item(push_item)
delete_meta_kwargs = {"image_name": name, "container": UPLOAD_CONTAINER_NAME}
self.upload_svc.delete(**delete_meta_kwargs)
return push_item

def ensure_offer_is_writable(self, destination: str, nochannel: bool) -> None:
Expand Down
6 changes: 5 additions & 1 deletion src/pubtools/_marketplacesvm/tasks/delete/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ def _delete(
push_item: VMIPushItem,
**kwargs,
) -> VMIPushItem:
marketplaces = self._convert_provider_name(push_item.marketplace_entity_type)
# We only support two hyperscalers (Azure, AWS)
if push_item.marketplace_entity_type:
marketplaces = self._convert_provider_name(push_item.marketplace_entity_type)
else:
marketplaces = ["azure-na", "azure-emea"]
if push_item.build in self.args.builds:
if self.args.dry_run:
log.info("Would have deleted: %s in build %s", push_item.image_id, push_item.build)
Expand Down
50 changes: 47 additions & 3 deletions tests/delete/conftest.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from typing import List
from datetime import datetime
from typing import Any, Dict, List

import pytest
from pushsource import (
Expand Down Expand Up @@ -44,6 +45,26 @@ def ami_release() -> AmiRelease:
return AmiRelease(**params)


@pytest.fixture
def release_params() -> Dict[str, Any]:
return {
"product": "sample-product",
"version": "7.0",
"arch": "x86_64",
"respin": 1,
"date": datetime.now(),
}


@pytest.fixture
def push_item_params() -> Dict[str, str]:
return {
"name": "name",
"description": "",
"build_info": KojiBuildInfo(name="test-build", version="7.0", release="20230101"),
}


@pytest.fixture
def security_group() -> AmiSecurityGroup:
params = {
Expand Down Expand Up @@ -149,10 +170,33 @@ def aws_rhcos_push_item(ami_release: AmiRelease, security_group: AmiSecurityGrou


@pytest.fixture
def pub_response(aws_rhcos_push_item: AmiPushItem, aws_push_item: AmiPushItem) -> List[AmiPushItem]:
def vhd_push_item(release_params: Dict[str, Any], push_item_params: Dict[str, str]) -> AmiPushItem:
"""Return a minimal VHDPushItem."""
release = AmiRelease(**release_params)
push_item_params.update(
{
"name": "azure-testing.vhd.xz",
"release": release,
"src": "mnt/azure/azure-testing.vhd.xz",
"dest": ['azure-testing'],
"build": "azure-testing",
}
)
return AmiPushItem(**push_item_params)


@pytest.fixture
def pub_response_ami(
aws_rhcos_push_item: AmiPushItem, aws_push_item: AmiPushItem
) -> List[AmiPushItem]:
return [aws_rhcos_push_item, aws_push_item]


@pytest.fixture
def pub_response_azure(vhd_push_item: VHDPushItem) -> List[VHDPushItem]:
return [vhd_push_item]


@pytest.fixture
def pub_response_diff_amis(
aws_push_item_2: AmiPushItem, aws_push_item: AmiPushItem
Expand All @@ -161,7 +205,7 @@ def pub_response_diff_amis(


@pytest.fixture
def bad_pub_response() -> List[VHDPushItem]:
def bad_pub_response_ami() -> List[VHDPushItem]:
params = {
"name": "vhd_pushitem",
"description": "fakevhd",
Expand Down
85 changes: 62 additions & 23 deletions tests/delete/test_delete.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,23 @@ def _delete_push_images(self, push_item, **kwargs):


@pytest.fixture()
def fake_source(pub_response: List[AmiPushItem]) -> Generator[mock.MagicMock, None, None]:
def fake_ami_source(pub_response_ami: List[AmiPushItem]) -> Generator[mock.MagicMock, None, None]:
with mock.patch("pubtools._marketplacesvm.tasks.delete.command.Source") as m:
m.get.return_value.__enter__.return_value = pub_response
m.get.return_value.__enter__.return_value = pub_response_ami
yield m


@pytest.fixture()
def fake_source_dif_amis(
def fake_azure_source(
pub_response_azure: List[AmiPushItem],
) -> Generator[mock.MagicMock, None, None]:
with mock.patch("pubtools._marketplacesvm.tasks.delete.command.Source") as m:
m.get.return_value.__enter__.return_value = pub_response_azure
yield m


@pytest.fixture()
def fake_ami_source_dif_amis(
pub_response_diff_amis: List[AmiPushItem],
) -> Generator[mock.MagicMock, None, None]:
with mock.patch("pubtools._marketplacesvm.tasks.delete.command.Source") as m:
Expand All @@ -49,11 +58,11 @@ def fake_source_dif_amis(


@pytest.fixture()
def bad_fake_source(
bad_pub_response: List[Dict[str, str]]
def bad_fake_ami_source(
bad_pub_response_ami: List[Dict[str, str]]
) -> Generator[mock.MagicMock, None, None]:
with mock.patch("pubtools._marketplacesvm.tasks.delete.command.Source") as m:
m.get.return_value.__enter__.return_value = bad_pub_response
m.get.return_value.__enter__.return_value = bad_pub_response_ami
yield m


Expand Down Expand Up @@ -101,8 +110,8 @@ def fake_rhsm_api(requests_mocker):
requests_mocker.register_uri("POST", re.compile("amazon/amis"))


def test_delete(
fake_source: mock.MagicMock,
def test_delete_ami(
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand All @@ -122,13 +131,43 @@ def test_delete(
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
# There's 2 as the AmiProduct deletes require trying aws-na and aws-emea
assert fake_cloud_instance.call_count == 2
assert fake_cloud_instance.call_args_list[0].args == ('aws-china-storage',)
assert fake_cloud_instance.call_args_list[1].args == ('aws-na',)


def test_delete_vhd(
fake_azure_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
"""Test a successfull delete."""
command_tester.test(
lambda: entry_point(VMDelete),
[
"test-delete",
"--credentials",
"eyJtYXJrZXRwbGFjZV9hY2NvdW50IjogInRlc3QtbmEiLCAiYXV0aCI6eyJmb28iOiJiYXIifQo=",
"--rhsm-url",
"https://rhsm.com/test/api/",
"--debug",
"--builds",
"azure-testing",
"pub:https://fakepub.com?task-id=12345",
],
)

fake_azure_source.get.assert_called_once()
# There's 2 as the AmiProduct deletes require trying aws-na and aws-emea
assert fake_cloud_instance.call_count == 1
for call in fake_cloud_instance.call_args_list:
assert call.args == ('azure-na',)


def test_delete_skip_build(
fake_source: mock.MagicMock,
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand All @@ -148,13 +187,13 @@ def test_delete_skip_build(
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
# 1 call for RHCOS delete
assert fake_cloud_instance.call_count == 1


def test_delete_ami_id_not_found_rhsm(
fake_source: mock.MagicMock,
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
requests_mocker,
Expand Down Expand Up @@ -192,13 +231,13 @@ def test_delete_ami_id_not_found_rhsm(
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
# 2 call for RHCOS delete
assert fake_cloud_instance.call_count == 2


def test_delete_dry_run(
fake_source: mock.MagicMock,
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand All @@ -219,13 +258,13 @@ def test_delete_dry_run(
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
# 0 calls for dry-run, should just report to log
assert fake_cloud_instance.call_count == 0


def test_delete_failed(
fake_source: mock.MagicMock,
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand All @@ -251,13 +290,13 @@ def _delete_push_images(self, push_item, **kwargs):
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
# 3 calls since we errored on aws-na, aws-emea, aws-us-storage
assert fake_cloud_instance.call_count == 3


def test_delete_failed_one(
fake_source_dif_amis: mock.MagicMock,
fake_ami_source_dif_amis: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand Down Expand Up @@ -287,13 +326,13 @@ def _delete_push_images(self, push_item, **kwargs):
],
)

fake_source_dif_amis.get.assert_called_once()
fake_ami_source_dif_amis.get.assert_called_once()
# 4 Calls since we errored on the first call
assert fake_cloud_instance.call_count == 4


def test_delete_not_AmiPushItem(
bad_fake_source: mock.MagicMock,
bad_fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
) -> None:
Expand All @@ -313,13 +352,13 @@ def test_delete_not_AmiPushItem(
],
)

bad_fake_source.get.assert_called_once()
bad_fake_ami_source.get.assert_called_once()
# No calls as there was nothing to work
assert fake_cloud_instance.call_count == 0


def test_delete_bad_rhsm(
fake_source: mock.MagicMock,
fake_ami_source: mock.MagicMock,
fake_cloud_instance: mock.MagicMock,
command_tester: CommandTester,
requests_mocker,
Expand All @@ -342,4 +381,4 @@ def test_delete_bad_rhsm(
],
)

fake_source.get.assert_called_once()
fake_ami_source.get.assert_called_once()
1 change: 1 addition & 0 deletions tests/logs/delete/test_delete/test_delete_vhd.jsonl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

7 changes: 7 additions & 0 deletions tests/logs/delete/test_delete/test_delete_vhd.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[ INFO] Loading items from pub:https://fakepub.com?task-id=12345
[ INFO] Deleting None in account azure-na
[ INFO] Delete finished for None in account azure-na
[ DEBUG] Listing all images from rhsm, https://rhsm.com/v1/internal/cloud_access_providers/amazon/amis
[ WARNING] AMI image: None not found, skipping update in rhsm.
[ INFO] Collecting results
[ INFO] Delete completed

0 comments on commit deda351

Please sign in to comment.