Skip to content

Commit c5bba9e

Browse files
committed
Refactor AzureService.publish
Refactor the code from `AzureService.publish` by decoupling some of its internals into privdate methods. The goal here is to clean up the code and make it more legible. Refers to SPSTRAT-595 Signed-off-by: Jonathan Gangi <[email protected]>
1 parent 332bac9 commit c5bba9e

File tree

2 files changed

+148
-55
lines changed

2 files changed

+148
-55
lines changed

cloudpub/ms_azure/service.py

Lines changed: 134 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
AzureResource,
1919
ConfigureStatus,
2020
CustomerLeads,
21+
DiskVersion,
2122
Listing,
2223
ListingAsset,
2324
ListingTrailer,
@@ -38,6 +39,7 @@
3839
from cloudpub.ms_azure.session import PartnerPortalSession
3940
from cloudpub.ms_azure.utils import (
4041
AzurePublishingMetadata,
42+
TechnicalConfigLookUpData,
4143
create_disk_version_from_scratch,
4244
is_azure_job_not_complete,
4345
is_sas_present,
@@ -653,6 +655,123 @@ def _publish_live(self, product: Product, product_name: str) -> None:
653655
)
654656
raise RuntimeError(failure_msg)
655657

658+
def _overwrite_disk_version(
659+
self,
660+
metadata: AzurePublishingMetadata,
661+
product_name: str,
662+
plan_name: str,
663+
source: VMImageSource,
664+
) -> TechnicalConfigLookUpData:
665+
"""Private method to overwrite the technical config with a new DiskVersion.
666+
667+
Args:
668+
metadata (AzurePublishingMetadata): the incoming publishing metadata
669+
product_name (str): the product (offer) name
670+
plan_name (str): the plan name
671+
source (VMImageSource): the source VMI to create and overwrite the new DiskVersion
672+
673+
Returns:
674+
TechnicalConfigLookUpData: The overwritten tech_config for the product/plan
675+
"""
676+
product, plan, tgt = self.get_product_plan_by_name(product_name, plan_name)
677+
log.warning(
678+
"Overwriting the plan \"%s\" on \"%s\" with the given image: \"%s\".",
679+
plan_name,
680+
tgt,
681+
metadata.image_path,
682+
)
683+
tech_config = self.get_plan_tech_config(product, plan)
684+
disk_version = create_disk_version_from_scratch(metadata, source)
685+
tech_config.disk_versions = [disk_version]
686+
return {
687+
"metadata": metadata,
688+
"tech_config": tech_config,
689+
"sas_found": False,
690+
"product": product,
691+
"plan": plan,
692+
"target": tgt,
693+
}
694+
695+
def _look_up_sas_on_technical_config(
696+
self, metadata: AzurePublishingMetadata, product_name: str, plan_name: str, target: str
697+
) -> TechnicalConfigLookUpData:
698+
"""Private method to lookup for the TechnicalConfig of a given target.
699+
700+
Args:
701+
metadata (AzurePublishingMetadata): the incoming publishing metadata.
702+
product_name (str): the product (offer) name
703+
plan_name (str): the plan name
704+
target (str): the submission target to look up the TechnicalConfig object
705+
706+
Returns:
707+
TechnicalConfigLookUpData: The data retrieved for the given submission target.
708+
"""
709+
product, plan, tgt = self.get_product_plan_by_name(
710+
product_name, plan_name, first_target=target
711+
)
712+
log.info(
713+
"Retrieving the technical config for \"%s\" on \"%s\".",
714+
metadata.destination,
715+
tgt,
716+
)
717+
tech_config = self.get_plan_tech_config(product, plan)
718+
sas_found = False
719+
720+
if is_sas_present(tech_config, metadata.image_path, metadata.check_base_sas_only):
721+
log.info(
722+
"The destination \"%s\" on \"%s\" already contains the SAS URI: \"%s\".",
723+
metadata.destination,
724+
tgt,
725+
metadata.image_path,
726+
)
727+
sas_found = True
728+
return {
729+
"metadata": metadata,
730+
"tech_config": tech_config,
731+
"sas_found": sas_found,
732+
"product": product,
733+
"plan": plan,
734+
"target": tgt,
735+
}
736+
737+
def _create_or_update_disk_version(
738+
self,
739+
tech_config_lookup: TechnicalConfigLookUpData,
740+
source: VMImageSource,
741+
disk_version: Optional[DiskVersion],
742+
) -> DiskVersion:
743+
"""Private method to create/update the DiskVersion of a given TechnicalConfig object.
744+
745+
Args:
746+
tech_config_lookup (TechnicalConfigLookUpData): the incoming data to process
747+
source (VMImageSource): the new VMI source to attach
748+
disk_version (Optional[DiskVersion]): the disk version if it exists (for updates).
749+
750+
Returns:
751+
DiskVersion: The updated DiskVersion
752+
"""
753+
metadata = tech_config_lookup["metadata"]
754+
target = tech_config_lookup["target"]
755+
tech_config = tech_config_lookup["tech_config"]
756+
757+
# Check the images of the selected DiskVersion if it exists
758+
if disk_version:
759+
log.info(
760+
"DiskVersion \"%s\" exists in \"%s\" on \"%s\" for the image \"%s\".",
761+
disk_version.version_number,
762+
metadata.destination,
763+
target,
764+
metadata.image_path,
765+
)
766+
# Update the disk version with the new SAS
767+
disk_version = set_new_sas_disk_version(disk_version, metadata, source)
768+
return disk_version
769+
# The disk version doesn't exist, we need to create one from scratch
770+
log.info("The DiskVersion doesn't exist, creating one from scratch.")
771+
disk_version = create_disk_version_from_scratch(metadata, source)
772+
tech_config.disk_versions.append(disk_version)
773+
return disk_version
774+
656775
def publish(self, metadata: AzurePublishingMetadata) -> None:
657776
"""
658777
Associate a VM image with a given product listing (destination) and publish it if required.
@@ -667,7 +786,6 @@ def publish(self, metadata: AzurePublishingMetadata) -> None:
667786
product_name = metadata.destination.split("/")[0]
668787
plan_name = metadata.destination.split("/")[-1]
669788
disk_version = None
670-
sas_found = False
671789
log.info(
672790
"Preparing to associate the image \"%s\" with the plan \"%s\" from product \"%s\"",
673791
metadata.image_path,
@@ -685,47 +803,23 @@ def publish(self, metadata: AzurePublishingMetadata) -> None:
685803
# Note: If `overwrite` is True it means we can set this VM image as the only one in the
686804
# plan's technical config and discard all other VM images which may've been present.
687805
if metadata.overwrite is True:
688-
product, plan, tgt = self.get_product_plan_by_name(product_name, plan_name)
689-
log.warning(
690-
"Overwriting the plan \"%s\" on \"%s\" with the given image: \"%s\".",
691-
plan_name,
692-
tgt,
693-
metadata.image_path,
694-
)
695-
tech_config = self.get_plan_tech_config(product, plan)
696-
disk_version = create_disk_version_from_scratch(metadata, source)
697-
tech_config.disk_versions = [disk_version]
806+
res = self._overwrite_disk_version(metadata, product_name, plan_name, source)
807+
tgt = res["target"]
808+
tech_config = res["tech_config"]
809+
disk_version = tech_config.disk_versions[0] # only 1 as it was overwritten
698810
else:
699811
# Otherwise we need to check whether SAS isn't already present
700812
# in any of the targets "preview", "live" or "draft" and if not attach and publish it.
701-
for initial_target in list_all_targets(start_with="preview"):
702-
703-
# 3.1 Retrieve the VM Technical configuration for the given plan
704-
product, plan, tgt = self.get_product_plan_by_name(
705-
product_name, plan_name, first_target=initial_target
706-
)
707-
log.info(
708-
"Retrieving the technical config for \"%s\" on \"%s\".",
709-
metadata.destination,
710-
tgt,
813+
for target in list_all_targets(start_with="preview"):
814+
res = self._look_up_sas_on_technical_config(
815+
metadata, product_name, plan_name, target
711816
)
712-
tech_config = self.get_plan_tech_config(product, plan)
713-
714-
if is_sas_present(tech_config, metadata.image_path, metadata.check_base_sas_only):
715-
log.info(
716-
"The destination \"%s\" on \"%s\" already contains the SAS URI: \"%s\".",
717-
metadata.destination,
718-
tgt,
719-
metadata.image_path,
720-
)
721-
# We don't want to seek for SAS anymore as it was already found
722-
sas_found = True
817+
tech_config = res["tech_config"]
818+
tgt = res["target"]
819+
# We don't want to seek for SAS anymore as it was already found
820+
if res["sas_found"]:
723821
break
724-
else:
725-
# Seek SAS URI until it reaches the last target
726-
continue
727-
728-
if not sas_found:
822+
else:
729823
# At this point there's no SAS URI in any target so we can safely add it
730824

731825
# Here we can have the metadata.disk_version set or empty.
@@ -736,23 +830,8 @@ def publish(self, metadata: AzurePublishingMetadata) -> None:
736830
tgt,
737831
metadata.image_path,
738832
)
739-
disk_version = seek_disk_version(tech_config, metadata.disk_version)
740-
741-
# Check the images of the selected DiskVersion if it exists
742-
if disk_version:
743-
log.info(
744-
"DiskVersion \"%s\" exists in \"%s\" on \"%s\" for the image \"%s\".",
745-
disk_version.version_number,
746-
metadata.destination,
747-
tgt,
748-
metadata.image_path,
749-
)
750-
disk_version = set_new_sas_disk_version(disk_version, metadata, source)
751-
752-
else: # The disk version doesn't exist, we need to create one from scratch
753-
log.info("The DiskVersion doesn't exist, creating one from scratch.")
754-
disk_version = create_disk_version_from_scratch(metadata, source)
755-
tech_config.disk_versions.append(disk_version)
833+
dv = seek_disk_version(tech_config, metadata.disk_version)
834+
disk_version = self._create_or_update_disk_version(res, source, dv)
756835

757836
# 4. With the updated disk_version we should adjust the SKUs and submit the changes
758837
if disk_version:
@@ -773,6 +852,7 @@ def publish(self, metadata: AzurePublishingMetadata) -> None:
773852
# 5. Proceed to publishing if it was requested.
774853
# Note: The publishing will only occur if it made changes in disk_version.
775854
if not metadata.keepdraft:
855+
product = res["product"]
776856
# Get the submission state
777857
submission: ProductSubmission = cast(
778858
List[ProductSubmission],

cloudpub/ms_azure/utils.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# SPDX-License-Identifier: GPL-3.0-or-later
22
import logging
33
from operator import attrgetter
4-
from typing import Any, Dict, List, Optional, Tuple
4+
from typing import Any, Dict, List, Optional, Tuple, TypedDict
55

66
from deepdiff import DeepDiff
77

88
from cloudpub.common import PublishingMetadata # Cannot circular import AzurePublishingMetadata
99
from cloudpub.models.ms_azure import (
1010
ConfigureStatus,
1111
DiskVersion,
12+
PlanSummary,
13+
Product,
1214
VMImageDefinition,
1315
VMImageSource,
1416
VMIPlanTechConfig,
@@ -113,6 +115,17 @@ def __validate(self):
113115
raise ValueError(f"Invalid SAS URI \"{self.image_path}\". Expected: http/https URL.")
114116

115117

118+
class TechnicalConfigLookUpData(TypedDict):
119+
"""A typed dict to be used for private methods data exchange."""
120+
121+
metadata: AzurePublishingMetadata
122+
tech_config: VMIPlanTechConfig
123+
sas_found: bool
124+
product: Product
125+
plan: PlanSummary
126+
target: str
127+
128+
116129
def get_image_type_mapping(architecture: str, generation: str) -> str:
117130
"""Return the image type required by VMImageDefinition."""
118131
gen_map = {

0 commit comments

Comments
 (0)