
    e9                     6   d 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	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 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ZddiZ G d de
j<                        Z G d de       Z! G d de       Z"y)z"Routes to/from Compute Engine VMs.    )absolute_import)division)unicode_literalsN)base_classes)lister)
exceptions)	ssh_utils)external_helper)internal_helpers)ssh)log)
properties)
console_io)filesEXAMPLESzg        To route to/from Compute Engine virtual machine instances, run:

          $ {command}
        c                   ^     e Zd ZdZeZed        Z fdZd Z	d Z
d Zd Zed        Z xZS )	Routesa  Routes to/from Compute Engine virtual machine instances.

  Routes to/from Compute Engine virtual machine instances.

  NOTE: The name filtering will cycle through all the VMs in the project.
  Depending on the size of the project, this could be a considerable amount
  of work.

  If that is the case, use the --regexp flag to filter down the amount
  of VMs considered in the filtering.
  c                 .    t         j                  |       y )N)_RoutesArgsArgsclsparsers     &lib/surface/compute/diagnose/routes.pyr   zRoutes.ArgsB   s    V    c           	         t         t        |   |       d| _        t	        j
                  | j                               }|j                  }t        j                         }|j                  |       || _
        || _        t        j                  j                  j                  j!                         }t"        j%                  |      }t&        j)                  |j*                  | j,                  j.                  ||j0                  || j2                  | j4                        }|j6                  }|st9        j:                         }|j<                  }	|j>                  }
|j@                  }|jB                  }tE        jF                  |       d}|r|	stI        jJ                  |      sytL        jN                  jQ                          |D ]  }d|jR                  z  }tL        jN                  jU                  |       tL        jN                  jU                  dtW        |      z         	 | jY                  |||	|       |
r	 | je                  |||	|      }|rO|s| jg                  |||	|      }|r| ji                  |||||	|       n?tL        jN                  jU                  d       ntL        jN                  jU                  d	       tL        jN                  jU                  d
        y# tZ        j\                  $ rH}tM        j^                  d       tM        j^                  ta        jb                  |             Y d}~rd}~ww xY w# t8        jj                  $ r2}tM        j^                  ta        jb                  |             Y d}~d}~ww xY w)z"Default run method implementation.F)serviceprojectzonesfiltershttp	batch_urlz&The following VMs will be tracerouted.NzChecking instance %s-zError routing to instancez#Unable to obtain self ip. Aborting.z<Please make sure traceroute is installed in PATH to move on. )6superr   Run_use_accounts_servicer   ComputeApiHolderReleaseTrack	resourcesr	   BaseSSHCLIHelper_args_ssh_helperr   VALUEScorer   	GetOrFailr   
GetFilters_RoutesQueriesObtainInstancesnamescompute	instancesr   r!   r"   userr   GetDefaultSshUsernamedry_runreverse_traceroutetraceroute_argsexternal_route_ipr   PrintHeaderr   PromptContinuer   outflushnamePrintlenTracerouteInstancer   ToolExceptionerrorsix	text_typeCheckTracerouteObtainSelfIpReverseTracerouteInstanceCommandError)selfargsholderresource_registry
ssh_helperr   r    r6   r7   r9   r:   r;   r<   promptinstanceheaderehas_traceroute	__class__s                     r   r&   z
Routes.RunF   s   	&$D!!&D**4+<+<+>?F((++-JNN4 DJ!D $$,,668G$$T*G..

&&jjYY.. / "I 99D&&(d llG00**O..  +5F)B)B6)JGGMMO%5f	ggmmF	ggmmC#f+%&/7 1	3 
	&//$0AC.$"&"3"3HdG4E#G ,,Xt=N-<g->@ ggmmABGGMMNP 
ggmmBC  %% 		-.		#--"#.  	&
))CMM!$
%
%	&s1   K5BL:L7/=L22L7:M?(M::M?c                 l   t        j                  |      }t        j                  j	                  d|z         t        j                  |      }d|g}|r||z  }|r%t        j                  dj                  |             yt        j                  d|       t        j                  j	                  d       y)aD  Runs a traceroute from localhost to a GCE VM.

    Args:
      instance: Compute Engine VM.
      traceroute_args: Additional traceroute args to be passed on.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    z>>> Tracerouting to %s
traceroute 
Traceroute)	proc_namecommand_listz>>>N)r   GetInstanceNetworkTitleStringr   r?   rB   r	   GetExternalIPAddressr
   	DryRunLogjoinRunSubprocess)rM   rS   r;   r9   rP   instance_stringexternal_ipcmds           r   rD   zRoutes.TracerouteInstance   s     'DDXNOGGMM*_<=00:K
%C	_c.##lM	ggmmEr   c                 n   t        j                  |      }t        j                  j	                  d|z         t        j                  j                          |rd}d|g}|r||z  }t        j                  |||| j                  | j                  |       |s t        j                  j	                  d       yy)a  Runs a traceroute from a GCE VM to localhost.

    Args:
      instance: Compute Engine VM.
      user: The user to use to SSH into the instance.
      external_route_ip: the ip to which traceroute from the VM
      traceroute_args: Additional traceroute args to be passed on.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    Raises:
      ssh.CommandError: there was an error running a SSH command
    z <<< Reverse tracerouting from %s	<SELF-IP>rY   )r]   rS   r7   rN   rQ   r9   z<<<N)
r   r^   r   r?   rB   r@   r
   RunSSHCommandToInstancer,   r-   )	rM   rS   r7   r<   r;   r9   rP   rc   re   s	            r   rK   z Routes.ReverseTracerouteInstance   s     'DDXNOGGMM4FG GGMMO%*
+C	_c++ZZ## 	ggmmE r   c           
         t        j                  |      }t        j                  j	                  d|z         |rt        j                  j                  d       t        j                  j                          ddg}	 t        j                  t        j                        5 }t        j                  |||| j                  | j                  ||      }ddd       d	k(  r t        j                  j                  d
       nt        j                  j                  d       t        j                  j                          |d	k(  S # 1 sw Y   pxY w# t        $ r}	t        j                  j	                  t!        j"                  |	             t        j                  j	                  d       t        j                  j                          t%        j&                  dj)                  |      t!        j"                  |	            d}	~	ww xY w)a  Checks whether the instance has traceroute in PATH.

    Args:
      instance: Compute Engine VM.
      user: The user to use to SSH into the instance.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    Returns:
      True if the instance has traceroute in PATH,
      False otherwise
    Raises:
      ssh.CommandError: there was an error running a SSH command
    zChecking traceroute for %s: z[DRY-RUN] No command executed.whichrY   r]   rS   r7   rN   rQ   explicit_output_filer9   N
rZ   r   zTraceroute found in PATHzTraceroute not found in PATH)r   r^   r   r?   writerB   r@   r   
FileWriterosdevnullr
   rh   r,   r-   	ExceptionrG   rH   r   rL   ra   )
rM   rS   r7   r9   rP   rc   re   dev_nullreturn_coderU   s
             r   rI   zRoutes.CheckTraceroute   sZ    'DDXNOGGMM0?BC	ggmm45GGMMOL
!C>BJJ'8%==''!) ( a	ggmm./	ggmm23GGMMO!) ('  >	ggmmCMM!$%	ggmmD	ggmmoSXXc]CMM!,<==	>s1   <#E 1D?E ?EE 	H B'G;;H c           	         t        j                  |      }t        j                  j	                  d|z         t        j                  j                          |rt        j                  j                  d       t        j                         }ddg}	 t        j                  |||| j                  | j                  ||       |j'                         j)                  d	      }	t+        j,                  d
|	      }
|
rP|
j/                  d      }t        j                  j                  |       t        j                  j                          |S y# t        $ rz}t        j                  j	                  d       t        j                  j                          t        j                  dj!                  |      t#        j$                  |            d}~ww xY w)a  Returns the localhost ip as seen from the VM.

    Args:
      instance: Compute Engine VM.
      user: The user to use to SSH into the instance.
      dry_run: Whether to only print commands instead of running them.
      resource_registry: gcloud class used for obtaining data from the
        resources.
    Returns:
      A string containing the local ip,
      None if the obtaining was unsuccessful
    Raises:
      ssh.CommandError: there was an error running a SSH command
    zObtaining self ip from %s: rg   echoz$SSH_CLIENTrk   rm   rZ   Nzutf-8z$(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})   )r   r^   r   r?   rn   r@   rB   ioBytesIOr
   rh   r,   r-   rr   r   rL   ra   rG   rH   getvaluedecoderesearchgroup)rM   rS   r7   r9   rP   rc   tempre   rU   who_am_i_strresultress               r   rJ   zRoutes.ObtainSelfIp  sB    'DDXNOGGMM//ABGGMMO	ggmmK ::<D=
!C>--zz%%# ==?))'2LYY>MFLLOc	ggmmC	ggmmoj  >	ggmmD	ggmmoSXXc]CMM!,<==>s   0E 	GA5GGc                      y)Nr6    )rM   s    r   resource_typezRoutes.resource_type4  s    r   )__name__
__module____qualname____doc__DETAILED_HELPdetailed_helpclassmethodr   r&   rD   rK   rI   rJ   propertyr   __classcell__)rW   s   @r   r   r   3   sS    
  - Mf0#J,\.`  r   r   c                   0    e Zd ZdZed        Zed        Zy)r   z2Helper to setting and getting values for the args.c                    t         j                  j                  |       t        j                  j                  |       |j                  dd       |j                  ddd       |j                  dd	d
       |j                  ddd       |j                  dd       |j                  dt        j                  dd       y)z(Creates the flags stmts for the command.z--containeraP              The name or ID of a container inside of the virtual machine instance
            to connect to. This only applies to virtual machines that are using
            a Container-Optimized OS virtual machine image.
            For more information, see
            [](https://cloud.google.com/compute/docs/containers)
            )helpz--external-route-ipNz{For reverse traceroute, this will be the ip given to the VM instance to traceroute to. This will override all obtained ips.)defaultr   z--reverse-traceroute
store_truez<If enabled, will also run traceroute from the VM to the host)actionr   z
--ssh-flagappendaA          Additional flags to be passed to *ssh(1)*. It is recommended that flags
        be passed using an assignment operator and quotes. This flag will
        replace occurences of ``%USER%'' and ``%INSTANCE%'' with their
        dereferenced values. Example:

          $ {command} example-instance --zone us-central1-a           --ssh-flag="-vvv" --ssh-flag="-L 80:%INSTANCE%:80"

        is equivalent to passing the flags ``--vvv'' and ``-L
        80:162.222.181.197:80'' to *ssh(1)* if the external IP address of
        'example-instance' is 162.222.181.197.
        z--userzm        User for login to the selected VMs.
        If not specified, the default user will be used.
        r;   zX            Flags and positionals passed to the underlying traceroute call.
            zC            $ {command} example-instance -- -w 0.5 -q 5 42
        )nargsr   example)r	   r+   r   r   ZonalListeradd_argumentargparse	REMAINDERr   s     r   r   z_RoutesArgs.Args<  s     ##F+!!&)    
B	  D K  M   "        r   c                     g }|j                   r|j                  d|j                   z         |sy dj                  |      }|S )Nz
name eq %sz AND )regexpr   ra   )r   rN   r    s      r   r1   z_RoutesArgs.GetFilters~  s<    G{{nn\DKK/0ll7#GNr   N)r   r   r   r   r   r   r1   r   r   r   r   r   9  s,    :? ?B  r   r   c                        e Zd ZdZed        Zy)r2   z9Helper for getting instance queries using the gcloud SDK.c           	         g }t        j                  |d   |d   |d   |d   |d   |d   |      }t        |      }g }|s|}|S |D ]  }d}d}	d}
|D ]7  }||j                  k(  r|} n$||j                  v r|}	'||j                  v s6|}
9 |r|j                  |       Y|	r|j                  |	       m|
sp|j                  |
        |S )	z3Returns a list of instances according to the flags.r   r   r   r    r!   r"   )r   r   requested_zonesfilter_exprr!   r"   errorsN)r   GetZonalResourceslistrA   selfLinkr   )r   r4   kwargsr   r   r6   filtered_instancesrA   
name_matchin_namein_self_linkrS   s               r   r3   z_RoutesQueries.ObtainInstances  s
    F%%y!y!w9%F^%F VI $4 1 $
!HX]]" "Jx}}$Gx(((#L " 

#
#J
/

#
#G
,

#
#L
1- 0 r   N)r   r   r   r   r   r3   r   r   r   r2   r2     s    A* *r   r2   )#r   
__future__r   r   r   r   rx   rp   r|   googlecloudsdk.api_lib.computer   r   googlecloudsdk.callioper   "googlecloudsdk.command_lib.computer	   +googlecloudsdk.command_lib.compute.diagnoser
   r   #googlecloudsdk.command_lib.util.sshr   googlecloudsdk.corer   r   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   rG   r   BaseCommandr   objectr   r2   r   r   r   <module>r      s    ) '  '  	 	 	 7 1 . 8 G H 3 # * 2 * 
 	C\%% CLN& Nb.V .r   