summaryrefslogtreecommitdiff
path: root/cloudinit/sources/helpers
diff options
context:
space:
mode:
authorThomas Stringer <git@trstringer.com>2020-09-10 14:29:54 -0400
committerGitHub <noreply@github.com>2020-09-10 14:29:54 -0400
commite56b55452549cb037da0a4165154ffa494e9678a (patch)
tree96be0a4e985e2c2ff1a91fcde8a438c2cdd4af8e /cloudinit/sources/helpers
parent987f89efa1615087c6d87470f758fc609b14e1b8 (diff)
downloadvyos-cloud-init-e56b55452549cb037da0a4165154ffa494e9678a.tar.gz
vyos-cloud-init-e56b55452549cb037da0a4165154ffa494e9678a.zip
Retrieve SSH keys from IMDS first with OVF as a fallback (#509)
* pull ssh keys from imds first and fall back to ovf if unavailable * refactor log and diagnostic messages * refactor the OpenSSLManager instantiation and certificate usage * fix unit test where exception was being silenced for generate cert * fix tests now that certificate is not always generated * add documentation for ssh key retrieval * add ability to check if http client has security enabled * refactor certificate logic to GoalState
Diffstat (limited to 'cloudinit/sources/helpers')
-rwxr-xr-xcloudinit/sources/helpers/azure.py50
1 files changed, 37 insertions, 13 deletions
diff --git a/cloudinit/sources/helpers/azure.py b/cloudinit/sources/helpers/azure.py
index 507f6ac8..79445a81 100755
--- a/cloudinit/sources/helpers/azure.py
+++ b/cloudinit/sources/helpers/azure.py
@@ -288,12 +288,16 @@ class InvalidGoalStateXMLException(Exception):
class GoalState:
- def __init__(self, unparsed_xml: str,
- azure_endpoint_client: AzureEndpointHttpClient) -> None:
+ def __init__(
+ self,
+ unparsed_xml: str,
+ azure_endpoint_client: AzureEndpointHttpClient,
+ need_certificate: bool = True) -> None:
"""Parses a GoalState XML string and returns a GoalState object.
@param unparsed_xml: string representing a GoalState XML.
- @param azure_endpoint_client: instance of AzureEndpointHttpClient
+ @param azure_endpoint_client: instance of AzureEndpointHttpClient.
+ @param need_certificate: switch to know if certificates is needed.
@return: GoalState object representing the GoalState XML string.
"""
self.azure_endpoint_client = azure_endpoint_client
@@ -322,7 +326,7 @@ class GoalState:
url = self._text_from_xpath(
'./Container/RoleInstanceList/RoleInstance'
'/Configuration/Certificates')
- if url is not None:
+ if url is not None and need_certificate:
with events.ReportEventStack(
name="get-certificates-xml",
description="get certificates xml",
@@ -741,27 +745,38 @@ class WALinuxAgentShim:
GoalState.
@return: The list of user's authorized pubkey values.
"""
- if self.openssl_manager is None:
+ http_client_certificate = None
+ if self.openssl_manager is None and pubkey_info is not None:
self.openssl_manager = OpenSSLManager()
+ http_client_certificate = self.openssl_manager.certificate
if self.azure_endpoint_client is None:
self.azure_endpoint_client = AzureEndpointHttpClient(
- self.openssl_manager.certificate)
- goal_state = self._fetch_goal_state_from_azure()
- ssh_keys = self._get_user_pubkeys(goal_state, pubkey_info)
+ http_client_certificate)
+ goal_state = self._fetch_goal_state_from_azure(
+ need_certificate=http_client_certificate is not None
+ )
+ ssh_keys = None
+ if pubkey_info is not None:
+ ssh_keys = self._get_user_pubkeys(goal_state, pubkey_info)
health_reporter = GoalStateHealthReporter(
goal_state, self.azure_endpoint_client, self.endpoint)
health_reporter.send_ready_signal()
return {'public-keys': ssh_keys}
@azure_ds_telemetry_reporter
- def _fetch_goal_state_from_azure(self) -> GoalState:
+ def _fetch_goal_state_from_azure(
+ self,
+ need_certificate: bool) -> GoalState:
"""Fetches the GoalState XML from the Azure endpoint, parses the XML,
and returns a GoalState object.
@return: GoalState object representing the GoalState XML
"""
unparsed_goal_state_xml = self._get_raw_goal_state_xml_from_azure()
- return self._parse_raw_goal_state_xml(unparsed_goal_state_xml)
+ return self._parse_raw_goal_state_xml(
+ unparsed_goal_state_xml,
+ need_certificate
+ )
@azure_ds_telemetry_reporter
def _get_raw_goal_state_xml_from_azure(self) -> str:
@@ -774,7 +789,11 @@ class WALinuxAgentShim:
LOG.info('Registering with Azure...')
url = 'http://{}/machine/?comp=goalstate'.format(self.endpoint)
try:
- response = self.azure_endpoint_client.get(url)
+ with events.ReportEventStack(
+ name="goalstate-retrieval",
+ description="retrieve goalstate",
+ parent=azure_ds_reporter):
+ response = self.azure_endpoint_client.get(url)
except Exception as e:
msg = 'failed to register with Azure: %s' % e
LOG.warning(msg)
@@ -785,7 +804,9 @@ class WALinuxAgentShim:
@azure_ds_telemetry_reporter
def _parse_raw_goal_state_xml(
- self, unparsed_goal_state_xml: str) -> GoalState:
+ self,
+ unparsed_goal_state_xml: str,
+ need_certificate: bool) -> GoalState:
"""Parses a GoalState XML string and returns a GoalState object.
@param unparsed_goal_state_xml: GoalState XML string
@@ -793,7 +814,10 @@ class WALinuxAgentShim:
"""
try:
goal_state = GoalState(
- unparsed_goal_state_xml, self.azure_endpoint_client)
+ unparsed_goal_state_xml,
+ self.azure_endpoint_client,
+ need_certificate
+ )
except Exception as e:
msg = 'Error processing GoalState XML: %s' % e
LOG.warning(msg)