
    fj                     N   d dl Z d dlZd dlZd dlZd dlZd dlZd dlZd dlmZ d dl	m	Z	 d dl
mZm
Z
 d dlmZmZmZmZmZ d dlmZ d dlmZ d dlmZmZmZmZmZmZ d d	lmZ d d
lm Z   ejB                  e"      Z#dZ$dZ%dZ&dZ'dZ( ejR                  ddd      Z* ed      Z+dede+f   dede+f   fdZ,e,d        Z-e,d        Z.ddde/dej`                  fdZ1d Z2e,d        Z3ed         Z4e,dd!d"d#d$e/d%e5d&ee6   d'e7d(e7dejp                  fd)       Z9d*e/d+e/d,e/de6fd-Z: G d. d/      Z; G d0 d1e<      Z= G d2 d3      Z> G d4 d5      Z? G d6 d7      Z@ G d8 d9      ZAe,	 	 dGd:e/d;ej                  d<eee/      d=ee/   fd>       ZCe,d:e/d?d@fdA       ZDdB ZE G dC dDe<      ZF G dE dF      ZGy)H    N)contextmanager)datetime)sleeptime)CallableListOptionalTypeVarUnion)ElementTree)escape)distrossubp
temp_utils
url_helperutilversion)events)errorsz168.63.129.16boot-telemetryzsystem-info
diagnostic
compressedzazure-dsz initialize reporter for azure dsT)namedescriptionreporting_enabledTfunc.returnc                       fd}|S )Nc                      t        j                  j                  j                  t              5   | i |cd d d        S # 1 sw Y   y xY w)Nr   r   parent)r   ReportEventStack__name__azure_ds_reporter)argskwargsr   s     A/usr/lib/python3/dist-packages/cloudinit/sources/helpers/azure.pyimplz)azure_ds_telemetry_reporter.<locals>.impl'   sF    $$$
 	)
 ((	) 	) 	)s   AA )r   r)   s   ` r(   azure_ds_telemetry_reporterr+   &   s    ) K    c                     t        j                         st        d      t        j	                  d       	 t        t                     t        t        j                               z
  } 	 t        j                  g dd      \  }}d}|rd|v r|j                  d      d	   }|st        d
      | t        |      dz  z   }	 t        j                  g dd      \  }}d}|rd|v r|j                  d      d	   }|st        d      | t        |      dz  z   }t        j                  t        ddt!        j"                  |       j%                         dz   dt!        j"                  |      j%                         dz   dt!        j"                  |      j%                         dz   t        j&                        }t        j(                  |       |S # t        $ r}t        d      |d}~ww xY w# t        j                  $ r}t        d|z        |d}~wt        $ r}t        d|z        |d}~ww xY w# t        j                  $ r}t        d|z        |d}~wt        $ r}t        d|z        |d}~ww xY w)z[Report timestamps related to kernel initialization and systemd
    activation of cloud-initz1distro not using systemd, skipping boot telemetryzCollecting boot telemetryz*Failed to determine kernel start timestampN)	systemctlshow-pUserspaceTimestampMonotonicT)capture=   z8Failed to parse UserspaceTimestampMonotonic from systemdi@B z-Failed to get UserspaceTimestampMonotonic: %sz<Failed to parse UserspaceTimestampMonotonic from systemd: %s)r.   r/   zcloud-init-localr0   InactiveExitTimestampMonotonicz;Failed to parse InactiveExitTimestampMonotonic from systemdz0Failed to get InactiveExitTimestampMonotonic: %sz?Failed to parse InactiveExitTimestampMonotonic from systemd: %sr   zkernel_start=Zz user_start=z cloudinit_activation=)r   uses_systemdRuntimeErrorLOGdebugfloatr   r   uptime
ValueErrorr   splitProcessExecutionErrorr   ReportingEventBOOT_EVENT_TYPEr   utcfromtimestamp	isoformatDEFAULT_EVENT_ORIGINreport_event)kernel_starteout_tsm
user_startcloudinit_activationevts           r(   get_boot_telemetryrN   2   s    !NOOII)*PTV}uT[[]';;F
Q 3#:))C.#CJ  "U3Z'%9:
 	
Q 3#:))C.#CM   ,uSzG/CD 

 %%l3==?#E%%j1;;=C%%&:;EEG#M		
 	##
C  JO  PGHaOP$ %% ;a?
	  JQN
	2 %% >B
	  M
 	sa   1G (AG( ?AH- 	G%G  G%(H*;H

H*H%%H*-I/ II/I**I/c                  0   t        j                         } t        j                  t        ddt        j                         d| d   d| d   d| d   d	   d
| d   d   d| d   d   d| d   t        j                        }t        j                  |       |S )z%Collect and report system informationzsystem informationzcloudinit_version=z, kernel_version=releasez
, variant=variantz, distro_name=distr   z, distro_version=r4   z	, flavor=   z, python_version=python)	r   system_infor   r@   SYSTEMINFO_EVENT_TYPEr   version_stringrD   rE   )inforM   s     r(   get_system_inforY      s     D



 ""$OOLOLOLON	
 	##C"  Jr,   logger_funcmsgc                    t        |      r ||        t        j                  t        d| t        j                        }t        j
                  |dh       |S )zReport a diagnostic eventzdiagnostic messagelogexcluded_handler_types)callabler   r@   DIAGNOSTIC_EVENT_TYPErD   rE   )r\   r[   rM   s      r(   report_diagnostic_eventrc      sQ     C


##	C UG< Jr,   c                 *   t        j                  t        j                  |            }d|j	                  d      d}t        j                  t        | t        j                  |      t
        j                        }t        j                  |h d       |S )zReport a compressed eventzgz+b64ascii)encodingdata>   r^   printwebhookr_   )base64encodebyteszlibcompressdecoder   r@   COMPRESSED_EVENT_TYPEjsondumpsrD   rE   )
event_nameevent_contentcompressed_data
event_datarM   s        r(   report_compressed_eventrv      s}    ((})EFO&&w/J 



:##	C $?
 Jr,   c                      t         j                  d       	 t        j                  dgdd      \  } }t        d|        y# t        $ r1}t        dt        |      z  t         j                         Y d}~yd}~ww xY w)	zReport dmesg to KVP.zDumping dmesg log to KVPdmesgFT)rn   r2   z$Exception when dumping dmesg log: %srZ   N)r9   r:   r   rv   	Exceptionrc   reprwarning)rH   rI   exs      r(   report_dmesg_to_kvpr}      sh     II()
G9UDAQ- 
2T"X=	
 	

s   (A   	A:	'A55A:c              #      K   t        j                         }t        j                  t         j                  j	                  |              	 d  t        j                  |       y # t        j                  |       w xY wwN)osgetcwdchdirpath
expanduser)newdirprevdirs     r(   cdr      sL     iikGHHRWW'(
s   AA>
A$ A>$A;;A>      )rg   retry_sleeptimeout_minutesurlheadersrg   r   r   c          	         |dz  t               z   }d}d}|s |dz  }	 t        j                  | ||d      }	 t	        d
| |fz  t        j                         |S # t        j                  $ r_}t	        d| |||j
                  |j                  fz  t        j                         t               |z   |k\  sd	t        |      v r Y d}~nd}~ww xY wt        |       |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.
    <   r   Nr4   )r   r   )r   rg   timeoutzdFailed HTTP request with Azure endpoint %s during attempt %d with exception: %s (code=%r headers=%r)rZ   zNetwork is unreachablez@Successful HTTP request with Azure endpoint %s after %d attempts)r   r   readurlUrlErrorrc   coder   r9   r:   strr   )	r   r   rg   r   r   r   attemptresponserG   s	            r(   http_with_retriesr      s     "TV+GGH1	!))W4H , 	g	'II
 O5 "" 	#EAFFAII67  II	 $/+s1v5 6	& 	k5 s   A C,ACCusernamehostnamedisableSshPwdc                 v    t        j                  d      }|j                  | ||      }|j                  d      S )Na.          <ns0:Environment xmlns:ns0="http://schemas.dmtf.org/ovf/environment/1"
         xmlns:ns1="http://schemas.microsoft.com/windowsazure"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <ns1:ProvisioningSection>
            <ns1:Version>1.0</ns1:Version>
            <ns1:LinuxProvisioningConfigurationSet>
              <ns1:ConfigurationSetType>LinuxProvisioningConfiguration
              </ns1:ConfigurationSetType>
              <ns1:UserName>{username}</ns1:UserName>
              <ns1:DisableSshPasswordAuthentication>{disableSshPwd}
              </ns1:DisableSshPasswordAuthentication>
              <ns1:HostName>{hostname}</ns1:HostName>
            </ns1:LinuxProvisioningConfigurationSet>
          </ns1:ProvisioningSection>
          <ns1:PlatformSettingsSection>
            <ns1:Version>1.0</ns1:Version>
            <ns1:PlatformSettings>
              <ns1:ProvisionGuestAgent>true</ns1:ProvisionGuestAgent>
            </ns1:PlatformSettings>
          </ns1:PlatformSettingsSection>
        </ns0:Environment>
        )r   r   r   utf-8)textwrapdedentformatencode)r   r   r   OVF_ENV_TEMPLATErets        r(   build_minimal_ovfr     sG      	2 
!
!HM " C ::gr,   c                   l    e Zd ZdddZd Zd
dej                  fdZ	 ddee	   dej                  fd	Z
y)AzureEndpointHttpClientWALinuxAgentz
2012-11-30)zx-ms-agent-namezx-ms-versionc                     d|d| _         y )NDES_EDE3_CBC)zx-ms-cipher-namez!x-ms-guest-agent-public-x509-cert)extra_secure_headers)selfcertificates     r(   __init__z AzureEndpointHttpClient.__init__?  s     .1<%
!r,   r   c                     | j                   }|r5| j                   j                         }|j                  | j                         t	        ||      S )N)r   )r   copyupdater   r   )r   r   securer   s       r(   getzAzureEndpointHttpClient.getE  s?    ,,ll'')GNN4445 g66r,   Nrg   c                     | j                   }|+| j                   j                         }|j                  |       t        |||      S )N)rg   r   )r   r   r   r   )r   r   rg   extra_headersr   s        r(   postzAzureEndpointHttpClient.postL  s@     ,,$ll'')GNN=) 4AAr,   )FNN)r$   
__module____qualname__r   r   r   UrlResponser   r	   bytesr   r*   r,   r(   r   r   9  sO    )$G

7
(>(> 7 @DB!%B			Br,   r   c                       e Zd ZdZy)InvalidGoalStateXMLExceptionz9Raised when GoalState XML is invalid or has missing data.N)r$   r   r   __doc__r*   r,   r(   r   r   V  s    Cr,   r   c            	       8    e Zd Z	 ddeeef   dededdfdZd Z	y)		GoalStateunparsed_xmlazure_endpoint_clientneed_certificater   Nc                    || _         	 t        j                  |      | _        | j                  d      | _	        | j                  d      | _
        | j                  d      | _        dD ]9  }t        | |      d|z  }t        |t        j                         t        |       d| _        | j                  d	      }|m|rjt        j                   d
dt"              5  | j                   j%                  |d      j&                  | _        | j                  t        d      	 ddd       yyy# t        j                  $ r$}t        d|z  t        j                          d}~ww xY w# 1 sw Y   yxY w)ah  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 need_certificate: switch to know if certificates is needed.
        @return: GoalState object representing the GoalState XML string.
        z!Failed to parse GoalState XML: %srZ   Nz./Container/ContainerIdz4./Container/RoleInstanceList/RoleInstance/InstanceIdz./Incarnation)container_idinstance_idincarnationzMissing %s in GoalState XMLzD./Container/RoleInstanceList/RoleInstance/Configuration/Certificateszget-certificates-xmlzget certificates xmlr!   T)r   z/Azure endpoint returned empty certificates xml.)r   r   
fromstringroot
ParseErrorrc   r9   r{   _text_from_xpathr   r   r   getattrr   certificates_xmlr   r#   r%   r   contents)r   r   r   r   rG   attrr\   r   s           r(   r   zGoalState.__init__[  s    &;"	#..|<DI !112KL00B
  00AB 	8DtT"*3d:'E2377		8 !%##*
 ?/((+2( 
 )-(B(B(F(F )G )( % ((06I  1   0?1 %% 	#3a7KK 	2 s$   D+ AE%+E">EE"%E.c                 V    | j                   j                  |      }||j                  S y r   )r   findtext)r   xpathelements      r(   r   zGoalState._text_from_xpath  s'    ))..'<<r,   )T)
r$   r   r   r   r   r   r   boolr   r   r*   r,   r(   r   r   Z  sA    
 "&	5CJ'5  75 	5
 
5nr,   r   c                       e Zd ZdddZd Zd Zed        Zej                  d        Ze	d        Z
ee	d	               Ze	d
        Ze	d        Ze	d        Ze	d        Zy)OpenSSLManagerzTransportPrivate.pemzTransportCert.pem)private_keyr   c                 d    t        j                         | _        d | _        | j	                          y r   )r   mkdtemptmpdir_certificategenerate_certificater   s    r(   r   zOpenSSLManager.__init__  s&     ((* !!#r,   c                 B    t        j                  | j                         y r   )r   del_dirr   r   s    r(   clean_upzOpenSSLManager.clean_up  s    T[[!r,   c                     | j                   S r   r   r   s    r(   r   zOpenSSLManager.certificate  s       r,   c                     || _         y r   r   )r   values     r(   r   zOpenSSLManager.certificate  s
    !r,   c                    t         j                  d       | j                  t         j                  d       y t        | j                        5  t        j
                  ddddddd	d
ddd| j                  d   d| j                  d   g       d}t        | j                  d         D ]  }d|vs||j                         z  } || _        d d d        t         j                  d       y # 1 sw Y   xY w)Nz7Generating certificate for communication with fabric...zCertificate already generated.opensslreqz-x509z-nodesz-subjz/CN=LinuxTransportz-days32768z-newkeyzrsa:2048z-keyoutr   z-outr    CERTIFICATEzNew certificate generated.)	r9   r:   r   r   r   r   certificate_namesopenrstrip)r   r   lines      r(   r   z#OpenSSLManager.generate_certificate  s    		KL'II67_ 	+II(**=9**=9$ KT33MBC 1 ,4;;=0K1  +D/	+0 			./1	+ 	+s   AC'-C''C0c                 F    ddd| g}t        j                   ||      \  }}|S )Nr   x509z-nooutrg   )r   )actioncertcmdresultrI   s        r(   _run_x509_actionzOpenSSLManager._run_x509_action  s+     &(F3IIc-	r,   c                 f    | j                  d|      }g d}t        j                  ||      \  }}|S )Nz-pubkey)z
ssh-keygenz-iz-mPKCS8z-fz
/dev/stdinr   )r   r   )r   r   pub_key
keygen_cmdssh_keyrI   s         r(   _get_ssh_key_from_certz%OpenSSLManager._get_ssh_key_from_cert  s2    ''	;?L
YYz8
r,   c                     | j                  d|      }|j                  d      }||dz   d j                  d      }dj                  |      S )a   openssl 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
'

        Azure control plane passes that fingerprint as so:
        '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
        z-fingerprintr3   r4   :r   )r   r   r>   join)r   r   raw_fpeqoctetss        r(   _get_fingerprint_from_certz)OpenSSLManager._get_fingerprint_from_cert  sM     &&~{C[[Q$**3/wwvr,   c                 r   t        j                  |      j                  d      }|j                  }ddddd|j	                  d      g}t        | j                        5  t        j                   dj                  di | j                  d	d
j                  |            \  }}ddd       |S # 1 sw Y   S xY w)zDecrypt the certificates XML document using the our private key;
        return the list of certs and private keys contained in the doc.
        z.//Datas   MIME-Version: 1.0s<   Content-Disposition: attachment; filename="Certificates.p7m"s?   Content-Type: application/x-pkcs7-mime; name="Certificates.p7m"s!   Content-Transfer-Encoding: base64r,   r   zuopenssl cms -decrypt -in /dev/stdin -inkey {private_key} -recip {certificate} | openssl pkcs12 -nodes -password pass:T   
)shellrg   Nr*   )r   r   r   r   r   r   r   r   r   r   r   )r   r   tagcertificates_contentlinesrH   rI   s          r(   _decrypt_certs_from_xmlz&OpenSSLManager._decrypt_certs_from_xml  s    
 $$%56;;IF"xx KN0 ''0
 _ 	YY* ##)6D,0,B,BD ZZ&FC	 
	 
s   AB,,B6c                 P   | j                  |      }g }i }|j                         D ]}  }|j                  |       t        j                  d|      rg }-t        j                  d|      sDdj                  |      }| 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
  
splitlinesappendrematchr   r   r  )	r   r   rH   currentkeysr   r   r   fingerprints	            r(   parse_certificatesz!OpenSSLManager.parse_certificates  s     **+;<NN$ 
	DNN4 xx.58$?"ii055kB"==kJ$+[!
	 r,   N)r$   r   r   r   r   r   propertyr   setterr+   r   staticmethodr   r   r  r
  r  r*   r,   r(   r   r     s    -*
$
" ! ! " " !0 !0>   ! 
 ! ! ! ! ! !0 ! !r,   r   c                       e Zd Z ej                  d      Z ej                  d      ZdZdZdZ	dZ
deded	ed
dfdZedd       Zeded
dfd       Z	 	 ddedededed
ef
dZeded
dfd       Zy)GoalStateHealthReportera          <?xml version="1.0" encoding="utf-8"?>
        <Health xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:xsd="http://www.w3.org/2001/XMLSchema">
          <GoalStateIncarnation>{incarnation}</GoalStateIncarnation>
          <Container>
            <ContainerId>{container_id}</ContainerId>
            <RoleInstanceList>
              <Role>
                <InstanceId>{instance_id}</InstanceId>
                <Health>
                  <State>{health_status}</State>
                  {health_detail_subsection}
                </Health>
              </Role>
            </RoleInstanceList>
          </Container>
        </Health>
        z        <Details>
          <SubStatus>{health_substatus}</SubStatus>
          <Description>{health_description}</Description>
        </Details>
        ReadyNotReadyProvisioningFailedi   
goal_stater   endpointr   Nc                 .    || _         || _        || _        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)r   r  r   r  s       r(   r   z GoalStateHealthReporter.__init__?  s    " &&;#!r,   c                    | j                  | j                  j                  | j                  j                  | j                  j                  | j
                        }t        j                  d       	 | j                  |       t        j                  d       y # t        $ r$}t        d|z  t        j                          d }~ww xY w)N)r   r   r   statusz Reporting ready to Azure fabric.documentz#exception while reporting ready: %srZ   zReported ready to Azure fabric.)build_reportr   r   r   r   PROVISIONING_SUCCESS_STATUSr9   r:   _post_health_reportry   rc   errorrX   )r   r&  rG   s      r(   send_ready_signalz)GoalStateHealthReporter.send_ready_signalT  s    $$((44))66((4433	 % 
 			45	$$h$7 	23  	#59II 	s   2B 	C#CCr   c                    | j                  | j                  j                  | j                  j                  | j                  j                  | j
                  | j                  |      }	 | j                  |       t        j                  d       y # t        $ r&}d|z  }t        |t        j                          d }~ww xY w)N)r   r   r   r$  	substatusr   r%  z%exception while reporting failure: %srZ   z!Reported failure to Azure fabric.)r'  r   r   r   r   PROVISIONING_NOT_READY_STATUSPROVISIONING_FAILURE_SUBSTATUSr)  ry   rc   r9   r*  r{   )r   r   r&  rG   r\   s        r(   send_failure_signalz+GoalStateHealthReporter.send_failure_signalh  s    $$((44))66((445599# % 
	$$h$7 	78  	9A=C#CSYY?	s   )B 	C !B;;C r   r   r   r$  c                 >   d}|<| j                   j                  t        |      t        |d | j                               }| j                  j                  t        t        |            t        |      t        |      t        |      |      }|j                  d      S )Nr   )health_substatushealth_description)r   r   r   health_statushealth_detail_subsectionr   )%HEALTH_DETAIL_SUBSECTION_XML_TEMPLATEr   r   "HEALTH_REPORT_DESCRIPTION_TRIM_LENHEALTH_REPORT_XML_TEMPLATEr   r   )	r   r   r   r   r$  r-  r   health_detailhealth_reports	            r(   r'  z$GoalStateHealthReporter.build_report{  s       FFMM!'	!2#) I$"I"IJ$ N M 77>>s;/0-{+ .%2 ? 
 ##G,,r,   r&  c                     t        d       t        j                  d       dj                  | j                        }| j
                  j                  ||ddi       t        j                  d       y )Nr   z&Sending health report to Azure fabric.zhttp://{}/machine?comp=healthzContent-Typeztext/xml; charset=utf-8)rg   r   z/Successfully sent health report to Azure fabric)r   r9   r:   r   r"  r!  r   )r   r&  r   s      r(   r)  z+GoalStateHealthReporter._post_health_report  sc    ( 	a		:;-44T^^D##(()+DE 	) 	

 			CDr,   )r   Nr   )r$   r   r   r   r   r8  r6  r(  r.  r/  r7  r   r   r   r   r+   r+  r0  r   r'  r)  r*   r,   r(   r  r    s   !0	", -<HOO	-) #*$.!%9"),&""  7" 	"
 
"* !4 !4& !9s 9t 9 !90 -- - 	-
 - 
-8 !EE Ed E !Er,   r  c                   8   e Zd ZdefdZd Zedej                  ddfd       Z	e	 ddej                  de
ee      fd       Zed	eddfd
       Zededefd       Zedefd       Zedeeef   dedefd       Zedededefd       Zedededefd       Zy)WALinuxAgentShimr  c                 .    || _         d | _        d | _        y r   )r  openssl_managerr   )r   r  s     r(   r   zWALinuxAgentShim.__init__  s     9=HL"r,   c                 R    | j                   | j                   j                          y y r   )r?  r   r   s    r(   r   zWALinuxAgentShim.clean_up  s%    +  ))+ ,r,   distror   Nc                     t         j                  d       	 |j                  |       y # t        $ r(}t	        d|z  t         j
                         Y d }~y d }~ww xY w)NzEjecting the provisioning isoz(Failed ejecting the provisioning iso: %srZ   )r9   r:   eject_mediary   rc   r*  )r   iso_devrA  rG   s       r(   	eject_isozWALinuxAgentShim.eject_iso  sN    		12	w' 	#:Q>II 	s   ) 	AAAc                    d}| j                   '|%t               | _         | j                   j                  }| j                  t	        |      | _        | j                  |du      }d}|| j                  ||      }t        || j                  | j                        }|| j                  ||       |j                          |S )a  Gets 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.
        Nr   )rA  )r?  r   r   r   r   _fetch_goal_state_from_azure_get_user_pubkeysr  r  rE  r+  )r   rA  pubkey_inforD  http_client_certificater  ssh_keyshealth_reporters           r(   "register_with_azure_and_fetch_dataz3WALinuxAgentShim.register_with_azure_and_fetch_data  s     #''K,C#1#3D &*&:&:&F&F#%%-)@'*D& 664D@ 7 

 "--j+FH122DMM
 NN76N2))+r,   r   c                     | j                   t        d      | _         | j                  d      }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.
        NFrG  r   )r   r   rH  r  r  r0  )r   r   r  rM  s       r(   &register_with_azure_and_report_failurez7WALinuxAgentShim.register_with_azure_and_report_failure  s^     %%-)@)FD&666N
122DMM
 	+++Dr,   r   c                 F    | j                         }| j                  ||      S )a   Fetches 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)r   r   unparsed_goal_state_xmls      r(   rH  z-WALinuxAgentShim._fetch_goal_state_from_azure  s,     #'"I"I"K--#%5
 	
r,   c                    t         j                  d       dj                  | j                        }	 t	        j
                  ddt              5  | j                  j                  |      }ddd       t         j                  d	       j                  S # 1 sw Y   *xY w# t        $ r$}t        d|z  t         j                          d}~ww xY w)
zFetches the GoalState XML from the Azure endpoint and returns
        the XML as a string.

        @return: GoalState XML string
        zRegistering with Azure...z!http://{}/machine/?comp=goalstatezgoalstate-retrievalzretrieve goalstater!   Nz9failed to register with Azure and fetch GoalState XML: %srZ   z#Successfully fetched GoalState XML.)r9   rX   r   r  r   r#   r%   r   r   ry   rc   r{   r:   r   )r   r   r   rG   s       r(   rS  z3WALinuxAgentShim._get_raw_goal_state_xml_from_azure  s     	,-188G	((*0( ?
  5599#>? 			78   ? ?  	#KKK
 	s/   B B*B BB 	C(CCrU  c                 B   	 t        || j                  |      }dj                  d|j                  z  d|j                  z  d|j                  z  g      }t        |t        j                         |S # t        $ r$}t        d|z  t        j
                          d}~ww xY w)a  Parses 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: %srZ   Nz, zGoalState XML container id: %szGoalState XML instance id: %szGoalState XML incarnation: %s)r   r   ry   rc   r9   r{   r   r   r   r   r:   )r   rU  r   r  rG   r\   s         r(   rT  z*WALinuxAgentShim._parse_raw_goal_state_xml+  s    	"'** J ii0:3J3JJ/*2H2HH/*2H2HH
 	 ;  	#4q8KK 	s   A1 1	B:BBr  rJ  c                     g }|j                   Z|X| j                  Lt        j                  d       | j                  j	                  |j                         }| j                  ||      }|S )a  Gets 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.)r   r?  r9   r:   r  _filter_pubkeys)r   r  rJ  rL  keys_by_fingerprints        r(   rI  z"WALinuxAgentShim._get_user_pubkeysM  sn    : ''3'$$0IIGH"&"6"6"I"I++# ++,?MHr,   rZ  c                     g }|D ]t  }d|v r|d   r|j                  |d          !d|v r:|d   r5|d   }|| v r|j                  | |          Ht        j                  d|       _t        j                  d|       v |S )a8  Filter 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.
        r   r  zIovf-env.xml specified PublicKey fingerprint %s not found in goalstate XMLzFovf-env.xml specified PublicKey with neither value nor fingerprint: %s)r  r9   r{   )rZ  rJ  r  pubkeyr  s        r(   rY  z WALinuxAgentShim._filter_pubkeysw  s     ! 	F& VG_F7O,&(VM-B$]3"55KK 3K @AKK8# 0	( r,   r   )r$   r   r   r   r   r   r+   r   DistrorE  r	   r   rN  rQ  r   r   rH  r   rS  r   rT  listrI  r  dictrY  r*   r,   r(   r=  r=    se   M M
, ! D  ! !@D#nn#	$s)	# !#J !E# E$ E !E !
 $
	
 !
 !!E ! !!4 !!&sEz!2  
	 !B !'#'26'	' !'R !T ! ! ! !r,   r=  r  rA  rJ  rD  c                     t        |       }	 |j                  |||      |j                          S # |j                          w xY w)Nr  )rA  rJ  rD  )r=  rN  r   )r  rA  rJ  rD  shims        r(   get_metadata_from_fabricrc    sB     X.D66{G 7 
 	s	   2 Ar*  zerrors.ReportableErrorc                     t        |       }|j                         }	 |j                  |       |j                          y # |j                          w xY w)Nra  rP  )r=  as_encoded_reportrQ  r   )r  r*  rb  r   s       r(   report_failure_to_fabricrf    sC    X.D))+K333Ls   A Ac                 |    t        d| z  t        j                         t        d|z  t        j                         y )Nzdhclient output stream: %srZ   zdhclient error stream: %s)rc   r9   r:   )rH   errs     r(   dhcp_log_cbri    s0    $s*		 #c)syyr,   c                       e Zd Zy)NonAzureDataSourceN)r$   r   r   r*   r,   r(   rk  rk    s    r,   rk  c                       e Zd ZdddZdddddddddd	dee   dee   d	ee   d
ee   dee   deee	      dedee   deddfdZ
defdZededd fd       Z	 ddededefdZ	 	 	 d dedededefdZd Zd Zd Zy)!	OvfEnvXmlz)http://schemas.dmtf.org/ovf/environment/1z)http://schemas.microsoft.com/windowsazure)ovfwaNF	r   passwordr   custom_datadisable_ssh_password_authpublic_keyspreprovisioned_vmpreprovisioned_vm_typeprovision_guest_proxy_agentr   rq  r   rr  rs  rt  ru  rv  rw  r   c       	             || _         || _        || _        || _        || _        |xs g | _        || _        || _        |	| _        y r   rp  )
r   r   rq  r   rr  rs  rt  ru  rv  rw  s
             r(   r   zOvfEnvXml.__init__  sN     !  &)B&'2'8b!2&<#+F(r,   c                 4    | j                   |j                   k(  S r   )__dict__)r   others     r(   __eq__zOvfEnvXml.__eq__  s    }}..r,   ovf_env_xmlc                 <   	 t        j                  |      }|j                  d| j                        st        d      t               }|j                  |       |j                  |       |S # t         j                  $ r}t        j                  |      |d}~ww xY w)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)r   r   r   r   "ReportableErrorOvfParsingExceptionr   
NAMESPACESrk  rm  &_parse_linux_configuration_set_section _parse_platform_settings_section)clsr}  r   rG   instances        r(   
parse_textzOvfEnvXml.parse_text  s    	P))+6D
 yy3S^^D$O  ;77=11$7 %% 	P;;aHaO	Ps   A, ,B?BBr   required	namespacec                 :   |j                  d|d|t        j                        }t        |      dk(  r2d|z  }t        j                  |       |rt        j                  |      y t        |      dkD  r#t        j                  d|t        |      fz        |d   S )Nz./r   r   missing configuration for %rr4   *multiple configuration matches for %r (%d))findallrm  r  lenr9   r:   r   !ReportableErrorOvfInvalidMetadata)r   noder   r  r  matchesr\   s          r(   _findzOvfEnvXml._find  s     ,,"D)9+?+?
 w<1047CIIcN>>sCC\A::<W&' 
 qzr,   decode_base64
parse_boolc                    |j                  d|z   t        j                        }t        |      dk(  r3d|z  }t        j                  |       |rt        j                  |      |S t        |      dkD  r#t        j                  d|t        |      fz        |d   j                  }	|	|}	|r4|	2t        j                  dj                  |	j                                     }	|rt        j                  |	      }	|	S )Nz./wa:r   r  r4   r  r   )r  rm  r  r  r9   r:   r   r  r   rj   	b64decoder   r>   r   translate_bool)
r   r  r   r  r  r  defaultr  r\   r   s
             r(   _parse_propertyzOvfEnvXml._parse_property  s     ,,w~y/C/CDw<1047CIIcN>>sCCN\A::<W&' 
 
 =EU.$$RWWU[[]%;<E''.Er,   c                 t   | j                  |dd      }| j                  |dd      }| j                  |ddd      | _        | j                  |dd      | _        | j                  |d	d      | _        | j                  |d
d      | _        | j                  |ddd      | _        | j                  |       y )NProvisioningSectionTr  !LinuxProvisioningConfigurationSet
CustomDataF)r  r  UserNameUserPasswordHostName DisableSshPasswordAuthentication)r  r  )r  r  rr  r   rq  r   rs  _parse_ssh_section)r   r   provisioning_section
config_sets       r(   r  z0OvfEnvXml._parse_linux_configuration_set_section8  s    #zz'$  *  
 ZZ /   

  //	 0 
 ,,
T - 
 ,, - 
 ,,
T - 
 *.)=)=.	 *> *
& 	
+r,   c                     | j                  |dd      }| j                  |dd      }| j                  |dddd      | _        | j                  |dd      | _        | j                  |d	dd
      | _        y )NPlatformSettingsSectionTr  PlatformSettingsPreprovisionedVmF)r  r  r  PreprovisionedVMTypeProvisionGuestProxyAgentr  r  )r  r  ru  rv  rw  )r   r   platform_settings_sectionplatform_settingss       r(   r  z*OvfEnvXml._parse_platform_settings_sectionZ  s    $(JJ+d %/ %
! !JJ%'9D ' 
 "&!5!5 "6 "
 '+&:&:" '; '
#
 ,0+?+?&	 ,@ ,
(r,   c                 t   g | _         | j                  |dd      }|y | j                  |dd      }|y |j                  dt        j                        D ]`  }| j                  |dd      }| j                  |dd      }| j                  |dd	d
      }|||d}| j                   j                  |       b y )NSSHFr  
PublicKeysz./wa:PublicKeyFingerprintPathValuer   r  )r  r   r   )rt  r  r  rm  r  r  r  )	r   r  ssh_sectionpublic_keys_section
public_keyr  r   r   r   s	            r(   r  zOvfEnvXml._parse_ssh_sectionu  s    jjUUjC"jj ) 
 &-55i22
 	-J ..ME / K ''
FU'KD((GR% ) E  +G
 ##G,	-r,   )ro  )FFN)r$   r   r   r  r	   r   r   r   r   r_  r   r|  classmethodr  r  r  r  r  r  r*   r,   r(   rm  rm    s`   :9J #'"&"&'+48,0"'04,1G 3-G 3-	G
 3-G e_G $,D>G d4j)G  G !)G &*G 
G./t / S [  :   	
 : $ " " 	"
 " "H ,D
6-r,   rm  r   )Hrj   rp   loggingr   r  r   rl   
contextlibr   r   r   r   typingr   r   r	   r
   r   	xml.etreer   xml.sax.saxutilsr   	cloudinitr   r   r   r   r   r   cloudinit.reportingr   cloudinit.sources.azurer   	getLoggerr$   r9   DEFAULT_WIRESERVER_ENDPOINTrA   rV   rb   ro   r#   r%   r   r+   rN   rY   r   r@   rc   rv   r}   r   r_  r   intr   r   r   r   ry   r   r   r   r  r=  r]  rc  rf  ri  rk  rm  r*   r,   r(   <module>r     s      	 	   %   ; ; ! # J J & *g! . "% $ $ +F++	2  CL	hsAv&6 	8CF;K 	 P Pf  6 "	$* 

 

   
 !3	3 3 5/	3
 3 3 3 3l 14
DB B:D9 D< <~} }@[E [E|b bJ  (,!	NN $s)$ c]	  s 3K  	 	N- N-r,   