
    Y                        S r SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJ	r
  SSKJr  SS	KJr  SS
KJr  SSK	r	SSKrSSKJr  SSKJr  SSKJr  SSKrS rS rS rS rS rS rS r     S'S jr\R<                  R>                  4S jr S\R<                  R>                  SSSSS4S jr!S r"S r# " S S\RH                  5      r%S r&S(S jr'S  r(S! r)S" r* S)S# jr+S$ r,S% r-S& r.g)*zLibrary for obtaining API clients and messages.

This should only be called by api_lib.util.apis, core.resources, gcloud meta
commands, and module tests.
    )	apis_util)resource)
exceptions)log)
properties)requests)	transport)regional)apis_mapN)urljoin)urlparse)
urlunparsec                 D    [         R                  R                  X 5      U 4$ N)r   _API_NAME_ALIASESget)api_names    0lib/googlecloudsdk/api_lib/util/apis_internal.py_GetApiNameAndAliasr   '   s    

%
%
)
)(
=x	HH    c                     [        U 5      u  p[        R                  R                  U 0 5      n[        R
                  " U5       H  u  p4UR                  (       d  M  Us  $    g r   )r   r   MAPr   six	iteritemsdefault_version)r   _api_versverapi_defs        r   _GetDefaultVersionr    ,   sO    #H-+(\\h+(mmH-lcj . 
r   c                  P    [        [        R                  R                  5       5      $ )z6Returns list of avaiblable apis, ignoring the version.)sortedr   r   keys r   r   _GetApiNamesr%   5   s    	!!#	$$r   c                     [        U 5      u  p[        R                  R                  U S5      nUc  [        R
                  " U 5      e[        UR                  5       5      $ )zReturn available versions for given api.

Args:
  api_name: str, The API name (or the command surface name, if different).

Raises:
  apis_util.UnknownAPIError: If api_name does not exist in the APIs map.

Returns:
  list, of version names.
N)r   r   r   r   r   UnknownAPIErrorlistr#   )r   r   version_maps      r   _GetVersionsr*   :   sQ     $H-+(  40+

#
#H
--	k 	!!r   c                    [        U 5      u  pU [        R                  ;  a  [        R                  " U 5      e[
        R                  R                  R                  5       nUR                  SR                  X5      5      nU(       d  UR                  US5      nU=(       d    Un[        R                  U    nUb  X;  a  [        R                  " X5      eXQ   nU$ )a  Returns the APIDef for the specified API and version.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.

Raises:
  apis_util.UnknownAPIError: If api_name does not exist in the APIs map.
  apis_util.UnknownVersionError: If api_version does not exist for given
    api_name in the APIs map.

Returns:
  APIDef, The APIDef for the specified API and version.
z{}/{}N)r   r   r   r   r'   r   VALUESapi_client_overrides	AllValuesr   formatUnknownVersionError)r   api_versionapi_name_aliasversion_overridesversion_overrideapi_versionsr   s          r   	GetApiDefr6   M   s     1:(X\\!

#
#H
-- ''<<FFH '**7>>, 	(,,^TB /K+h',K;

'
'
>>'G	.r   c                 .    [        X5      n[        U5      $ )a  Returns the client class for the API specified in the args.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.

Returns:
  base_api.BaseApiClient, Client class for the specified API.
)r6   _GetClientClassFromDefr   r1   r   s      r   _GetClientClassr:   s   s     h,'		((r   c                     U R                   R                  nUR                  SS5      u  p#[        X#/S9n[	        XC5      $ )zReturns the apitools client class for the API definition specified in args.

Args:
  api_def: apis_map.APIDef, The definition of the API.

Returns:
  base_api.BaseApiClient, Client class for the specified API.
.   fromlist)apitoolsclient_full_classpathrsplit
__import__getattr)r   rA   module_pathclient_class_name
module_objs        r   r8   r8      sC     "**@@#8#?#?Q#G ++0CD*		//r   Fc                   ^^ U(       a  Ub   eOUc  SSK Jn  UR                  [        R                  U(       a  UOSS9nT(       az  [        XT5      (       ai  [        X5      mTTR                  ;  aN  UU4S jn[        R                  " 5       R                  UR                  / U[        R                  R                  S9  [        X5      n	U(       a  U	R                   n
O[#        XU	T5      n
U	" U
SUS9nUb  XKl        [&        R(                  R*                  R,                  R/                  5       nU(       a#  UR1                  S	U5        S
nSUR2                  U'   U$ )a{  Returns an instance of the API client specified in the args.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.
  no_http: bool, True to not create an http object for this client.
  http_client: bring your own http client to use. Incompatible with
    no_http=True.
  check_response_func: error handling callback to give to apitools.
  http_timeout_sec: int, seconds of http timeout to set, defaults if None.
  region: str, Region (or multi-region) for regionalized endpoints (REP).

Returns:
  base_api.BaseApiClient, An instance of the specified API client.
r   )
transportsunset)response_encodingtimeoutc                   > U R                   (       a  [        U R                   S   [        R                  R                  5      (       a  [        U R                   S   R
                  [        R                  R                  5      (       aI  [        R                  " SR                  U TSR                  [        TR                  5      5      5      5      eU e)Nr   zc{}

Note: the region [{}] may not be available for this service. Known available regions are: [{}].z, )args
isinstanceurllib3r   MaxRetryErrorreasonNameResolutionErrorr
   UnavailableRegionErrorr/   joinr"   regional_endpoints)er   regions    r   %_UnavailableRegionDnsExceptionHandlerA_GetClientInstance.<locals>._UnavailableRegionDnsExceptionHandler   s    
 ffQVVAY(:(:(H(HII&&)""G$6$6$J$JL L11>>Dfvtyy0J0J)KL?NO O 'r   )exc_handlerexc_typeF)urlget_credentialshttpkeyzX-Google-Project-Overrideapikey)googlecloudsdk.core.credentialsrI   GetApitoolsTransportr	   ENCODING_ShouldUseRegionalEndpointsr6   rV   core_requestsRequestWrapperWrapRequestsessionr   r   ConnectionErrorr:   BASE_URL_GetEffectiveApiEndpointcheck_response_funcr   r,   coreapi_keyGetAddGlobalParamadditional_http_headers)r   r1   no_httphttp_clientrm   http_timeout_secrX   rI   rY   client_classendpointclient_instancero   headerr   s         `       @r   _GetClientInstancerz      sM   0  ;11#,,$4 ' 2 CK
 -hVLL(0g	w11	1	 	$$&22=((88	 	3 	
 !7,$$H'|V5H !
/ $*='""**..0'""5'2(F6>O++F3	r   c                 j   [        X5      nU[        R                  R                  :X  a  UR                  R
                  nOKU[        R                  R                  :X  a  UR                  R                  nOUR                  R                  nUR                  SS5      u  pV[        XV/S9n[        Xv5      $ )a  Returns the GAPIC client class for the API def specified by the args.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.
  transport_choice: apis_util.GapicTransport, The transport to be used by the
    client.
r<   r=   r>   )r6   r   GapicTransportGRPC_ASYNCIOgapicasync_client_full_classpathRESTrest_client_full_classpathrA   rB   rC   rD   )r   r1   transport_choicer   rA   rE   rF   rG   s           r   _GetGapicClientClassr      s     h,'11>>>#MMEE933888#MMDD#MM??#8#?#?Q#G ++0CD*		//r   c
           
      F  ^ ^^^ UU UU4S jn
/ nT(       a_  [        T TT5      (       aM  SSKJn  [        T T5      nTUR                  ;  a+  UR                  TUR                  S9nUR                  U5        [        T TUS9nU" UU
[        T T5      UUU=(       d    / U-   U	S9$ )aR  Returns an instance of the GAPIC API client specified in the args.

For apitools API clients, the API endpoint override is something like
http://compute.googleapis.com/v1/. For GAPIC API clients, the DEFAULT_ENDPOINT
is something like compute.googleapis.com. To use the same endpoint override
property for both, we use the netloc of the API endpoint override.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.
  credentials: google.auth.credentials.Credentials, the credentials to use.
  address_override_func: function, function to call to override the client
    host. It takes a single argument which is the original host.
  transport_choice: apis_util.GapicTransport, The transport to be used by the
    client.
  attempt_direct_path: bool, True if we want to attempt direct path gRPC where
    possible.
  redact_request_body_reason: str, the reason why the request body must be
    redacted if --log-http is used. If None, the body is not redacted.
  custom_interceptors: list[grpc interceptor], a list of custom interceptors
  to add to the channel.
  region: str, Region (or multi-region) for regionalized endpoints (REP).
  channel_options: dict, optional channel arguments to pass to the underlying
    gRPC channel.

Returns:
  An instance of the specified GAPIC API client.
c                 ^  >  [         R                  R                  R                  T5      R	                  5       nU(       a  [        U5      R                  n T(       a  T" U 5      n Ub  U $ [        TTT5      (       a  [        U T5      $ [        U 5      $ ! [         R
                   a    S n Nqf = fr   )r   r,   api_endpoint_overridesPropertyrp   NoSuchPropertyErrorr   netlocre   _GetRegionalizedEndpointUniversifyAddress)addressendpoint_overrideaddress_override_funcr   r1   rX   s     r   AddressOverride0_GetGapicClientInstance.<locals>.AddressOverride!  s    $++BBKK
CE 
 *+22g%g.g$n #8[&AA%gv66W%%# )) s   7B B,+B,r   )gapic_util_internal)known_available_regions)r   )r   mtls_enabledattempt_direct_pathredact_request_body_reasoncustom_interceptorschannel_options)	re   googlecloudsdk.corer   r6   rV   $UnavailableRegionDnsErrorInterceptorappendr   _MtlsEnabled)r   r1   credentialsr   r   r   r   r   rX   r   r   region_interceptorsr   r   interceptorrv   s   `` `    `       r   _GetGapicClientInstancer      s    P& &2 +Hk6JJ7+.GW///'LL
'*D*D M Fk  -%.>@, 
++6-!;.4"8KK%
 r   c                     [         R                  R                  R                  nUR	                  5       nU b-  UR
                  U:w  a  U R                  UR
                  US5      n U $ )z2Update a URL based on the current universe domain.r=   )r   r,   rn   universe_domainrp   defaultreplace)r   universe_domain_propertyr   s      r   r   r   S  s]    '..33CC,002/&&/9oo6>>-q2G	.r   c                     Uc  [        S5      eU R                  S5      S:  a  [        SU  S35      eU R                  SS5      u  p#U SU SU 3$ )a  Returns regionalized domain.

Regional endpoints (REPs) have the following format:
  {service}.{region}.rep.googleapis.com

Args:
  domain: Domain for the API in form {service}.googleapis.com.
  region: REP region (or multi-region).

Returns:
  str, Regionalized domain.
zRegion must be provided.r<      z@Base URLs should have form {service}.googleapis.com; received: [z].r=   z.rep.)
ValueErrorcountsplit)domainrX   servicebase_domains       r   r   r   ^  sp     ^
/
00\\#
	hb	"# #  c1-'9AfXU;-	00r   c                       \ rS rSrSrSrg)UnsupportedEndpointModeErroriu  zGError when regional/endpoint_mode property is unsupported by a command.r$   N)__name__
__module____qualname____firstlineno____doc____static_attributes__r$   r   r   r   r   u  s    Or   r   c                    [         R                  R                  R                  R	                  5       n[         R                  R                  R
                  R	                  5       nU[         R                  R                  R                  :X  a  Uc  [        SU S35      eU[         R                  R                  R                  :X  a7  U[         R                  R                  R                  :X  a  [        SU S35      eUbS  U[         R                  R                  R                  :X  d+  Uc)  U[         R                  R                  R                  :X  a  g[        X5      R                  nU[         R                  R                  R                  :X  a,  U[         R                  R                  R                  :X  a  X%;   $ X%;  a  [        R                  " SX5        g)a  Returns whether or not regional endpoint should be used.

Depending on the user-specified regional/endpoint_mode setting and the
developer-specified command annotation, this function calculates whether or
not to use regional endpoints. In case of an invalid combination, an error
will be raised. The full matrix is as follows:

+--------------+-------------------------------------------------------------+
|              |                    Command compatibility                    |
|  User mode   +---------------+---------------+-----------------------------+
|              | Only supports | Only supports | Supports both               |
|              | global        | regional      |                             |
+--------------+---------------+---------------+-----------------------------+
| regional     | Error         | Regional      | Regional client             |
|              |               | client        |                             |
+--------------+---------------+---------------+-----------------------------+
| global       | Global client | Error         | Global client               |
+--------------+---------------+---------------+-----------------------------+
| regional-    | Global client | Regional      | If region available:        |
| preferred    |               | client        | Regional client             |
|              |               |               | Otherwise: Global client    |
+--------------+---------------+---------------+-----------------------------+
| (unset)      | Global client | Regional      | Global client               |
|              |               | client        |                             |
+--------------+---------------+---------------+-----------------------------+

Args:
  api_name: str, The API name.
  api_version: str, The version of the API.
  region: The region (or multi-region).
Returns:
  bool, Whether to use regional endpoints.
Raises:
  UnsupportedEndpointModeError: If the command does not support the given
    endpoint mode.
z9The regional/endpoint_mode property is currently set to [z8], but this command does not support regional endpoints.z5], but this command only supports regional endpoints.FzDAPI [%s] does not contain a known regional endpoint for region [%s].T)r   r,   r
   endpoint_moderp   endpoint_compatibilityREGIONALr   GLOBALREQUIRED	SUPPORTEDr6   rV   REGIONAL_PREFERREDr   info)r   r1   rX   modecompatibilityr   s         r   re   re   y  s   J 
			#	#	1	1	5	5	7$##,,CCGGI-	Z''000]5J
&
CD6 J= 	=> > j((///z((11:::
&
CD6 J: 	:; ; 	""++22	2
,z0099CCC  &h<OO
j((;;;
:,,55??
?,, * HHN 
r   c                     [        X5      nUR                  (       a  U=(       d    [        X5      nOU=(       d    [        X5      nUR                  =(       d    UR
                  $ )zReturns mtls endpoint.)r6   r@   r:   r   mtls_endpoint_overrideMTLS_BASE_URL)r   r1   rv   r   s       r   _GetMtlsEndpointr     sK    h,'I?8#ILN#7#NL		'	'	E<+E+EEr   c                    [         R                  R                  R                  R	                  5       (       a  g[         R                  R                  R
                  R	                  5       (       d  g[        X5      nUR                  $ )a  Checks if the API of the given version should use mTLS.

If context_aware/always_use_mtls_endpoint is True, then mTLS will always be
used.

If context_aware/use_client_certificate is True, then mTLS will be used only
if the API version is in the mTLS allowlist.

gcloud maintains a client-side allowlist for the mTLS feature
(go/gcloud-rollout-mtls).

Args:
  api_name: str, The API name.
  api_version: str, The version of the API.

Returns:
  True if the given service and version is in the mTLS allowlist.
TF)r   r,   context_awarealways_use_mtls_endpointGetBooluse_client_certificater6   enable_mtlsr9   s      r   r   r     sb    & $$==EEGG				(	(	?	?	G	G	I	Ih,'			r   c                     [        U5      n[        U 5      nUR                  S:X  d  UR                  S:w  a  U $ [        SR                  UR                  UR
                  5      UR                  5      $ )zFConstructs a normalized endpoint URI depending on the client base_url./z{}://{})r   pathr   r/   schemer   )r   base_urlurl_baseurl_endpoint_overrides       r   _BuildEndpointOverrider     sn    h("#45]]c2773>	,33,3356>mm
E Er   c                 $   [        X5      R                  (       a  [        X5      nO[        X5      n[	        US5      (       a  UR
                  nO [        X5      R
                  n[        U5      $ ! [         a    SR                  X5      n N(f = f)zReturns base url for given api.rk   zhttps://{}.googleapis.com/{})
r6   r@   r:   r   hasattrrk   _GetResourceModuleAttributeErrorr/   r   )r   r1   rv   client_base_urls       r   _GetBaseUrlFromApir     s    x%.."89L'>L\:&&"++O*8AJJo
 
?	++	  6==
os   A1 1BBc                 `    [         R                  R                  R                  U 5      R	                  5       n[        X5      nUR                  (       a  U=(       d    [        X5      nOU=(       d    [        X5      n[        X5      nU(       a  [        XF5      nU$ [        X5      (       a  [        [        XU5      5      nU$ [        XU5      (       a;  [!        U5      n[#        UR$                  U5      n	['        UR)                  U	S95      nU$ UnU$ ! [         R
                   a    Sn Nf = f)z)Returns effective endpoint for given api.N)r   )r   r,   r   r   rp   r   r6   r@   r:   r   r   r   r   r   r   re   r   r   r   r   _replace)
r   r1   rv   rX   r   r   r   r   r   regionalized_domains
             r   rl   rl     s   "))@@II#% 
 h,'I?8#ILN#7#NL&x=/$%6HG 
. H**=G 
. #8&AA(H28??FK**2E*FGG 
. G	.1 
	'	' s   7D D-,D-c                 V    [        X5      n[        UR                  R                  S/S9$ )a  Returns the messages module for the API specified in the args.

Args:
  api_name: str, The API name (or the command surface name, if different).
  api_version: str, The version of the API.

Returns:
  Module containing the definitions of messages for the specified API.
	somethingr>   )r6   rC   r@   messages_full_modulepathr9   s      r   _GetMessagesModuler   0  s2     h,' 
//;-
I Ir   c                     [        X5      nUR                  (       a%  [        UR                  R                  S-   S-   S/S9$ [        UR                  R                  S-   S-   S/S9$ )z/Imports and returns given api resources module.r<   	resourcesr   r>   )r6   r@   rC   
class_pathr~   r9   s      r   r   r   A  sm     h,' ##c)K7;-  
mm${2k]
 r   c              #   6  #     [        X5      nUR                   Hi  n[        R                  " U UUR                  UR
                  UR                  UR                  UR                  UR                  UR                  5	      v   Mk     g! [         a     gf = f7f)z)Yields all collections for for given api.N)r   Collectionsresource_utilCollectionInfork   DOCS_URLcollection_namer   
flat_pathsparamsenable_uri_parsingImportError)r   r1   resources_module
collections       r   _GetApiCollectionsr   Q  s     )(@ '22
((



#
#

#
#

$
$
//







'
'
 
 3 
 		s(   BB	 A:B	
BBBB)FNNNNr   )NN)/r   googlecloudsdk.api_lib.utilr   r   r   r   r   r   r   r   rf   r	   googlecloudsdk.core.utilr
   %googlecloudsdk.generated_clients.apisr   r   six.moves.urllib.parser   r   r   rP   r   r    r%   r*   r6   r:   r8   rz   r|   GRPCr   r   r   r   Errorr   re   r   r   r   r   rl   r   r   r   r$   r   r   <module>r      s   2 A * # * 9 ) - :  
 * + - I
%
"&#L)0"  %#'+/(,"Nf +4*B*B*G*G08 --22#Wt1.P:#3#3 PNbF:E,( 6:BI" r   