
    im2                        d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
 d dlmZmZmZmZ d dlmZ d dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ  e j6                  e      ZdZ G d d      Z G d dej@                        Z! G d de!      Z"d Z#d Z$d Z%de&fdZ'e"ejP                  ffe!ejP                  ejR                  ffgZ*d Z+y)    N)suppress)gaierrorgetaddrinfo	inet_ntoa)pack)dminetperformancesources)
url_helper)util)dhcp)NoDHCPLeaseError)EphemeralIPNetwork)ec2
CloudStackc                   P    e Zd ZdZd Zd Z ej                  dd      d        Zy)	CloudStackPasswordServerClienta  
    Implements password fetching from the CloudStack password server.

    http://cloudstack-administration.readthedocs.org/
       en/latest/templates.html#adding-password-management-to-your-templates
    has documentation about the system.  This implementation is following that
    found at
    https://github.com/shankerbalan/cloudstack-scripts/
       blob/master/cloud-set-guest-password-debian
    c                     || _         y N)virtual_router_address)selfr   s     H/usr/lib/python3/dist-packages/cloudinit/sources/DataSourceCloudStack.py__init__z'CloudStackPasswordServerClient.__init__/   s
    &<#    c                     d| j                    d}d|i}t        j                  ||dd      }|j                         st	        d      |j
                  j                  d      j                         S )	Nhttp://z:8080DomU_Request      )headerstimeoutretriesz+Failed to fetch VM password from CloudStackzutf-8)r   uhelpreadurlokRuntimeErrorcontentsdecodestrip)r   domu_requesturlr!   resps        r   _do_requestz*CloudStackPasswordServerClient._do_request2   sh    334E:!<0}}S'2qIwwyLMM}}##G,2244r   zGetting passwordalwayslog_modec                 t    | j                  d      }|dv ry |dk(  rt        d      | j                  d       |S )Nsend_my_password) saved_passwordbad_requestz-Error when attempting to fetch root password.r5   )r.   r'   )r   passwords     r   get_passwordz+CloudStackPasswordServerClient.get_password=   sG    ##$67--}$NOO)*r   N)	__name__
__module____qualname____doc__r   r.   r
   timedr8    r   r   r   r   #   s5    	=	5 [)H= >r   r   c                        e Zd ZdZdZdZdZ fdZd Z	 	 	 d fd	Z	d Z
d	 Zed
efd       Zd Z ej"                  dd      d        Zd Zed        Z xZS )DataSourceCloudStackFr   x   2   c                     t         |   |||       t        j                  j	                  |j
                  d      | _        d| _        i | _        d | _        y )Ncslatest)	superr   ospathjoinseed_dirapi_vercfgvr_addr)r   sys_cfgdistropaths	__class__s       r   r   zDataSourceCloudStack.__init__P   sE    &%0U^^T:  r   c                 *   t         j                  d       dD ]+  }t        j                  |      }|s|j	                         c S  t         j                  d       t        t        j                        5  t        j                         j                  | j                  d      }|r|j	                         cddd       S 	 ddd       t         j                  d| j                  j                  j                         	 | j                  j                  j                  | j                  j                        }|j                  d      }|r|j	                         S 	 t         j                  d       y# 1 sw Y   xY w# t        t         t"        f$ r Y 8w xY w)	zTry obtaining a "domain-name" DHCP lease parameter:
        - From systemd-networkd lease (case-insensitive)
        - From ISC dhclient
        - From dhcpcd (ephemeral)
        - Return empty string if not found (non-fatal)
        z.Try obtaining domain name from networkd leases)
DOMAINNAMEDomaindomain-namezHCould not obtain FQDN from networkd leases. Falling back to ISC dhclientrU   NzBCould not obtain FQDN from ISC dhclient leases. Falling back to %sz7No domain name found in any DHCP lease; returning emptyr4   )LOGdebugr   networkd_get_option_from_leasesr*   r   NoDHCPLeaseMissingDhclientErrorIscDhclientget_key_from_latest_leaserO   dhcp_clientclient_nameget_newest_leasefallback_interfacegetr   FileNotFoundErrorAttributeError)r   key
domainnamedomain_namelatest_leases        r   _get_domainnamez$DataSourceCloudStack._get_domainnameY   sd    			BC: 	*C==cBJ!''))	*
 				
 d::; 	+**,FF]K "((*	+ 	+ 		+ 			KK##//	

	;;22CC..L '**=9K"((** 
 			KL/	+ 	+& !"3^D 		s    4A E/<AE; /E8;FFc                 R   t         |   |||      }|rd|j                  vrt        j	                  d       | j                         }|rG|j                   d| }t        j	                  d|       t        j                  ||j                        S t        j	                  d|       |S )z
        Returns instance's hostname / fqdn
        First probes the parent class method.

        If fqdn is requested, and the parent method didn't return it,
        then attach the domain-name from DHCP response.
        .zFQDN requestedzObtained the following FQDN: %szNCould not determine domain name for FQDN. Fall back to hostname as an FQDN: %s)	rF   get_hostnamehostnamerV   rW   rg   r   DataSourceHostname
is_default)r   fqdn
resolve_ipmetadata_onlyrk   rd   rQ   s         r   rj   z!DataSourceCloudStack.get_hostname   s     7'j-HCx000II&'--/J"++,Aj\:		;TB11$8K8KLLII7
 r   c                    | j                         }|j                  dk  ryt        j                  | j                  d      g}t        j                         }t        j                  ||j                  |j                  t        j                        \  }}|r!t        j                  d|       t        |      S t        j                  d|t        t        j                         |z
               t        |      S )Nr   Fzlatest/meta-data/instance-id)urlsmax_waitr"   	status_cbzUsing metadata source: '%s'z>Giving up on waiting for the metadata from %s after %s seconds)get_url_paramsmax_wait_secondsr$   combine_urlmetadata_addresstime	monotonicwait_for_urltimeout_secondsrV   warningrW   criticalintbool)r   
url_paramsrr   
start_timer,   	_responses         r   wait_for_metadata_servicez.DataSourceCloudStack.wait_for_metadata_service   s    ((*
&&!+ %%'E

 ^^%
++00..kk	
Y II3S9 Cy LL$DNN$z12	 Cyr   c                     | j                   S r   )rL   r   s    r   get_config_objz#DataSourceCloudStack.get_config_obj   s    xxr   returnc                      t               S )z#Check if running on this datasource)is_platform_viabler>   r   r   	ds_detectzDataSourceCloudStack.ds_detect   s     "##r   c                 |   i }t        j                  || j                  dz         r5|d   | _        |d   | _        t
        j                  d| j                         y| j                  rAt        j                         }t
        j                  d|       t        | j                  |      }nt        j                         }	 |5  t        | j                        }t        |t              r|j!                  d      n|| _        | j"                  st%        d	      d
| j"                   d| _        | j)                         s
	 d d d        y| j+                         cd d d        S # 1 sw Y   y xY w# t,        $ r t
        j/                  d       Y yt0        $ r)}t
        j/                  dt3        |             Y d }~yd }~ww xY w)N/)basez	user-dataz	meta-dataz%Using seeded cloudstack data from: %sTzAttempting DHCP on: %sdhcp-server-identifierzNo virtual router found!r   Fz#Unable to obtain a DHCP lease on %sz$Failed fetching metadata service: %s)r   read_optional_seedrJ   userdata_rawmetadatarV   rW   perform_dhcp_setupr	   find_fallback_nicr   rO   nullcontextget_vr_address
isinstancedictr`   rM   r'   rx   r   _crawl_metadatar   r}   	Exceptionstr)r   seed_retprimary_nicnetwork_contextrM   es         r   	_get_datazDataSourceCloudStack._get_data   su   ""84==33FH ( 5D$[1DMII=t}}M""//1KII.<0kJO"..0O	  .(5 "'40 KK 89  
 ||&'ABB*1$,,q(A%557 . . ++-. . .   	KK={K 	KK>AG	sI   >E)  A;E;E) E	E) E&"E) &E) )F;
F;F66F;zCrawling metadatar/   r0   c                    t        j                  | j                  | j                        | _        t        j
                  | j                  | j                        | _        t        | j                        }	 |j                         }|rd|ddid| _
        y# t        $ r( t        j                  t        d| j                         Y yw xY w)NTexpireF)
ssh_pwauthr7   chpasswdz/Failed to fetch password from virtual router %s)r   get_instance_userdatarK   rx   r   get_instance_metadatar   r   rM   r8   rL   r   r   logexcrV   )r   password_clientset_passwords      r   r   z$DataSourceCloudStack._crawl_metadata   s    55LL$//
 11LL$//
 9F	*779L "& , %!   	KKA 	s   5B .CCc                      | j                   d   S )Nzinstance-idr   r   s    r   get_instance_idz$DataSourceCloudStack.get_instance_id  s    }}]++r   c                      | j                   d   S )Nzavailability-zoner   r   s    r   availability_zonez&DataSourceCloudStack.availability_zone  s    }}011r   )FFF)r9   r:   r;   r   dsnameurl_max_waiturl_timeoutr   rg   rj   r   r   staticmethodr   r   r   r
   r=   r   r   propertyr   __classcell__)rQ   s   @r   r@   r@   H   s    F LK)Z 	8> $t $ $"H [*X> ?8, 2 2r   r@   c                       e Zd ZdZdZy)DataSourceCloudStackLocalau  Run in init-local using a dhcp discovery prior to metadata crawl.

    In init-local, no network is available. This subclass sets up minimal
    networking with dhclient on a viable nic so that it can talk to the
    metadata service. If the metadata service provides network configuration
    then render the network configuration for that instance based on metadata.
    TN)r9   r:   r;   r<   r   r>   r   r   r   r     s     r   r   c                  z    	 t        dd      } | d   d   d   S # t        $ r t        j                  d       Y y w xY w)Nzdata-serverP   r      zDNS Entry data-server not found)r   r   rV   rW   )addrinfos    r   get_data_serverr     sI    !}b1
 {1~a  	  		34s    ::c            
         t        j                  d      j                         } | D ]W  }|j                  d      }|d   dk(  st	        t        dt        |d   d                  }t        j                  d|       |c S  y )	Nz/proc/net/route	   00000000z<L      z"Found default route, gateway is %s)	r   load_text_file
splitlinessplitr   r   r   rV   rW   )lineslineitemsgws       r   get_default_gatewayr   '  sz     12==?E 

4 8z!4c%(B&789BII:B?I r   c                    t               }|rt        j                  d|       |S t        j                  d      }|rt        j                  d|       |S t        t        j                        5  t        j                         j                  | d      }|r!t        j                  d|       |cd d d        S 	 d d d        t        t              5  | j                  j                  | j                        }|r6t        j                  d|| j                  j                         |cd d d        S 	 d d d        t        j                  d       t               S # 1 sw Y   xY w# 1 sw Y   4xY w)Nz4Found metadata server '%s' via data-server DNS entrySERVER_ADDRESSz-Found SERVER_ADDRESS '%s' via networkd_leasesr   z&Found SERVER_ADDRESS '%s' via dhclientz1Found SERVER_ADDRESS '%s' via ephemeral %s lease z$No DHCP found, using default gateway)r   rV   rW   r   rX   r   rY   rZ   r[   ra   r\   r^   r_   r]   r   )rO   latest_addressrf   s      r   r   r   4  sS    %&N		B	
  99:JKN		;^	
 
 
$66	7 "))+EE,
 II>O!" " 	" 
#	$ 
 ))::%%
 IIC""..
  
  
  	
  II45  -" "
  
 s   ->EAEEE(r   c                      t        j                  d      } | st        j                  d       y| j	                  t
              S )Nzsystem-product-namez-system-product-name not available in dmi dataF)r   read_dmi_datarV   rW   
startswithCLOUD_STACK_DMI_NAME)product_names    r   r   r   f  s8    $$%:;L		AB""#788r   c                 6    t        j                  | t              S r   )r   list_from_dependsdatasources)dependss    r   get_datasource_listr   v  s    $$Wk::r   ),loggingrG   ry   
contextlibr   socketr   r   r   structr   	cloudinitr   r	   r
   r   r   r$   r   cloudinit.netr   cloudinit.net.dhcpr   cloudinit.net.ephemeralr   cloudinit.sources.helpersr   	getLoggerr9   rV   r   r   
DataSourcer@   r   r   r   r   r   r   DEP_FILESYSTEMDEP_NETWORKr   r   r>   r   r   <module>r      s     	   3 3  4 4 )   / 6 )g!# " "JE27-- E2P	 4 	!
/!d9D 9 !7!7 9:G22G4G4GHI;r   