U
    ]                     @   s   d Z ddlZddlmZmZ ddlmZmZmZ ddl	m
Z
 ddlmZ zddlmZ W n ek
rp   dZY nX eeZG dd	 d	eZd
d ZdS )z;Common code for DNS Authenticator Plugins built on Lexicon.    N)	HTTPErrorRequestException)UnionDictAny)errors)
dns_common)ConfigResolverc                   @   s@   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dS )LexiconClientzI
    Encapsulates all communication with a DNS provider via Lexicon.
    c                 C   s
   d | _ d S )N)provider)self r   D/usr/lib/python3/dist-packages/certbot/plugins/dns_common_lexicon.py__init__   s    zLexiconClient.__init__c              
   C   sh   |  | z| jjd||d W nB tk
rb } z$tjd|dd td|W 5 d}~X Y nX dS )a  
        Add a TXT record using the supplied information.

        :param str domain: The domain to use to look up the managed zone.
        :param str record_name: The record name (typically beginning with '_acme-challenge.').
        :param str record_content: The record content (typically the challenge validation).
        :raises errors.PluginError: if an error occurs communicating with the DNS Provider API
        TXTtypenameZcontentz'Encountered error adding TXT record: %sTexc_infozError adding TXT record: {0}N)	_find_domain_idr   Zcreate_recordr   loggerdebugr   PluginErrorformatr   domainZrecord_nameZrecord_contenter   r   r   add_txt_record   s    	
zLexiconClient.add_txt_recordc              
   C   s   z|  | W n: tjk
rH } ztjd|dd W Y dS d}~X Y nX z| jjd||d W n2 tk
r } ztjd|dd W 5 d}~X Y nX dS )a  
        Delete a TXT record using the supplied information.

        :param str domain: The domain to use to look up the managed zone.
        :param str record_name: The record name (typically beginning with '_acme-challenge.').
        :param str record_content: The record content (typically the challenge validation).
        :raises errors.PluginError: if an error occurs communicating with the DNS Provider  API
        z7Encountered error finding domain_id during deletion: %sTr   Nr   r   z)Encountered error deleting TXT record: %s)r   r   r   r   r   r   Zdelete_recordr   r   r   r   r   del_txt_record0   s    	zLexiconClient.del_txt_recordc                 C   s   t |}|D ]}z4t| jdr.|| jjd< n|| j_| j  W  dS  tk
r| } z| ||}|rl|W 5 d}~X Y q t	k
r } z| 
||}|r|W 5 d}~X Y qX qtd||dS )z
        Find the domain_id for a given domain.

        :param str domain: The domain for which to find the domain_id.
        :raises errors.PluginError: if the domain_id cannot be found.
        optionsr   NzAUnable to determine zone identifier for {0} using zone names: {1})r   Zbase_domain_name_guesseshasattrr   r    r   Zauthenticater   _handle_http_error	Exception_handle_general_errorr   r   r   )r   r   Zdomain_name_guessesdomain_namer   resultr   r   r   r   E   s(    

 zLexiconClient._find_domain_idc                 C   s   t d||S )Nz/Error determining zone identifier for {0}: {1}.)r   r   r   r   r   r%   r   r   r   r"   i   s     z LexiconClient._handle_http_errorc                 C   s$   t |ds td||S d S )NzNo domain foundz9Unexpected error determining zone identifier for {0}: {1})str
startswithr   r   r   r'   r   r   r   r$   m   s     z#LexiconClient._handle_general_errorN)
__name__
__module____qualname____doc__r   r   r   r   r"   r$   r   r   r   r   r
      s   $r
   c                 C   sL   d| i}| | ts"| | n&i }| | ||| < t | }|S )ao  
    Convenient function to build a Lexicon 2.x/3.x config object.
    :param str lexicon_provider_name: the name of the lexicon provider to use
    :param dict lexicon_options: options specific to lexicon
    :param dict provider_options: options specific to provider
    :return: configuration to apply to the provider
    :rtype: ConfigurationResolver or dict
    Zprovider_name)updater	   Z	with_dictZwith_env)Zlexicon_provider_nameZlexicon_optionsZprovider_optionsZconfigZprovider_configr   r   r   build_lexicon_configt   s    


r/   )r-   ZloggingZrequests.exceptionsr   r   Zacme.magic_typingr   r   r   Zcertbotr   Zcertbot.pluginsr   Zlexicon.configr	   ImportErrorZ	getLoggerr*   r   objectr
   r/   r   r   r   r   <module>   s   

]