x[hRddlZddlZddlZddlZddlZddlZddlZddlmZddl m Z m Z ddl m Z m Z ddl mZmZmZmZmZddlmZddlmZddlmZmZmZmZmZmZdd lm Z dd l!m"Z"ejFe$Z%d Z&d Z'd Z(dZ)dZ*e jVdddZ,edZ-dede-fdede-ffdZ.e.dZ/e.dZ0ddde1de jdfdZ3dZ4e.dZ5ed Z6e.dd!d"d#d$e1d%e7d&ee8d'e9d(e9dejtf d)Z;d*e1d+e1d,e1de8fd-Z<Gd.d/Z=Gd0d1e>Z?Gd2d3Z@Gd4d5ZAGd6d7ZBGd8d9ZCe. dGd:e1d;ejdZEe.d:e1d?d@fdAZFdBZGGdCdDe>ZHGdEdFZIy)HN)contextmanager)datetimetimezone)sleeptime)CallableListOptionalTypeVarUnion) ElementTree)escape)distrossubp temp_utils url_helperutilversion)events)errorsz 168.63.129.16boot-telemetryz system-info diagnostic compressedzazure-dsz initialize reporter for azure dsT)name descriptionreporting_enabledTfunc.returncfd}|S)Nctjjjt5|i|cdddS#1swYyxYw)Nrrparent)rReportEventStack__name__azure_ds_reporter)argskwargsrs A/usr/lib/python3/dist-packages/cloudinit/sources/helpers/azure.pyimplz)azure_ds_telemetry_reporter..impl*sF  $ $ $  ) ((  ) ) )s AA )rr*s` r)azure_ds_telemetry_reporterr,)s) Kc ,tjs tdtj d t t t tjz } tjgdd\}}d}|rd|vr|jdd }|s td |t |d z z} tjgdd\}}d}|rd|vr|jdd }|s td|t |d z z}tjtddt!j"|t$j&j)dt!j"|t$j&j)dt!j"|t$j&j)tj*}tj,||S#t$r}td|d}~wwxYw#tj$r}td |z|d}~wt$r}td |z|d}~wwxYw#tj$r}td|z|d}~wt$r}td|z|d}~wwxYw)z[Report timestamps related to kernel initialization and systemd activation of cloud-initz1distro not using systemd, skipping boot telemetryzCollecting boot telemetryz*Failed to determine kernel start timestampN) systemctlshow-pUserspaceTimestampMonotonicT)capture=z8Failed to parse UserspaceTimestampMonotonic from systemdi@Bz-Failed to get UserspaceTimestampMonotonic: %sz H H J  " ":x|| < F F H  " "$hll ik    ## C  JS PGHaOP$  % % ;a ?    JQ N  2  % % > B    M   sa1G/(AH ?AI/ H 8 HH  IH.. I:I  IJ$I33 J?JJc0tj}tjtddt j d|dd|dd|dd d |dd d |dd d|dtj}tj||S)z%Collect and report system informationzsystem informationzcloudinit_version=z, kernel_version=releasez , variant=variantz, distro_name=distrz, distro_version=r5z , flavor=z, python_version=python) r system_inforr@SYSTEMINFO_EVENT_TYPErversion_stringrErF)inforNs r)get_system_inforZs    D     " " $ O O LO LO LO N  ## C"  Jr- logger_funcmsgct|r||tjtd|tj}tj |dh|S)zReport a diagnostic eventzdiagnostic messagelogexcluded_handler_types)callablerr@DIAGNOSTIC_EVENT_TYPErErF)r]r\rNs r)report_diagnostic_eventrdsQ C    ##  C  UG< Jr-c*tjtj|}d|j dd}t j t|tj|t j}t j|hd|S)zReport a compressed eventzgz+b64ascii)encodingdata>r_printwebhookr`) base64 encodebyteszlibcompressdecoderr@COMPRESSED_EVENT_TYPEjsondumpsrErF) event_name event_contentcompressed_data event_datarNs r)report_compressed_eventrws}((})EFO&&w/J    :##  C   $? Jr-ctjd tjdgdd\}}td|y#t$r1}t dt |ztjYd}~yd}~wwxYw) zReport dmesg to KVP.zDumping dmesg log to KVPdmesgFT)ror3z$Exception when dumping dmesg log: %sr[N)r9r:rrw Exceptionrdreprwarning)rIrJexs r)report_dmesg_to_kvpr~shII() G9UDAQ-   2T"X =    s(A A: 'A55A:c#Ktj}tjtjj | dtj|y#tj|wxYwwN)osgetcwdchdirpath expanduser)newdirprevdirs r)cdrsLiikGHHRWW   '(  sAA> A$A>$A;;A>)rh retry_sleeptimeout_minutesurlheadersrhrrc |dztz}d}d}|s |dz } tj|||d} t d ||fztj|S#tj$r_}t d||||j |j fztjt|z|k\s d t|vrYd}~nd}~wwxYwt||sŌ) zReadurl wrapper for querying wireserver. :param retry_sleep: Time to sleep before retrying. :param timeout_minutes: Retry up to specified number of minutes. :raises UrlError: on error fetching data. <rNr5)rr)rrhtimeoutzdFailed HTTP request with Azure endpoint %s during attempt %d with exception: %s (code=%r headers=%r)r[zNetwork is unreachablez@Successful HTTP request with Azure endpoint %s after %d attempts) rrreadurlUrlErrorrdcoderr9r:strr) rrrhrrrattemptresponserHs r)http_with_retriesrs"TV+GGH1  !))W4H , g 'II O5""  #EAFFAII67 II  $/+s1v56 & k5sAC ,ACC usernamehostname disableSshPwdcvtjd}|j|||}|jdS)Na. 1.0 LinuxProvisioningConfiguration {username} {disableSshPwd} {hostname} 1.0 true )rrrutf-8)textwrapdedentformatencode)rrrOVF_ENV_TEMPLATErets r)build_minimal_ovfrsG  2  ! !HM " C ::g r-cleZdZdddZdZd dej fdZ d dee dej fd Z y) AzureEndpointHttpClient WALinuxAgentz 2012-11-30)zx-ms-agent-namez x-ms-versioncd|d|_y)N DES_EDE3_CBC)zx-ms-cipher-namez!x-ms-guest-agent-public-x509-cert)extra_secure_headers)self certificates r)__init__z AzureEndpointHttpClient.__init__Ds .1<% !r-rc|j}|r5|jj}|j|jt ||S)N)r)rcopyupdaterr)rrsecurers r)getzAzureEndpointHttpClient.getJs?,, ll'')G NN444 5 g66r-Nrhc|j}|+|jj}|j|t|||S)N)rhr)rrrr)rrrh extra_headersrs r)postzAzureEndpointHttpClient.postQs@,,  $ll'')G NN= ) 4AAr-)FNN) r% __module__ __qualname__rrr UrlResponserr bytesrr+r-r)rr>sO)$G  7 (>(>7@DB!%B   Br-rceZdZdZy)InvalidGoalStateXMLExceptionz9Raised when GoalState XML is invalid or has missing data.N)r%rr__doc__r+r-r)rr[sCr-rc 8eZdZ ddeeefdededdfdZdZ y) GoalState unparsed_xmlazure_endpoint_clientneed_certificaterNc||_ tj||_|jd|_ |jd|_ |jd|_ dD]9}t||d|z}t |t jt|d|_|jd }|m|rjtj d d t" 5|jj%|d j&|_|j td dddyyy#tj$r$}t d|zt jd}~wwxYw#1swYyxYw)ahParses 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 need_certificate: switch to know if certificates is needed. @return: GoalState object representing the GoalState XML string. z!Failed to parse GoalState XML: %sr[Nz./Container/ContainerIdz4./Container/RoleInstanceList/RoleInstance/InstanceIdz ./Incarnation) container_id instance_id incarnationzMissing %s in GoalState XMLzD./Container/RoleInstanceList/RoleInstance/Configuration/Certificateszget-certificates-xmlzget certificates xmlr"T)rz/Azure endpoint returned empty certificates xml.)rET fromstringroot ParseErrorrdr9r|_text_from_xpathrrrgetattrrcertificates_xmlrr$r&rcontents)rrrrrHattrr]rs r)rzGoalState.__init__`s&;"  l3DI!112KL00 B  00AB 8DtT"*3d:'E2377  8 !%## *  ?/((+2(  )-(B(B(F(F)G)(%((06I1   0?1}}  #3a7KK    2  s$D+AE%+E">EE"%E.cV|jj|}| |jSyr)rfindtext)rxpathelements r)rzGoalState._text_from_xpaths'))..'  << r-)T) r%rrr rrrboolrrr+r-r)rr_sA "& 5CJ'5 75 5  5nr-rceZdZdddZdZdZedZejdZe dZ e e d Z e d Z e d Ze d Ze d Zy)OpenSSLManagerzTransportPrivate.pemzTransportCert.pem) private_keyrcdtj|_d|_|j yr)rmkdtemptmpdir _certificategenerate_certificaters r)rzOpenSSLManager.__init__s& ((*   !!#r-cBtj|jyr)rdel_dirrrs r)clean_upzOpenSSLManager.clean_ups T[[!r-c|jSrrrs r)rzOpenSSLManager.certificates   r-c||_yrr)rvalues r)rzOpenSSLManager.certificates !r-ctjd|jtjdyt|j5t j ddddddd d d d d |j dd|j dgd}tj|j djD]}d|vs||jz }||_dddtjdy#1swYxYw)Nz7Generating certificate for communication with fabric...zCertificate already generated.opensslreqz-x509z-nodesz-subjz/CN=LinuxTransportz-days32768z-newkeyzrsa:3072z-keyoutrz-outr CERTIFICATEzNew certificate generated.) r9r:rrrrcertificate_namesrload_text_file splitlinesrstrip)rrlines r)rz#OpenSSLManager.generate_certificates KL    ' II6 7   _ + II(**=9**=9 $K++&&}5jl 1!,4;;=0K  1 +D 3 +4 ./5 + +s A7C?C??DcFddd|g}tj||\}}|S)Nrx509z-nooutrh)r)actioncertcmdresultrJs r)_run_x509_actionzOpenSSLManager._run_x509_actions+&(F3IIc-  r-cf|jd|}gd}tj||\}}|S)Nz-pubkey)z ssh-keygenz-iz-mPKCS8z-fz /dev/stdinr)rr)rrpub_key keygen_cmdssh_keyrJs r)_get_ssh_key_from_certz%OpenSSLManager._get_ssh_key_from_certs2'' ;?L YYz8 r-c|jd|}|jd}||dzdjd}dj|S)aopenssl x509 formats fingerprints as so: 'SHA1 Fingerprint=07:3E:19:D1:4D:1C:79:92:24:C6:A0:FD:8D:DA:\ B6:A8:BF:27:D4:73\n' Azure control plane passes that fingerprint as so: '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473' z -fingerprintr4r5:r)rrr>join)rrraw_fpeqoctetss r)_get_fingerprint_from_certz)OpenSSLManager._get_fingerprint_from_certsM&&~{C [[ Q$**3/wwvr-crtj|jd}|j}ddddd|j dg}t |j 5tjdjd i|jd d j| \}}d d d |S#1swYSxYw)zDecrypt the certificates XML document using the our private key; return the list of certs and private keys contained in the doc. z.//DatasMIME-Version: 1.0s<Content-Disposition: attachment; filename="Certificates.p7m"s?Content-Type: application/x-pkcs7-mime; name="Certificates.p7m"s!Content-Transfer-Encoding: base64r-rzuopenssl cms -decrypt -in /dev/stdin -inkey {private_key} -recip {certificate} | openssl pkcs12 -nodes -password pass:T )shellrhNr+) rrrrrrrrrrr)rrtagcertificates_contentlinesrIrJs r)_decrypt_certs_from_xmlz&OpenSSLManager._decrypt_certs_from_xmls mm,-229="xx K N 0  ' ' 0   _ YY*##)6D,0,B,BDZZ& FC    s AB,,B6cP|j|}g}i}|jD]}}|j|tjd|rg}-tjd|sDdj |}|j |}|j|}|||<g}|S)zGiven the Certificates XML document, return a dictionary of fingerprints and associated SSH keys derived from the certs.z[-]+END .*?KEY[-]+$z[-]+END .*?CERTIFICATE[-]+$ )r rappendrematchrrr) rrrIcurrentkeysrrr fingerprints r)parse_certificatesz!OpenSSLManager.parse_certificates s**+;<NN$ D NN4 xx.58$?"ii0 55kB"==kJ $+[!  r-N)r%rrrrrpropertyrsetterr,r staticmethodrrrr rr+r-r)rrs-* $ "!!""!0!0B ! !! ! ! !!0!!r-rc eZdZejdZejdZdZdZdZ dZ de de d e d d fd Zedd Zede d d fdZ dde de de de d ef dZeded d fdZy )GoalStateHealthReportera {incarnation} {container_id} {instance_id} {health_status} {health_detail_subsection} z
{health_substatus} {health_description}
ReadyNotReadyProvisioningFailedi goal_staterendpointrNc.||_||_||_y)a?Creates instance that will report provisioning status to an endpoint @param goal_state: An instance of class GoalState that contains goal state info such as incarnation, container id, and instance id. These 3 values are needed when reporting the provisioning status to Azure @param azure_endpoint_client: Instance of class AzureEndpointHttpClient @param endpoint: Endpoint (string) where the provisioning status report will be sent to @return: Instance of class GoalStateHealthReporter N) _goal_state_azure_endpoint_client _endpoint)rrrr s r)rz GoalStateHealthReporter.__init__Fs"&&;#!r-c|j|jj|jj|jj|j }t jd |j|t jdy#t$r$}td|zt jd}~wwxYw)N)rrrstatusz Reporting ready to Azure fabric.documentz#exception while reporting ready: %sr[zReported ready to Azure fabric.) build_reportr"rrrPROVISIONING_SUCCESS_STATUSr9r:_post_health_reportrzrderrorrY)rr(rHs r)send_ready_signalz)GoalStateHealthReporter.send_ready_signal[s$$((44))66((4433 %  45   $ $h $ 7 23  #59II    s2B C#CCrc|j|jj|jj|jj|j |j |} |j|tjdy#t$r&}d|z}t|tjd}~wwxYw)N)rrrr& substatusrr'z%exception while reporting failure: %sr[z!Reported failure to Azure fabric.) r)r"rrrPROVISIONING_NOT_READY_STATUSPROVISIONING_FAILURE_SUBSTATUSr+rzrdr9r,r|)rrr(rHr]s r)send_failure_signalz+GoalStateHealthReporter.send_failure_signalos$$((44))66((445599# %    $ $h $ 7 78  9A=C #CSYY ?  s)B C!B;;Crrrr&c>d}|<|jjt|t|d|j}|jjtt |t|t|t||}|j dS)Nr)health_substatushealth_description)rrr health_statushealth_detail_subsectionr)%HEALTH_DETAIL_SUBSECTION_XML_TEMPLATErr"HEALTH_REPORT_DESCRIPTION_TRIM_LENHEALTH_REPORT_XML_TEMPLATErr) rrrrr&r/r health_detail health_reports r)r)z$GoalStateHealthReporter.build_reports   FFMM!' !2#) I$"I"IJ$NM77>>s;/0 -{+ .%2 ? ##G,,r-r(ctdtjddj|j}|j j ||dditjdy)Nrz&Sending health report to Azure fabric.zhttp://{}/machine?comp=healthz Content-Typeztext/xml; charset=utf-8)rhrz/Successfully sent health report to Azure fabric)rr9r:rr$r#r)rr(rs r)r+z+GoalStateHealthReporter._post_health_reportsc( a :;-44T^^D ##(( )+DE ) CDr-)rNr)r%rrrrr:r8r*r0r1r9rrrrr,r-r2rr)r+r+r-r)rr s!0 ",-II   s) AAAcd}|j'|%t|_|jj}|jt ||_|j |du}d}||j ||}t||j|j}||j|||j|S)aGets the VM's GoalState from Azure, uses the GoalState information to report ready/send the ready signal/provisioning complete signal to Azure, and then uses pubkey_info to filter and obtain the user's pubkeys from the GoalState. @param pubkey_info: List of pubkey values and fingerprints which are used to filter and obtain the user's pubkey values from the GoalState. @return: The list of user's authorized pubkey values. Nr)rC) rArrrr_fetch_goal_state_from_azure_get_user_pubkeysrr rGr-)rrC pubkey_inforFhttp_client_certificaterssh_keyshealth_reporters r)"register_with_azure_and_fetch_dataz3WALinuxAgentShim.register_with_azure_and_fetch_datas#'    'K,C#1#3D &*&:&:&F&F #  % % -)@'*D &664D@7   "--j+FH1 22DMM    NN76N 2))+r-rc|jtd|_|jd}t||j|j}|j |y)zGets the VM's GoalState from Azure, uses the GoalState information to report failure/send provisioning failure signal to Azure. @param: user visible error description of provisioning failure. NFrIr)rrrJrr r2)rrrrOs r)®ister_with_azure_and_report_failurez7WALinuxAgentShim.register_with_azure_and_report_failures^  % % -)@)FD &666N 1 22DMM  ++ +Dr-rcF|j}|j||S)aFetches the GoalState XML from the Azure endpoint, parses the XML, and returns a GoalState object. @param need_certificate: switch to know if certificates is needed. @return: GoalState object representing the GoalState XML )"_get_raw_goal_state_xml_from_azure_parse_raw_goal_state_xml)rrunparsed_goal_state_xmls r)rJz-WALinuxAgentShim._fetch_goal_state_from_azures,#'"I"I"K-- #%5  r-ctjddj|j} t j ddt 5|jj|}dddtjd jS#1swY*xYw#t$r$}td|ztjd}~wwxYw) zFetches the GoalState XML from the Azure endpoint and returns the XML as a string. @return: GoalState XML string zRegistering with Azure...z!http://{}/machine/?comp=goalstatezgoalstate-retrievalzretrieve goalstater"Nz9failed to register with Azure and fetch GoalState XML: %sr[z#Successfully fetched GoalState XML.)r9rYrr rr$r&rrrzrdr|r:r)rrrrHs r)rUz3WALinuxAgentShim._get_raw_goal_state_xml_from_azures ,-188G ((*0( ?  5599#>  ? 78    ? ?   #KKK    s/BB*BBB C (CC rWcB t||j|}dj d|jzd|jzd|jzg}t|tj|S#t$r$}td|ztj d}~wwxYw)aParses a GoalState XML string and returns a GoalState object. @param unparsed_goal_state_xml: GoalState XML string @param need_certificate: switch to know if certificates is needed. @return: GoalState object representing the GoalState XML z"Error processing GoalState XML: %sr[Nz, zGoalState XML container id: %szGoalState XML instance id: %szGoalState XML incarnation: %s) rrrzrdr9r|rrrrr:)rrWrrrHr]s r)rVz*WALinuxAgentShim._parse_raw_goal_state_xml2s "'** Jii0:3J3JJ/*2H2HH/*2H2HH   ;  #4q8KK    sA11 B:BBrrLcg}|jZ|X|jLtjd|jj |j}|j ||}|S)aGets and filters the VM admin user's authorized pubkeys. The admin user in this case is the username specified as "admin" when deploying VMs on Azure. See https://docs.microsoft.com/en-us/cli/azure/vm#az-vm-create. cloud-init expects a straightforward array of keys to be dropped into the admin user's authorized_keys file. Azure control plane exposes multiple public keys to the VM via wireserver. Select just the admin user's key(s) and return them, ignoring any other certs. @param goal_state: GoalState object. The GoalState object contains a certificate XML, which contains both the VM user's authorized pubkeys and other non-user pubkeys, which are used for MSI and protected extension handling. @param pubkey_info: List of VM user pubkey dicts that were previously obtained from provisioning data. Each pubkey dict in this list can either have the format pubkey['value'] or pubkey['fingerprint']. Each pubkey['fingerprint'] in the list is used to filter and obtain the actual pubkey value from the GoalState certificates XML. Each pubkey['value'] requires no further processing and is immediately added to the return list. @return: A list of the VM user's authorized pubkey values. z/Certificate XML found; parsing out public keys.)rrAr9r:r_filter_pubkeys)rrrLrNkeys_by_fingerprints r)rKz"WALinuxAgentShim._get_user_pubkeysTsn:  ' ' 3'$$0 IIG H"&"6"6"I"I++# ++,?MHr-r\cg}|D]t}d|vr|dr|j|d!d|vr:|dr5|d}||vr|j||Htjd|_tjd|v|S)a8Filter and return only the user's actual pubkeys. @param keys_by_fingerprint: pubkey fingerprint -> pubkey value dict that was obtained from GoalState Certificates XML. May contain non-user pubkeys. @param pubkey_info: List of VM user pubkeys. Pubkey values are added to the return list without further processing. Pubkey fingerprints are used to filter and obtain the actual pubkey values from keys_by_fingerprint. @return: A list of the VM user's authorized pubkey values. rrzIovf-env.xml specified PublicKey fingerprint %s not found in goalstate XMLzFovf-env.xml specified PublicKey with neither value nor fingerprint: %s)rr9r|)r\rLrpubkeyrs r)r[z WALinuxAgentShim._filter_pubkeys~s! F& VG_ F7O,&(VM-B$]3 "55KK 3K @AKK8#  0 ( r-r)r%rrrrrr,rDistrorGr r rPrSrrrJrrUr rVlistrKrdictr[r+r-r)r?r?seMM ,!D!!@D#nn# $s) #!#J! E# E$ E! E!  $    !  !!E!!!4!!&sEz!2  !B!'#'26' '!'R!T!!!!r-r?r rCrLrFct|} |j||||jS#|jwxYw)Nr )rCrLrF)r?rPr)r rCrLrFshims r)get_metadata_from_fabricresB X .D66{G7   s 2Ar,zerrors.ReportableErrorct|}|j} |j||jy#|jwxYw)NrcrR)r?as_encoded_reportrSr)r r,rdrs r)report_failure_to_fabricrhsC X .D))+K 33 3L  s AAc|td|ztjtd|ztjy)Nzdhclient output stream: %sr[zdhclient error stream: %s)rdr9r:)rIerrs r) dhcp_log_cbrks0$s* #c)syyr-c eZdZy)NonAzureDataSourceN)r%rrr+r-r)rmrmsr-rmceZdZdddZdddddddddd deedeed eed eed eed eee d edeededdfdZ defdZ e deddfdZ ddededefdZ d dedededefdZdZdZdZy)! OvfEnvXmlz)http://schemas.dmtf.org/ovf/environment/1z)http://schemas.microsoft.com/windowsazure)ovfwaNF rpasswordr custom_datadisable_ssh_password_auth public_keyspreprovisioned_vmpreprovisioned_vm_typeprovision_guest_proxy_agentrrsrrtrurvrwrxryrc ||_||_||_||_||_|xsg|_||_||_| |_yrrr) rrrsrrtrurvrwrxrys r)rzOvfEnvXml.__init__sN!     &)B&'2'8b!2&<#+F(r-c4|j|jk(Sr)__dict__)rothers r)__eq__zOvfEnvXml.__eq__s}}..r- ovf_env_xmlc< tj|}|j d|j  tdt}|j||j||S#tj$r}tj||d}~wwxYw)zParser for ovf-env.xml data. :raises NonAzureDataSource: if XML is not in Azure's format. :raises errors.ReportableErrorOvfParsingException: if XML is unparsable or invalid. ) exceptionNz./wa:ProvisioningSectionz=Ignoring non-Azure ovf-env.xml: ProvisioningSection not found) rrrr"ReportableErrorOvfParsingExceptionr NAMESPACESrmro&_parse_linux_configuration_set_section _parse_platform_settings_section)clsrrrHinstances r) parse_textzOvfEnvXml.parse_texts P==-D 99/ @ H$O ;77=11$7}} P;;aHa O PsA,,B?BBrrequired namespacec"|jd|d|tj}|s2d|z}tj ||rt j |yt|dkDr#t j d|t|fz|dS)Nz./rmissing configuration for %rr5*multiple configuration matches for %r (%d)r)findallrorr9r:r!ReportableErrorOvfInvalidMetadatalen)rnoderrrmatchesr]s r)_findzOvfEnvXml._finds,,"D )9+?+? 047C IIcN>>sCC \A ::<W&'  qzr- decode_base64 parse_boolc|jd|ztj}|s3d|z}tj ||rt j ||St|dkDr#t j d|t|fz|dj} | |} |r4| 2tjdj| j} |rtj| } | S)Nz./wa:rr5rrr)rrorr9r:rrrrrk b64decoderr>rtranslate_bool) rrrrrrdefaultrr]rs r)_parse_propertyzOvfEnvXml._parse_propertys,,w~y/C/CD047C IIcN>>sCCN w* &  +r-c|j|dd}|j|dd}|j|dddd|_|j|dd|_|j|d ddd|_y) NPlatformSettingsSectionTrPlatformSettingsPreprovisionedVmF)rrrPreprovisionedVMTypeProvisionGuestProxyAgent)rrrwrxry)rrplatform_settings_sectionplatform_settingss r)rz*OvfEnvXml._parse_platform_settings_sectionbs$(JJ +d%/% !!JJ %'9D' "&!5!5   "6" '+&:&:  "';' # ,0+?+?  & ,@, (r-ctg|_|j|dd}|y|j|dd}|y|jdtjD]`}|j |dd}|j |dd}|j |dd d }|||d }|jj |by) NSSHFr PublicKeysz./wa:PublicKey FingerprintPathValuer)rr)rrr)rvrrrorrr) rr ssh_sectionpublic_keys_section public_keyrrrrs r)rzOvfEnvXml._parse_ssh_section~sjjUUjC   "jj )   & -55 i22  -J..ME/K'' FU'KD((GR%)E +G    # #G , -r-)rq)FFN)r%rrrr rrrr rarr~ classmethodrrrrrrr+r-r)roros`:9J#'"&"&'+48,0"'04,1G3-G3- G 3- G e_ G$,D>Gd4j)G G!) G&*G G./t/S[:    :$ ## #  #  #J ,D 8-r-ror)Jrkrqloggingrrrrm contextlibrrrrrtypingrr r r r xml.etreer rxml.sax.saxutilsr cloudinitrrrrrrcloudinit.reportingrcloudinit.sources.azurer getLoggerr%r9DEFAULT_WIRESERVER_ENDPOINTrArWrcrpr$r&rr,rOrZrr@rdrwr~rrarintrrrrrzrrrrr?r_rerhrkrmror+r-r)rs    %';;'#JJ&*g!."%$$+F++ 2  CL hsAv&6 8CF;K RRj6"  $*     ! 3 33 5/ 3  3  333l 14 DBB:D9D<<~D[E[E|bbJ(,!   NN $s)$ c]  s3K  P-P-r-