o
    :F¶dÅ  ã                   @   sz  d dl mZ d dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZ d dlmZ d dlmZ d dlmZ d dlZd dlZd dlZd dlZd dl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"m#Z#m$Z$ d dl%Z%d dl&m'Z' d dl(m)Z) dZ*dj+e
edZ,dZ-dZ.dZ/dZ0dZ1dZ2dZ3dZ4dZ5ej6 7ej6 8d¡d¡Z9dZ:dZ;ej6 7e9d¡Z<ej6 7e9d¡Z=ej6 8ej6 7dd¡¡Z>ej6 8ej6 7dd ¡¡Z?ej6 8ej6 7dd!d"¡¡Z@ej%d#kråd$nd%ZAejBd&d'd(ejCd)d*„ ƒƒZDeDjEd+d,d(ejFd-e:d.d/ejFd0e9d1e G¡ d2ejFd3d4d(ejFd5d6ejHd7d8d9ejFd:d;d<d=d>ejId?d@„ ƒƒƒƒƒƒƒZJeDjEddAd(ejIdBdC„ ƒƒZKeDjEdDdEd(ejIejLejMdFdG„ ƒƒƒƒZNeDjEdHdId(ejFdJd=e	ejHdKd=dLdMdNejIdOdP„ ƒƒƒZOeDjEdQdRd(ejIdSdT„ ƒƒZPdUdV„ ZQdWdX„ ZRG dYdZ„ dZeSƒZTd d[d\„ZUd]d^„ ZVd_d`„ ZWd¡dbdc„ZXddde„ ZYdfdg„ ZZdhdi„ Z[eDjEdjdkd(ejFdJd=dldmejIdndo„ ƒƒƒZ\dpdq„ Z]dddddde;dfdrds„Z^d¢dtdu„Z_d¢dvdw„Z`dxdy„ Zadzd{„ Zbd|d}„ Zcd~d„ Zdd€d„ Zed‚dƒ„ Zfd„d…„ Zgd†d‡„ Zhdˆd‰„ ZidŠd‹„ Zjd£dŒd„ZkdŽd„ Zldd‘„ Zmd’d“„ Znd”d•„ Zod–d—„ Zpd˜d™„ Zqdšd›„ ZreDjEdœdd(ejIejLejMdždŸ„ ƒƒƒƒZsdS )¤é    )Úprint_functionN)Úcli)Ú"CLI_RC_CANNED_QUERIES_SECTION_NAMEÚ#CLI_RC_COMMAND_ALIASES_SECTION_NAMEÚ!CLI_RC_PARAM_ALIASES_SECTION_NAMEÚCLI_RC_DEFAULT_LOCATIONÚOCI_CLI_AUTH_API_KEYÚOCI_CLI_AUTH_SESSION_TOKENÚOCI_CLI_AUTH_INSTANCE_PRINCIPALÚOCI_CLI_AUTH_RESOURCE_PRINCIPAL)Úcli_util)Úidentity_cli)Úpymd5)Ú	is_region)ÚREGIONS)ÚconfigÚ
exceptionsÚsigner)Úserialization)Údefault_backenda  
    This command provides a walkthrough of creating a valid CLI config file.

    The following links explain where to find the information required by this script:

    User API Signing Key, OCID and Tenancy OCID:


    
    https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#Other


    Region:


    
    https://docs.cloud.oracle.com/Content/General/Concepts/regions.htm

    General config documentation:


    
    https://docs.cloud.oracle.com/Content/API/Concepts/sdkconfig.htm

    


aR  
    This command provides a walkthrough of setting up instance principal authentication for an OCI compute instance.

    The following links provide information about topics and resources referenced by this script:

    Resource OCIDs:


    
    https://docs.oracle.com/en-us/iaas/Content/General/Concepts/identifiers.htm


    Compute Instances:


    
    https://docs.oracle.com/en-us/iaas/Content/Compute/Concepts/computeoverview.htm


    Dynamic Groups:


    
    https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm


    Policies:


    
    https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/policies.htm


    In order to successfully run this command, you must:


        - have an existing instance from which you want to run commands using instance principal authentication

        - be an administrator in your tenancy so that you can create/update the necessary dynamic group and policy used to enable instance principal authentication for your instance


    This script also requires an existing form of valid authentication to successfully run. If you do not have an existing config file and you ran this command using {api_key_auth} or {security_token_auth} auth, you will be prompted to create a new config file to use for authentication during this instance principal setup process.

    


)Zapi_key_authZsecurity_token_authaë  
    

    If you haven't already, you can install the CLI on your instance by connecting to your instance using SSH and running the following command:


    
    bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"


    After you have installed the CLI on your instance, you can test out your instance principal authentication by connecting to your instance using SSH and running the following example command (Note: if you entered a custom policy that does not allow your dynamic group to view all compute instances in your instance's compartment, then the following example command will not work):


    
    oci compute instance list --compartment-id {compartment_id} --auth {auth}

    

a  
    

    If you haven't already uploaded your API Signing public key through the console, follow the instructions on the page linked below in the section 'How to upload the public key':

    
    https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#How2

    

a  
[OCI_CLI_CANNED_QUERIES]
# For list results, this gets the ID and display-name of each item in the list. Note that when the names of attirbutes have
# dashes in them they need to be surrounded with double quotes. This query knows to look for a list because of the
# [*] syntax
get_id_and_display_name_from_list=data[*].{id: id, "display-name": "display-name"}

get_id_and_display_name_from_single_result=data.{id: id, "display-name": "display-name"}

# Retrieves a comma separated string, for example:
#     ocid1.instance.oc1.phx.xyz....,cli_test_instance_675195,RUNNING
get_id_display_name_and_lifecycle_state_from_single_result_as_csv=data.[id, "display-name", "lifecycle-state"] | join(`,`, @)

# Retrieves comma separated strings from a list of results
get_id_display_name_and_lifecycle_state_from_list_as_csv=data[*].[join(`,`, [id, "display-name", "lifecycle-state"])][]

# Filters where the display name contains some text
filter_by_display_name_contains_text=data[?contains("display-name", `your_text_here`)]

# Filters where the display name contains some text and pull out certain attributes(id and time-created)
filter_by_display_name_contains_text_and_get_attributes=data[?contains("display-name", `your_text_here`)].{id: id, timeCreated: "time-created"}

# Get the top 5 results from a list operation
get_top_5_results=data[:5]

# Get the last 2 results from a list operation
get_last_2_results=data[-2:]

# List instance public IPs from list vnics response
# Example: oci compute instance list-vnics --instance-id $I --query query://list_public_ips
list_public_ips=data[?"public-ip" != null]."public-ip"

# Get first public IP from list vnics response
# Example: oci compute instance list-vnics --instance-id $I --query query://get_public_ip
get_public_ip=data[?"public-ip" != null]."public-ip" | [0]
az  
[OCI_CLI_COMMAND_ALIASES]
# This lets you use "ls" instead of "list" for any list command in the CLI
ls = list

# This lets you do "oci os object rm" rather than "oci os object delete". This is an example of a "command sequence alias", where the alias on the left
# hand side only applies when the command sequence on the right hand side is invoked. You can think of these as being of the form:
#    <alias> = <dot-separated sequence of groups and sub-groups>.<command or group to alias>
#
# So in our example, <alias> = rm, <sequence of groups and sub-groups> = os object, <command or group to alias> = delete
rm = os.object.delete
a-  
[OCI_CLI_PARAM_ALIASES]
# Parameter aliases either need to start with a double dash (--) or be a single dash (-) followed by a single letter. For example: --foo, -f
--ad = --availability-domain
--dn = --display-name
--egress-rules = --egress-security-rules
--ingress-rules = --ingress-security-rules
zN/Az_public.pemz.pemzConfig creation canceled.ú~z.ociZoci_api_keyÚDEFAULTZsessionsr   z.bashrcz.bash_profileÚlibz
oracle-cliÚwin32zoci.exeÚociÚsetupzSetup commands for CLI)Úhelpc                   C   s   d S ©N© r   r   r   ú5usr/lib/python3.10/site-packages/oci_cli/cli_setup.pyÚsetup_groupÕ   s   r    ÚkeyszçGenerates an API Signing RSA key pair. A passphrase for the private key can be provided using either the 'passphrase' or 'passphrase-file' option. If neither option is provided, the user will be prompted for a passphrase via stdin.z
--key-namezdA name for the API Signing key. Generated key files will be {key-name}.pem and {key-name}_public.pem)Údefaultr   z--output-dirz?An optional directory to output the generated API Signing keys.)r"   r   Útypez--passphrasez>An optional passphrase to encrypt the private API Signing key.z--passphrase-filez€An optional file with the first line specifying a passphrase to encrypt the API Signing private key (or '-' to read from stdin).Úr©Úmode)r   r#   z--overwriteFzDAn option to overwrite existing files without a confirmation prompt.T)r"   r   Zis_flagc                 C   sÖ   |r	|r	t  d¡‚|r| ¡ }|r| ¡ rt  d¡‚|stƒ }tj |¡}tj |¡s0t	 
|¡ t	 ¡ }| ¡ }ttj || t ¡||ƒ ttj || t ¡|||ƒ t|ƒ}t  d |¡¡ t  t jtdd¡ d S )Nz:Cannot specify both passphrase and passphrase-file optionszEpassphrase-file must specify a password in the first line of the filezPublic key fingerprint: {}T©Úpreserve_paragraphs)ÚclickÚ
UsageErrorÚreadlineÚisspaceÚprompt_for_passphraseÚosÚpathÚ
expanduserÚexistsr   Úcreate_directoryÚgenerate_keyÚ
public_keyÚwrite_public_key_to_fileÚjoinÚPUBLIC_KEY_FILENAME_SUFFIXÚwrite_private_key_to_fileÚPRIVATE_KEY_FILENAME_SUFFIXÚpublic_key_to_fingerprintÚechoÚformatÚ	wrap_textÚupload_public_key_instructions)Úkey_nameÚ
output_dirÚ
passphraseZpassphrase_fileÚ	overwriteÚprivate_keyr4   Úfingerprintr   r   r   Úgenerate_key_pairÛ   s$   


rE   z/Interactive script to generate oci config file.c               
      sæ  t  t jtdd¡ tƒ \} }| st  t¡ t d¡ t jddd„ d}t jdd	d„ d}t	ƒ }t j
d
ddr˜tj tj t jdtd¡¡}tj |¡sQt |¡ t ¡ }| ¡ }t  dt¡}ttj ||t ¡|ƒsrt  t¡ d S tƒ }	tj ||t ¡‰ tˆ ||	ƒs‹t  t¡ d S t|ƒ}
t  d |
¡¡ n0t jdtd\‰ }}tj ˆ ¡‰ d }	|rºt jdd‡ fdd„d\}	}t| ¡ ƒ}
t  d |
¡¡ |	rÓt j
dddsÓd }	t| ||
ˆ |||	|d t  d | ¡¡ t  t jt dd¡ d S )NT©Útextr(   r   zEnter a user OCIDc                 S   ó   t | tjd ƒS )NÚuser©Úvalidate_ocidr   ZPATTERNS©Úocidr   r   r   Ú<lambda>  ó    z%generate_oci_config.<locals>.<lambda>©Ú
value_proczEnter a tenancy OCIDc                 S   rH   )NÚtenancyrJ   rL   r   r   r   rN   	  rO   zDo you want to generate a new API Signing RSA key pair? (If you decline you will be asked to supply the path to an existing key.)©r"   z-Enter a directory for your keys to be created)rG   r"   zEnter a name for your keyzFingerprint: {}z7Enter the location of your API Signing private key file©rG   rQ   z)Enter the passphrase for your private keyc                    s
   t ˆ | ƒS r   )Úvalidate_private_key_passphrase©rA   ©Zprivate_key_filer   r   rN   (  ó   
 )rG   Ú
hide_inputrQ   z‹Do you want to write your passphrase to the config file? (If not, you will need to enter it when prompted each time you run an oci command)F)Úpass_phraseÚprofile_namezConfig written to {}r'   )!r)   r;   r=   Ú generate_oci_config_instructionsÚprompt_for_config_locationÚ"config_generation_canceled_messageÚsysÚexitÚpromptÚprompt_for_regionÚconfirmr.   r/   Úabspathr0   ÚDEFAULT_DIRECTORYr1   r   r2   r3   r4   ÚDEFAULT_KEY_NAMEr5   r6   r7   r-   r9   r8   r:   r<   Úvalidate_private_key_fileÚwrite_configr>   )Úconfig_locationr[   Úuser_idZ	tenant_idÚregionZkey_locationrC   r4   r?   Zkey_passphraserD   Zhas_passphraser   rW   r   Úgenerate_oci_configþ   s\   





ørl   zinstance-principalz`Interactive script to set up instance principal authentication for an existing compute instance.c                    sP  t  t jtdd¡ d ‰ | jd tks| jd tkrt| ƒ‰ ˆ r)‡ fdd„}|t_	t 
dd| ¡}t 
dd| ¡}d }| jd tkrM| jd tkrMt | j¡}t jd	dd
s^t  d¡ t d¡ td|jƒ\}}|jj}| |¡}|jj}t jddd
r	td|jƒ\}	}|jj}
t  d¡ |jj}||v r—|}n!d|v r¯d|| d¡| d¡…  d |¡ }n	d| d |¡ }t jd|d
}| jtjd|	|d t jddd
rÓd}nd}|st jddd
rtd|j ƒ\}}t  d¡ t! "|jj#¡}t jd|dd „ d!}| jtj$d||d" n=|r|d# }ntd#|j%ƒ\}}t jd$d%d „ d&}
t  d'¡}t  d¡ d( |¡}t jd|d
}| jtj&d||
||d) d}|r’t jd*d+d „ d&}t  d,¡}t  d-¡ t  d¡ d. |
|¡}t jd|d/d „ d!}|}t jd0 |¡dd
r†td1|jƒ\}}| jtj'd||||d2 t  d3¡ t  t jt(j|td4dd¡ d S )5NTrF   Úauthc                      s   ˆ S r   r   r   rV   r   r   Úpassphrase_providerK  s   z5setup_instance_principal.<locals>.passphrase_providerÚcoreZcomputeZidentityznDo you have an existing compute instance for which you would like to set up instance principal authentication?rS   zØPlease create a compute instance and then run this command again. For information regarding how to create a compute instance, please visit https://docs.oracle.com/en-us/iaas/Content/GSG/Reference/overviewworkflow.htmé   Úinstancez>Do you want to add this instance to an existing dynamic group?Fzdynamic groupz¢For information about dynamic group matching rule syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Tasks/managingdynamicgroups.htm#WritingÚ{zAny Ú}z, instance.id = '{}'}}zAny {zGEnter the matching rule(s) you would like to set for this dynamic groupZACTIVE)Úwait_for_stateZdynamic_group_idÚmatching_rulez2Do you want to create a new policy for this group?z.Do you want to update a policy for this group?ÚpolicyzFor information about policy syntax, please visit https://docs.oracle.com/en-us/iaas/Content/Identity/Concepts/policysyntax.htmz‘Enter the statement(s) you would like to set for this policy (please enter your statements in JSON format, as a bracket-enclosed list of strings)c                 S   ó   t | ƒS r   ©Úvalidate_statements©Ú
statementsr   r   r   rN   {  ó    z*setup_instance_principal.<locals>.<lambda>©r"   rQ   )rt   Z	policy_idr{   rR   z'Enter a name for your new dynamic groupc                 S   rw   r   ©Úvalidate_resource_name©Únamer   r   r   rN   ƒ  r|   rP   z.Enter a description for your new dynamic groupzAny {{instance.id = '{}'}})rt   Úcompartment_idr   ru   ÚdescriptionzEEnter a name for the new policy to be used for your new dynamic groupc                 S   rw   r   r~   r€   r   r   r   rN     r|   zLEnter a description for the new policy to be used for your new dynamic groupa  WARNING: Using the default policy at the prompt below will grant all permissions for all your OCI resources to every instance in the dynamic group. Please ensure that this is the policy you want to use. If not, you can enter your custom policy statement(s) at the prompt.zD["Allow dynamic-group {} to manage all-resources in compartment {}"]c                 S   rw   r   rx   rz   r   r   r   rN   ”  r|   zªThis policy is currently set to be put in compartment {}, which is the compartment that your instance is in. Do you want to create this policy in a different compartment?Zcompartment)rt   r‚   r   r{   rƒ   zHSuccessfully set up instance principal authentication for your instance!)r‚   rm   ))r)   r;   r=   Ú%instance_principal_setup_instructionsÚobjr   r	   Úget_passphraser   r-   Zbuild_clientr
   r   Úbuild_configrc   r_   r`   Úget_resourceZget_instanceÚdatar‚   Zget_compartmentr   Zget_dynamic_groupru   ÚindexÚrindexr<   ra   Zinvoker   Zupdate_dynamic_groupZ
get_policyÚjsonÚdumpsr{   Zupdate_policyZget_tenancyZcreate_dynamic_groupZcreate_policyÚ$instance_principal_setup_end_message)Úctxrn   Zcompute_clientZidentity_clientZ
config_objZinstance_ocidÚresultZinstance_compartment_ocidZinstance_compartment_nameZ
group_ocidZ
group_nameZcurrent_ruleZdefault_group_ruleZ
group_ruleZ
new_policyZpolicy_ocidZdefault_policy_statementZpolicy_statementZtenancy_ocidZgroup_descriptionZpolicy_nameZpolicy_descriptionZpolicy_compartment_ocidr   rV   r   Úsetup_instance_principal?  s€   



(
€







"r‘   z
oci-cli-rczñGenerates a oci_cli_rc file that can contain parameter default values and other configuration information such as command aliases and predefined queries.

This command will populate the file with some default aliases and predefined queries.
z--fileza+b)r&   ZlazyzIThe file into which default aliases and predefined queries will be loaded)Úshow_defaultr"   r#   r   c              
   C   sP  t | dƒr| jdkrt d¡‚tj | j¡s=zt tj | j¡¡ W n t	y< } z|j
t
jkr1n‚ W Y d }~nd }~ww |  d¡ |  ¡  ¡ }t|v rUtjdtjd n|  d t¡ ¡ ¡ t d t¡¡ t|v rttjd	tjd n|  d t¡ ¡ ¡ t d
 t¡¡ t|v r”tjdtjd d S |  d t¡ ¡ ¡ t d t¡¡ d S )Nr   z<stdout>z4This command does not support writing data to stdoutr   ziPredefined queries will not be written as the specified file already contains a section for these queries©Úfilez

{}z+Predefined queries written under section {}zhCommand aliases will not be written as the specified file already contains a section for command aliasesz(Command aliases written under section {}zlParameter aliases will not be written as the specified file already contains a section for parameter aliasesz*Parameter aliases written under section {})Úhasattrr   r)   r*   r.   r/   r1   ÚmakedirsÚdirnameÚOSErrorÚerrnoÚEEXISTÚseekÚreadÚdecoder   r;   r_   ÚstderrÚwriter<   Údefault_canned_queriesÚencoder   Údefault_command_aliasesr   Údefault_param_aliases)r”   Úexcr‰   r   r   r   Úsetup_cli_rcž  s4   
þ€þ
r¥   ZautocompletezHInteractive script to set up tab completion for commands and parameters.c                   C   s6   t jdkrt d¡ d S t jdkrtƒ  d S tƒ  d S )NÚcygwinz?Tab completion only available on Windows when using Powershell.r   )r_   Úplatformr)   r;   Úsetup_autocomplete_windowsÚsetup_autocomplete_non_windowsr   r   r   r   Úsetup_autocompleteÇ  s   




rª   c                  C   sh  d} t j d| ¡}t j t j t¡¡}t j ||¡}t j |¡s-t d 	|¡¡ t
 d¡ t d 	|¡¡ t g d¢¡ t
jj¡ ¡ }d 	|¡}tj|dd	r­t j t j |¡¡sbt  t j |¡¡ t|d
d;}| d¡ | ¡ }| |v r‰t dj	| |d¡ 	 W d   ƒ d S | d 	|¡¡ t d¡ t d¡ W d   ƒ d S 1 s¦w   Y  d S t d¡ d S )NzOciTabExpansion.ps1Úbinú;Could not locate autocomplete script at {}. Exiting script.rp   ú"Using tab completion script at: {})Z
powershellz
-NoProfilezecho $profilezmTo set up autocomplete, we need to add a few lines to your Powershell profile: {}. Please confirm this is ok.TrS   úa+r%   r   zÙIt looks like tab completion for oci is already configured in {ps_profile_file_path}. If you want to re-run the setup command please remove any lines containing '{oci_tab_completion_file}' from {ps_profile_file_path}.)Úoci_tab_completion_fileÚps_profile_file_pathz
. {}
z]Success!
Reload your Powershell profile or restart your shell for the changes to take effect.z×In order to run the autocomplete script, you may also need to set your Powershell execution policy to allow for running local scripts (as an Administrator run Set-ExecutionPolicy RemoteSigned in a Powershell prompt)ú*Exiting script. Tab completion not set up.)r.   r/   r6   r—   rd   Ú__file__r1   r)   r;   r<   r_   r`   Ú
subprocessÚcheck_outputr   ÚstdoutÚencodingÚstriprc   r–   Úopenr›   rœ   rŸ   )r¯   Úscript_relative_pathÚpath_to_install_dirÚcompletion_script_filer°   Úconfirm_promptÚfÚcontentr   r   r   r¨   Õ  s4   


ú
"ö
r¨   c                  C   sL   t j t¡} t j t¡}| s|rtS | r |r t ¡  ¡ dkr tS | r$tS d S )NÚdarwin)r.   r/   ÚisfileÚUSER_BASH_RCÚUSER_BASH_PROFILEr§   ÚsystemÚlower)Zbashrc_existsZbash_profile_existsr   r   r   Ú_get_default_rc_fileù  s   rÅ   c                   @   s   e Zd ZdS )ÚCLIInstallErrorN)Ú__name__Ú
__module__Ú__qualname__r   r   r   r   rÆ     s    rÆ   c                 C   s‚   |dvrt dƒ‚|dkrdnd}|dkrdnd}	 td | ||¡ƒ}| ¡ | ¡ kr,d	S | ¡ | ¡ kr6dS |r@|s@|| ¡ kS q)
N)NÚyÚnz-Valid values for default are 'y', 'n' or NonerÊ   ÚYrË   ÚNTz{} ({}/{}): F)Ú
ValueErrorÚprompt_inputr<   rÄ   )Úmsgr"   rÊ   rË   Zansr   r   r   Ú
prompt_y_n  s   ùrÑ   c                  C   sD   t  ¡  ¡ dkr
tnt} td | ¡dd}|r t| dƒ ¡  | S d S )Nr¿   zCCould not automatically find a suitable file to use. Create {} now?rÊ   rS   Úa)	r§   rÃ   rÄ   rÂ   rÁ   rÑ   r<   r¸   Úclose)ZrcfileZans_yesr   r   r   Ú_default_rc_file_creation_step  s   rÔ   c                  C   s\   d } t ƒ }|s
tƒ } | ptd|ƒ} | r,tj tj | ¡¡}tj |¡s*td 	|¡ƒ |S d S )NzPEnter a path to an rc file to update (file will be created if it does not exist)z%Automatically created rc file at '{}')
rÅ   rÔ   Úprompt_input_with_defaultr.   r/   Úrealpathr0   rÀ   Úprint_statusr<   )Zrc_fileZdefault_rc_fileÚrc_file_pathr   r   r   Úget_rc_file_path   s   rÙ   Ú c                 C   s   t d|  ƒ d S )Nz-- )Úprint©rÐ   r   r   r   r×   .  s   r×   c                 C   s"   t jdkrtd|  ƒS td|  ƒS )N)é   r   z
===> )r_   Úversion_infoÚinputZ	raw_inputrÜ   r   r   r   rÏ   2  s   
rÏ   c                 C   s&   |rt d | |¡ƒp|S t d | ¡ƒS )Nz{} (leave blank to use '{}'): z{}: )rÏ   r<   )rÐ   r"   r   r   r   rÕ   9  s   rÕ   c               	   C   sÌ  t  d¡ tƒ } | stdƒ‚tj dd¡}tj tj t	¡¡}tj ||¡}tj 
|¡s9t  d |¡¡ t d¡ t  d |¡¡ tj d¡}|}d	j|d
}dj| d}t j|ddrßtj 
|¡rmt |d¡ t |¡ z|}|}	tj tj |	¡¡s…t tj |	¡¡ t ||	¡ W n tyŸ   t  d ||¡¡ Y d S w t| dd'}
|
 d¡ |
 ¡ }d|vr½|
 d |¡¡ n	t  dj| d¡ W d   ƒ n1 sÐw   Y  t  d |¡¡ d S t  d¡ d S )NzJTo set up autocomplete, we would update few lines in rc/bash_profile file.zNo suitable profile file found.r«   zoci_autocomplete.shr¬   rp   r­   z~/lib/oci_autocomplete.shz\[[ -e "{soft_link_completion_script_file}" ]] && source "{soft_link_completion_script_file}")Ú soft_link_completion_script_filezRWe need to add a few lines to your {rc_file_path} file. Please confirm this is ok.)rØ   TrS   i¤  z†Unable to symlink ~/lib/oci_autocomplete.sh to {}. 
Add '{}' to your rc file and restart your terminal for the changes to take effect.r®   r%   r   zlib/oci_autocomplete.shz
{}
zèIt looks like tab completion for oci is already configured in {rc_file_path}. If you want to re-run the setup command please remove the line containing 'oci_autocomplete.sh' from {rc_file_path} and run oci setup authenticate again.
zLSuccess! 
 Restart your terminal or Run '{}' for the changes to take effect.r±   )r)   r;   rÙ   rÆ   r.   r/   r6   r—   rd   r²   r1   r<   r_   r`   r0   rc   ÚchmodÚremoveÚisdirr–   ÚsymlinkÚ	Exceptionr¸   r›   rœ   rŸ   )rØ   r¹   rº   r»   Z	soft_linkrà   Zbash_profile_liner¼   ÚsrcÚdstr½   r¾   r   r   r   r©   @  sX   


ÿÿü
€ø

r©   zrepair-file-permissionsah  Resets permissions on a given file to an appropriate access level for sensitive files. Generally this is used to fix permissions on a private key file or config file to meet the requirements of the CLI.
On Windows, full control will be given to System, Administrators, and the current user.  On Unix, Read / Write permissions will be given to the current user.z"The file to repair permissions on.)Úrequiredr   c                 C   sL   t j | ¡} t j | ¡st d | ¡¡‚t j | ¡st d¡‚t 	| ¡ d S )NzCould not find file: {}z)This command is only supported for files.)
r.   r/   r0   r1   r)   r*   r<   rÀ   r   Ú"apply_user_only_access_permissionsr“   r   r   r   Úrepair_file_permissionsv  s   
rê   c              	   C   s€   | j tjjtjjd}d}d}| |d¡ |d¡ dd¡}t |¡}t	 
|¡ ¡ }d dd„ t|d d d	… |d
d d	… ƒD ƒ¡S )N)r¶   r<   s   -----BEGIN PUBLIC KEY-----s   -----END PUBLIC KEY-----ó    ó   
ú:c                 s   s    | ]	\}}|| V  qd S r   r   )Ú.0rÒ   Úbr   r   r   Ú	<genexpr>  s   € z,public_key_to_fingerprint.<locals>.<genexpr>é   rp   )Zpublic_bytesr   ZEncodingZPEMZPublicFormatZSubjectPublicKeyInfoÚreplaceÚbase64Ú	b64decoder   Zmd5Ú	hexdigestr6   Úzip)r4   ÚbytesÚheaderZfooterÚkeyZfp_plainr   r   r   r:   …  s   þ
.r:   c	                 K   sÞ   t j | ¡}
t| dƒU}|
r| d¡ | d |¡¡ |r%| d |¡¡ | d |¡¡ | d |¡¡ | d |¡¡ | d |¡¡ |rO| d	 |¡¡ |rY| d
 |¡¡ W d   ƒ n1 scw   Y  t | ¡ d S )NrÒ   z

z[{}]
zuser={}
zfingerprint={}
zkey_file={}
ztenancy={}
z
region={}
zpass_phrase={}
zsecurity_token_file={}
)r.   r/   r1   r¸   rŸ   r<   r   ré   )Úfilenamerj   rD   Úkey_filerR   rk   rZ   r[   Zsecurity_token_fileÚkwargsZexisting_filer½   r   r   r   rh   “  s$   
€îrh   c                 C   s‚   |st j | ¡rt d | ¡¡sdS t| dƒ}| tj	|d¡ W d   ƒ n1 s+w   Y  t 
| ¡ |s?t d | ¡¡ dS )Nú1File {} already exists, do you want to overwrite?FÚwb)r4   zPublic key written to: {}T©r.   r/   rÀ   r)   rc   r<   r¸   rŸ   r   Zserialize_keyré   r;   )rú   r4   rB   Úsilentr½   r   r   r   r5   ­  s    ÿ
r5   c                 C   s„   |st j | ¡rt d | ¡¡sdS t| dƒ}| tj	||d¡ W d   ƒ n1 s,w   Y  t 
| ¡ |s@t d | ¡¡ dS )Nrý   Frþ   )rC   rA   zPrivate key written to: {}Trÿ   )rú   rC   rA   rB   r   r½   r   r   r   r8   ¼  s    ÿ
r8   c              	   C   sn   t | dƒ(}ztj| ¡ | d¡tƒ d}||fW W  d   ƒ S  ty,   t d¡‚w 1 s0w   Y  d S )NÚrbÚascii©r‰   ÚpasswordZbackendz3Incorrect passphrase, could not decrypt private key)	r¸   r   Úload_pem_private_keyrœ   r¡   r   rÎ   r)   ÚBadParameter)rú   rA   r½   rC   r   r   r   rU   Ë  s   ý
þürU   c              	   C   sÀ   t j | ¡} t j | ¡st d | ¡¡‚t| dƒ=}ztj	| 
¡ d tƒ d}| d|fW W  d   ƒ S  tyG   | dd f Y W  d   ƒ S  tyU   t d | ¡¡‚w 1 sYw   Y  d S )NzNo file found at: {}r  r  FTz,Could not load file as private key. File: {})r.   r/   r0   rÀ   r)   r  r<   r¸   r   r  rœ   r   Ú	TypeErrorrÎ   )rú   r½   rC   r   r   r   rg   Õ  s   
ýúÿùrg   c                 C   s&   t |  d¡ƒdkrt d | ¡¡‚d S )Nrí   é   zInvalid fingerprint: {})ÚlenÚsplitr)   r  r<   )rD   r   r   r   Úvalidate_fingerprintå  s   ÿr  c                 C   s8   t | ƒst| ƒst d | ttƒ¡¡ t d¡sd S | S )Nz¦Unrecognized region: {}. Please enter a number between 1 to {}, or valid regions can be found here: https://docs.cloud.oracle.com/Content/General/Concepts/regions.htmzAContinue with unrecognized region? (Enter 'n' to re-enter region))r   Úis_valid_region_indexr)   r;   r<   r	  r   rc   ©rk   r   r   r   Úvalidate_regionê  s
   
r  c                 C   s(   |   ¡ ottƒt| ƒ  kodkS   S )Nrp   )Úisdigitr	  r   Úintr  r   r   r   r  ó  s   (r  c                 C   s&   t j | ¡}t j |¡rt d¡‚|S )Nz2Config location must be a filename not a directory)r.   r/   r0   rã   r)   r  )rú   Zfilename_expandedr   r   r   Úprocess_config_filenameø  s   
r  c                 C   s   |  | ¡s
t d¡‚| S )Nz{Invalid OCID format. Instructions to find OCIDs: https://docs.cloud.oracle.com/Content/API/Concepts/apisigningkey.htm#Other)Úmatchr)   r  ©rM   Úpatternr   r   r   rK      s   

rK   c                 C   ó"   t  d¡}| | ¡st d¡‚| S )NzF^(ocid1.)([0-9a-zA-Z-_]+.)(oc[1-3].)([0-9a-zA-Z-_]*.)([0-9a-zA-Z-_]+)$z†Invalid OCID format. OCID syntax can be found here: https://docs.oracle.com/en-us/iaas/Content/General/Concepts/identifiers.htm#Oracle©ÚreÚcompiler  r)   r  r  r   r   r   Úvalidate_resource_ocid  s   


r  c                 C   s*   zt  | ¡ W | S  ty   t d¡‚w )NzRPlease enter your statements in JSON format, as a bracket-enclosed list of strings)rŒ   ÚloadsrÎ   r)   r  rz   r   r   r   ry     s   ý
ÿry   c                 C   r  )Nz^[a-zA-Z0-9._-]+$z|Invalid resource name. The name cannot contain spaces; only letters, numerals, hyphens, periods, or underscores are allowed.r  )r   r  r   r   r   r     s   


r   c                 C   sp   | s	t  d¡ d S dd„ | ¡ D ƒ}|d r| d¡ |r!|  ¡ } | |v r6|s6t  dj| d |¡d¡ d } | S )Nz!Cannot specify blank profile namec                 S   s   g | ]}|  ¡ ‘qS r   )Úupper)rî   Úsectionr   r   r   Ú
<listcomp>'  s    z)validate_profile_name.<locals>.<listcomp>r   z|Profile {section} already exists in config. Cannot specify a profile that conflicts with any existing profile(s): {sections}ú, )r  Úsections)r)   r;   r  Úappendr  r<   r6   )ÚvalueÚconfig_parserrB   Z	makeUpperr  r   r   r   Úvalidate_profile_name"  s   

þr#  c               
      s   t j tjdt j td¡td¡} t j | ¡rit	 
¡ ‰ z'ˆ  | ¡ tjd | ¡ddrAd }|s<tjd‡ fdd	„d
}|r/| |fW S W n t	jyU } zW Y d }~nd }~ww t d | ¡¡s`dS t  | ¡ | tfS t j | ¡}|r|t j |¡s|t |¡ | tfS )Nz Enter a location for your configr   r}   zsConfig file: {} already exists. Do you want add a profile here? (If no, you will be prompted to overwrite the file)TrS   ú6Enter the name of the profile you would like to createc                    s
   t | ˆ ƒS r   ©r#  ©r!  ©r"  r   r   rN   A  rX   z,prompt_for_config_location.<locals>.<lambda>rP   zQFile: {} already exists. Do you want to overwrite (Removes existing profiles!!!)?)NN)r.   r/   rd   r)   ra   r6   re   r  r1   ÚconfigparserÚConfigParserrœ   rc   r<   ÚErrorrâ   r—   r   r2   ÚDEFAULT_PROFILE_NAME)ri   r[   Úer—   r   r'  r   r]   8  s0   "
ÿ
û€ÿ
ú
r]   c               
      sv   t  ¡ ‰ z tj t¡sttfW S ˆ  t¡ tj	d‡ fdd„d} W t| fS  t j
y: } z	W Y d }~t| fS d }~ww )Nr$  c                    s   t | ˆ ddƒS )NTFr%  r&  r'  r   r   rN   ]  s    z,prompt_session_for_profile.<locals>.<lambda>rP   )r(  r)  r.   r/   r1   ÚDEFAULT_CONFIG_LOCATIONr+  rœ   r)   ra   r*  )r[   r,  r   r'  r   Úprompt_session_for_profileV  s   


ÿý
€ýr.  c                     sŽ   d } d‰ t tƒ}dd„ t|ƒD ƒ‰‡ ‡fdd„tdtˆƒˆ ƒD ƒ}d dd„ |D ƒ¡}| s9tjd |¡t	d	} | r-t
| ƒrE|t| ƒd
  S | S )Né   c                 S   s    g | ]\}}d   |d |¡‘qS )z{}: {}rp   )r<   )rî   rŠ   Znumeric_regionr   r   r   r  j  s     z%prompt_for_region.<locals>.<listcomp>c                    s   g | ]
}ˆ||ˆ  … ‘qS r   r   )rî   rŠ   ©ZCHUNK_LENGTHZnumeric_region_listr   r   r  k  s    r   z,
c                 S   s   g | ]}d   |¡‘qS )r  )r6   )rî   Zchunked_regionr   r   r   r  l  s    z(Enter a region by index or name(e.g.
{})rT   rp   )Úsortedr   Ú	enumerateÚranger	  r6   r)   ra   r<   r  r  r  )rk   Zsorted_region_listZchunked_region_listZregion_listr   r0  r   rb   d  s    ÿrb   c                  C   s*   t jd t¡d dddd} | tkrd S | S )Nz@Enter a passphrase for your private key ("{}" for no passphrase)TF)rG   r"   rY   r’   Zconfirmation_prompt)r)   ra   r<   ÚNO_PASSPHRASErV   r   r   r   r-   s  s
   þr-   c                 C   sZ   t jdd}| | ¡ | |¡ t| dƒ}| |¡ W d   ƒ d S 1 s&w   Y  d S )NrÚ   )Údefault_sectionÚw)r(  r)  rœ   Úremove_sectionr¸   rŸ   )Úconfig_fileZprofile_name_to_terminater   Zconfig_file_handler   r   r   Úremove_profile_from_config{  s   

"ÿr9  c              
   C   sž   d}|rKt jdj| ddd„ d}z||ƒ}d}W n/ tjyH } z"|jdkr1t  d	j| d¡ nt  d
|j ¡ t 	d¡ W Y d }~nd }~ww |s||fS )NTzEnter the {resource} OCID)Úresourcec                 S   rw   r   )r  rL   r   r   r   rN   ˆ  r|   zget_resource.<locals>.<lambda>rP   FZNotAuthorizedOrNotFoundzªError: Could not find {resource} with the given OCID; please ensure that you have entered the correct {resource} OCID and that you are authorized to access the {resource}zError: rp   )
r)   ra   r<   r   ZServiceErrorÚcoder;   Úmessager_   r`   )Zresource_typeZget_funcZprompt_ocidZresource_ocidr   r,  r   r   r   rˆ   …  s   

€ûûrˆ   c                 C   sl   zt  | j¡}t |d |d ¡}W d S  tjy   Y d S  tjy5   t  ¡ }t |d |¡}| Y S w )Nrû   rZ   )	r   r‡   r…   r   Zload_private_key_from_filer   ZConfigFileNotFoundZMissingPrivateKeyPassphraser-   )r   Zclient_configrC   rA   r   r   r   r†   –  s   õúr†   zfind-installationsz:Finds and lists locations of all default OCI CLI installs.c              
   C   s^  g }g }t  d¡ tj t¡rt}| d|f¡ t  d¡ tjdgdtj	tj	dd}|j
dkrjd|jv rjg }tjd	gdtj	tj	dd}| |j ¡ ¡ tjd
gdtj	tj	dd}| |j ¡ ¡ | dd |¡f¡ t  d¡ tjdgdtj	tj	dd}|j
dkr«d|jv r«t d|j¡}t d|d ¡}d t|d ƒ¡}dj|d}| d|f¡ t  d¡ tjdgdtj	tj	dd}|j
dkrÝt d|j¡}tj |d  ¡ d d¡}| d|f¡ t  d¡ z6dtjv rtjd }	t  d |	¡¡ |	 tj¡D ]}
tj |
dt¡}| tj|dd¡ qünt  d ¡ W n ty+ } zW Y d }~nd }~ww t  ¡  t|ƒdkr=t  d!¡ n$t  d"¡ tt|ƒƒD ]}t  d#j|d || d || d d$¡ qHt  ¡  t|ƒdkrrt  d%¡ nt  d&¡ tt|ƒƒD ]}t  d'j|d || d(¡ q}t  ¡  t  t jd)dd*¡ d+}t  t j|dd*¡ |  ¡  d S ),Nz9Checking for CLI installer script default installation...zCLI Installer Scriptz%Checking for Homebrew installation...z	brew listT)Úshellrµ   rž   Úuniversal_newlinesr   zoci-clizbrew --cellar oci-clizbrew --prefix oci-cliZHomebrewr  z Checking for yum installation...zyum list installedzpython[0-9]+-oci-cliz[0-9]+Ú.z./usr/lib/python{version}/site-packages/oci_cli)ÚversionZyumz Checking for pip installation...zpip3 show oci-clizLocation: .*
rp   Úoci_cliZpip3z.Searching for CLI executables on your $PATH...ÚPATHzYour current $PATH is {}z**)Ú	recursivez*No PATH variable found in your environmentz+No OCI CLI package installations were foundz8The following OCI CLI package installations were found:
z	[{index}] {method}: {location})rŠ   ÚmethodÚlocationz/No OCI CLI executables were found on your $PATHz<The following OCI CLI executables were found on your $PATH:
z	[{index}] {location})rŠ   rE  zbVisit https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/cliuninstall.htm to uninstall OCI-CLIrF   zôPLEASE NOTE: This command lists CLI installations in default locations and CLI executables on your $PATH. There may be additional (unlisted) CLI installations at other non-default locations or CLI executables that are not on your current $PATH.)r)   r;   r.   r/   r1   ÚDEFAULT_INSTALL_DIRr   r³   ÚrunÚPIPEÚ
returncoderµ   r·   r6   r  ÚfindallÚlistr<   r
  ÚenvironÚpathsepÚOCI_EXECUTABLE_NAMEÚextendÚglobrå   r	  r3  r=   r`   )r   Zpackage_locationsZexecutable_locationsZinstallation_locr   Úpackage_nameZpython_version_numÚpython_versionZlocation_lineZpath_envr/   Úsearch_pathÚexÚiZfind_install_noter   r   r   Úfind_cli_installations¨  s˜   

ÿÿÿ
ÿ
ÿ


þ
€€ÿ

ÿ
 þrV  r   )rÚ   )FF)FT)tÚ
__future__r   r)   Zoci_cli.cli_rootr   Zoci_cli.cli_constantsr   r   r   r   r   r	   r
   r   rA  r   Z0services.identity.src.oci_cli_identity.generatedr   Zoci_cli.utilr   ró   r(  r.   Úos.pathr³   r_   r™   rŒ   r  rP  Zoci.regionsr   r   r   r   r   r   r§   Zcryptography.hazmat.primitivesr   Zcryptography.hazmat.backendsr   r\   r<   r„   rŽ   r>   r    r¢   r£   r4  r7   r9   r^   r/   r6   r0   re   rf   r+  ZDEFAULT_TOKEN_DIRECTORYr-  rÁ   rÂ   rF  rN  ÚgroupZhelp_option_groupr    ÚcommandÚoptionÚPathZFileÚhelp_optionrE   rl   Zpass_contextZwrap_exceptionsr‘   r¥   rª   r¨   rÅ   rå   rÆ   rÑ   rÔ   rÙ   r×   rÏ   rÕ   r©   rê   r:   rh   r5   r8   rU   rg   r  r  r  r  rK   r  ry   r   r#  r]   r.  rb   r-   r9  rˆ   r†   rV  r   r   r   r   Ú<module>   sà   (-Ó/
%
?[#$

	
6


	
	

