o
    f                     @   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 )
zBring 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|rt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: %szsystem 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	