
    B                     z   d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlZddlZddl	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Z e
j:                  d      Z e
j:                  d      Zd Z 	 ddZ!d Z"d Z#d Z$d Z%d Z&d Z'd Z(d Z)d Z*d Z+	 ddZ,d Z-d Z.y) z%Bigtable authorized views API helper.    )absolute_import)division)unicode_literalsN)encoding)
exceptions)util)yaml)
console_io)resource_diff)edita      To create an authorized view, specify a JSON or YAML formatted
    representation of a valid authorized view protobuf.
    Lines beginning with "#" are ignored.

    Example:
    {
      "subsetView":
      {
        "rowPrefixes": ["store1#"],
        "familySubsets":
        {
          "column_family_name":
          {
            "qualifiers":["address"],
            "qualifierPrefixes":["tel"]
          }
        }
      },
      "deletionProtection": true
    }
  a      Please pecify a JSON or YAML formatted representation of the new authorized
    view. Lines beginning with "#" are ignored.

    Example:
    {
      "subsetView":
      {
        "rowPrefixes": ["store1#"],
        "familySubsets":
        {
          "column_family_name":
          {
            "qualifiers":["address"],
            "qualifierPrefixes":["tel"]
          }
        }
      },
      "deletionProtection": true
    }

    Current authorized view:
  c                     |j                   r&t        |j                   |j                        |_        nt	        d|j                        |_        d|j                  _        |S )a
  Parse argument and construct create authorized view request.

  Args:
    unused_ref: the gcloud resource (unused).
    args: input arguments.
    req: the real request to be sent to backend service.

  Returns:
    The real request to be sent to backend service.
  T)	is_createpre_encodedN)definition_file/ParseAuthorizedViewFromYamlOrJsonDefinitionFiler   authorizedView!PromptForAuthorizedViewDefinitionname)
unused_refargsreqs      7lib/googlecloudsdk/api_lib/bigtable/authorized_views.py!ModifyCreateAuthorizedViewRequestr   X   s\     
Hd..C ;D$4$4C !# 
*    c                 l   t        j                         j                  }| rt               }nt	        ||      }	 t        j                  |      }	 t        j                  |      }|st        |       t        j                  ||      }|S # t
        j                  $ r t        d      t
        j                  $ r}t        dj                  |            d}~ww xY w# t        j                   $ r}t#        dj                  |            d}~wt$        $ r}t#        dj                  |            d}~ww xY w)a  Prompt user to fill out a JSON/YAML format representation of an authorized view.

  Returns the parsed authorized view proto message from user's response.

  Args:
    is_create: True if the prompt is for creating an authorized view. False if
      the prompt is for updating an authorized view.
    pre_encoded: True if all binary fields in the authorized view definition are
      already Base64-encoded. We skip the step of applying Base64 encoding in
      this case.
    current_authorized_view: The current authorized view definition. Only used
      in the update case to be included as part of the initial commented prompt.

  Returns:
    an authorized view proto message with fields filled accordingly.

  Raises:
    ChildProcessError if the user did not save the temporary file.
    ChildProcessError if there is a problem running the editor.
    ValueError if the user's response does not follow YAML or JSON format.
    ValueError if the YAML/JSON object cannot be parsed as a valid authorized
      View.
  zEdit aborted by user.z1There was a problem applying your changes. [{0}].NzGProvided response is not a properly formatted YAML or JSON file. [{0}].zEProvided response cannot be parsed as a valid authorized view. [{0}].)r   GetAdminMessagesAuthorizedView%BuildCreateAuthorizedViewFileContents%BuildUpdateAuthorizedViewFileContentsr   
OnlineEditNoSaveExceptionChildProcessErrorEditorExceptionformatr	   load*Base64EncodingYamlAuthorizedViewDefinitionr   PyValueToMessageYAMLParseError
ValueErrorAttributeError)	r   r   current_authorized_viewauthorized_view_message_type	help_textcontenteauthorized_view_to_parseauthorized_views	            r   r   r   y   s'   4 "&!6!6!8!G!G57I5Iooi(G#yy101IJ//$&>O 
/ 
		 5
3
44			 
;BB1E  
		 
	&)  
 
O	 s;   B	 8C 	0C9CCD3.DD3D..D3c                    t        j                         j                  }	 t        j                  |       }|st        |       t        j                  ||      }|S # t        j                  t        j                  f$ r}t        j                  d|      d}~wt        $ r }t        dj                  | |            d}~ww xY w)a  Create an authorized view proto message from a YAML or JSON formatted definition file.

  Args:
    file_path: Path to the YAML or JSON definition file.
    pre_encoded: True if all binary fields in the authorized view definition are
      already Base64-encoded. We skip the step of applying Base64 encoding in
      this case.

  Returns:
    an authorized view proto message with fields filled accordingly.

  Raises:
    BadArgumentException if the file cannot be read.
    BadArgumentException if the file does not follow YAML or JSON format.
    ValueError if the YAML/JSON object cannot be parsed as a valid authorized
      view.
  z--definition-fileNz>File [{0}] cannot be parsed as a valid authorized view. [{1}].)r   r   r   r	   	load_pathr&   r   r'   FileLoadErrorr(   calliope_exceptionsBadArgumentExceptionr*   r)   r$   )	file_pathr   r,   r0   r1   r/   s         r   r   r      s    $ "&!6!6!8!G!G#~~i801IJ//$&>O 
 

d11	2 K

2
23F
JJ	 
HOOq	
 s#   8A #B?=BB?B::B?c                    | rd| vr| S | d   }d|v r,|j                  dg       D cg c]  }t        |       c}|d<   d|v r|d   j                         D ]m  \  }}d|v r,|j                  dg       D cg c]  }t        |       c}|d<   d|v r,|j                  dg       D cg c]  }t        |       c}|d<   ||d   |<   o | S c c}w c c}w c c}w )z\Apply base64 encoding to all binary fields in the authorized view definition in YAML format.
subsetViewrowPrefixesfamilySubsets
qualifiersqualifierPrefixes)getUtf8ToBase64itemsyaml_authorized_viewyaml_subset_viewsfamily_namefamily_subsets        r   r&   r&         	5I!I),7&&!1!5!5mR!H'!HAQ!H']# ((&6&G&M&M&O"]		&%2%6%6|R%H'
%HLO%H'
l# 
	-%2%6%67JB%O.
%OLO%O.
)* 8E'4 'P 
''
.
   C3C#Cc                    | rd| vr| S | d   }d|v r,|j                  dg       D cg c]  }t        |       c}|d<   d|v r|d   j                         D ]m  \  }}d|v r,|j                  dg       D cg c]  }t        |       c}|d<   d|v r,|j                  dg       D cg c]  }t        |       c}|d<   ||d   |<   o | S c c}w c c}w c c}w )z\Apply base64 decoding to all binary fields in the authorized view definition in YAML format.r9   r:   r;   r<   r=   )r>   Base64ToUtf8r@   rA   s        r   *Base64DecodingYamlAuthorizedViewDefinitionrK      rG   rH   c                 x    t        j                  t        j                  t        j                  |                   S )z)Encode a utf-8 string as a base64 string.)sixensure_textbase64	b64encodeensure_binary)rD   s    r   r?   r?     s'    	))#*;*;A*>?	@@r   c                     	 t        j                  t        j                  |             S # t        t
        j                  f$ r }t        dj                  | |            d}~ww xY w)z)Decode a base64 string as a utf-8 string.z_Error decoding base64 string [{0}] in the current authorized view definition into utf-8. [{1}].N)	rM   rN   rO   	b64decode	TypeErrorbinasciiErrorr)   r$   rD   errors     r   rJ   rJ     sX    ??6++A.//
X^^	$ 
	))/5)9 s   '* A#AA#c                 b   | | j                   y| j                   }|j                  |j                  D ]  }t        |        |j                  `|j                  j                  D ]F  }|j
                  }|j                  D ]  }t        |        |j                  D ]  }t        |        H yy)z>Raises a ValueError if the view contains non-ascii characters.N)r9   r:   
CheckAsciir;   additionalPropertiesvaluer<   r=   )r1   subset_view
row_prefixadditional_propertyrF   	qualifierqualifier_prefixs          r   (CheckOnlyAsciiCharactersInAuthorizedViewrb     s     : : B
**+(!--
 . **88MM)//m$//)9 0+==
#$ >	  N +r   c                     	 | j                  d       y# t        $ r }t        dj                  | |            d}~ww xY w)zCheck if a string is ascii.asciiztNon-ascii characters [{0}] found in the current authorized view definition, please use --pre-encoded instead. [{1}].N)decodeUnicodeErrorr)   r$   rW   s     r   rZ   rZ   .  sB    HHW	 
	@@Fq%@P s    	=8=c                  *   t        j                         } t        j                         D ]H  }| j	                  d       |r| j	                  d       | j	                  |       | j	                  d       J | j	                  d       | j                         S )zQBuilds the help text for creating an authorized view as the initial file content.# 
)ioStringIOCREATE_HELP
splitlineswritegetvalue)buflines     r   r   r   9  sh    
#$$&dIIcN	iinIIdOIIdO ' ))D/	r   c                     d}|j                   r&t        |j                   |j                        |_        nBt	        | j                         |j                         }t        d|j                  |      |_        |j                  j                  t        d|      }|j                  j                  t        d|      }|j                  r"|t	        | j                         d      }t        j                  |      }|j                  j                  |j                  j                  |_        |j                  j                  |j                  j                  |_	        t        j                         }t        j                   ||      }|j#                  d|	       |j%                         r)t'        j(                  d
|j%                         z   d       nt'        j(                  dd       d|j                  _        |j,                  rd|_        |S )a  Parse argument and construct update authorized view request.

  Args:
    original_ref: the gcloud resource.
    args: input arguments.
    req: the real request to be sent to backend service.

  Returns:
    The real request to be sent to backend service.
  NF)r   r   r+   r]   deletion_protection)check_ascii)originalchangeddefault)outzLDifference between the current authorized view and the new authorized view:
T)messagecancel_on_noz5The authorized view will NOT change with this update.)r   r   r   r   GetCurrentAuthorizedViewRelativeNamer   r9   AddFieldToUpdateMaskdeletionProtectioninteractivecopydeepcopyrk   rl   r   ResourceDiffPrintrp   r
   PromptContinuer   ignore_warningsignoreWarnings)original_refr   r   r+   new_authorized_viewrq   differs          r   !ModifyUpdateAuthorizedViewRequestr   F  s    !	Hd..C 7!!#)9)9%9 ;$$ 7C 	"".
}c
2C**6
4c
:C	& 8

#
#
%5! --(?@
$$0'*'9'9'D'D$
,,8



/
/ , ++-C''(2EF LLL$
||~$ LLN	
  I !#	C	*r   c                 (   t        j                         }t        j                         j                  |       }	 |j                  j                  |      }|rt        |       |S # t        j                  $ r}t        j                  |      d}~ww xY w)a  Get the current authorized view resource object given the authorized view name.

  Args:
    authorized_view_name: The name of the authorized view.
    check_ascii: True if we should check to make sure that the returned
      authorized view contains only ascii characters.

  Returns:
    The view resource object.

  Raises:
    ValueError if check_ascii is true and the current authorized view definition
    contains invalid non-ascii characters.
  )r   N)r   GetAdminClientr   =BigtableadminProjectsInstancesTablesAuthorizedViewsGetRequest)projects_instances_tables_authorizedViewsGetrb   api_exceptions	HttpErrorr   HttpException)authorized_view_nameru   clientrequestr1   rX   s         r   r|   r|     s      &!!#aa b '*FFJJO .?		!	! *

"
"5
))*s   )A$ $B7BBc                     t        j                  |       }|st        |      }|dk(  r*t        j                  t        j                  |d            S |dk(  r(t        j                  t        j                  |            S y)z=Serializes a authorized view protobuf to either JSON or YAML.json   )indentr	   N)	r   MessageToDictrK   rM   	text_typer   dumpsr	   dump)r1   r   serialized_formatauthorized_view_dicts       r   SerializeToJsonOrYamlr     sq     "//@	E & ==$8CDD& ==#7899 !r   c                    t        j                         }t        j                         D ]H  }|j	                  d       |r|j	                  d       |j	                  |       |j	                  d       J t        | |      }|j                         D ]H  }|j	                  d       |r|j	                  d       |j	                  |       |j	                  d       J |j	                  d       |j                         S )a1  Builds the help text for updating an existing authorized view.

  Args:
    current_authorized_view: The current authorized view resource object.
    pre_encoded: When pre_encoded is False, user is passing utf-8 values for
      binary fields in the authorized view definition and expecting us to apply
      base64 encoding. Thus, we should also display utf-8 values in the help
      text, which requires base64 decoding the binary fields in the
      `current_authorized_view`.

  Returns:
    A string containing the help text for update authorized view.
  rh   ri   rj   )rk   rl   UPDATE_HELPrn   ro   r   rp   )r+   r   rq   rr   #serialized_original_authorized_views        r   r   r     s     	#$$&dIIcN	iinIIdOIIdO ' )>{)% 2<<>dIIcN	iinIIdOIIdO ? ))D/	r   c                 v    |j                   }|r#|j                  |       dk(  r|dz   | z   |_         |S | |_         |S )zAdding a new field to the update mask of the UpdateAuthorizedViewRequest.

  Args:
    field: the field to be updated.
    req: the original UpdateAuthorizedViewRequest.

  Returns:
    req: the UpdateAuthorizedViewRequest with update mask refreshed.
  r   ,)
updateMaskcount)fieldr   update_masks      r   r~   r~     sI     +1$"S(50cn 
* CN	*r   )N)r   )/__doc__
__future__r   r   r   rO   rU   r   rk   r   textwrapapitools.base.pyr   r   r   googlecloudsdk.api_lib.bigtabler   googlecloudsdk.api_lib.utilgooglecloudsdk.callioper5   googlecloudsdk.corer	   googlecloudsdk.core.consoler
   googlecloudsdk.core.resourcer   googlecloudsdk.core.utilr   rM   dedentrm   r   r   r   r   r&   rK   r?   rJ   rb   rZ   r   r   r|   r   r   r~    r   r   <module>r      s     , &  '    	   % 9 0 2 E $ 2 6 ) 
hoo  . hoo  2D 59:z"J00A
%&
M`*> 5;: Fr   