Skip to content

Commit 2f208e6

Browse files
authored
Merge pull request #107 from release-engineering/simplify_sas
Azure: Allow partial SAS comparison
2 parents ee25ebe + de35242 commit 2f208e6

File tree

4 files changed

+76
-26
lines changed

4 files changed

+76
-26
lines changed

cloudpub/ms_azure/service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ def publish(self, metadata: AzurePublishingMetadata) -> None:
620620
tech_config.disk_versions = [disk_version]
621621

622622
# We just want to append a new image if the SAS is not already present.
623-
elif not is_sas_present(tech_config, metadata.image_path):
623+
elif not is_sas_present(tech_config, metadata.image_path, metadata.check_base_sas_only):
624624
# Here we can have the metadata.disk_version set or empty.
625625
# When set we want to get the existing disk_version which matches its value.
626626
log.debug("Scanning the disk versions from %s" % metadata.destination)

cloudpub/ms_azure/utils.py

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ def __init__(
5151
legacy_sku_id (str, optional):
5252
Only required when ``support_legacy == True``. The SKU ID for Gen1.
5353
Defaults to ``{sku_id}-gen1``
54+
check_base_sas_only (bool, optional):
55+
Indicates to skip checking SAS parameters when set as ``True``.
56+
Default to ``False``
5457
**kwargs
5558
Arguments for :class:`~cloudpub.common.PublishingMetadata`.
5659
"""
@@ -60,6 +63,7 @@ def __init__(
6063
self.support_legacy = support_legacy
6164
self.recommended_sizes = recommended_sizes or []
6265
self.legacy_sku_id = kwargs.pop("legacy_sku_id", None)
66+
self.check_base_sas_only = kwargs.pop("check_base_sas_only", False)
6367

6468
if generation == "V1" or not support_legacy:
6569
self.legacy_sku_id = None
@@ -113,7 +117,7 @@ def get_image_type_mapping(architecture: str, generation: str) -> str:
113117
return gen_map.get(generation, "")
114118

115119

116-
def is_sas_eq(sas1: str, sas2: str) -> bool:
120+
def is_sas_eq(sas1: str, sas2: str, base_only=False) -> bool:
117121
"""
118122
Compare 2 SAS URI and determine where they're equivalent.
119123
@@ -127,10 +131,12 @@ def is_sas_eq(sas1: str, sas2: str) -> bool:
127131
This comparison is necessary as each time a SAS URI is generated it returns a different value.
128132
129133
Args:
130-
sas1:
134+
sas1 (str):
131135
The left SAS to compare the equivalency
132-
sas2:
136+
sas2 (str):
133137
The right SAS to compare the equivalency
138+
base_only (bool):
139+
When True it will only compare the base SAS and not its arguments. Defaults to False.
134140
135141
Returns:
136142
True when both SAS URIs are equivalent, False otherwise.
@@ -147,25 +153,26 @@ def is_sas_eq(sas1: str, sas2: str) -> bool:
147153
log.debug("Got different base SAS: %s - Expected: %s" % (base_sas1, base_sas2))
148154
return False
149155

150-
# Parameters lengh differs
151-
if len(params_sas1) != len(params_sas2):
152-
log.debug(
153-
"Got different lengh of SAS parameters: len(%s) - Expected len(%s)"
154-
% (params_sas1, params_sas2)
155-
)
156-
return False
157-
158-
# Parameters values differs
159-
for k, v in params_sas1.items():
160-
if v != params_sas2.get(k, None):
161-
log.debug("The SAS parameter %s doesn't match %s." % (v, params_sas2.get(k, None)))
156+
if not base_only:
157+
# Parameters lengh differs
158+
if len(params_sas1) != len(params_sas2):
159+
log.debug(
160+
"Got different lengh of SAS parameters: len(%s) - Expected len(%s)"
161+
% (params_sas1, params_sas2)
162+
)
162163
return False
163164

165+
# Parameters values differs
166+
for k, v in params_sas1.items():
167+
if v != params_sas2.get(k, None):
168+
log.debug("The SAS parameter %s doesn't match %s." % (v, params_sas2.get(k, None)))
169+
return False
170+
164171
# Equivalent SAS
165172
return True
166173

167174

168-
def is_sas_present(tech_config: VMIPlanTechConfig, sas_uri: str) -> bool:
175+
def is_sas_present(tech_config: VMIPlanTechConfig, sas_uri: str, base_only: bool = False) -> bool:
169176
"""
170177
Check whether the given SAS URI is already present in the disk_version.
171178
@@ -174,12 +181,14 @@ def is_sas_present(tech_config: VMIPlanTechConfig, sas_uri: str) -> bool:
174181
The plan's technical configuraion to seek the SAS_URI.
175182
sas_uri (str)
176183
The SAS URI to check whether it's present or not in disk version.
184+
base_only (bool):
185+
When True it will only compare the base SAS and not its arguments. Defaults to False.
177186
Returns:
178187
bool: True when the SAS is present in the plan, False otherwise.
179188
"""
180189
for disk_version in tech_config.disk_versions:
181190
for img in disk_version.vm_images:
182-
if is_sas_eq(img.source.os_disk.uri, sas_uri):
191+
if is_sas_eq(img.source.os_disk.uri, sas_uri, base_only):
183192
return True
184193
return False
185194

tests/ms_azure/test_service.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1076,7 +1076,9 @@ def test_publish_nodiskversion(
10761076
mock_filter.assert_called_once_with(
10771077
product=product_obj, resource="virtual-machine-plan-technical-configuration"
10781078
)
1079-
mock_is_sas.assert_called_once_with(technical_config_obj, metadata_azure_obj.image_path)
1079+
mock_is_sas.assert_called_once_with(
1080+
technical_config_obj, metadata_azure_obj.image_path, False
1081+
)
10801082
mock_prep_img.assert_not_called()
10811083
mock_upd_sku.assert_called_once_with(
10821084
disk_versions=expected_tech_config.disk_versions,
@@ -1134,6 +1136,7 @@ def test_publish_saspresent(
11341136
mock_is_sas.assert_called_once_with(
11351137
technical_config_obj,
11361138
metadata_azure_obj.image_path,
1139+
False,
11371140
)
11381141
mock_prep_img.assert_not_called()
11391142
mock_disk_scratch.assert_not_called()
@@ -1202,6 +1205,7 @@ def test_publish_novmimages(
12021205
mock_is_sas.assert_called_once_with(
12031206
technical_config_obj,
12041207
metadata_azure_obj.image_path,
1208+
False,
12051209
)
12061210
mock_prep_img.assert_not_called()
12071211
mock_disk_scratch.assert_not_called()
@@ -1267,6 +1271,7 @@ def test_publish_disk_has_images(
12671271
mock_is_sas.assert_called_once_with(
12681272
technical_config_obj,
12691273
metadata_azure_obj.image_path,
1274+
False,
12701275
)
12711276
mock_prep_img.assert_called_once_with(
12721277
metadata=metadata_azure_obj,
@@ -1389,6 +1394,7 @@ def test_publish_live_x64_only(
13891394
mock_is_sas.assert_called_once_with(
13901395
technical_config_obj,
13911396
metadata_azure_obj.image_path,
1397+
False,
13921398
)
13931399
mock_prep_img.assert_called_once_with(
13941400
metadata=metadata_azure_obj,
@@ -1479,6 +1485,7 @@ def test_publish_live_arm64_only(
14791485
mock_is_sas.assert_called_once_with(
14801486
technical_config_obj,
14811487
metadata_azure_obj.image_path,
1488+
False,
14821489
)
14831490
mock_prep_img.assert_called_once_with(
14841491
metadata=metadata_azure_obj,

tests/ms_azure/test_utils.py

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,31 +102,65 @@ def test_get_image_type_mapping(self, metadata_azure_obj: AzurePublishingMetadat
102102
assert res == "x64Gen2"
103103

104104
@pytest.mark.parametrize(
105-
"sas1,sas2,expected",
105+
"sas1,sas2,base_only,expected",
106106
[
107-
("https://foo.com/bar", "https://foo.com/bar?foo=bar", False),
108-
("https://foo.com/bar?foo=bar&st=aaaaa", "https://foo.com/bar?foo=bar&st=bbb", True),
107+
("https://foo.com/bar", "https://foo.com/bar?foo=bar", False, False),
108+
(
109+
"https://foo.com/bar?foo=bar&st=aaaaa",
110+
"https://foo.com/bar?foo=bar&st=bbb",
111+
False,
112+
True,
113+
),
109114
(
110115
"https://foo.com/bar?foo=bar&st=a&se=b&sig=c&bar=foo",
111116
"https://foo.com/bar?foo=bar&st=d&se=e&sig=f&bar=foo",
117+
False,
112118
True,
113119
),
114120
(
115121
"https://foo.com/bar?foo=bar&st=a&se=b&sig=c&bar=foo",
116122
"https://foo.com/bar?foo=foo&st=d&se=e&sig=f",
117123
False,
124+
False,
125+
),
126+
(
127+
"https://foo.com/bar?foo=bar&st=aaaaa",
128+
"https://bar.com/foo?foo=bar&st=bbb",
129+
False,
130+
False,
131+
),
132+
(
133+
"https://foo.com/bar?bar=foo&st=aaaaa",
134+
"https://foo.com/bar?foo=bar&st=bbb",
135+
False,
136+
False,
137+
),
138+
(
139+
"https://foo.com/bar?foo=bar&st=aaaaa",
140+
"https://bar.com/foo?foo=bar&st=bbb",
141+
True,
142+
False,
143+
),
144+
(
145+
"https://foo.com/bar?bar=foo&st=aaaaa",
146+
"https://foo.com/bar?foo=bar&st=bbb",
147+
True,
148+
True,
118149
),
119-
("https://foo.com/bar?foo=bar&st=aaaaa", "https://bar.com/foo?foo=bar&st=bbb", False),
120-
("https://foo.com/bar?bar=foo&st=aaaaa", "https://foo.com/bar?foo=bar&st=bbb", False),
121150
],
122151
)
123152
def test_is_sas_present(
124-
self, sas1: str, sas2: str, expected: bool, technical_config_obj: VMIPlanTechConfig
153+
self,
154+
sas1: str,
155+
sas2: str,
156+
base_only: bool,
157+
expected: bool,
158+
technical_config_obj: VMIPlanTechConfig,
125159
) -> None:
126160
# Test positive
127161
technical_config_obj.disk_versions[0].vm_images[0].source.os_disk.uri = sas1
128162

129-
res = is_sas_present(tech_config=technical_config_obj, sas_uri=sas2)
163+
res = is_sas_present(tech_config=technical_config_obj, sas_uri=sas2, base_only=base_only)
130164
assert res is expected
131165

132166
def test_prepare_vm_images_gen1(

0 commit comments

Comments
 (0)