o
    Ü!dH%  ã                   @   sÔ   d dl Z 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
 G dd„ deƒZG dd„ deƒZG d	d
„ d
eƒZdd„ ZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZG dd„ deƒZdS )é    N©ÚOrderedDict)ÚEKSError)Úordered_yaml_loadÚordered_yaml_dumpc                   @   ó   e Zd ZdZdS )ÚKubeconfigErrorz& Base class for all kubeconfig errors.N©Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r   r   úHusr/lib/python3.10/site-packages/awscli/customizations/eks/kubeconfig.pyr      ó    r   c                   @   r   )ÚKubeconfigCorruptedErrorz+ Raised when a kubeconfig cannot be parsed.Nr	   r   r   r   r   r      r   r   c                   @   r   )ÚKubeconfigInaccessableErrorz< Raised when a kubeconfig cannot be opened for read/writing.Nr	   r   r   r   r   r   !   r   r   c                	   C   s(   t ddg fdg fdddt ƒ fdg fgƒS )N)Z
apiVersionZv1ÚclustersÚcontexts)úcurrent-contextÚ )ÚkindZConfigZpreferencesÚusersr   r   r   r   r   Ú_get_new_kubeconfig_content%   s   ùr   c                   @   s&   e Zd Zddd„Zdd„ Zdd„ ZdS )	Ú
KubeconfigNc                 C   s   || _ |d u r
tƒ }|| _d S ©N)Úpathr   Úcontent)Úselfr   r   r   r   r   Ú__init__2   s   
zKubeconfig.__init__c                 C   s
   t | jƒS )z+ Return the stored content in yaml format. )r   r   ©r   r   r   r   Údump_content8   s   
zKubeconfig.dump_contentc                 C   s&   d| j vrdS |dd„ | j d D ƒv S )zg
        Return true if this kubeconfig contains an entry
        For the passed cluster name.
        r   Fc                 S   s   g | ]}|d  ‘qS )Únamer   )Ú.0Úclusterr   r   r   Ú
<listcomp>C   s    ÿz*Kubeconfig.has_cluster.<locals>.<listcomp>)r   )r   r"   r   r   r   Úhas_cluster<   s
   
ÿzKubeconfig.has_clusterr   )r
   r   r   r   r!   r&   r   r   r   r   r   1   s    
r   c                   @   s,   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	S )
ÚKubeconfigValidatorc                 C   s   t d d ƒj| _d S r   )r   r   Ú_validation_contentr    r   r   r   r   H   s   zKubeconfigValidator.__init__c                 C   s*   t |tƒs	tdƒ‚|  |¡ |  |¡ dS )z¢
        Raises KubeconfigCorruptedError if the passed content is invalid

        :param config: The config to validate
        :type config: Kubeconfig
        z(Internal error: Not a Kubeconfig object.N)Ú
isinstancer   r   Ú_validate_config_typesÚ_validate_list_entry_types)r   Úconfigr   r   r   Úvalidate_configM   s   

z#KubeconfigValidator.validate_configc                 C   sx   t |jtƒs
tdƒ‚| j ¡ D ]*\}}||jv r9|j| dur9t |j| t|ƒƒs9td |t|j| ƒt|ƒ¡ƒ‚qdS )z¼
        Raises KubeconfigCorruptedError if any of the entries in config
        are the wrong type

        :param config: The config to validate
        :type config: Kubeconfig
        zContent not a dictionary.Nz%{0} is wrong type:{1} (Should be {2}))r)   r   Údictr   r(   ÚitemsÚtypeÚformat)r   r,   ÚkeyÚvaluer   r   r   r*   Z   s"   
ÿýþ€üz*KubeconfigValidator._validate_config_typesc                 C   s\   | j  ¡ D ]&\}}||jv r+t|j| ƒtkr+|j| D ]}t|tƒs*td |¡ƒ‚qqdS )zË
        Raises KubeconfigCorruptedError if any lists in config contain objects
        which are not dictionaries

        :param config: The config to validate
        :type config: Kubeconfig
        zEntry in {0} not a dictionary.N)	r(   r/   r   r0   Úlistr)   r   r   r1   )r   r,   r2   r3   Úelementr   r   r   r+   q   s   

ÿÿ€üz.KubeconfigValidator._validate_list_entry_typesN)r
   r   r   r   r-   r*   r+   r   r   r   r   r'   G   s
    r'   c                   @   s   e Zd Zddd„Zdd„ ZdS )ÚKubeconfigLoaderNc                 C   s   |d u rt ƒ }|| _d S r   )r'   Ú
_validator)r   Ú	validatorr   r   r   r   ƒ   s   
zKubeconfigLoader.__init__c              
   C   s¼   zt |dƒ}t|ƒ}W d  ƒ n1 sw   Y  W n5 ty= } z|jtjkr,d}ntd |¡ƒ‚W Y d}~nd}~w tjyP } zt	d |¡ƒ‚d}~ww t
||ƒ}| j |¡ |S )aP  
        Loads the kubeconfig found at the given path.
        If no file is found at the given path,
        Generate a new kubeconfig to write back.
        If the kubeconfig is valid, loads the content from it.
        If the kubeconfig is invalid, throw the relevant exception.

        :param path: The path to load a kubeconfig from
        :type path: string

        :raises KubeconfigInaccessableError: if the kubeconfig can't be opened
        :raises KubeconfigCorruptedError: if the kubeconfig is invalid

        :return: The loaded kubeconfig
        :rtype: Kubeconfig
        ÚrNz&Can't open kubeconfig for reading: {0}z'YamlError while loading kubeconfig: {0})Úopenr   ÚIOErrorÚerrnoÚENOENTr   r1   ÚyamlZ	YAMLErrorr   r   r7   r-   )r   r   ÚstreamZloaded_contentÚeZloaded_configr   r   r   Úload_kubeconfigˆ   s,   
ÿ€ÿþ€ÿ€ÿ
z KubeconfigLoader.load_kubeconfigr   )r
   r   r   r   rA   r   r   r   r   r6   ‚   s    
r6   c                   @   s   e Zd Zdd„ ZdS )ÚKubeconfigWriterc              
   C   sä   t j |j¡}zt  |¡ W n ty- } z|jtjkr#td |¡ƒ‚W Y d}~nd}~ww z.t  	t  
|jt jt jB t jB d¡d¡}t|j|ƒ W d  ƒ W dS 1 sUw   Y  W dS  ttfyq } ztd |¡ƒ‚d}~ww )a  
        Write config to disk.
        OK if the file doesn't exist.

        :param config: The kubeconfig to write
        :type config: Kubeconfig

        :raises KubeconfigInaccessableError: if the kubeconfig
        can't be opened for writing
        z'Can't create directory for writing: {0}Ni€  zw+z&Can't open kubeconfig for writing: {0})Úosr   ÚdirnameÚmakedirsÚOSErrorr<   ÚEEXISTr   r1   Úfdopenr:   ÚO_CREATÚO_RDWRÚO_TRUNCr   r   r;   )r   r,   Ú	directoryr@   r?   r   r   r   Úwrite_kubeconfig­   s:   ÿÿ€ÿýû&úÿ€ÿz!KubeconfigWriter.write_kubeconfigN)r
   r   r   rM   r   r   r   r   rB   ¬   s    rB   c                   @   s(   e Zd Zdd„ Zddd„Zddd„ZdS )	ÚKubeconfigAppenderc                 C   sœ   ||j vr
g |j |< |j | }t|tƒstd |t|ƒt¡ƒ‚d}t|ƒD ]\}}d|v r?d|v r?|d |d kr?|||< d}q%|sG| |¡ ||j |< |S )zÝ
        Insert entry into the array at content[key]
        Overwrite an existing entry if they share the same name

        :param config: The kubeconfig to insert an entry into
        :type config: Kubeconfig
        z1Tried to insert into {0},which is a {1} not a {2}Fr"   T)r   r)   r4   r   r1   r0   Ú	enumerateÚappend)r   r,   r2   ÚentryÚarrayÚfoundÚcounterZexisting_entryr   r   r   Úinsert_entryÎ   s,   



þþ€

zKubeconfigAppender.insert_entryNc                 C   s4   t dt d|d fd|d fgƒfd|p|d fgƒS )zE Generate a context to associate cluster and user with a given alias.Úcontextr$   r"   Úuserr   )r   r$   rW   Úaliasr   r   r   Ú_make_contextí   s   

þûz KubeconfigAppender._make_contextc                 C   sL   | j |||d}|  |d|¡ |  |d|¡ |  |d|¡ |d |jd< |S )ag  
        Insert the passed cluster entry and user entry,
        then make a context to associate them
        and set current-context to be the new context.
        Returns the new context

        :param config: the Kubeconfig to insert the pair into
        :type config: Kubeconfig

        :param cluster: the cluster entry
        :type cluster: OrderedDict

        :param user: the user entry
        :type user: OrderedDict

        :param alias: the alias for the context; defaults top user entry name
        :type context: str

        :return: The generated context
        :rtype: OrderedDict
        )rX   r   r   r   r"   r   )rY   rU   r   )r   r,   r$   rW   rX   rV   r   r   r   Úinsert_cluster_user_pair÷   s   z+KubeconfigAppender.insert_cluster_user_pairr   )r
   r   r   rU   rY   rZ   r   r   r   r   rN   Í   s    

rN   )rC   r>   Úloggingr<   Zbotocore.compatr   Z$awscli.customizations.eks.exceptionsr   Z&awscli.customizations.eks.ordered_yamlr   r   r   r   r   r   Úobjectr   r'   r6   rB   rN   r   r   r   r   Ú<module>   s    ;*!