
    O                     D   S 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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Jr  SSKr\R8                  " S5      r\R8                  " S\R<                  5      rSr \ S-   r!\ S-   r"Sr#Sr$/ SQr%S r&S r'S r(S r)S r*S r+S7S jr,S  r-S! r.S" r/S# r0S$ r1S% r2S& r3S' r4S( r5 S8S) jr6S* r7 S9S+ jr8 S:S, jr9S- r:S:S. jr;S/ r<S0 r=S:S1 jr>S:S2 jr?S:S3 jr@S4 rAS5 rBS:S6 jrCg);z6Common helper methods for Service Management commands.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)
list_pager)apis)log)
properties)	resources)yaml)resource_printer)files)retryz^.+@([^.@][^@]+)$z)^([a-f0-9][a-f0-9]:){19}[a-f0-9][a-f0-9]$zgcloud endpoints operations zdescribe {0}zwait {0}zservicemanagement.servicesz"servicemanagement.services.configs)
zservicemanagement.services.getz-servicemanagement.services.getProjectSettingsz!servicemanagement.services.deletez!servicemanagement.services.updatezservicemanagement.services.bindz0servicemanagement.services.updateProjectSettingsz servicemanagement.services.checkz!servicemanagement.services.reportz'servicemanagement.services.setIamPolicyz'servicemanagement.services.getIamPolicyc                  0    [         R                  " SS5      $ Nservicemanagementv1)r	   GetMessagesModule     5lib/googlecloudsdk/api_lib/endpoints/services_util.pyr   r   A       			 3T	::r   c                  0    [         R                  " SS5      $ r   )r	   GetClientInstancer   r   r   r   r   E   r   r   c                      g)Nz servicemanagement.googleapis.comr   r   r   r   GetServiceManagementServiceNamer   I   s    	+r   c                     U (       a5  [         R                  R                  R                  R	                  U 5        U $ [         R                  R                  R                  R                  SS9n U $ )zValidate the project ID, if supplied, otherwise return the default project.

Args:
  project_id: The ID of the project to validate. If None, gcloud's default
              project's ID will be returned.

Returns:
  The validated project ID.
T)required)r   VALUEScoreprojectValidateGet
project_ids    r   GetValidatedProjectr'   M   s\     ""++J7 
 ""''//33T3BJ	r   c                     [        5       R                  nU" U UUS9n[        5       R                  R	                  U5      $ )aL  Returns the project settings for a given service, project, and view.

Args:
  service: The service for which to return project settings.
  consumer_project_id: The consumer project id for which to return settings.
  view: The view (CONSUMER_VIEW or PRODUCER_VIEW).

Returns:
  A ProjectSettings message with the settings populated.
)serviceNameconsumerProjectIdview)r   2ServicemanagementServicesProjectSettingsGetRequestr   services_projectSettingsr$   )serviceconsumer_project_idr+   get_requestrequests        r   GetProjectSettingsr2   ^   sF     #$DD 
 +' 
		5	5	9	9'	BBr   c                 0    [        5       R                  U S9$ )N)producerProjectId)r   $ServicemanagementServicesListRequestr%   s    r   GetProducedListRequestr6   x   s!    			A	A" 
B 
 r   c                 N    [         R                  " U /U[        R                  S9  g)zPrints the given resource.

Args:
  resource: The resource to print out.
  print_format: The print_format value to pass along to the resource_printer.
)r   print_formatoutN)r   Printr
   r9   )resourcer8   s     r   PrettyPrintr<   ~   s!     

''r   c                     [        5       nUR                  R                  nXR                  UR                  UR
                  4;   a$  [        R                  " U 5      R                  5       $ g)zConvert a ConfigChange.ChangeType enum to a string.

Args:
  change_type: The ConfigChange.ChangeType enum to convert.

Returns:
  An easily readable string representing the ConfigChange.ChangeType enum.
z	[unknown])	r   ConfigChangeChangeTypeValueValuesEnumADDEDREMOVEDMODIFIEDsix	text_typelower)change_typemessagesenumss      r   PushAdvisorChangeTypeToStringrI      sQ      (



9
9%[[%--@@==%++--r   c                     SR                  U R                  U R                  U R                  [	        U R
                  5      S9nU R                   H!  nUSR                  UR                  5      -  nM#     U$ )zConvert a ConfigChange message to a printable string.

Args:
  config_change: The ConfigChange message to convert.

Returns:
  An easily readable string representing the ConfigChange message.
zbElement [{element}] (old value = {old_value}, new value = {new_value}) was {change_type}. Advice:
)element	old_value	new_valuerF   z	* {0})formatrK   oldValuenewValuerI   
changeTypeadvicesdescription)config_changeresultadvices      r   PushAdvisorConfigChangeToStringrW      s    DEKV%--'00'009!,,.	 FL F/ 	 %%f
iv1122F & 
-r   c                 "  ^ [        5       n[        5       nUR                  R                  nUR                  UR
                  /mUR                  U S9n[        [        R                  " UR                  UU4S jSSSS95      nU(       a  US   $ S$ )	a.  Return the latest Rollout for a service.

This function returns the most recent Rollout that has a status of SUCCESS
or IN_PROGRESS.

Args:
  service: The name of the service for which to retrieve the active Rollout.

Returns:
  The Rollout message corresponding to the active Rollout for the service.
r)   c                 "   > U R                   T;   $ N)status)rallowed_statusess    r   <lambda>,GetActiveRolloutForService.<locals>.<lambda>   s    ahh*::r      pageSizerollouts)	predicatelimitbatch_size_attributefieldr   N)r   r   RolloutStatusValueValuesEnumSUCCESSIN_PROGRESS,ServicemanagementServicesRolloutsListRequestlistr   YieldFromListservices_rollouts)r.   clientrG   statusesreqrU   r^   s         @r   GetActiveRolloutForServicers      s     & (33(&&(<(<=== 	> 	# 

"
"
:)	& &$&r   c                     U (       aK  U R                   (       a:  U R                   R                  R                   Vs/ s H  oR                  PM     sn$ / $ s  snf )zGet the active service config IDs from a Rollout message.

Args:
  rollout: The rollout message to inspect.

Returns:
  A list of active service config IDs as indicated in the rollout message.
)trafficPercentStrategypercentagesadditionalPropertieskey)rolloutps     r   $GetActiveServiceConfigIdsFromRolloutr{      sU     //"99EE!!" # "aEE " # # I#s   Ac                 .    [        U 5      n[        U5      $ r[   )rs   r{   )r.   active_rollouts     r   #GetActiveServiceConfigIdsForServicer~      s    -g6.	-n	==r   c                     U R                  5       nU H)  nUR                  UR                  5       5      (       d  M)    g   g)zChecks to see if a file name matches one of the given extensions.

Args:
  filename: The full path to the file to check
  extensions: A list of candidate extensions.

Returns:
  True if the filename matches one of the extensions, otherwise False.
TF)rE   endswith)filename
extensionsfexts       r   FilenameMatchesExtensionr      s7     nn!czz#))+  
r   c                     [        U / SQ5      $ )N)z.pbz.descriptorz
.proto.binr   r   s    r   IsProtoDescriptorr      s    	!4
6 6r   c                     [        U S/5      $ )Nz.protor   r   s    r   
IsRawProtor      s    	!(XJ	77r   c                      [        U 5      (       a  [        R                  " U 5      $ [        R                  " U 5      $ ! [        R                   a*  n[
        R                  " SR                  X5      5      eS nAff = f)Nz-Could not open service config file [{0}]: {1})r   r   ReadBinaryFileContentsReadFileContentsErrorcalliope_exceptionsBadFileExceptionrN   )	file_pathexs     r   ReadServiceConfigFiler     sn    O##)))44!!),,	 O

.
.7>>yMO OOs   %> > A<%A77A<c                     [        5       n[        5       n[        R                  " X$R                  5      nXl        X6l        UR                  U US9nUR                  R                  U5      $ )a?  Pushes a given normalized Google service configuration.

Args:
  service_name: name of the service
  project: the producer project Id
  config_dict: the parsed contents of the Google Service Config file.
  config_id: The id name for the config

Returns:
  Result of the ServicesConfigsCreate request (a Service object)
)r)   r.   )
r   r   r   DictToMessageServicer4   id-ServicemanagementServicesConfigsCreateRequestservices_configsCreate)service_namer"   config_dict	config_idrG   rp   service_configcreate_requests           r   !PushNormalizedGoogleServiceConfigr     so      (& ))+7G7GH.%,"<<"  =  
 
	 	 	'	'	77r   c                 D    U R                  S0 5      R                  S5      $ )NserviceConfigr   )get)responses    r   0GetServiceConfigIdFromSubmitConfigSourceResponser   +  s    	or	*	.	.t	44r   c                    [        5       n[        5       nUR                  US9nUR                  R	                  U5        UR                  UUS9nUR                  U US9n	UR                  R                  U	5      n
[        X5      nUR                  S0 5      nUR                  S/ 5      nSnU H  nUR                  SS5      R                  5       nUS	:X  a  [        R                  O[        R                  nS
R                  UR                  S5      UR                  S5      S9nU" U5        US	:X  d  M  US-  nM     US:  a/  SR                  XS:  a  SOS5      n[         R"                  " U5      eU$ )a  Pushes a given set of service configuration files.

Args:
  service_name: name of the service.
  config_files: a list of ConfigFile message objects.
  is_async: whether to wait for aync operations or not.
  validate_only: whether to perform a validate-only run of the operation
                   or not.
  config_id: an optional name for the config

Returns:
  Full response from the SubmitConfigSource request.

Raises:
  ServiceDeployErrorException: the SubmitConfigSource API call returned a
    diagnostic with a level of ERROR.
)r   )configSourcevalidateOnly)r)   submitConfigSourceRequestr   diagnosticsr   kind ERRORz	{l}: {m}
locationmessage)lmra   zW{0} diagnostic error{1} found in service configuration deployment. See log for details.s)r   r   ConfigSourcer   extendSubmitConfigSourceRequest-ServicemanagementServicesConfigsSubmitRequestr   SubmitProcessOperationResultr   upperr
   errorwarningrN   r   ServiceDeployErrorException)r   config_filesis_asyncvalidate_onlyr   rG   rp   config_sourceconfig_source_requestsubmit_requestapi_response	operationr   r   
num_errors
diagnosticr   loggermsgexception_msgs                       r   PushMultipleServiceConfigFilesr   /  s{   &  (&''9'5-\*"<<   = 
 <<"$9 =  
 ((//?,$\<)]]:r*(]B/+*j>>&"%++-D'/SYYs{{F



..
$
y(A  CC
3KwAoj   !^89?#NS:D  
0
0
??	/r   c                     [        5       nUR                  UUUR                  R                  R                  S9n[	        X/UUS9$ )a  Pushes a given Open API service configuration.

Args:
  service_name: name of the service
  spec_file_contents: the contents of the Open API spec file.
  spec_file_path: the path of the Open API spec file.
  is_async: whether to wait for aync operations or not.
  validate_only: whether to perform a validate-only run of the operation
                 or not.

Returns:
  Full response from the SubmitConfigSource request.
)fileContentsfilePathfileType)r   )r   
ConfigFileFileTypeValueValuesEnumOPEN_API_YAMLr   )r   spec_file_contentsspec_file_pathr   r   rG   config_files          r   PushOpenApiServiceConfigr   k  sT       (##%##'' $ + 
(mX6C
E Er   c                     [        5       n[        5       nUR                  U S9n UR                  R	                  U5        g! [
        R                  [
        R                  4 a     gf = f)zCheck if a service resource exists.

Args:
  service_name: name of the service to check if exists.

Returns:
  Whether or not the service exists.
rY   TF)r   r   #ServicemanagementServicesGetRequestservicesr$   apitools_exceptionsHttpForbiddenErrorHttpNotFoundError)r   rG   rp   r0   s       r   DoesServiceExistr     sr      (&<< = +
OO$  
0
0

/
/
1  	s   A $A('A(c                     [        5       n[        5       nUR                  U US9nUR                  R	                  U5      n[        XbS9  g)zCreates a Service resource.

Args:
  service_name: name of the service to be created.
  project: the project Id
  is_async: If False, the method will block until the operation completes.
)r)   r4   )r   N)r   r   ManagedServicer   r   GetProcessedOperationResult)r   r"   r   rG   rp   r   rU   s          r   CreateServicer     sM      (&** + . ??!!.1&f8r   c                 <    [         R                  " [        U 5      S L$ r[   )rematchFINGERPRINT_REGEX)fingerprints    r   ValidateFingerprintr     s    	#[	1	==r   c                 l    [         R                  U =(       d    S5      SL=(       a    [        U 5      S:*  $ )a  Returns true if the input is a valid email string.

This method uses a somewhat rudimentary regular expression to determine
input validity, but it should suffice for basic sanity checking.

It also verifies that the email string is no longer than 254 characters,
since that is the specified maximum length.

Args:
  email: The email string to validate

Returns:
  A bool -- True if the input is valid, False otherwise
r   N   )EMAIL_REGEXr   len)emails    r   ValidateEmailStringr     s,     
		5;B	't	3	IE
c8IIr   c                 v   [        X5      nU(       aT  [        R                  UR                  S5      5      n[        R
                  R                  SR                  U5      5        U$ [        R                  UR                  S5      5      n[        R
                  R                  SR                  U5      5        U$ )a  Validate and process Operation outcome for user display.

Args:
  result: The message to process (expected to be of type Operation)'
  is_async: If False, the method will block until the operation completes.

Returns:
  The processed Operation message in Python dict form
namezdAsynchronous operation is in progress... Use the following command to wait for its completion:
 {0}
z`Operation finished successfully. The following command can describe the Operation details:
 {0}
)r   OP_WAIT_CMDrN   r   r
   r\   r:   OP_DESCRIBE_CMD)rU   r   opcmds       r   r   r     s     #64"


RVVF^
,CJJ ++16#;8 
)	 
 
 
0CJJ 66<fSkC 
)r   c                    U (       d  g[        5       n[        XR                  5        [        R                  " U 5      nU(       dy  US   n[
        R                  R                  USS9n[        R                  R                  SR                  U5      5        [        R                  " [        U[        5       5      5      nU$ )a  Validate and process Operation result message for user display.

This method checks to make sure the result is of type Operation and
converts the StartTime field from a UTC timestamp to a local datetime
string.

Args:
  result: The message to process (expected to be of type Operation)'
  is_async: If False, the method will block until the operation completes.

Returns:
  The processed message in Python dict form
Nr   zservicemanagement.operations)
collectionz.Waiting for async operation {0} to complete...)r   RaiseIfResultNotTypeOf	Operationr   MessageToDictr   REGISTRYParser
   r\   r:   rN   WaitForOperationr   )rU   r   rG   result_dictop_nameop_refs         r   r   r     s     

 (!3!34&&v.+	&!G%%1 & 3F JJ8??HJ(()9!#*% &K 
r   c                 V    U(       a  U c  g [        X5      (       d  [        SU-  5      eg )Nzresult must be of type %s)
isinstance	TypeError)test_objectexpected_typenonetype_oks      r   r   r     s.    [(
	K	/	/
/-?
@@ 
0r   c                   ^^ S[         l        [        5       mU R                  nUU4S jn [        R
                  " SSSS9R                  X2/SSS	9  [         R                  R                  b%  [        R                  " SR                  U5      5      e[         R                  $ ! [        R                   a&    [        R                  " S
R                  U5      5      ef = f)a  Waits for an operation to complete.

Args:
  operation_ref: A reference to the operation on which to wait.
  client: The client object that contains the GetOperation request object.

Raises:
  TimeoutError: if the operation does not complete in time.
  OperationErrorException: if the operation fails.

Returns:
  The Operation object, if successful. Raises an exception on failure.
Nc                    > TR                  U S9nTR                  R                  U5      nUR                  (       a  U[        l        gg)N)operationsIdTF)%ServicemanagementOperationsGetRequest
operationsr$   doner   operation_response)operation_idr1   rU   rp   rG   s      r   _CheckOperation)WaitForOperation.<locals>._CheckOperation   sI    <<! = G ""7+F{{,2)r   g?i'  i@w )exponential_sleep_multiplierwait_ceiling_msmax_wait_msFi  )should_retry_ifsleep_mszTTimed out while waiting for operation {0}. Note that the operation is still pending.z0The operation with ID {0} resulted in a failure.)r   r  r   r  r   RetryerRetryOnResultMaxRetrialsExceptionr   TimeoutErrorrN   r   OperationErrorException)operation_refrp   r  r  rG   s    `  @r   r   r     s     )-% (++,L	MMsE(**7-%~u# +8 +% ((..:

,
,:AA,OQ Q
 
	,	,, 
	#	# L

!
! #66<f\6JL LLs   &B" ":Cc                 F   ^  U 4S jnU 4S jnU" 5       =(       d    U" 5       $ )zTries to load input string as JSON first, then YAML if that fails.

Args:
  input_string: The string to convert to a dictionary

Returns:
  A dictionary of the resulting decoding, or None if neither format could be
  detected.
c                  ~   >  [         R                  " T 5      $ ! [         a    [        R                  " S5         g f = f)Nz2No JSON detected in service config. Trying YAML...)jsonloads
ValueErrorr
   info)input_strings   r   TryJsonLoadJsonOrYaml.<locals>.TryJsonL  s6    EZZ%% E	hhCDEs     <<c                  R  >  [         R                  " T5      $ ! [         R                   ay  n [        U R                  S5      (       aT  U R                  R
                  n[        R                  " SUR                  S-   < SUR                  S-   < S35         S n A g  S n A g S n A ff = f)Nproblem_markz.Service config YAML had an error at position (ra   :))
r   loadYAMLParseErrorhasattrinner_errorr$  r
   r   linecolumn)emarkr   s     r   TryYamlLoadJsonOrYaml.<locals>.TryYamlR  s}    2YY|$$ 2		/	/}}))		YYq[$++a-1 	2 	2 
02s    B&A*B!!B&r   )r   r!  r/  s   `  r   LoadJsonOrYamlr1  B  s    E2 
	gir   c                    [        5       n[        5       nUR                  R                  5       nUR                  R                  UR                  R                  R                  U SS95        UR                  US9nUR                  UUS9nUR                  UUS9nUR                  R                  U5      n	[        X5      n
U
R                  SS5      $ )a)  Creates a Rollout for a Service Config within it's service.

Args:
  service_config_id: The service config id
  service_name: The name of the service
  is_async: (Optional) Wheter or not operation should be asynchronous

Returns:
  The rollout object or long running operation if is_async is true
g      Y@)rx   value)rv   )r)   ru   )ry   r)   r   N)r   r   TrafficPercentStrategyPercentagesValuerw   appendAdditionalPropertyrh   .ServicemanagementServicesRolloutsCreateRequestro   r   r   r   )service_config_idr   r   rG   rp   rv   traffic_percent_strategyry   rollout_createrollout_operationr   s              r   CreateRolloutr=  _  s      (&//@@B+""))&&77JJu K .0 &<< = 5  8' JJ K . ..55nE/:"	
D	!!r   )r  r[   )FN)F)D__doc__
__future__r   r   r   r  r   apitools.base.pyr   r   r   r    googlecloudsdk.api_lib.endpointsgooglecloudsdk.api_lib.utilr	   googlecloudsdk.callioper   googlecloudsdk.corer
   r   r   r   googlecloudsdk.core.resourcer   googlecloudsdk.core.utilr   r   rC   compiler   
IGNORECASEr   OP_BASE_CMDr   r   SERVICES_COLLECTIONCONFIG_COLLECTIONALL_IAM_PERMISSIONSr   r   r   r'   r2   r6   r<   rI   rW   rs   r{   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r1  r=  r   r   r   <module>rM     sJ    = &  '  	 % > ' 7 , E # * ) $ 9 * * 
 jj-.JJ0"--A ,.J&2 8  ;;,"C4
".'D >
"6
8O 158:5
 CG9| E:29(>J$0!HA1-h :"r   