
"·T``  ã               @   sô   d  d l  Z  d  d l 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
 d d	 d
 d i Z e j e ƒ Z d d d „ Z d d „  Z d d d „ Z d d „  Z d d d d d „ Z d d „  Z d S)é    N)Údmi)Úlog)Únet)Ú
url_helper)Úsubp)ÚutilÚpublicZeth0ZprivateZeth1c             C   s  | s" t  |  ƒ } t j d | ƒ | s4 t d ƒ ‚ d j t j d d ƒ t j d d ƒ ƒ } d d	 d
 | d | g } d d d d | d g } t j d ƒ s© t d ƒ ‚ yA t j | ƒ t j d | | ƒ t j | ƒ t j d | ƒ Wn+ t	 k
 rt
 j t d | | ƒ ‚  Yn X| S)zíBring up NIC using an address using link-local (ip4LL) IPs. On
       DigitalOcean, the link-local domain is per-droplet routed, so there
       is no risk of collisions. However, to be more safe, the ip4LL
       address is random.
    z,selected interface '%s' for reading metadatazPunable to find interfaces to access themeta-data server. This droplet is broken.z169.254.{0}.{1}/16é   é¨   r   éÿ   ÚipÚaddrÚaddÚdevÚlinkÚsetZupz4No 'ip' command available to configure ip4LL addressz#assigned ip4LL address '%s' to '%s'zbrought device '%s' upzRip4LL address assignment of '%s' to '%s' failed. Droplet networking will be broken)Úget_link_local_nicÚLOGÚdebugÚRuntimeErrorÚformatÚrandomZrandintr   ZwhichÚ	Exceptionr   Úlogexc)ÚdistroÚnicr   Úip_addr_cmdZip_link_cmd© r   úH/usr/lib/python3/dist-packages/cloudinit/sources/helpers/digitalocean.pyÚassign_ipv4_link_local   s*    
r   c                s?   ‡  f d d †  t  j ƒ  Dƒ } | s) d  St | d d d „  ƒS)Nc                s(   g  |  ] } ˆ  j  j | ƒ r | ‘ q Sr   )Z
networkingZis_physical)Ú.0Úf)r   r   r   ú
<listcomp><   s   	z&get_link_local_nic.<locals>.<listcomp>Úkeyc             S   s   t  j |  d ƒ S)NZifindex)ÚcloudnetZread_sys_net_int)Údr   r   r   Ú<lambda>B   s    z$get_link_local_nic.<locals>.<lambda>)r$   Zget_devicelistÚmin)r   Znicsr   )r   r   r   :   s
    r   c             C   sœ   |  s t  j d ƒ d St  j d ƒ d d d d |  g } y! t j | ƒ t  j d |  ƒ Wn; t k
 r— } z t j t  d	 |  | ƒ WYd d } ~ Xn Xd S)
zzRemove the ip4LL address. While this is not necessary, the ip4LL
       address is extraneous and confusing to users.
    zLno link_local address interface defined, skipping link local address cleanupNzcleaning up ipv4LL addressr   r   Úflushr   zremoved ip4LL addresses from %sz)failed to remove ip4LL address from '%s'.)r   r   r   r   r   r   )r   r   Úer   r   r   Údel_ipv4_link_localE   s    r*   c             C   sí  d d „  } g  } t  j ƒ  } t j d | ƒ x}|  D]u} |  | d } t j d | ƒ | j d ƒ } | | k rŠ t d | | f ƒ ‚ | j | ƒ } | j d d	 ƒ }	 t j |	 | ƒ }
 |
 | k rå t j d
 |	 | | |
 ƒ n d } t j | | | ƒ d d d | d |
 i } g  } xa d D]Y } | j | d ƒ } | sDq#| | ƒ } |	 d k shd | k ro| d =| j | ƒ q#W| | d <| j | ƒ t j d |
 | ƒ q5 W| rÝt j d | ƒ | j d d d | i ƒ d d d | i S) aÅ  Convert the DigitalOcean Network description into Cloud-init's netconfig
       format.

       Example JSON:
        {'public': [
              {'mac': '04:01:58:27:7f:01',
               'ipv4': {'gateway': '45.55.32.1',
                        'netmask': '255.255.224.0',
                        'ip_address': '45.55.50.93'},
               'anchor_ipv4': {
                        'gateway': '10.17.0.1',
                        'netmask': '255.255.0.0',
                        'ip_address': '10.17.0.9'},
               'type': 'public',
               'ipv6': {'gateway': '....',
                        'ip_address': '....',
                        'cidr': 64}}
           ],
          'private': [
              {'mac': '04:01:58:27:7f:02',
               'ipv4': {'gateway': '10.132.0.1',
                        'netmask': '255.255.0.0',
                        'ip_address': '10.132.75.35'},
               'type': 'private'}
           ]
        }
    c          	   S   s‡   d d d d d |  j  d ƒ d |  j  d ƒ i } d |  j  d ƒ k rp d	 j |  j  d ƒ |  j  d
 ƒ ƒ | d <n |  j  d ƒ | d <| S)NÚtypeZstaticZcontrolZautoÚaddressZ
ip_addressÚgatewayú:z{0}/{1}ZcidrZnetmask)Úgetr   )ZpcfgZsubpartr   r   r   Ú_get_subnet_partw   s    z7convert_network_configuration.<locals>._get_subnet_partznic mapping: %sr   zconsidering %sZmaczVDid not find network interface on system with mac '%s'. Cannot apply configuration: %sr+   Úunknownz6Found %s interface '%s' on '%s', assigned name of '%s'zfFound interface '%s' on '%s', which is not a public or private interface. Using default system naming.ZphysicalÚmac_addressÚnameÚipv4Úipv6Úanchor_ipv4Úanchor_ipv6Nr   Zanchorr-   Úsubnetsznic '%s' configuration: %szadded dns servers: %sZ
nameserverr,   Úversionr	   Úconfig)r4   r5   r6   r7   )r$   Zget_interfaces_by_macr   r   r/   r   ÚNIC_MAPÚappend)r:   Zdns_serversr0   Znic_configsZmacs_to_nicsÚnr   r2   Z
sysfs_nameZnic_typeZif_nameÚmsgZncfgr8   ZnetdefZ
raw_subnetZsub_partr   r   r   Úconvert_network_configurationZ   sL    	
r?   é   é   c             C   sS   t  j |  d | d | d | ƒ} | j ƒ  s= t d |  ƒ ‚ t j | j j ƒ  ƒ S)NÚtimeoutÚsec_betweenÚretrieszunable to read metadata at %s)r   ZreadurlÚokr   ÚjsonÚloadsÚcontentsÚdecode)ZurlrB   rC   rD   Zresponser   r   r   Úread_metadataº   s
    rJ   c              C   sp   t  j d ƒ }  |  d k r d St  j d ƒ } | rG t j d | ƒ n d } t j | ƒ t | ƒ ‚ d | f S)	Nzsystem-manufacturerZDigitalOceanFzsystem-serial-numberz8system identified via SMBIOS as DigitalOcean Droplet: %sz¦system identified via SMBIOS as a DigitalOcean Droplet, but did not provide an ID. Please file a support ticket at: https://cloud.digitalocean.com/support/tickets/newT)FN)r   Zread_dmi_datar   r   Zcriticalr   )Zvendor_nameZ
droplet_idr>   r   r   r   Úread_sysinfoÂ   s    	
rK   )rF   r   Z	cloudinitr   r   Zloggingr   r$   r   r   r   r;   Z	getLoggerÚ__name__r   r   r   r*   r?   rJ   rK   r   r   r   r   Ú<module>   s   &`