o
    w7er                     @   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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)log)net)subp
url_helperutileth0eth1)publicprivatec              	   C   s   |st | }td| |stddtddtdd}dd	d
|d|g}dddd|dg}tds9tdzt| td|| t| td| W |S  t	yc   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      ipaddradddevlinkset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randomrandintr   which	Exceptionr   logexc)distronicr   ip_addr_cmd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  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>B   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>I   s    z$get_link_local_nic.<locals>.<lambda>)key)r.   get_devicelistmin)r    nicsr$   r+   r%   r   A   s   
r   c              
   C   s~   | s	t d dS t d dddd| g}zt| t d|  W dS  ty> } 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 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_localL   s   

r8   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addressr<   :z{0}/{1}cidrr?   netmask)getr   )pcfgsubpartr$   r$   r%   _get_subnet_part   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: %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.physical)r=   mac_addressname)ipv4ipv6anchor_ipv4anchor_ipv6Nr
   anchorr<   subnetsznic '%s' configuration: %szadded dns servers: %s
nameserver)r=   r?   r   )versionconfig)r.   get_interfaces_by_macr   r   rC   r   NIC_MAPappend)rT   dns_serversrF   nic_configsmacs_to_nicsnr!   rJ   
sysfs_namenic_typeif_namemsgncfgrQ   netdef
raw_subnetsub_partr$   r$   r%   convert_network_configurationc   s`   

	

rd         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)urlrg   rh   ri   responser$   r$   r%   read_metadata   s   rr   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_idr_   r$   r$   r%   read_sysinfo   s   


rx   )N)re   re   rf   )rl   r   	cloudinitr   r   loggingr   r.   r   r   r   rV   	getLogger__name__r   r&   r   r8   rd   rr   rx   r$   r$   r$   r%   <module>   s   


/

n	