
    x[h                     R   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	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jF                  e$      Z%dZ&dZ'dZ(dZ)dZ* e jV                  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        Z0ddde1de jd                  fdZ3d Z4e.d        Z5ed         Z6e.dd!d"d#d$e1d%e7d&ee8   d'e9d(e9dejt                  fd)       Z;d*e1d+e1d,e1de8fd-Z< G d. d/      Z= G d0 d1e>      Z? G d2 d3      Z@ G d4 d5      ZA G d6 d7      ZB G d8 d9      ZCe.	 	 dGd:e1d;ej                  d<eee1      d=ee1   fd>       ZEe.d:e1d?d@fdA       ZFdB ZG G dC dDe>      ZH G dE dF      ZIy)H    N)contextmanager)datetimetimezone)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"                  | t$        j&                        j)                         dt!        j"                  |t$        j&                        j)                         dt!        j"                  |t$        j&                        j)                         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/   r0   zcloud-init-localr1   InactiveExitTimestampMonotonicz;Failed to parse InactiveExitTimestampMonotonic from systemdz0Failed to get InactiveExitTimestampMonotonic: %sz?Failed to parse InactiveExitTimestampMonotonic from systemd: %sr   zkernel_start=z user_start=z cloudinit_activation=)r   uses_systemdRuntimeErrorLOGdebugfloatr   r   uptime
ValueErrorr   splitProcessExecutionErrorr   ReportingEventBOOT_EVENT_TYPEr   fromtimestampr   utc	isoformatDEFAULT_EVENT_ORIGINreport_event)kernel_starteout_tsm
user_startcloudinit_activationevts           r)   get_boot_telemetryrO   5   s    !NOOII)*PTV}uT[[]';;F
Q 3#:))C.#CJ  "U3Z'%9:
 	
Q 3#:))C.#CM   ,uSzG/CD 

 ""<>HHJ"":x||<FFH""$hllik		
 	##C  JS  PGHaOP$ %% ;a?
	  JQN
	2 %% >B
	  M
 	sa   1G/ (AH ?AI /	H	8HH	IH..I:I		IJ$I33J?JJ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=r5   z	, flavor=   z, python_version=python)	r   system_infor   r@   SYSTEMINFO_EVENT_TYPEr   version_stringrE   rF   )inforN   s     r)   get_system_inforZ      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_TYPErE   rF   )r]   r\   rN   s      r)   report_diagnostic_eventrd      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dumpsrE   rF   )
event_nameevent_contentcompressed_data
event_datarN   s        r)   report_compressed_eventrw      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)ro   r3   z$Exception when dumping dmesg log: %sr[   N)r9   r:   r   rw   	Exceptionrd   reprwarning)rI   rJ   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>      )rh   retry_sleeptimeout_minutesurlheadersrh   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   Nr5   )r   r   )r   rh   timeoutzdFailed HTTP request with Azure endpoint %s during attempt %d with exception: %s (code=%r headers=%r)r[   zNetwork is unreachablez@Successful HTTP request with Azure endpoint %s after %d attempts)r   r   readurlUrlErrorrd   coder   r9   r:   strr   )	r   r   rh   r   r   r   attemptresponserH   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__D  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.getJ  s?    ,,ll'')GNN4445 g66r-   Nrh   c                     | j                   }|+| j                   j                         }|j                  |       t        |||      S )N)rh   r   )r   r   r   r   )r   r   rh   extra_headersr   s        r)   postzAzureEndpointHttpClient.postQ  s@     ,,$ll'')GNN=) 4AAr-   )FNN)r%   
__module____qualname__r   r   r   UrlResponser   r
   bytesr   r+   r-   r)   r   r   >  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   [  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: %sr[   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   ET
fromstringroot
ParseErrorrd   r9   r|   _text_from_xpathr   r   r   getattrr   certificates_xmlr   r$   r&   r   contents)r   r   r   r   rH   attrr]   r   s           r)   r   zGoalState.__init__`  s    &;"	l3DI !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   _  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                  | j                  d         j                         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:3072z-keyoutr   z-outr    CERTIFICATEzNew certificate generated.)r9   r:   r   r   r   r   certificate_namesr   load_text_file
splitlinesrstrip)r   r   lines      r)   r   z#OpenSSLManager.generate_certificate  s   		KL'II67_ 	+II(**=9**=9$ K++&&}5jl1 !,4;;=0K	1
  +D3	+4 			./5	+ 	+s   A7C?C??Dc                 F    ddd| g}t        j                   ||      \  }}|S )Nr   x509z-nooutrh   )r   )actioncertcmdresultrJ   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_keyrJ   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\n'

        Azure control plane passes that fingerprint as so:
        '073E19D14D1C799224C6A0FD8DDAB6A8BF27D473'
        z-fingerprintr4   r5   :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   
)shellrh   Nr+   )r   r   r   r   r   r   r   r   r   r   r  )r   r   tagcertificates_contentlinesrI   rJ   s          r)   _decrypt_certs_from_xmlz&OpenSSLManager._decrypt_certs_from_xml  s    
 mm,-229="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  r   appendrematchr  r   r  )	r   r   rI   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 !0B   ! 
 ! ! ! ! ! !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__F  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: %sr[   zReported ready to Azure fabric.)build_reportr"  r   r   r   PROVISIONING_SUCCESS_STATUSr9   r:   _post_health_reportrz   rd   errorrY   )r   r(  rH   s      r)   send_ready_signalz)GoalStateHealthReporter.send_ready_signal[  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: %sr[   z!Reported failure to Azure fabric.)r)  r"  r   r   r   PROVISIONING_NOT_READY_STATUSPROVISIONING_FAILURE_SUBSTATUSr+  rz   rd   r9   r,  r|   )r   r   r(  rH   r]   s        r)   send_failure_signalz+GoalStateHealthReporter.send_failure_signalo  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)rh   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   r:  r8  r*  r0  r1  r9  r   r   r   r   r,   r-  r2  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   )rA  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: %sr[   )r9   r:   eject_mediarz   rd   r,  )r   iso_devrC  rH   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   )rC  )rA  r   r   r   r   _fetch_goal_state_from_azure_get_user_pubkeysr  r   rG  r-  )r   rC  pubkey_inforF  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.
        NFrI  r   )r   r   rJ  r  r   r2  )r   r   r  rO  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)   rJ  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: %sr[   z#Successfully fetched GoalState XML.)r9   rY   r   r   r   r$   r&   r   r   rz   rd   r|   r:   r   )r   r   r   rH   s       r)   rU  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rW  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: %sr[   Nz, zGoalState XML container id: %szGoalState XML instance id: %szGoalState XML incarnation: %s)r   r   rz   rd   r9   r|   r  r   r   r   r:   )r   rW  r   r  rH   r]   s         r)   rV  z*WALinuxAgentShim._parse_raw_goal_state_xml2  s    	"'** J ii0:3J3JJ/*2H2HH/*2H2HH
 	 ;  	#4q8KK 	s   A1 1	B:BBr  rL  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   rA  r9   r:   r  _filter_pubkeys)r   r  rL  rN  keys_by_fingerprints        r)   rK  z"WALinuxAgentShim._get_user_pubkeysT  sn    : ''3'$$0IIGH"&"6"6"I"I++# ++,?MHr-   r\  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|   )r\  rL  r  pubkeyr  s        r)   r[  z WALinuxAgentShim._filter_pubkeys~  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   DistrorG  r
   r	   rP  rS  r   r   rJ  r   rU  r   rV  listrK  r  dictr[  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   rC  rL  rF  c                     t        |       }	 |j                  |||      |j                          S # |j                          w xY w)Nr   )rC  rL  rF  )r?  rP  r   )r   rC  rL  rF  shims        r)   get_metadata_from_fabricre    sB     X.D66{G 7 
 	s	   2 Ar,  zerrors.ReportableErrorc                     t        |       }|j                         }	 |j                  |       |j                          y # |j                          w xY w)Nrc  rR  )r?  as_encoded_reportrS  r   )r   r,  rd  r   s       r)   report_failure_to_fabricrh    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: %sr[   zdhclient error stream: %s)rd   r9   r:   )rI   errs     r)   dhcp_log_cbrk    s0    $s*		 #c)syyr-   c                       e Zd Zy)NonAzureDataSourceN)r%   r   r   r+   r-   r)   rm  rm    s    r-   rm  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   rs  r   rt  ru  rv  rw  rx  ry  r   c       	             || _         || _        || _        || _        || _        |xs g | _        || _        || _        |	| _        y r   rr  )
r   r   rs  r   rt  ru  rv  rw  rx  ry  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                        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   
NAMESPACESrm  ro  &_parse_linux_configuration_set_section _parse_platform_settings_section)clsr  r   rH   instances        r)   
parse_textzOvfEnvXml.parse_text  s    	P==-D
 99/@H$O  ;77=11$7 }} 	P;;aHaO	Ps   A, ,B?BBr   required	namespacec                 "   |j                  d|d|t        j                        }|s2d|z  }t        j	                  |       |rt        j                  |      y t        |      dkD  r#t        j                  d|t        |      fz        |d   S )Nz./r  missing configuration for %rr5   *multiple configuration matches for %r (%d)r   )findallro  r  r9   r:   r   !ReportableErrorOvfInvalidMetadatalen)r   noder   r  r  matchesr]   s          r)   _findzOvfEnvXml._find  s     ,,"D)9+?+?
 047CIIcN>>sCC\A::<W&' 
 qzr-   decode_base64
parse_boolc                    |j                  d|z   t        j                        }|s3d|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  r5   r  r   r   )r  ro  r  r9   r:   r   r  r  r   rk   	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047CIIcN>>sCCNw<!::<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  rt  r   rs  r   ru  _parse_ssh_section)r   r   provisioning_section
config_sets       r)   r  z0OvfEnvXml._parse_linux_configuration_set_section@  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d      | _        y )
NPlatformSettingsSectionTr  PlatformSettingsPreprovisionedVmF)r  r  r  PreprovisionedVMTypeProvisionGuestProxyAgent)r  r  rw  rx  ry  )r   r   platform_settings_sectionplatform_settingss       r)   r  z*OvfEnvXml._parse_platform_settings_sectionb  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   r   )rv  r  r  ro  r  r  r  )	r   r  ssh_sectionpublic_keys_section
public_keyr  r   r   r   s	            r)   r  zOvfEnvXml._parse_ssh_section~  s    jjUUjC"jj ) 
 &-55i22
 	-J ..ME / K ''
FU'KD((GR% ) E  +G
 ##G,	-r-   )rq  )FFN)r%   r   r   r  r
   r   r   r   r	   ra  r   r~  classmethodr  r  r  r  r  r  r+   r-   r)   ro  ro    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 [  :   	
 : $ # # 	#
 # #J ,D
8-r-   ro  r   )Jrk   rq   loggingr   r  r   rm   
contextlibr   r   r   r   r   typingr   r	   r
   r   r   	xml.etreer   r   xml.sax.saxutilsr   	cloudinitr   r   r   r   r   r   cloudinit.reportingr   cloudinit.sources.azurer   	getLoggerr%   r9   DEFAULT_WIRESERVER_ENDPOINTrA   rW   rc   rp   r$   r&   r   r,   rO   rZ   r   r@   rd   rw   r~   r   ra  r   intr   r   r   r   rz   r   r   r   r  r?  r_  re  rh  rk  rm  ro  r+   r-   r)   <module>r     s  
    	 	   % '  ; ; ' # J J & *g! . "% $ $ +F++	2  CL	hsAv&6 	8CF;K 	 R Rj  6 "	$* 

 

   
 !3	3 3 5/	3
 3 3 3 3l 14
DB B:D9 D< <~ D[E [E|b bJ  (,!	NN $s)$ c]	  s 3K  	 	P- P-r-   