From dc5cdc3a25c5644db372e6b8aa670404ff9fe93b Mon Sep 17 00:00:00 2001 From: narrieta Date: Tue, 15 Mar 2022 13:21:47 -0700 Subject: [PATCH] Make extension manifests optional --- .../extensions_goal_state_from_vm_settings.py | 4 +- .../vm_settings-no_extension_manifests.json | 78 +++++++++++++++++++ ..._extensions_goal_state_from_vm_settings.py | 17 ++++ 3 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tests/data/hostgaplugin/vm_settings-no_extension_manifests.json diff --git a/azurelinuxagent/common/protocol/extensions_goal_state_from_vm_settings.py b/azurelinuxagent/common/protocol/extensions_goal_state_from_vm_settings.py index f0997e8194..241f789990 100644 --- a/azurelinuxagent/common/protocol/extensions_goal_state_from_vm_settings.py +++ b/azurelinuxagent/common/protocol/extensions_goal_state_from_vm_settings.py @@ -360,7 +360,9 @@ def _parse_extensions(self, vm_settings): is_multi_config = extension_gs.get('isMultiConfig') if is_multi_config is not None: extension.supports_multi_config = is_multi_config - extension.manifest_uris.append(extension_gs['location']) + location = extension_gs.get('location') + if location is not None: + extension.manifest_uris.append(location) fail_over_location = extension_gs.get('failoverLocation') if fail_over_location is not None: extension.manifest_uris.append(fail_over_location) diff --git a/tests/data/hostgaplugin/vm_settings-no_extension_manifests.json b/tests/data/hostgaplugin/vm_settings-no_extension_manifests.json new file mode 100644 index 0000000000..b5653ef76d --- /dev/null +++ b/tests/data/hostgaplugin/vm_settings-no_extension_manifests.json @@ -0,0 +1,78 @@ +{ + "hostGAPluginVersion": "1.0.8.123", + "vmSettingsSchemaVersion": "0.0", + "activityId": "89d50bf1-fa55-4257-8af3-3db0c9f81ab4", + "correlationId": "c143f8f0-a66b-4881-8c06-1efd278b0b02", + "inSvdSeqNo": 978, + "extensionsLastModifiedTickCount": 637829610574739741, + "extensionGoalStatesSource": "Fabric", + "statusUploadBlob": { + "statusBlobType": "PageBlob", + "value": "https://md-ssd-xpdjf15s.blob.core.windows.net/$system/u-sqlwatcher.f338f67e.status?sv=2018-03-28&sr=b&sk=system-1&sig=88Y3NM%2b1aU%3d&se=9999-01-01T00%3a00%3a00Z&sp=rw" + }, + "inVMMetadata": { + "subscriptionId": "8d3c2715-f063-40b8-9402-49784992ae8d", + "resourceGroupName": "SYSTEMCENTERCURRENTBRANCH", + "vmName": "ubuntu-sqlwatcher", + "location": "centralus", + "vmId": "f338f67e-5d06-4f13-892a-ff1b047ba5bf", + "vmSize": "Standard_D2s_v3", + "osType": "Linux", + "vmImage": { + "publisher": "Canonical", + "offer": "UbuntuServer", + "sku": "18.04-LTS", + "version": "18.04.202005220" + } + }, + "gaFamilies": [ + { + "name": "Prod", + "uris": [ + "https://zrdfepirv2dz5prdstr07a.blob.core.windows.net/7d89d439b79f4452950452399add2c90/Microsoft.OSTCLinuxAgent_Prod_uscentral_manifest.xml", + "https://rdfepirv2dm1prdstr09.blob.core.windows.net/7d89d439b79f4452950452399add2c90/Microsoft.OSTCLinuxAgent_Prod_uscentral_manifest.xml", + "https://zrdfepirv2dm5prdstr06a.blob.core.windows.net/7d89d439b79f4452950452399add2c90/Microsoft.OSTCLinuxAgent_Prod_uscentral_manifest.xml" + ] + } + ], + "extensionGoalStates": [ + { + "name": "Microsoft.Azure.Monitor.WorkloadInsights.Test.Workload.LinuxConfigAgent", + "version": "3.0", + "state": "uninstall", + "autoUpgrade": true, + "runAsStartupTask": false, + "isJson": true, + "useExactVersion": true, + "isMultiConfig": false + }, + { + "name": "Microsoft.Azure.Monitor.WorkloadInsights.Test.Workload.LinuxInstallerAgent", + "version": "11.0", + "state": "uninstall", + "autoUpgrade": true, + "runAsStartupTask": false, + "isJson": true, + "useExactVersion": true, + "isMultiConfig": false + }, + { + "name": "Microsoft.Azure.Monitor.Workloads.Workload.WLILinuxExtension", + "version": "0.2.127", + "location": "https://umsakzkwhng2ft0jjptl.blob.core.windows.net/deeb2df6-c025-e6fb-b015-449ed6a676bc/deeb2df6-c025-e6fb-b015-449ed6a676bc_manifest.xml", + "failoverLocation": "https://umsafmqfbv4hgrd1hqff.blob.core.windows.net/deeb2df6-c025-e6fb-b015-449ed6a676bc/deeb2df6-c025-e6fb-b015-449ed6a676bc_manifest.xml", + "state": "enabled", + "autoUpgrade": true, + "runAsStartupTask": false, + "isJson": true, + "useExactVersion": true, + "settingsSeqNo": 7, + "isMultiConfig": false, + "settings": [ + { + "publicSettings": "{\"workloadConfig\": null}" + } + ] + } + ] +} \ No newline at end of file diff --git a/tests/protocol/test_extensions_goal_state_from_vm_settings.py b/tests/protocol/test_extensions_goal_state_from_vm_settings.py index 3428269ca6..400b885d5b 100644 --- a/tests/protocol/test_extensions_goal_state_from_vm_settings.py +++ b/tests/protocol/test_extensions_goal_state_from_vm_settings.py @@ -70,6 +70,22 @@ def test_it_should_parse_missing_status_upload_blob_as_none(self, _): self.assertIsNone(extensions_goal_state.status_upload_blob, "Expected status upload blob to be None") self.assertEqual("BlockBlob", extensions_goal_state.status_upload_blob_type, "Expected status upload blob to be Block") + def test_it_should_parse_missing_extension_manifests_as_empty(self, _): + data_file = mockwiredata.DATA_FILE_VM_SETTINGS.copy() + data_file["vm_settings"] = "hostgaplugin/vm_settings-no_extension_manifests.json" + with mock_wire_protocol(data_file) as protocol: + extensions_goal_state = protocol.get_goal_state().extensions_goal_state + + self.assertEqual(3, len(extensions_goal_state.extensions), "Incorrect number of extensions. Got: {0}".format(extensions_goal_state.extensions)) + self.assertEqual([], extensions_goal_state.extensions[0].manifest_uris, "Expected an empty list of manifests for {0}".format(extensions_goal_state.extensions[0])) + self.assertEqual([], extensions_goal_state.extensions[1].manifest_uris, "Expected an empty list of manifests for {0}".format(extensions_goal_state.extensions[1])) + self.assertEqual( + [ + "https://umsakzkwhng2ft0jjptl.blob.core.windows.net/deeb2df6-c025-e6fb-b015-449ed6a676bc/deeb2df6-c025-e6fb-b015-449ed6a676bc_manifest.xml", + "https://umsafmqfbv4hgrd1hqff.blob.core.windows.net/deeb2df6-c025-e6fb-b015-449ed6a676bc/deeb2df6-c025-e6fb-b015-449ed6a676bc_manifest.xml", + ], + extensions_goal_state.extensions[2].manifest_uris, "Incorrect list of manifests for {0}".format(extensions_goal_state.extensions[2])) + def test_it_should_default_to_block_blob_when_the_status_blob_type_is_not_valid(self, _): data_file = mockwiredata.DATA_FILE_VM_SETTINGS.copy() data_file["vm_settings"] = "hostgaplugin/vm_settings-invalid_blob_type.json" @@ -84,6 +100,7 @@ def test_its_source_channel_should_be_host_ga_plugin(self, _): self.assertEqual(GoalStateChannel.HostGAPlugin, extensions_goal_state.channel, "The channel is incorrect") + class CaseFoldedDictionaryTestCase(AgentTestCase): def test_it_should_retrieve_items_ignoring_case(self): dictionary = json.loads('''{