o
    x[hÿ  ã                   @   sŽ   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dœZ	e 
e¡Zddd	„Zd
d„ Zddd„Zdd„ Zddd„Zdd„ ZdS )é    N)Údmi)Únet)Ú
url_helperÚutilÚeth0Úeth1)ÚpublicÚprivatec              	   C   s�   |st | ƒ}t d|¡ |stdƒ‚d t dd¡t dd¡¡}z| j ||¡ | j 	|¡ t d||¡ W |S  t
yG   t td	||¡ ‚ w )
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   éÿ   z&brought device '%s' up with address %szRip4LL address assignment of '%s' to '%s' failed. Droplet networking will be broken)Úget_link_local_nicÚLOGÚdebugÚRuntimeErrorÚformatÚrandomÚrandintÚnet_opsÚadd_addrÚlink_upÚ	Exceptionr   Úlogexc)ÚdistroÚnicÚaddr© r   úH/usr/lib/python3/dist-packages/cloudinit/sources/helpers/digitalocean.pyÚassign_ipv4_link_local   s0   ÿÿöûør   c                    s.   ‡ fdd„t  ¡ D ƒ}|sd S t|dd„ d�S )Nc                    s   g | ]
}ˆ j  |¡r|‘qS r   )Ú
networkingÚis_physical)Ú.0Úf©r   r   r   Ú
<listcomp>9   s    
ýÿz&get_link_local_nic.<locals>.<listcomp>c                 S   s   t  | d¡S )NÚifindex)ÚcloudnetÚread_sys_net_int)Údr   r   r   Ú<lambda>@   s    z$get_link_local_nic.<locals>.<lambda>)Úkey)r&   Úget_devicelistÚmin)r   Únicsr   r#   r   r   8   s   
þr   c              
   C   sr   |s	t  d¡ dS t  d¡ z| j |¡ t  d|¡ W dS  ty8 } zt t d||¡ W Y d}~dS d}~ww )zwRemove 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 addresszremoved ip4LL addresses from %sz)failed to remove ip4LL address from '%s'.)r   r   r   Ú
flush_addrr   r   r   )r   r   Úer   r   r   Údel_ipv4_link_localC   s   ÿ
€ÿr0   c                 C   sR  dd„ }g }t  ¡ }t d|¡ | D ]�}| | d }t d|¡ | d¡}||vr1td||f ƒ‚| |¡}| dd	¡}	t |	|¡}
|
|krPt d
|	|||
¡ n	d}t |||¡ d||
dœ}g }dD ]}| |d¡}|snqc||ƒ}|	dkszd|v r}|d= | |¡ qc||d< | |¡ t d|
|¡ q|r¤t d|¡ | d|dœ¡ d|dœ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   sZ   dd|   d¡|   d¡dœ}d|   d¡v r$d |   d¡|   d¡¡|d	< |S |   d
¡|d
< |S )NÚstaticÚautoÚ
ip_addressÚgateway)ÚtypeÚcontrolÚaddressr4   ú:z{0}/{1}Úcidrr7   Únetmask)Úgetr   )ÚpcfgÚsubpartr   r   r   Ú_get_subnet_partu   s   üÿþz7convert_network_configuration.<locals>._get_subnet_partznic mapping: %sr   zconsidering %sÚmaczVDid not find network interface on system with mac '%s'. Cannot apply configuration: %sr5   Ú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.Úphysical)r5   Úmac_addressÚname)Úipv4Úipv6Úanchor_ipv4Úanchor_ipv6Nr   Úanchorr4   Úsubnetsznic '%s' configuration: %szadded dns servers: %sÚ
nameserver)r5   r7   r
   )ÚversionÚconfig)r&   Úget_interfaces_by_macr   r   r;   r   ÚNIC_MAPÚappend)rL   Údns_serversr>   Únic_configsÚmacs_to_nicsÚnr   rB   Ú
sysfs_nameÚnic_typeÚif_nameÚmsgÚncfgrI   ÚnetdefÚ
raw_subnetÚsub_partr   r   r   Úconvert_network_configurationX   s`   
þÿ
û	ÿý

r\   é   é   c                 C   s6   t j| |||d�}| ¡ std|  ƒ‚t |j ¡ ¡S )N)ÚtimeoutÚsec_betweenÚretrieszunable to read metadata at %s)r   ÚreadurlÚokr   ÚjsonÚloadsÚcontentsÚdecode)Úurlr_   r`   ra   Úresponser   r   r   Úread_metadataÆ   s   ÿrj   c                  C   sN   t  d¡} | dkrdS t  d¡}|rt d|¡ d|fS d}t |¡ t|ƒ‚)Nzsystem-manufacturerÚDigitalOcean)FNz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)r   Úread_dmi_datar   r   Úcriticalr   )Úvendor_nameÚ
droplet_idrW   r   r   r   Úread_sysinfoÏ   s   

þøÿ
rp   )N)r]   r]   r^   )rd   Úloggingr   Ú	cloudinitr   r   r&   r   r   rN   Ú	getLoggerÚ__name__r   r   r   r0   r\   rj   rp   r   r   r   r   Ú<module>   s   


&

n	