o
    c                     @   s  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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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(G dd dej)Z*G dd dej+Z,G dd de-Z.G dd dej/Z0d d! Z1d"d# Z2G d$d% d%e(3ej4e-Z5G d&d' d'e5Z6G d(d) d)e5Z7G d*d+ d+e5Z8G d,d- d-e5Z9G d.d/ d/e5Z:G d0d1 d1e5Z;G d2d3 d3e5Z<G d4d5 d5e5Z=G d6d7 d7e5Z>G d8d9 d9e5Z?G d:d; d;e?Z@G d<d= d=e?ZAG d>d? d?e5ZBG d@dA dAe5ZCG dBdC dCe5ZDdS )DaA  A yaml to calliope command translator.

Calliope allows you to register a hook that converts a yaml command spec into
a calliope command class. The Translator class in this module implements that
interface and provides generators for a yaml command spec. The schema for the
spec can be found in yaml_command_schema.yaml.
    )absolute_import)division)unicode_literalsN)messages)encoding)
exceptions)HttpBadRequestError)waiter)base)command_loading)
completers)	arg_utils)registry)yaml_command_schema)yaml_command_schema_util)labels_util)log)	resources)
console_io)resource_transform)filesc                   @   s   e Zd ZdZdd ZdS )
Translatorz8Class that implements the calliope translator interface.c                 C   s   t |d |}t ||S )N)r   CommandDataCommandBuilderGenerate)selfpathcommand_dataspec r    Y/tmp/google-cloud-sdk/lib/googlecloudsdk/command_lib/util/apis/yaml_command_translator.py	Translate<   s   zTranslator.TranslateN)__name__
__module____qualname____doc__r"   r    r    r    r!   r   9   s    r   c                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )DeclarativeIamRolesCompleterzAn IAM role completer for a resource argument.

  The Complete() method override bypasses the completion cache.

  Attributes:
    _get_resource_ref: DeclarativeArgumentGenerator.GetPrimaryResource method
      to parse the resource ref.
  c                    s    t t| jdi | || _d S )Nr    )superr'   __init___get_resource_ref)r   get_resource_refkwargs	__class__r    r!   r)   K   s   
z%DeclarativeIamRolesCompleter.__init__c                 C   s$   |  |j}| }ddddd|gS )Niamzlist-grantable-rolesz--quietz--flatten=namez--format=disable)r*   parsed_argsSelfLink)r   parameter_inforesource_refresource_urir    r    r!   GetListCommandO   s
   z+DeclarativeIamRolesCompleter.GetListCommandc                    s,   |  |}| ||} fdd|pg D S )z;Bypasses the cache and returns completions matching prefix.c                    s"   g | ]}|d ur|  r|qS N)
startswith).0itemprefixr    r!   
<listcomp>[   s
    z9DeclarativeIamRolesCompleter.Complete.<locals>.<listcomp>)r5   GetAllItems)r   r;   r2   commanditemsr    r:   r!   CompleteW   s
   

z%DeclarativeIamRolesCompleter.Complete)r#   r$   r%   r&   r)   r5   r@   __classcell__r    r    r-   r!   r'   A   s
    	r'   c                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )r   z3Generates calliope commands based on the yaml spec.c                 C   s   i | _ | t | t | t | t | t | t | t | t	 | t
 | t | t | t | t | t d S r6   )command_generatorsRegisterCommandGeneratorDescribeCommandGeneratorListCommandGeneratorDeleteCommandGeneratorCreateCommandGeneratorWaitCommandGeneratorUpdateCommandGeneratorGenericCommandGeneratorGetIamPolicyCommandGeneratorSetIamPolicyCommandGenerator#AddIamPolicyBindingCommandGenerator&RemoveIamPolicyBindingCommandGeneratorImportCommandGeneratorExportCommandGeneratorConfigExportCommandGeneratorr   r    r    r!   r)   d   s   












zCommandBuilder.__init__c                 C   s,   |j | jv rtd|j || j|j < d S )Nz.Command type [{}] has already been registered.)command_typerB   
ValueErrorformat)r   command_generatorr    r    r!   rC   w   s
   z'CommandBuilder.RegisterCommandGeneratorc                 C   s4   |j | jvrtdd||j | j|j  |S )a  Returns the command generator for a spec and path.

    Args:
      spec: yaml_command_schema.CommandData, the spec for the command being
        generated.
      path: Path for the command.

    Raises:
      ValueError: If we don't know how to generate the given command type (this
        is not actually possible right now due to the enum).

    Returns:
      The command generator.
    z'Command [{}] unknown command type [{}]. )rS   rB   rT   rU   join)r   r   r   r    r    r!   GetCommandGenerator}   s
   z"CommandBuilder.GetCommandGeneratorc                 C   s   |  ||}| S )a  Generates a calliope command from the yaml spec.

    Args:
      spec: yaml_command_schema.CommandData, the spec for the command being
        generated.
      path: Path for the command.

    Returns:
      calliope.base.Command, The command that implements the spec.
    )rY   r   )r   r   r   	generatorr    r    r!   r      s   zCommandBuilder.GenerateN)r#   r$   r%   r&   r)   rC   rY   r   r    r    r    r!   r   a   s    r   c                   @   sH   e Zd ZdZdd Zedd Zedd Zdd	 Zd
d Z	dd Z
dS )AsyncOperationPollerz(An implementation of a operation poller.c                 C   s<   || _ || _| j jjsd| _n|| _|| _|o|jj| _dS )a4  Creates the poller.

    Args:
      spec: yaml_command_schema.CommandData, the spec for the command being
        generated.
      resource_ref: resources.Resource, The resource reference for the resource
        being operated on (not the operation itself). If None, the operation
        will just be returned when it is done instead of getting the resulting
        resource.
      args: Namespace, The args namespace.
      operation_collection: str, collection name of operation
      method: registry.APIMethod, method used to make original api request
    N)	r   argsasync_extract_resource_resultr3   _operation_collection
collection	full_name_resource_collection)r   r   r3   r\   operation_collectionmethodr    r    r!   r)      s   
zAsyncOperationPoller.__init__c                 C   s,   | j jjp	| j jj}tj| j| j jj|dS )Napi_version)r   r]   rf   requestr   	GetMethodr_   rd   )r   rf   r    r    r!   operation_method   s   z%AsyncOperationPoller.operation_methodc                 C   s   t j| jd| jjjdS )Ngetre   )r   rh   rb   r   rg   rf   rR   r    r    r!   resource_get_method   s
   z(AsyncOperationPoller.resource_get_methodc                 C   s   t || jjjj}t|tjr|j}|| jjjj	v s"|| jjjj
v rBt || jjjj}|s7|| jjjj
v r7d}|r@tt|dS dS )z
Overrides.zThe operation failed.TF)getattrr   r]   statefield
isinstanceapitools_messagesEnumnamesuccess_valueserror_valueserrorr	   OperationErrorSerializeError)r   	operationresultru   r    r    r!   IsDone   s   zAsyncOperationPoller.IsDonec                 C   s   | j  }| }i }| D ]}t|| jjj|j	|j	|||j	< q|di |}| jjj
D ]	}||| j|}q0| j |S )zOverrides.

    Args:
      operation_ref: googlecloudsdk.core.resources.Resource.

    Returns:
      fetched operation message.
    Nr    )ri   GetRequestTypeRelativeName
all_fieldsrl   r   r]   operation_get_method_paramsrj   rr   modify_request_hooksr\   Call)r   operation_refrequest_typerelative_namefieldsfrg   hookr    r    r!   Poll   s   
	zAsyncOperationPoller.Pollc                 C   sH   |}| j r| j}|  }tj| j ||dd ||}t|| jjj	S )zOverrides.

    Args:
      operation: api_name_messages.Operation.

    Returns:
      result of result_service.Get request.
    T)is_primary_resource)
r3   rk   r{   r   ParseResourceIntoMessager   _GetAttributer   r]   result_attribute)r   rx   ry   
get_methodrg   r    r    r!   	GetResult   s   	


zAsyncOperationPoller.GetResultN)r#   r$   r%   r&   r)   propertyri   rk   rz   r   r   r    r    r    r!   r[      s    

r[   c                 C   sB   t | tjr| S ztjt| ddddW S  ty    |  Y S w )z/Serializes the error message for better format.   T),z: )indent	sort_keys
separators)ro   sixstring_typesjsondumpsr   MessageToDict	Exception)ru   r    r    r!   rw     s   rw   c              
   C   sX   |r*| dD ]"}z| du rW  dS t| |} W q ty)   td|t| w | S )aX  Gets attributes and sub-attributes out of an object.

  Args:
    obj: The object to extract the attributes from.
    attr_path: str, The dotted path of attributes to extract.

  Raises:
    AttributeError: If the attribute doesn't exist on the object.

  Returns:
    The desired attribute or None if any of the parent attributes were None.
  .Nz*Attribute path [{}] not found on type [{}])splitrl   AttributeErrorrU   type)obj	attr_pathattrr    r    r!   r     s   r   c                   @   s   e Zd ZdZdd Zdd Zd,ddZd	d
 Zdd Zdd Z	dd Z
d-ddZ	d,ddZdd Zdd Zd,ddZdd Z	d.ddZd,d d!Zd"d# Zd$d% Zd&d' Zejd(d) Zd*d+ ZdS )/BaseCommandGeneratorz"Base class for command generation.c                 C   s"   || _ tj|j| _|   d S r6   )r   r   CommandTypeHasRequestMethodrS   has_request_methodInitializeGeneratorForCommand)r   r   r    r    r!   r)   2  s
   zBaseCommandGenerator.__init__c                 C   s:   ddl m} | jr|  | _ng | _|| jjj| _	dS )z*Initializes the arg_generator for command.r   arg_marshallingN)
$googlecloudsdk.command_lib.util.apisr   r   _GetMethodsmethodsDeclarativeArgumentGeneratorr   	argumentsparamsarg_generator)r   r   r    r    r!   r   8  s   
z2BaseCommandGenerator.InitializeGeneratorForCommandNc              	   C   sF   g }| j jjD ]}|tj||p| j jj| j jj| j jjd q|S )N)disable_pagination)	r   rg   collectionsappendr   rh   rd   rf   r   )r   rd   r   r`   r    r    r!   r   F  s   
z BaseCommandGenerator._GetMethodsc                 C   s   | j | j}| |}|D ]}|| q| jjjr)| jj D ]}|| q!| jjj	r7|j
| jjj	 | jjjrG|j
| jjj dS dS )zPerforms argument actions common to all commands.

    Adds all generated arguments to the parser
    Sets the command output format if specified

    Args:
      parser: The argparse parser.
    N)r   GenerateArgsr   _ExcludeAddToParserr   r   additional_arguments_hookoutputrU   display_info	AddFormatflatten
AddFlatten)r   parserr\   argr    r    r!   _CommonArgsP  s   	



z BaseCommandGenerator._CommonArgsc                    s4    fdd}t  dddu r  | dS dS )zGenerates and registers a function to create a URI from a resource.

    Args:
      args: The argparse namespace.

    Returns:
      f(resource) -> str, A function that converts the given resource payload
      into a URI.
    c                    s:   t | jjj}jj j}j| |}|	 S r6   )
rl   r   responseid_fieldr   GetPrimaryResourcer   rd   GetResponseResourceRefr1   )resourceid_valuerd   refr\   r   r    r!   URIFunco  s   
z6BaseCommandGenerator._RegisterURIFunc.<locals>.URIFuncuriNT)rl   GetDisplayInfo
AddUriFunc)r   r\   r   r    r   r!   _RegisterURIFunce  s   
	z%BaseCommandGenerator._RegisterURIFuncc                 C   s.   | j jjD ]}tjd|dd| q|S )zExcludes specified arguments from the parser.

    Args:
      parser: The argparse parser.

    Returns:
      The argparse parser.
    z--{} help)r   r   excluder
   ArgumentrU   RemoveFromParser)r   r   r   r    r    r!   r   {  s   	zBaseCommandGenerator._Excludec                 C   sD   | j jjs| jS | j| j|}||}| j j||}| |S r6   )r   rg   modify_method_hookr   r   r   Parser   )r   r\   	specifiedr   new_method_namer    r    r!   _GetRuntimeMethods  s   


z'BaseCommandGenerator._GetRuntimeMethodsc              
   C   s:  |  || _| j| j|}|j}||}| jjjr7t	j
| | jjj|| || ||| jjjddd | jjjrF|| jj||fS | jjjrT| jj||}n5i }|r]|| | jjjrj|| jjj | jj|||| jjj| jj|d}| jjjD ]}	|	|||}q|j|| j|| j|d}
||
fS )a/  Performs run actions common to all commands.

    Parses the resource argument into a resource reference
    Prompts the user to continue (if applicable)
    Calls the API method with the request generated from the parsed arguments

    Args:
      args: The argparse parser.
      existing_message: the apitools message returned from previous request.
      update_mask: auto-generated mask from updated fields.

    Returns:
      (resources.Resource, response), A tuple of the parsed resource reference
      and the API response from the method call.
    T)messagedefaultthrow_if_unattendedcancel_on_noexisting_message)limit	page_size)r   r   r   r   rd   r   r   inputconfirmation_promptr   PromptContinue_Format_GetDisplayResourceType_GetDisplayNamedefault_continuerg   issue_request_hookcreate_request_hookupdatestatic_fieldsCreateRequestr   labelsrS   r   r   LimitPageSize)r   r\   r   update_maskr   rd   r   rg   r   r   r   r    r    r!   
_CommonRun  sN   









zBaseCommandGenerator._CommonRunc                 C   s   t ||||S r6   )r   FormatResourceAttrStr)r   format_stringr3   display_typedisplay_namer    r    r!   r     s   zBaseCommandGenerator._Formatc                 C   s8   | j | j|j}|r|jr|||S |r| S d S r6   )r   r   r   primary_resourcedisplay_name_hookName)r   r3   r\   primary_resource_argr    r    r!   r     s   
z$BaseCommandGenerator._GetDisplayNamec                 C   s8   | j jj }r	|S | j| j|j}|r|js|jS d S r6   )	r   rg   display_resource_typer   r   r   r   is_parent_resourcerr   )r   r\   spec_displayr   r    r    r!   r     s   
z,BaseCommandGenerator._GetDisplayResourceTypec                 C   s   | j jjrR| || j jjjd}|rRg }| j jjjr+|dt	|| j jjj | j jjj
r@|dt	|| j jjj
 |rJtd|tt|| j jjr_t	|| j jj}| j jjD ]}|||}qd|S )aA  Process the API response.

    Args:
      response: The apitools message object containing the API response.
      args: argparse.Namespace, The parsed args.

    Raises:
      core.exceptions.Error: If an error was detected and extracted from the
        response.

    Returns:
      A possibly modified response.
    r   z
Code: [{}]zMessage: [{}]rW   )r   r   ru   _FindPopulatedAttributern   r   coder   rU   r   r   r   ErrorrX   r   	text_typer   modify_response_hooks)r   r   r\   ru   r   r   r    r    r!   _HandleResponse  s,   

z$BaseCommandGenerator._HandleResponsec                 C   s   t | jjjD ]B\}}ztjjt|| jjj|| jjj	p | jj
j	d}||fW   S  tjyI } z|t| jjjd kr?|W Y d }~qd }~ww d S )N)r`   rf      )	enumerater   r]   r   r   REGISTRYr   rl   response_name_fieldrf   rg   	UserErrorlen)r   rx   ir`   r   er    r    r!   _GetOperationRef  s   z%BaseCommandGenerator._GetOperationRefTc           
      C   s   |  |\}}| jjjp|}|r#tj| ||| || 	|| |jr:tj| d
tj|| | |S | j| j|j}t| j|rJ|nd|||}	|	|rZ|	|S | j|	||dS )a6  Handles polling for operations if the async flag is provided.

    Args:
      args: argparse.Namespace, The parsed args.
      resource_ref: resources.Resource, The resource reference for the resource
        being operated on (not the operation itself)
      operation: The operation message response.
      request_string: The format string to print indicating a request has been
        issued for the resource. If None, nothing is printed.
      extract_resource_result: bool, True to return the original resource as
        the result or False to just return the operation response when it is
        done. You would set this to False for things like Delete where the
        resource no longer exists when the operation is done.

    Returns:
      The response (either the operation or the original resource).
    z$Check operation [{{{}}}] for status.Nr\   )r  r   r]   request_issued_messager   statusPrintr   r   r   rU   r   REL_NAME_FORMAT_KEYr   r   r   rd   r[   rz   r   _WaitForOperationWithPoller)
r   r\   r3   rx   request_stringr^   r   rc   rd   pollerr    r    r!   _HandleAsync  s6   





z!BaseCommandGenerator._HandleAsyncc                 C   sT   |  dtj|| |}|r| |j|nd }t|||  ||j| ||S )Nz*Waiting for operation [{{{}}}] to complete)	r   rU   r   r  r   r   r3   r	   WaitFor)r   r  r   r\   progress_stringr   r    r    r!   r  @  s"   

z0BaseCommandGenerator._WaitForOperationWithPollerc                 C   s|   |s|S |d }zt ||}W n
 ty   Y dS w t|tr4|D ]}| ||dd }|r3|  S q!| ||dd S )a  Searches the given object for an attribute that is non-None.

    This digs into the object search for the given attributes. If any attribute
    along the way is a list, it will search for sub-attributes in each item
    of that list. The first match is returned.

    Args:
      obj: The object to search
      attributes: [str], A sequence of attributes to use to dig into the
        resource.

    Returns:
      The first matching instance of the attribute that is non-None, or None
      if one could nto be found.
    r   Nr   )rl   r   ro   listr   )r   r   
attributesr   xr    r    r!   r   M  s   
z,BaseCommandGenerator._FindPopulatedAttributec           	      C   sZ   ddl m} | d}| j||}|j}|r|gng }||}|j}||	||S )Nr   r   rj   )
r   r   r   r   r   r   r   rd   r   r   )	r   r\   r   get_methodsr   r   r   get_arg_generatorr   r    r    r!   _GetExistingResourcek  s   

z)BaseCommandGenerator._GetExistingResourcec                    s6  | j jr	t|}| j jrt|}| j jdur'| j jr"t|}nt|}| j j	r4tj
| j j	 |}| j jrDtjdi | j j|}t|ds\ddd  fdd| j j D |_| jrtdd	 | jD }td
d	 | jD }d|}d|}t|dkrd| d| }nd| d| }||jd< |S )zConfigures top level attributes of the generated command.

    Args:
      command: The command being generated.

    Returns:
      calliope.base.Command, The command that implements the spec.
    Ndetailed_helpDESCRIPTIONEXAMPLES)descriptionexamplesc                    s   i | ]\}}  |||qS r    )rj   )r8   kvkey_mapr    r!   
<dictcomp>  s    z:BaseCommandGenerator._ConfigureCommand.<locals>.<dictcomp>c                 s   s&    | ]}|j j d |j j V  qdS )/N)r`   api_namerf   r8   rd   r    r    r!   	<genexpr>  s
    
z9BaseCommandGenerator._ConfigureCommand.<locals>.<genexpr>c                 s   s    | ]}|j jV  qd S r6   )r`   docs_urlr&  r    r    r!   r'    s    z, r   zThis command uses *z?* APIs. The full documentation for these APIs can be found at: zThis command uses the *z<* API. The full documentation for this API can be found at: zAPI REFERENCEr    )r   hiddenr
   Hiddenauto_generatedAutogenerateduniverse_compatibleUniverseCompatibleDefaultUniverseOnlyrelease_tracksReleaseTracksdeprecated_data	Deprecatehasattr	help_textr?   r  r   setr   rX   r  )r   r>   	api_namesdoc_urlsapi_name_strdoc_url_strapi_infor    r!  r!   _ConfigureCommandz  sJ   	








z&BaseCommandGenerator._ConfigureCommandc                 C   s   d S r6   r    rR   r    r    r!   	_Generate  s   zBaseCommandGenerator._Generatec                 C   s   |   }| | |S r6   )r=  r<  )r   r>   r    r    r!   r     s   
zBaseCommandGenerator.Generater6   )NN)T)r#   r$   r%   r&   r)   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r  r<  abcabstractmethodr=  r   r    r    r    r!   r   /  s2    


	=

"

-2
r   c                   @   s0   e Zd ZdZejjZdd Zdd Z	dd Z
dS )	rJ   z&Generator for generic/custom commands.c                 C   s   | j jrtj| d S d S r6   )r   r]   r
   
ASYNC_FLAGr   )r   r   r    r    r!   _AddAsyncFlag  s   z%GenericCommandGenerator._AddAsyncFlagc                 C   s|   t dd | jD }| jj}|r|r|jrd S tj| tj| tj	| tj
| | jjjr<tj| d S d S )Nc                 s   s     | ]}|  o| V  qd S r6   )ListItemFieldHasTokenizedRequestr&  r    r    r!   r'    s
    
z:GenericCommandGenerator._AddPagingFlags.<locals>.<genexpr>)anyr   r   genericdisable_paging_flagsr
   FILTER_FLAGr   
LIMIT_FLAGPAGE_SIZE_FLAGSORT_BY_FLAGr   r   URI_FLAG)r   r   is_paginatedrE  r    r    r!   _AddPagingFlags  s   
z'GenericCommandGenerator._AddPagingFlagsc                       G  fdddt j}|S )at  Generates a generic command.

    A generic command has a resource argument, additional fields, and calls an
    API method. It supports async if the async configuration is given. Any
    fields is message_params will be generated as arguments and inserted into
    the request message.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       (   e Zd Ze fddZ fddZdS )z2GenericCommandGenerator._Generate.<locals>.Commandc                    s"     |   |   |  d S r6   )r   rA  rM  r   rR   r    r!   Args  s   

z7GenericCommandGenerator._Generate.<locals>.Command.Argsc                    sR     |  |\}} jjr#d }|rdtj} j||||d} ||S )NRequest issued for: [{{{}}}]r  )	r   r   r   r]   rU   r   NAME_FORMAT_KEYr  r   )self_r\   r   r   r  rR   r    r!   Run  s   
z6GenericCommandGenerator._Generate.<locals>.Command.RunNr#   r$   r%   staticmethodrQ  rV  r    rR   r    r!   Command      rY  r
   rY  r   rY  r    rR   r!   r=    s   z!GenericCommandGenerator._GenerateN)r#   r$   r%   r&   r   r   GENERICrS   rA  rM  r=  r    r    r    r!   rJ     s    rJ   c                   @       e Zd ZdZejjZdd ZdS )rD   z Generator for describe commands.c                    rN  )a  Generates a Describe command.

    A describe command has a single resource argument and an API method to call
    to get the resource. The result is returned using the default output format.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       rO  )z3DescribeCommandGenerator._Generate.<locals>.Commandc                         |  d S r6   r   rP  rR   r    r!   rQ  
     z8DescribeCommandGenerator._Generate.<locals>.Command.Argsc                    s     |\}} ||S r6   )r   r   rU  r\   
unused_refr   rR   r    r!   rV    s   z7DescribeCommandGenerator._Generate.<locals>.Command.RunNrW  r    rR   r    r!   rY    s    rY  )r
   DescribeCommandr\  r    rR   r!   r=    s   
z"DescribeCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   DESCRIBErS   r=  r    r    r    r!   rD         rD   c                   @   r^  )rE   zGenerator for list commands.c                    rN  )a  Generates a List command.

    A list command operates on a single resource and has flags for the parent
    collection of that resource. Because it extends the calliope base List
    command, it gets flags for things like limit, filter, and page size. A
    list command should register a table output format to display the result.
    If arguments.resource.response_id_field is specified, a --uri flag will also
    be enabled.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       rO  )z/ListCommandGenerator._Generate.<locals>.Commandc                    s(     |   jjjstj|  d S d S r6   )r   r   r   r   r
   rK  r   rP  rR   r    r!   rQ  /  s   

z4ListCommandGenerator._Generate.<locals>.Command.Argsc                    s$     |  |\}} ||S r6   )r   r   r   rb  rR   r    r!   rV  7  s   
z3ListCommandGenerator._Generate.<locals>.Command.RunNrW  r    rR   r    r!   rY  ,      rY  )r
   ListCommandr\  r    rR   r!   r=    s   zListCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   LISTrS   r=  r    r    r    r!   rE     rf  rE   c                   @   r^  )rF   zGenerator for delete commands.c                    rN  )a  Generates a Delete command.

    A delete command has a single resource argument and an API to call to
    perform the delete. If the async section is given in the spec, an --async
    flag is added and polling is automatically done on the response. For APIs
    that adhere to standards, no further configuration is necessary. If the API
    uses custom operations, you may need to provide extra configuration to
    describe how to poll the operation.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       rO  )z1DeleteCommandGenerator._Generate.<locals>.Commandc                    s&     |   jjrtj|  d S d S r6   )r   r   r]   r
   r@  r   rP  rR   r    r!   rQ  Y  s   
z6DeleteCommandGenerator._Generate.<locals>.Command.Argsc                    sp     |\}} jjr" j|||dtjdd}|jr" ||S  ||}tj	 
|| |d |S )Nz#Delete request issued for: [{{{}}}]F)r  r^   kind)r   r   r]   r  rU   r   rT  r   r   DeletedResourcer   r   )rU  r\   r   r   rR   r    r!   rV  _  s"   z5DeleteCommandGenerator._Generate.<locals>.Command.RunNrW  r    rR   r    r!   rY  V  rZ  rY  )r
   DeleteCommandr\  r    rR   r!   r=  D  s   z DeleteCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   DELETErS   r=  r    r    r    r!   rF   ?  rf  rF   c                   @   r^  )rG   zGenerator for create commands.c                    rN  )a  Generates a Create command.

    A create command has a single resource argument and an API to call to
    perform the creation. If the async section is given in the spec, an --async
    flag is added and polling is automatically done on the response. For APIs
    that adhere to standards, no further configuration is necessary. If the API
    uses custom operations, you may need to provide extra configuration to
    describe how to poll the operation.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       rO  )z1CreateCommandGenerator._Generate.<locals>.Commandc                    :     |   jjrtj|   jjjrt	|  d S d S r6   )
r   r   r]   r
   r@  r   r   r   r   AddCreateLabelsFlagsrP  rR   r    r!   rQ       

z6CreateCommandGenerator._Generate.<locals>.Command.Argsc           
         s     |\}} j j|j}|o|j} jjr:|d ur&|s&dt	j
}nd} j||||d}|jr: ||S |rWt|}|di d}|sQ|d}t|}	n ||}	tj|	 |d  ||}|S )Nz#Create request issued for: [{{{}}}]zCreate request issuedrS  r   rr   rj  )r   r   r   r   r   r   r   r]   rU   r   rT  r  r   r   r   rj   r   TransformBaseNamer   r   CreatedResourcer   )
rU  r\   r   r   r   r   r  response_objra   resource_namerR   r    r!   rV    sB   

z5CreateCommandGenerator._Generate.<locals>.Command.RunNrW  r    rR   r    r!   rY    rg  rY  )r
   CreateCommandr\  r    rR   r!   r=  y  s   .z CreateCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   CREATErS   r=  r    r    r    r!   rG   t  rf  rG   c                   @   s,   e Zd ZdZejjZ	dddZdd Z	dS )rH   zGenerator for wait commands.Nc                 C   s0   t | j|r|nd || j|}| j|||dS )Nr	  )r[   r   GetCollectionInfora   r  )r   r   r3   r^   rd   r\   r  r    r    r!   _WaitForOperation  s   z&WaitCommandGenerator._WaitForOperationc                    rN  )aP  Generates a wait command for polling operations.

    A wait command takes an operation reference and polls the status until it
    is finished or errors out. This follows the exact same spec as in other
    async commands except the primary operation (create, delete, etc) has
    already been done. For APIs that adhere to standards, no further async
    configuration is necessary. If the API uses custom operations, you may need
    to provide extra configuration to describe how to poll the operation.

    Returns:
      calliope.base.Command, The command that implements the spec.
    c                       rO  )z/WaitCommandGenerator._Generate.<locals>.Commandc                    r_  r6   r`  rP  rR   r    r!   rQ    ra  z4WaitCommandGenerator._Generate.<locals>.Command.Argsc                    sD    j  j|}|j}||} j|d d||d} ||}|S )NF)r3   r^   rd   r\   )r   r   r   rd   r   ry  r   )rU  r\   specified_resourcerd   r   r   rR   r    r!   rV    s   
z3WaitCommandGenerator._Generate.<locals>.Command.RunNrW  r    rR   r    r!   rY    s    rY  r[  r\  r    rR   r!   r=    s   zWaitCommandGenerator._Generater6   )
r#   r$   r%   r&   r   r   WAITrS   ry  r=  r    r    r    r!   rH     s    
rH   c                   @   r^  )rI   zGenerator for update commands.c                    s(   ddl m G  fdddtj}|S )a  Generates an update command.

    An update command has a resource argument, additional fields, and calls an
    API method. It supports async if the async configuration is given. Any
    fields is message_params will be generated as arguments and inserted into
    the request message.

    Currently, the Update command is the same as Generic command.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   )r   c                       s*   e Zd Ze fddZ fddZdS )z1UpdateCommandGenerator._Generate.<locals>.Commandc                    ro  r6   )
r   r   r]   r
   r@  r   r   r   r   AddUpdateLabelsFlagsrP  rR   r    r!   rQ    rq  z6UpdateCommandGenerator._Generate.<locals>.Command.Argsc           
         s   d } j jr j jjr |} | _ j j|j}	|}|r? j jr2 j jj
r2d}n| j |}||i}nd } |||\}} j jrad }	|rXdtj}	 j||||	d}tj || |d  ||S )Nr   rR  rS  rj  )r   r   read_modify_updater  r   r   r   r   rd   GetMaskFieldPathdisable_auto_field_maskGetMaskStringr   r]   rU   r   rT  r  r   UpdatedResourcer   r   r   )
rU  r\   r   rd   	mask_pathmask_stringr   r   r   r  r   r   r    r!   rV    sD   




z5UpdateCommandGenerator._Generate.<locals>.Command.RunNrW  r    r  r    r!   rY    s    rY  )r   r   r
   rY  r\  r    r  r!   r=    s   2z UpdateCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   UPDATErS   r=  r    r    r    r!   rI     rf  rI   c                   @   r^  )rK   z&Generator for get-iam-policy commands.c                    s&   ddl m} G  fdddtj}|S )a%  Generates a get-iam-policy command.

    A get-iam-policy command has a single resource argument and an API method
    to call to get the resource. The result is returned using the default
    output format.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   iam_utilc                       s,   e Zd ZdZe fddZ fddZdS )z7GetIamPolicyCommandGenerator._Generate.<locals>.CommandzGet IAM policy command closure.c                    s     |  tj|  d S r6   )r   r
   rK  r   rP  rR   r    r!   rQ  Z  s   
z<GetIamPolicyCommandGenerator._Generate.<locals>.Command.Argsc                    sF    j jr j jjr j jj j jj j jj<  |\}} ||S r6   )r   r/   policy_versionrg   r   get_iam_policy_version_pathr   r   )rU  r\   _r   rR   r    r!   rV  _  s   z;GetIamPolicyCommandGenerator._Generate.<locals>.Command.RunNr#   r$   r%   r&   rX  rQ  rV  r    rR   r    r!   rY  W  s
    rY  )googlecloudsdk.command_lib.iamr  r
   rh  )r   r  rY  r    rR   r!   r=  E  s   z&GetIamPolicyCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   GET_IAM_POLICYrS   r=  r    r    r    r!   rK   @  rf  rK   c                   @   s(   e Zd ZdZejjZdd Zdd Z	dS )rL   z&Generator for set-iam-policy commands.c                 C   sp   d}d}| j jr| j jj}d|v r|d p|}| j jjp|}d|}||}t|dr6|| j jj|< dS dS )aQ  Set Field Mask on SetIamPolicy request message.

    If the API supports update_masks then adds the update_mask to the
    SetIamPolicy request (via static fields).

    Args:
      update_mask: str, comma separated string listing the Policy fields to be
        updated.
      method: APIMethod, used to identify update mask field.
    SetIamPolicyRequestsetIamPolicyRequestset_iam_policy_requestz{}.updateMask
updateMaskN)	r   r/   message_type_overridesset_iam_policy_request_pathrU   GetMessageByNamer4  rg   r   )r   r   rd   r  policy_request_path	overridesmask_field_pathupdate_requestr    r    r!   _SetPolicyUpdateMaskp  s    




z1SetIamPolicyCommandGenerator._SetPolicyUpdateMaskc                    (   ddl m  G  fdddtj}|S )aQ  Generates a set-iam-policy command.

    A set-iam-policy command takes a resource argument, a policy to set on that
    resource, and an API method to call to set the policy on the resource. The
    result is returned using the default output format.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   r  c                       0   e Zd ZdZe fddZ fddZdS )z7SetIamPolicyCommandGenerator._Generate.<locals>.CommandzSet IAM policy command closure.c                    s$    |   |  tj|  d S r6   )r   AddArgForPolicyFiler
   rK  r   rP  r  r   r    r!   rQ    s   

z<SetIamPolicyCommandGenerator._Generate.<locals>.Command.Argsc              
      s  d}d}j jrdj jjv rj jjd p|}j jjp|}|d }jj|j}||}|s:t	d
| |j|\}}j jrRj jjrRj jj|_|j jj|< || z	|\}	}
W n ty| } ztjd |d}~ww  |	 | |
|S ) Called when command is executed.Policyr  policy.policyzPolicy type [{}] not found.zERROR: Policy modification failed. For bindings with conditions, run "gcloud alpha iam policies lint-condition" to identify issues in conditions.N)r   r/   r  r  r   r   r   rd   r  rT   rU   ParsePolicyFileWithUpdateMaskpolicy_filer  versionrg   r   r  r   r   r   errr  LogSetIamPolicyr   r   r   )rU  r\   policy_type_namer  policy_field_pathrd   policy_typer  r   r   r   exr  r    r!   rV    sR   

z;SetIamPolicyCommandGenerator._Generate.<locals>.Command.RunNr  r    r  r    r!   rY    s
    rY  r  r  r
   rY  r\  r    r  r!   r=    s   6z&SetIamPolicyCommandGenerator._GenerateN)
r#   r$   r%   r&   r   r   SET_IAM_POLICYrS   r  r=  r    r    r    r!   rL   k  s
     rL   c                   @   s@   e Zd ZdZedd Zedd Zdd Zdd	 Zd
d Z	dS )$BaseIamPolicyBindingCommandGeneratorz.Base class for iam binding command generators.c                 C      | j jo| j jjS r6   )r   r/   enable_conditionrR   r    r    r!   _add_condition     z3BaseIamPolicyBindingCommandGenerator._add_conditionc                 C   r  r6   )r   r/   hide_special_member_typesrR   r    r    r!   _hide_special_member_types  r  z?BaseIamPolicyBindingCommandGenerator._hide_special_member_typesc                 C   s   |  |}| j|||S r6   )r   r   r   r   )r   r\   r   r    r    r!   _GetResourceRef  s   
z4BaseIamPolicyBindingCommandGenerator._GetResourceRefc                    s    | j G  fdddt  S )zGenerate a IAM role completer.c                       s    e Zd Z fddZ  ZS )z]BaseIamPolicyBindingCommandGenerator._GenerateDeclarativeIamRolesCompleter.<locals>.Completerc                    s   t  | jddi| d S )Nr+   r    )r(   r)   )r   r,   )	Completerr.   r+   r    r!   r)     s
   
zfBaseIamPolicyBindingCommandGenerator._GenerateDeclarativeIamRolesCompleter.<locals>.Completer.__init__)r#   r$   r%   r)   rA   r    r  r+   r-   r!   r    s    r  )r  r'   rR   r    r  r!   %_GenerateDeclarativeIamRolesCompleter  s   zJBaseIamPolicyBindingCommandGenerator._GenerateDeclarativeIamRolesCompleterc                 C   sb   |  d}| j||j}| j||}| jjr*| jjjr*t	|| jjj
| jjj ||}|S )z4GetIamPolicy helper function for add/remove binding.getIamPolicy)r   r   r   rd   r   r   r/   r  r   SetFieldInMessager  r   )r   r\   get_iam_methodsget_iam_methodget_iam_requestr  r    r    r!   _GetIamPolicy  s"   

z2BaseIamPolicyBindingCommandGenerator._GetIamPolicyN)
r#   r$   r%   r&   r   r  r  r  r  r  r    r    r    r!   r    s    

r  c                   @   *   e Zd ZdZejjZdddZdd Z	dS )	rM   z.Generator for add-iam-policy binding commands.Fc           	      C   s   ddl m} | j| j|j}|d}|r3||}| |}|d}|	||||j
|j| |S | |}||||j
|j |S )zGet the IAM policy and add the specified binding to it.

    Args:
      args: an argparse namespace.
      add_condition: True if support condition.

    Returns:
      IAM policy.
    r   r  BindingExpr)r  r  r   r   r   rd   r  $ValidateAndExtractConditionMutexRoler  "AddBindingToIamPolicyWithConditionmemberroleAddBindingToIamPolicy)	r   r\   add_conditionr  rd   binding_message_type	conditionr  condition_message_typer    r    r!   "_GetModifiedIamPolicyAddIamBinding  s"   





zFAddIamPolicyBindingCommandGenerator._GetModifiedIamPolicyAddIamBindingc                    r  )a  Generates an add-iam-policy-binding command.

    An add-iam-policy-binding command adds a binding to a IAM policy. A
    binding consists of a member, a role to define the role of the member, and
    an optional condition to define in what condition the binding is valid.
    Two API methods are called to get and set the policy on the resource.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   r  c                       r  )z>AddIamPolicyBindingCommandGenerator._Generate.<locals>.Commandz'Add IAM policy binding command closure.c                    4    j |  jjd |  tj|  d S N)role_completerr  r  )AddArgsForAddIamPolicyBindingr  r  r  r   r
   rK  r   rP  r  r    r!   rQ  A     
zCAddIamPolicyBindingCommandGenerator._Generate.<locals>.Command.Argsc              
      s   d}j jrj jjp|}|d }j|jd}j jr(j jjr(j jj|_|j jj|< z		|\}}W n t
yL } ztjd |d}~ww  | | ||S )r  r  r  r  zERROR: Policy modification failed. For a binding with condition, run "gcloud alpha iam policies lint-condition" to identify issues in condition.N)r   r/   r  r  r  r  r  rg   r   r   r   r   r  r  r  r   r   r   )rU  r\   r  r  r  r   r   r  r  r    r!   rV  K  s,   zBAddIamPolicyBindingCommandGenerator._Generate.<locals>.Command.RunNr  r    r  r    r!   rY  >  
    	rY  r  r\  r    r  r!   r=  +  s   -z-AddIamPolicyBindingCommandGenerator._GenerateNF)
r#   r$   r%   r&   r   r   ADD_IAM_POLICY_BINDINGrS   r  r=  r    r    r    r!   rM   	  s
    
rM   c                   @   r  )	rN   z1Generator for remove-iam-policy binding commands.Fc                 C   sb   ddl m} |r!||}| |}|j||j|j||jd |S | |}|||j|j |S )zGet the IAM policy and remove the specified binding to it.

    Args:
      args: an argparse namespace.
      add_condition: True if support condition.

    Returns:
      IAM policy.
    r   r  )all_conditions)	r  r  ValidateAndExtractConditionr  'RemoveBindingFromIamPolicyWithConditionr  r  allRemoveBindingFromIamPolicy)r   r\   r  r  r  r  r    r    r!   %_GetModifiedIamPolicyRemoveIamBindingt  s   


zLRemoveIamPolicyBindingCommandGenerator._GetModifiedIamPolicyRemoveIamBindingc                    r  )a  Generates a remove-iam-policy-binding command.

    A remove-iam-policy-binding command removes a binding from a IAM policy. A
    binding consists of a member, a role to define the role of the member, and
    an optional condition to define in what condition the binding is valid.
    Two API methods are called to get and set the policy on the resource.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   r  c                       r  )zARemoveIamPolicyBindingCommandGenerator._Generate.<locals>.Commandz*Remove IAM policy binding command closure.c                    r  r  ) AddArgsForRemoveIamPolicyBindingr  r  r  r   r
   rK  r   rP  r  r    r!   rQ    r  zFRemoveIamPolicyBindingCommandGenerator._Generate.<locals>.Command.Argsc                    s   d}j jrj jjp|}|d }j|jd}j jr(j jjr(j jj|_|j jj|< 	|\}} 
| | ||S )r  r  r  r  )r   r/   r  r  r  r  r  rg   r   r   r  r   r   r   )rU  r\   r  r  r  r   r   r  r    r!   rV    s   zERemoveIamPolicyBindingCommandGenerator._Generate.<locals>.Command.RunNr  r    r  r    r!   rY    r  rY  r  r\  r    r  r!   r=    s   $z0RemoveIamPolicyBindingCommandGenerator._GenerateNr  )
r#   r$   r%   r&   r   r   REMOVE_IAM_POLICY_BINDINGrS   r  r=  r    r    r    r!   rN   n  s
    
rN   c                   @   r^  )rO   zGenerator for import commands.c                    r  )aL  Generates an import command.

    An import command has a single resource argument and an API method to call
    to get the resource. The result is from a local yaml file provided
    by the `--source` flag, or from stdout if nothing is provided.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   utilc                       .   e Zd ZdZefddZ fddZdS )z1ImportCommandGenerator._Generate.<locals>.CommandzImport command enclosure.c                    s0     |   jjrtj|  | jddd d S )Nz--sourcea  
            Path to a YAML file containing the configuration export data. The
            YAML file must not contain any output-only fields. Alternatively, you
            may omit this flag to read from standard input. For a schema
            describing the export/import format, see:
            $CLOUDSDKROOT/lib/googlecloudsdk/schemas/...

            $CLOUDSDKROOT is can be obtained with the following command:

              $ gcloud info --format='value(installation.sdk_root)'
          r   )r   r   r]   r
   r@  r   add_argumentrP  rR   r    r!   rQ    s   

z6ImportCommandGenerator._Generate.<locals>.Command.Argsc              
      s  j j|j}| }|j}||j}tj	|j
pddd} |jjjjj|j} j|||d}d }	jjrjjj}
jjj}z|}	W n= tjy } z0|jdks\|s^|jjjj_jjjrod j_njjjr{jjjj_  W Y d }~nd }~ww |
r||	krtj !d"|j#S j$||d\}}jjrd }|d urd"t%j&}'||||}(||S )	N-F)binary)message_typestreamschema_pathi  z/Request not sent for [{}]: No changes detected.r   rR  ))r   r   r   rd   r{   request_fieldfield_by_namer   r   ReadFromFileOrStdinsourceGetSchemaPathr`   r%  r   rg   rf   r#   Importimport_abort_if_equivalentcreate_if_not_existsr  apitools_exceptions	HttpErrorstatus_codecreate_requestno_create_asyncr]   create_asyncr   r   r  r  rU   rr   r   r   rT  r  r   )rU  r\   rd   r  r  resource_message_classdatar  imported_resourceexisting_resourcer  r  ru   r   r   r  export_utilr   r    r!   rV    sn   






z5ImportCommandGenerator._Generate.<locals>.Command.RunNr  r    r  r    r!   rY    s
    rY  )!googlecloudsdk.command_lib.exportr  r
   ImportCommandr\  r    r  r!   r=    s   Xz ImportCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   IMPORTrS   r=  r    r    r    r!   rO     rf  rO   c                   @   r^  )rP   zGenerator for export commands.c                    r  )aV  Generates an export command.

    An export command has a single resource argument and an API method to call
    to get the resource. The result is exported to a local yaml file provided
    by the `--destination` flag, or to stdout if nothing is provided.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   r  c                       r  )z1ExportCommandGenerator._Generate.<locals>.CommandzExport command enclosure.c                    s     |  | jddd d S )Nz--destinationaf  
            Path to a YAML file where the configuration will be exported.
            The exported data will not contain any output-only fields.
            Alternatively, you may omit this flag to write to standard output.
            For a schema describing the export/import format, see
            $CLOUDSDKROOT/lib/googlecloudsdk/schemas/...
          r   )r   r  rP  rR   r    r!   rQ  P  s
   

z6ExportCommandGenerator._Generate.<locals>.Command.Argsc                    s    |\}}jj|j} |jjjj	j
t|j}|drNt|j} j|||d W d    n1 s=w   Y  tjd|j|jS  j|tj|d d S )Ndestination)r   r  r  zExported [{}] to '{}'.)r   r   r   r   rd   r  r`   r%  r   rg   rf   r   r#   IsSpecifiedr   
FileWriterr  Exportr   r  r  rU   rr   sysstdout)rU  r\   rc  r   rd   r  r  r  r    r!   rV  ]  s,   



z5ExportCommandGenerator._Generate.<locals>.Command.RunNr  r    r  r    r!   rY  M  s
    rY  )r  r  r
   ExportCommandr\  r    r  r!   r=  ;  s   #z ExportCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   EXPORTrS   r=  r    r    r    r!   rP   6  rf  rP   c                   @   r^  )rQ   z%Generator for config export commands.c                    s6   ddl m  ddl m G  fdddtj}|S )a  Generates a config export command.

    A config export command has a resource argument as well as configuration
    export flags (such as --output-format and --path). It will export the
    configuration for one resource to stdout or to file, or will output a stream
    of configurations for all resources of the same type within a project to
    stdout, or to multiple files. Supported formats are `KRM` and `Terraform`.

    Returns:
      calliope.base.Command, The command that implements the spec.
    r   )flags)python_command_utilc                       s,   e Zd Ze fddZfddZdS )z7ConfigExportCommandGenerator._Generate.<locals>.Commandc                    sx   | j ddd}|  }jj}|D ]}|j D ]\}}d|_q|| q j|dd  	|   
|  d S )NT)mutexrequiredFproject)r`   )	add_groupr   r   r   specsr?   r  r   
AddAllFlagAddPathFlagAddFormatFlag)r   mutex_groupresource_groupr\   r   r  value)declarative_config_flagsr   r    r!   rQ    s   
z<ConfigExportCommandGenerator._Generate.<locals>.Command.Argsc                    sV   j j|j}|o|j}t|dd r j||jd dS  j||j||	 dS )Nr  )r\   r`   r3   )
r   r   r   r   r`   rl   	RunExportra   ParseResourceArgr1   )rU  r\   resource_argr`   )r  r   r    r!   rV    s   
z;ConfigExportCommandGenerator._Generate.<locals>.Command.RunNrW  r    r  r  r   r    r!   rY    s    rY  )+googlecloudsdk.command_lib.util.declarativer  r  r
   rY  r\  r    r  r!   r=  x  s   z&ConfigExportCommandGenerator._GenerateN)	r#   r$   r%   r&   r   r   CONFIG_EXPORTrS   r=  r    r    r    r!   rQ   s  rf  rQ   )Er&   
__future__r   r   r   r>  r   r  apitools.base.protorpcliter   rp   apitools.base.pyr   r   r  apitools.base.py.exceptionsr   googlecloudsdk.api_lib.utilr	   googlecloudsdk.callioper
   r   googlecloudsdk.command_lib.utilr   r   r   r   r   r   $googlecloudsdk.command_lib.util.argsr   googlecloudsdk.corer   r   googlecloudsdk.core.consoler   googlecloudsdk.core.resourcer   googlecloudsdk.core.utilr   r   YamlCommandTranslatorr   ListCommandCompleterr'   objectr   OperationPollerr[   rw   r   with_metaclassABCMetar   rJ   rD   rE   rF   rG   rH   rI   rK   rL   r  rM   rN   rO   rP   rQ   r    r    r    r!   <module>   sl    ?f   
? *5H5O+p.
eWq=