B
    ÷±ô`]  ã               @   sJ  d dl mZmZmZ eZd dlZ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 d dlm  m  m  m  mZ dZdZdZdZyœd dlmZ d dlm Z  d d	lm!Z! d d
l"m#Z# d dl$m%Z& d dl'm(Z(m)Z) d dl*m+Z+m,Z, d dl-m.Z. d dl/m0Z0 d dl1m2Z2 d dl$m3Z3 d dl4m5Z5 W n, e6k
r` Z7 ze7ZdZW ddZ7[7X Y nX y,d dl8mZ d dl*m9Z9m:Z: d dl;m<Z< W n e6k
r¬   dZe=ZY nX yd dl>m%Z? W n e6k
rØ   dZ?Y nX e@ddddddddd d!	ZAe@d"d#d$d%ZBd&ZCd' De?¡ZEG d(d)„ d)eFƒZGG d*d+„ d+ƒZHd,d-„ ZIeJd.krFeIƒ  dS )/é    )Úabsolute_importÚdivisionÚprint_functionN)ÚKeyVaultClient)Úconfigparser)Ú
expanduserT)ÚAADTokenCredentials)Ú
CloudError)ÚMSIAuthentication)Úazure_cloud)Ú__version__)ÚAzureMissingResourceHttpErrorÚAzureHttpError)ÚServicePrincipalCredentialsÚUserPassCredentials)ÚNetworkManagementClient)ÚResourceManagementClient)ÚSubscriptionClient)ÚComputeManagementClient)ÚAuthenticationContextF)ÚCLIError)Úget_azure_cli_credentialsÚget_cli_profile)Úget_cli_active_cloudÚunknownZAZURE_PROFILEZAZURE_SUBSCRIPTION_IDZAZURE_CLIENT_IDZAZURE_SECRETZAZURE_TENANTZAZURE_AD_USERZAZURE_PASSWORDZAZURE_CLOUD_ENVIRONMENTZAZURE_ADFS_AUTHORITY_URL)	ÚprofileÚsubscription_idÚ	client_idÚsecretÚtenantÚad_userÚpasswordÚcloud_environmentÚadfs_authority_urlZAZURE_VAULT_NAMEZAZURE_VAULT_SECRET_NAMEZAZURE_VAULT_SECRET_VERSION)Ú
vault_nameÚsecret_nameÚsecret_versionz2.0.0zAnsible/{0}c               @   s¨   e Zd Zdd„ Zdd„ Zdd„ Zd%dd	„Zd
d„ Zdd„ Zd&dd„Z	dd„ Z
dd„ Zdd„ Zdd„ Zdd„ Zdd„ Zedd„ ƒZedd „ ƒZed!d"„ ƒZed#d$„ ƒZdS )'ÚAzureRMc          
      s  || _ d | _d | _d | _d | _d | _d | _d | _d| _|jrBd| _|  	|¡| _
| j
s^|  d¡ | j
 d¡‰ ˆ sxtj| _nÌdd„ t t¡D ƒ}‡ fdd„|D ƒ}t|ƒdkr¶|d	 | _nŽt|ƒdkrÔ|  d
 ˆ ¡¡ npt ˆ ¡jsú|  d dd„ |D ƒ¡¡ yt ˆ ¡| _W n8 tk
rB } z|  d ˆ |j¡¡ W d d }~X Y nX | j
 dd ¡d krb|  d¡ |  d¡ | j
d | _| j
 d¡r–| j
 d¡| _n| jjj| _| jjj| _| j
 d¡rÎ| j
 d¡| _n4| j
 d¡r | j
 d¡r | j
 d¡r t| j
d | j
d | j
d | jd| _nâ| j
 d¡d k	rœ| j
 d¡d k	rœ| j
 d¡d k	rœ| j
 d¡d k	rœ|  | j| j| j
d | j
d | j
d | j
d ¡| _nf| j
 d¡d k	rø| j
 d¡d k	rø| j
 d¡}|sÖd}t | j
d | j
d || jd| _n
|  d¡ d S )NFTz}Failed to get credentials. Either pass as parameters, set environment variables, or define a profile in ~/.azure/credentials.r"   c             S   s$   g | ]}t |d  tjƒr|d  ‘qS )é   )Ú
isinstancer   ZCloud)Ú.0Úx© r,   ún/home/dcms/DCMS/lib/python3.7/site-packages/ansible_collections/community/general/scripts/vault/azure_vault.pyú
<listcomp>Ú   s    z$AzureRM.__init__.<locals>.<listcomp>c                s   g | ]}|j ˆ kr|‘qS r,   )Úname)r*   r+   )Úraw_cloud_envr,   r-   r.   Û   s    r(   r   zOAzure SDK failure: more than one cloud matched for cloud_environment name '{0}'zAcloud_environment must be an endpoint discovery URL or one of {0}c             S   s   g | ]
}|j ‘qS r,   )r/   )r*   r+   r,   r,   r-   r.   ä   s    z0cloud_environment {0} could not be resolved: {1}r   z4Credentials did not include a subscription_id value.zsetting subscription_idr#   Úcredentialsr   r   r   )r   r   r   r"   r    r!   Úcommon)r   r"   a   Failed to authenticate with provided credentials. Some attributes were missing. Credentials must include client_id, secret and tenant or ad_user and password, or ad_user, password, client_id, tenant and adfs_authority_url(optional) for ADFS authentication, or be logged in using AzureCLI.)!Ú_argsÚ_cloud_environmentÚ_compute_clientÚ_resource_clientÚ_network_clientZ_adfs_authority_urlÚ_vault_clientZ	_resourceÚdebugÚ_get_credentialsr1   ÚfailÚgetr   ZAZURE_PUBLIC_CLOUDÚinspectÚ
getmembersÚlenÚformatÚurlparseÚschemeZ get_cloud_from_metadata_endpointÚ	ExceptionÚmessageÚlogr   Ú	endpointsZactive_directoryZactive_directory_resource_idÚazure_credentialsr   Ú$acquire_token_with_username_passwordr   )ÚselfÚargsZ
all_cloudsZmatched_cloudsÚer   r,   )r0   r-   Ú__init__Á   s„    


&

*
$
zAzureRM.__init__c             C   s   | j rt|d ƒ d S )NÚ
)r9   Úprint)rI   Úmsgr,   r,   r-   rE     s    zAzureRM.logc             C   s   t |ƒ‚d S )N)rC   )rI   rO   r,   r,   r-   r;   "  s    zAzureRM.failÚdefaultc          
   C   sÆ   t dƒ}|d7 }yt ¡ }| |¡ W n8 tk
r^ } z|  d |t|ƒ¡¡ W d d }~X Y nX tƒ }x:t	D ]2}y|j
||dd||< W ql tk
rœ   Y qlX qlW | 
d¡d k	s¾| 
d¡d k	rÂ|S d S )Nú~z/.azure/credentialszNFailed to access {0}. Check that the file exists and you have read access. {1}T)Úrawr   r    )r   ÚcpÚConfigParserÚreadrC   r;   r@   ÚstrÚdictÚAZURE_CREDENTIAL_ENV_MAPPINGr<   )rI   r   ÚpathÚconfigÚexcr1   Úkeyr,   r,   r-   Ú_get_profile%  s"     

zAzureRM._get_profilec             C   sl   t ƒ }x&t ¡ D ]\}}tj |d ¡||< qW |d d k	rL|  |d ¡}|S |d d k	sd|d d k	rh|S d S )Nr   r   r    )rW   rX   ÚitemsÚosÚenvironr<   r]   )rI   Úenv_credentialsÚ	attributeÚenv_variabler1   r,   r,   r-   Ú_get_env_credentials:  s    zAzureRM._get_env_credentialsc             C   s    t ƒ \}}tƒ }|||dœ}|S )N)r1   r   r"   )r   r   )rI   r1   r   r"   Úcli_credentialsr,   r,   r-   Ú_get_azure_cli_credentialsH  s    
z"AzureRM._get_azure_cli_credentialsNc          
   C   s\   t ƒ }y.t|ƒ}t|j ¡ ƒ}t|jƒ}||p0|dœS  tk
rV } zd S d }~X Y nX d S )N)r1   r   )r
   r   ÚnextZsubscriptionsÚlistrV   r   rC   )rI   Zsubscription_id_paramr1   Zsubscription_clientZsubscriptionr   r[   r,   r,   r-   Ú_get_msi_credentialsS  s    
zAzureRM._get_msi_credentialsc          
   C   s:  |   d¡ tƒ }x"t ¡ D ]\}}t||ƒ||< qW |d d k	r\|   d¡ |  |d ¡}|S |d d k	rv|   d¡ |S |d d k	r|   d¡ |S |  ¡ }|rª|   d¡ |S |  ¡ }|rÄ|   d¡ |S |  | d	¡¡}|ræ|   d
¡ |S yt	rö|   d¡ |  
¡ }	|	S  tk
r4 }
 z|   d |
¡¡ W d d }
~
X Y nX d S )NzGetting credentialsr   z.Retrieving credentials with profile parameter.r   z%Received credentials from parameters.r    zReceived credentials from env.z@Retrieved default profile credentials from ~/.azure/credentials.r   zRetrieved credentials from MSI.z,Retrieving credentials from AzureCLI profilez0Error getting AzureCLI profile credentials - {0})rE   rW   rX   r^   Úgetattrr]   rd   ri   r<   ÚHAS_AZURE_CLI_CORErf   r   r@   )rI   ÚparamsZarg_credentialsrb   rc   r1   ra   Zdefault_credentialsZmsi_credentialsre   Zcer,   r,   r-   r:   a  sD    







"zAzureRM._get_credentialsc       
      C   s8   |}|d k	r|d | }t |ƒ}| ||||¡}	t|	ƒS )Nú/)r   rH   r   )
rI   Ú	authorityÚresourceÚusernamer!   r   r   Zauthority_uriÚcontextZtoken_responser,   r,   r-   rH   ”  s    z,AzureRM.acquire_token_with_username_passwordc          
   C   sn   y| j }|j |¡ W nR tk
rh } z4|  d |t|ƒ¡¡ |  d |¡¡ |  d¡ W d d }~X Y nX d S )Nz)One-time registration of {0} failed - {1}z5You might need to register {0} using an admin accountz¨To register a provider using the Python CLI: https://docs.microsoft.com/azure/azure-resource-manager/resource-manager-common-deployment-errors#noregisteredproviderfound)Ú	rm_clientZ	providersÚregisterrC   rE   r@   rV   )rI   r\   Zresource_clientr[   r,   r,   r-   Ú	_registerž  s    zAzureRM._registerc             C   s$   || j | j||d}|j t¡ |S )N)Úbase_urlÚapi_version)rG   r   rZ   Zadd_user_agentÚANSIBLE_USER_AGENT)rI   Zclient_typeru   rv   Úclientr,   r,   r-   Úget_mgmt_svc_client«  s    zAzureRM.get_mgmt_svc_clientc             C   s
   t | jƒS )N)r   rG   )rI   r,   r,   r-   Úget_vault_client³  s    zAzureRM.get_vault_clientc             C   s
   | j jjS )N)r4   ÚsuffixesZkeyvault_dns)rI   r,   r,   r-   Úget_vault_suffix¶  s    zAzureRM.get_vault_suffixc             C   s6   |   d¡ | js0|  t| jjjd¡| _|  d¡ | jS )NzGetting network clientz
2017-06-01zMicrosoft.Network)rE   r7   ry   r   r4   rF   Úresource_managerrt   )rI   r,   r,   r-   Únetwork_client¹  s    

zAzureRM.network_clientc             C   s,   |   d¡ | js&|  t| jjjd¡| _| jS )NzGetting resource manager clientz
2017-05-10)rE   r6   ry   r   r4   rF   r}   )rI   r,   r,   r-   rr   Ã  s    
zAzureRM.rm_clientc             C   s6   |   d¡ | js0|  t| jjjd¡| _|  d¡ | jS )NzGetting compute clientz
2017-03-30zMicrosoft.Compute)rE   r5   ry   r   r4   rF   r}   rt   )rI   r,   r,   r-   Úcompute_clientÌ  s    

zAzureRM.compute_clientc             C   s    |   d¡ | js|  ¡ | _| jS )NzGetting the Key Vault client)rE   r8   rz   )rI   r,   r,   r-   Úvault_clientÖ  s    

zAzureRM.vault_client)rP   )N)Ú__name__Ú
__module__Ú__qualname__rL   rE   r;   r]   rd   rf   ri   r:   rH   rt   ry   rz   r|   Úpropertyr~   rr   r   r€   r,   r,   r,   r-   r'   ¿   s"   ]

3

	
r'   c               @   s<   e Zd Zdd„ Zdd„ Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )ÚAzureKeyVaultSecretc          
   C   s°   |   ¡ | _yt| jƒ}W n6 tk
rN } zt d t|ƒ¡¡ W d d }~X Y nX |  ¡  | jj	rj| jj	| _	| jj
r|| jj
| _
| jjrŽ| jj| _| ¡ | _|j| _t|  ¡ ƒ d S )Nz{0})Ú_parse_cli_argsr3   r'   rC   ÚsysÚexitr@   rV   Ú_get_vault_settingsr$   r%   r&   r|   Ú_vault_suffixr€   r8   rN   Úget_password_from_vault)rI   ZrmrK   r,   r,   r-   rL   á  s    
&



zAzureKeyVaultSecret.__init__c             C   sì   t jdd}|jddddd |jdd	dd
d |jddddd |jddddd |jdddd |jdddd |jdddd |jdddd |jdddd |jdddd |jddd d |jd!dd"d |jd#dd$d | ¡ S )%Nz=Obtain the vault password used to secure your Ansilbe secrets)Údescriptionz-nz--vault-nameÚstorezName of Azure Key Vault)ÚactionÚhelpz-sz--secret-namez,Name of the secret stored in Azure Key Vaultz-vz--secret-versionz%Version of the secret to be retrievedz--debugÚ
store_trueFz!Send the debug messages to STDOUT)rŽ   rP   r   z	--profilez/Azure profile contained in ~/.azure/credentialsz--subscription_idzAzure Subscription Idz--client_idzAzure Client Id z--secretzAzure Client Secretz--tenantzAzure Tenant Idz	--ad_userzActive Directory Userz
--passwordr!   z--adfs_authority_urlzAzure ADFS authority urlz--cloud_environmentz6Azure Cloud Environment name or metadata discovery URL)ÚargparseÚArgumentParserÚadd_argumentÚ
parse_args)rI   Úparserr,   r,   r-   r†   ú  s8    


z#AzureKeyVaultSecret._parse_cli_argsc             C   s*   d  | j| j¡}| j || j| j¡}|jS )Nzhttps://{0}{1})r@   r$   rŠ   r8   Z
get_secretr%   r&   Úvalue)rI   Z	vault_urlr   r,   r,   r-   r‹     s    z+AzureKeyVaultSecret.get_password_from_vaultc             C   sz   |   ¡ }d t| ¡ ƒkr<x\tD ]}t| || |d ¡ƒ qW n:|  ¡ }|sLd S x(tD ] }| |¡rRt| || |¡ƒ qRW d S )N)Ú_get_vault_env_settingsÚsetÚvaluesÚAZURE_VAULT_SETTINGSÚsetattrr<   Ú_load_vault_settings)rI   Úenv_settingsr\   Zfile_settingsr,   r,   r-   r‰     s    


z'AzureKeyVaultSecret._get_vault_settingsc             C   s2   t ƒ }x&t ¡ D ]\}}tj |d ¡||< qW |S )N)rW   rš   r^   r_   r`   r<   )rI   r   rb   rc   r,   r,   r-   r—   -  s    z+AzureKeyVaultSecret._get_vault_env_settingsc          	   C   sÒ   t j t j t¡¡d }t j t j t¡|d ¡}t j t j t j	 
d|¡¡¡}d }d }yt ¡ }| |¡ W n tk
r‚   Y nX |d k	rÎtƒ }x:tD ]2}y|j
d|dd||< W q˜ tk
rÈ   Y q˜X q˜W |S )Nr   z.iniZAZURE_VAULT_INI_PATHZazure_keyvaultT)rR   )r_   rY   ÚsplitextÚbasenameÚ__file__ÚjoinÚdirnamer   Ú
expandvarsr`   r<   rS   rT   rU   rC   rW   rš   )rI   rŸ   Zdefault_pathrY   rZ   Úsettingsr\   r,   r,   r-   rœ   3  s$    

z(AzureKeyVaultSecret._load_vault_settingsN)	r   r‚   rƒ   rL   r†   r‹   r‰   r—   rœ   r,   r,   r,   r-   r…   ß  s    r…   c               C   s    t st d tt¡¡ tƒ  d S )NzVThe Azure python sdk is not installed (try `pip install 'azure>={0}' --upgrade`) - {1})Ú	HAS_AZUREr‡   rˆ   r@   ÚAZURE_MIN_VERSIONÚHAS_AZURE_EXCr…   r,   r,   r,   r-   ÚmainJ  s    
r¨   Ú__main__)KÚ
__future__r   r   r   ÚtypeÚ__metaclass__r‘   r_   Úrer‡   r=   Zazure.keyvaultr   Zansible.module_utils.six.movesr   rS   Úos.pathr   Z+ansible.module_utils.six.moves.urllib.parseZmodule_utilsÚsixÚmovesÚurllibÚparserA   r¥   r§   rk   r   Z"msrestazure.azure_active_directoryr   Zmsrestazure.azure_exceptionsr	   r
   Zmsrestazurer   Zazure.mgmt.computer   Zazure_compute_versionZazure.commonr   r   Zazure.common.credentialsr   r   Zazure.mgmt.networkr   Zazure.mgmt.resource.resourcesr   Z!azure.mgmt.resource.subscriptionsr   r   Zadal.authentication_contextr   ÚImportErrorr[   Zazure.cli.core.utilr   r   Zazure.common.cloudr   rC   Zansible.releaseZansible_versionrW   rX   rš   r¦   r@   rw   Úobjectr'   r…   r¨   r   r,   r,   r,   r-   Ú<module>   s€   k$


  "k
