
    oF                     "   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mZ ddl	m
Z
 ddlmZ d	Zd
dddZdddZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd  Zd! Z d" Z!d# Z"d$ Z#d% Z$d& Z%d' Z&d( Z'd) Z(d* Z)d+ Z*d, Z+y)-zResource parsing helpers.    )absolute_import)division)unicode_literalsN)Any)
exceptions)parsersi  DATAPROC_METASTOREDATAPLEXBIGQUERY)dpmsdataplexbigqueryserviceslakes)r   r   c                 d    | dk  s| dkD  r%t        j                  ddj                  |             | S )zKPython hook to validate that the port is between 1024 and 65535, inclusive.i   i  z--portz-Port ({0}) is not in the range [1025, 65535].r   BadArgumentExceptionformat)ports    6lib/googlecloudsdk/command_lib/metastore/validators.pyValidatePortr   '   s:    	D[D5L

)
)AHHN  
+    c                     t        | d      S )z+Python hook to validate the scaling factor.z--scaling-factorValidateScalingFactorFloatscaling_factors    r   ValidateScalingFactorr   0   s    	#N4F	GGr   c                     t        | d      S )z/Python hook to validate the min scaling factor.z--min-scaling-factorr   r   s    r   ValidateMinScalingFactorr    5       	#N4J	KKr   c                     t        | d      S )z/Python hook to validate the max scaling factor.z--max-scaling-factorr   r   s    r   ValidateMaxScalingFactorr#   :   r!   r   c                 2   | dk  s| dkD  r%t        j                  |dj                  |             | dk  r0| dz  dz  dk7  r%t        j                  |dj                  |             | dk\  r-| dz  dk7  r%t        j                  |d	j                  |             | S )
z(Validate the scaling factor float value.g?   z4Scaling factor ({0}) is not in the range [0.1, 6.0].   
   r   zUScaling factor less than 1.0 ({0}) should be a multiple of 0.1 (e.g. (0.1, 0.2, 0.3))g      ?zQScaling greater than 1.0 ({0}) should be a multiple of 1.0 (e.g. (1.0, 2.0, 3.0))r   )r   	flag_names     r   r   r   ?   s    c^a/

)
)>EE	
  nr1A5:

)
)	228&2H 
 ~3q8

)
)	))/)? 
 
r   c                       fd}|S )z-Validates the gcs uri is formatted correctly.c                 t    | j                  d      s%t        j                  dj                  |             | S )Nzgs://z'Expected URI {0} to start with `gs://`.)
startswithr   r   r   )gcs_uriarg_names    r   ProcesszValidateGcsUri.<locals>.ProcessZ   s<    g&++
=DDWM  Nr    r-   r.   s   ` r   ValidateGcsUrir1   W   s     
.r   c                     t        j                  d      }|j                  |       s&t        j                  ddj                  | |            | S )Nz^(.+)/(.+)@(.+)$--kerberos-principalz0Kerberos Principal {0} does not match ReGeX {1}.)recompilematchr   r   r   )kerberos_principalpatterns     r   ValidateKerberosPrincipalr9   d   sO    JJ*+'	)	*

)
):AA	
  
r   c                 d    | dk  s| dkD  r%t        j                  ddj                  |             | S )z:Validates that the hour falls between 0 and 23, inclusive.r      z --maintenance-window-hour-of-dayz$Hour of day ({0}) is not in [0, 23].r   )hours    r   ValidateHourOfDayr=   p   s:    	AX

)
)*.55d;  
+r   c                 |    t        |       t        kD  r)t        j                  | dj	                  t                    | S )z\Validates that the string field is not longer than STRING_MAX_LENGTH, to avoid abuse issues.z7The string field can not be longer than {0} characters.)lenSTRING_MAX_LENGTHr   r   r   )r-   s    r   ValidateStringFieldrA   z   s=    ]&&

)
)AHH	
  
/r   c                 ~    t        j                  d      }|j                  |       st        j                  dd      | S )aA  Validates the connection name of a CloudSQL instance, must be in the form '{project_id}:{region}:{instance_id}'.

  Args:
    connection_name: The CloudSQL instance connection name string.

  Returns:
    The connection name string.
  Raises:
    BadArgumentException: when the input string does not match the pattern.
  z^([^:]+:){2}[^:]+$z--instance-connection-namezRThe instance connection name should be in the format project_id:region:instance_idr4   r5   r6   r   r   )connection_namer8   s     r   &ValidateCloudSqlInstanceConnectionNamerE      sB     JJ,-'		'

)
)$	) 
 
r   c                       fd}|S )z{Validates the resource name of a compute network, must be in the form 'projects/{project_id}/global/networks/{network_id}'.c                     t        j                  d      }|j                  |       st        j                  d      | S )Nz&^projects/[^/]+/global/networks/[^/]+$zdThe network resource name should be in the format projects/<project_id>/global/networks/<network_id>rC   resource_namer8   r-   s     r   r.   z,ValidateNetworkResourceName.<locals>.Process   sB    jjBCG=='++
@ 
 r   r/   r0   s   ` r   ValidateNetworkResourceNamerJ           
.r   c                       fd}|S )zValidates the resource name of a compute subnetwork, must be in the form 'projects/{project_id}/regions/{region_id}/subnetworks/{subnetwork_id}'.c                     t        j                  d      }|j                  |       st        j                  d      | S )Nz0^projects/[^/]+/regions/[^/]+/subnetworks/[^/]+$zzThe subnetwork resource name should be in the format projects/{project_id}/regions/{region_id}/subnetworks/{subnetwork_id}rC   rH   s     r   r.   z/ValidateSubnetworkResourceName.<locals>.Process   sB    jjLMG=='++
S 
 r   r/   r0   s   ` r   ValidateSubnetworkResourceNamerN      rK   r   c                     t        j                  d      }|j                  |       st        j                  dd      t        |       dkD  rt        j                  dd      | S )zValidates the hive database name.

  Args:
    db_name: the hive database name.

  Returns:
    the hive database name.
  Raises:
    BadArgumentException: when the database name doesn't conform to the pattern
    or is longer than 64 characters.
  z^[0-9a-zA-Z$_-]+$z--hive-database-namezhive database name must start with an alphanumeric character, and contain only the following characters: letters, numbers, dashes (-), and underscores (_).@   z3hive database name must be less than 64 characters.)r4   r5   r6   r   r   r?   )db_namer8   s     r   ValidateHiveDatabaseNamerR      sh     JJ+,'	w	

)
)	   	\B

)
)=  
.r   c                 x    	 t        j                  |        | S # t        $ r t        j                  dd      w xY w)zValidates the Cloud SQL IP address.

  Args:
    ip_address: the Cloud SQL IP address.

  Returns:
    the IP address.
  Raises:
    BadArgumentException: when the IP address is invalid.
  z--ip-addresszInvalid IP address.)	ipaddressIPv4Address
ValueErrorr   r   )
ip_addresss    r   ValidateCloudSqlIpAddressrX      sC    *%	 

)
) s     9c                     d }	  ||       st        j                  dd      	 | S # t        $ r t        j                  dd      w xY w)zValidates the subnet IP range.

  Args:
    cidr: the CIDR range for the subnet.

  Returns:
    the CIDR range.
  Raises:
    BadArgumentException: when the CIDR range is invalid.
  c                     g d}dg}dg}g d}dg}dg}||z   |z   |z   |z   |z   }t        j                  |       }|D ](  }	|j                  t        j                  |	            s( y y)	zMChecks if a given CIDR block is contained within a list of valid CIDR ranges.)z
10.0.0.0/8z172.16.0.0/12z192.168.0.0/16z100.64.0.0/10z192.0.0.0/24)z192.0.2.0/24z198.51.100.0/24z203.0.113.0/24z192.88.99.0/24z198.18.0.0/15TF)rT   IPv4Network	subnet_of)
cidrrfc_1918_spacesrfc_6598_spacesrfc_6890_spacesrfc_5737_spacesrfc_7526_spacesrfc_2544_spacesvalid_cidr_ranges
cidr_blockvalid_ranges
             r   IsCidrWithinValidRangesz6ValidateSubnetIpRange.<locals>.IsCidrWithinValidRanges   s     HO&'O%&OKO'(O&'O 	
	
	 	 		
 	  &&t,J(			i33K@	A ) r   z--subnet-ip-rangez]The subnet IP range is invalid, see https://cloud.google.com/vpc/docs/subnets.md#valid-rangeszInvalid CIDR address block.)r   r   rV   )r]   rg   s     r   ValidateSubnetIpRangerh      sf    2"4(++
G  ) 
+ 
 

)
)% s	   &  Ac                 ~    t        j                  d      }|j                  |       st        j                  dd      | S )a;  Validates the Cloud Storage bucket name used for CDC during migration, should not start with 'gs://'.

  Args:
    bucket_name: the Cloud Storage bucket name.

  Returns:
    the Cloud Storage bucket name.
  Raises:
    BadArgumentException: when the Cloud Storage bucket name doesn't conform to
    the pattern.
  z^(?!gs://)([a-z0-9\._-]+)$z--bucketzInvalid bucket namerC   )bucket_namer8   s     r   ValidateMigrationBucketNamerk   #  s@     JJ45'	{	#

)
)  
r   c                 ~    t        j                  d      }|j                  |       st        j                  dd      | S )a3  Validates the root path inside the Cloud Storage bucket used for CDC during migration, must start with a forward slash ('/') character.

  Args:
    root_path: the root path inside the Cloud Storage bucket.

  Returns:
    the root path.
  Raises:
    BadArgumentException: when the root path is invalid.
  z^/([^\n\r]*)$z--root-pathzInvalid root pathrC   )	root_pathr8   s     r   ValidateMigrationRootPathrn   9  s@     JJ'('	y	!

)
)  
r   c                     t        | ||      S )a^  Validates that the mutual exclusive configurations of Dataproc Metastore service are not set at the same time.

  Args:
    req: A request with `service` field.

  Returns:
    A request without service mutex configuration conflicts.
  Raises:
    BadArgumentException: when mutual exclusive configurations of service are
    set at the same time.
  )ValidateServiceMutexConfigForV1
unused_refunused_argsreqs      r   ValidateServiceMutexConfigru   N  s     
)[#	FFr   c                    |j                   j                  ru|j                   j                  j                  rU|j                   j                  j                  j                  r+t	        |j                         rt        j                  dd      |S )ax  Validates exclusively for V1 fields that the mutual exclusive configurations of Dataproc Metastore service are not set at the same time.

  Args:
    req: A request with `service` field.

  Returns:
    A request without service mutex configuration conflicts.
  Raises:
    BadArgumentException: when mutual exclusive configurations of service are
    set at the same time.
  r3   zoKerberos configuration cannot be used in conjunction with --network-config-from-file or --consumer-subnetworks.)servicehiveMetastoreConfigkerberosConfig	principal _IsNetworkConfigPresentInServicer   r   rq   s      r   rp   rp   ]  sl     
kk%%
++
)
)
8
8
++
)
)
8
8
B
B
*3;;
7

)
)	A 
 
*r   c                     t        |j                               }|j                  j                  j                  rd|vrt        j                  dd      |j                  j                  j                  rd|vrt        j                  dd      |S )a  Validates that the cron_schedule and backup_location are set when the scheduled backup is enabled.

  Args:
    unused_ref: A resource ref to the parsed metastore service resource.
    args: The parsed args namespace from CLI.
    req: A request with `service` field.

  Returns:
    A request with service scheduled backups configurations required.
  Raises:
    BadArgumentException: when cron_schedule and backup_location are not set
    when the scheduled backup is enabled.
  z--scheduled-backup-cronzI--scheduled-backup-cron must be set when the scheduled backup is enabled.z--scheduled-backup-locationzM--scheduled-backup-location must be set when the scheduled backup is enabled.)setGetSpecifiedArgNamesrw   scheduledBackupenabledr   r   )rr   argsrt   args_sets       r   ValidateScheduledBackupConfigsr   w  s     **,-(	kk!!))
#8
3

)
)!	  
kk!!))
'x
7

)
)%	 
 
*r   c                 J    | j                   xr | j                   j                  S N)networkConfig	consumers)rw   s    r   r{   r{     s    				B7#8#8#B#BBr   c                 t    t        |j                               }d|v rd|vrt        j                  dd      |S )a  Validate if users run update federation command with --clear-backends arg only.

  Args:
    unused_ref: A resource ref to the parsed Federation resource.
    args: The parsed args namespace from CLI.
    update_federation_req: The request for the API call.

  Returns:
    String request
  Raises:
    BadArgumentException: When users run update federation command with
    --clear-backends arg only.
  z--clear-backendsz--update-backendsz4--clear-backends must be used with --update-backends)r}   r~   r   r   )rr   r   update_federation_reqr   s       r   ValidateClearBackendsr     sH     **,-(8#(;8(K

)
)>  
r   c                 @    | j                         rt        |       dk\  S y)Nr   F)isdigitint)strings    r   _IsZeroOrPositiveNumberr     s    ^^v;!	r   c                 N    dj                  d | j                         D              S )N|c              3   &   K   | ]	  \  }}|  y wr   r/   ).0keyvalues      r   	<genexpr>z,_GetMetastoreTypeFromDict.<locals>.<genexpr>  s     =*<JC%*<s   )joinitems)
dictionarys    r   _GetMetastoreTypeFromDictr     s     	=**:*:*<=	==r   c                 @   | d   j                         dk(  rd}ndt        t              z   dz   }d| d   v r4t        j                  || d         r| d   S t        j                  dd	      | d   j                         dk(  rd
| d   z   S dt        | d      z   dz   | d   z   S )zValidate and process the format of short and long names for backends.

  Args:
    metastore_type_and_name: Metastore type and name.

  Returns:
    String backend name.

  Raises:
    BadArgumentException: When the input backend(s) are invalid
  r   r   z^projects\/.*[^\/]z)^projects\/.*[^\/]\/locations\/.[^\/]*\/(z)\/.[^\/]*$/r&   
--backendsInvalid backends formatz	projects/z{0}/)lowerr   METASTORE_RESOURCE_PATH_DICTr4   searchr   r   )metastore_type_and_namelong_name_regexs     r    _GenerateShortOrLongBackendNamesr     s     Q%%':5+O 	5
#$@
A	B
	 
 	#A&&	yy"9!"<=$Q''++
1  q!'')Z721555 ()@)CDE $A&'r   c                 h   i }| st        j                  dd      | j                  d      }|D ]   }|j                  d      }t        |      dk7  rt        j                  dd      |d   }t	        |      st        j                  dd      |d	   }|j                  d
      }t        |      dk7  rt        j                  dd      ||v rt        j                  dd      |d   t
        j                         vrt        j                  dd      t        |      }|t
        |d      d}	|	||<    |S )a  Validate backends argument if it has correct format, metastore type and the keys are positive number and not duplicated.

  In addition, parsing the backends to backend metastore dict

  Args:
    backends: A string is passed by user in format
      <key>=<metastore_type>:<name>,... For example:
      1=dpms:dpms1,2=dataplex:lake1

  Returns:
    Backend metastore dict
  Raises:
    BadArgumentException: When the input backends is invalid or duplicated keys
  r   zCannot be empty,=   r   r   z8Invalid backends format or key of backend is less than 0r&   :zDuplicated keys of backendszInvalid backends type)namemetastoreType)r   r   splitr?   r   METASTORE_TYPE_DICTkeysr   )
backendsbackend_dictbackenddatarank_and_metastorer   r   r   generated_namebackend_metastores_dicts
             r   &ValidateBackendsAndReturnMetastoreDictr     sl    ,	

)
),8I
JJNN3'dC
!#++
1  Q
C"3'++

D  q!E#kk#.
"#q(++
1  l++
5  q!)<)A)A)CC++
/  66MNN,-DQ-GH 0L? @ 
r   c                     |j                   j                  j                  D ]R  }|j                  j                  j                  | j                         j                               |j                  _        T |S )zGenerate the long backend name of Dataproc Metastore federation requests.

  Args:
    job_ref: A resource ref to the parsed Federation resource.
    request: The request for the API call.

  Returns:
    Modified request for the API call.
  )
federationbackendMetastoresadditionalPropertiesr   r   r   ParentRelativeName)job_refrequestprops      r   ParseBackendsIntoRequestr   !  sT       22GGdjjoo,,W^^-=-J-J-LMDJJO H	.r   c                     |j                   j                   |j                   j                  j                  |S |j                   j                  j                  D ]  }t        j                  |        |S )a  Validates that the kms keys are valid.

  Args:
    req: A request with `service` field.

  Returns:
    The unchaged request.
  Raises:
      InvalidResourceException: If the line is invalid.
      RequiredFieldOmittedException: If resource is underspecified.
      UnknownCollectionException: If no collection is provided or can be
          inferred.
      WrongResourceCollectionException: If the provided URL points into a
          collection other than the one specified.
  )rw   encryptionConfigkmsKeysr   ParseCloudKmsKey)rr   rs   rt   kms_keys       r   ValidateKmsKeysr   1  s\    " 
kk""*	kk""**2J--55gW% 6	*r   ),__doc__
__future__r   r   r   rT   r4   typingr   googlecloudsdk.callioper   $googlecloudsdk.command_lib.metastorer   r@   r   r   r   r   r    r#   r   r1   r9   r=   rA   rE   rJ   rN   rR   rX   rh   rk   rn   ru   rp   r   r{   r   r   r   r   r   r   r   r/   r   r   <module>r      s      '  '  	  . 8    
 )3H H
L
L
0
		*  :,2j,*G4"JC0>%P4n r   