
    <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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dZdZdZdZdZd Zd Z G d de       Z! ejD                  ejF                  jH                         G d de!ejJ                               Z& ejD                  ejF                  jN                  ejF                  jP                         G d de!ejJ                               Z)y)zendpoints deploy command.    )absolute_import)division)unicode_literalsN)config_reporter)
exceptions)services_util)
enable_api)base)log)
properties)
console_io)http_encodinga  Advice found for changes in the new service config. If this is a --validate-only run, the config push would have failed. See the outputted report for failure reason(s). If this is not a --validate-only run and you would like to ignore these warnings, rerun the command with --force. NOTE: setting this flag will ignore all change advice. For production systems, best practice is to set this for a single execution only after manually reviewing all changes with advice.zcAdvice found for changes in the new service config, but proceeding anyway because --force is set...zThe service {service_name} must exist in order to validate the configuration. Do you want to create the service in project {project_id}?zThe service {service_name} must exist in order to validate the configuration. To create the service in project {project_id}, rerun the command without the --validate-only flag.   c                 j    | j                  ddd       t        j                  j                  |        y)z:Add common arguments for this command to the given parser.service_config_file+zThe service configuration file (or files) containing the API specification to upload. Proto Descriptors, Open API (Swagger) specifications, and Google Service Configuration files in JSON and YAML formats are acceptable.)nargshelpN)add_argumentr
   
ASYNC_FLAGAddToParserparsers    (lib/surface/endpoints/services/deploy.py_CommonArgsr   >   s4    /  1 //f%    c                    t        j                         }t        j                         }|j                  |       }|j                  j                  |      }|j                  }dj                  t        j                  j                  j                  j                  |       t        j                  j                  j                  j                  |            S )z3Generate a service management url for this service.)serviceNamezShttps://console.cloud.google.com/endpoints/api/{service}/overview?project={project})serviceproject)r   GetMessagesModuleGetClientInstance#ServicemanagementServicesGetRequestservicesGetproducerProjectIdformatsixmovesurllibparsequote)r   messagesclientget_requestresponser    s         r   GenerateManagementUrlr1   J   s     ,,.(**,&<< = + __  -(&&'117ii&&,,227;ii&&,,227; 28 2=>r   c                   ^    e Zd ZdZed        Zd Zej                  fdZ	d
dZ
d Zd Zd Zy	)_BaseDeployz0Create deploy base class for all release tracks.c                 n    t        |        | j                  ddd       | j                  ddddd	       y
)zArgs is called by calliope to gather arguments for this command.

    Args:
      parser: An argparse parser that you can use to add arguments that go
          on the command line after this command. Positional arguments are
          allowed.
    z--validate-only
store_truezIf included, the command validates the service configuration(s), but does not deploy them. The service must exist in order to validate the configuration(s).)actionr   z--forcez-fFz]Force the deployment even if any hazardous changes to the service configuration are detected.)r6   defaultr   N)r   r   r   s    r   Argsz_BaseDeploy.Argsa   sP     
.  / 3  4r   c                     t        j                         }|j                  j                  }||j                  k7  rt        j                  |      }|j                  |t        j                  j                  |      |      S )a0  Constructs a ConfigFile message from a config file.

    Args:
      file_contents: The contents of the config file.
      filename: The full path to the config file.
      file_type: FileTypeValueValuesEnum describing the type of config file.

    Returns:
      The constructed ConfigFile message.
    )fileContentsfilePathfileType)
r   r!   
ConfigFileFileTypeValueValuesEnumFILE_DESCRIPTOR_SET_PROTOr   Encodeospathbasename)selffile_contentsfilename	file_typer-   
file_typess         r   MakeConfigFileMessagez!_BaseDeploy.MakeConfigFileMessagez   sq     ..0H$$<<JJ888#**=9m"!!(+   r   c                    d}t        j                  |      }|j                  j                  |       |j                  j                          |j                         }|r|j                  sy|j                  }|D ]9  }|j                  s|t        k  r |dt        j                  |             |dz  }; |t        kD  r	 |d|       |S )a  Run and display results (if any) from the Push Advisor.

    Args:
      service: The name of the service for which to compare configs.
      service_config_id: The new config ID to compare against the active config.
      log_func: The function to which to pass advisory messages
        (default: log.warning).

    Returns:
      The number of advisory messages returned by the Push Advisor.
    r   z%s
   zL%s total changes with advice found, check config report file for full list.
)r   ConfigReporter
new_configSetConfigId
old_configSetConfigUseDefaultId	RunReportconfigChangesadvicesNUM_ADVICE_TO_PRINTr   PushAdvisorConfigChangeToString)	rD   r   service_config_idlog_funcnum_changes_with_advicereporterchange_reportchangeschanges	            r   ShowConfigReportz_BaseDeploy.ShowConfigReport   s      --g6H ##$56 --/&&(M ; ;))G	"%88
6 @@HJ1$  !4457 #"r   c                      y)a  Run the Push Advisor and return whether the command should abort.

    Args:
      unused_force: bool, unused in the default implementation.

    Returns:
      True if the deployment should be aborted due to warnings, otherwise
      False if it's safe to continue.
    F )rD   unused_forces     r   CheckPushAdvisorz_BaseDeploy.CheckPushAdvisor   s     r   c                 V   t         j                  j                  j                  j	                  d      }	 t        j                  |||       t        j                  j                  d       y# t        j                  $ r( t        j                  dj                  ||             Y yw xY w)zAttempt to enable a service. If lacking permission, log a warning.

    Args:
      service_name: The service to enable.
      is_async: If true, return immediately instead of waiting for the operation
          to finish.
    Trequired
zAttempted to enable service [{0}] on project [{1}], but did not have required permissions. Please ensure this service is enabled before using your Endpoints service.
N)r   VALUEScorer    r%   r	   EnableServicer   statusPrintservices_exceptionsEnableServiceExceptionwarningr'   )rD   service_nameis_async
project_ids       r   AttemptToEnableServicez"_BaseDeploy.AttemptToEnableService   s     ""''//33T3BJ
Cz<B 
jjt55 C	kk   "(j!ACCs   6A- -8B('B(c                    t        j                         }t        j                         }|j                  j                  }dx| _        x| _        }g }|j                  | _        d}| j                  s|j                  d      sd|_	        |j                  D ]  }t        j                  |      }t        j                  |g d      rt        j                  |      }	|	s$t        j                  dj                  |            d|	v rd|	vr$t        j                  d	j                  |            | j
                  s'|	j!                  d      r|	j!                  d      | _        |j#                  | j%                  |||j&                               |	j!                  d
      dk(  ra| j
                  s'|	j!                  d      r|	j!                  d      | _        |j#                  | j%                  |||j(                               nd|	v rwt+        |j                        dkD  r$t        j                  dj                  |            | j                  rt-        j.                  d      |	j!                  d      | _        g } nt        j                  dj                  |            t        j0                  |      r.|j#                  | j%                  |||j2                               Pt        j4                  |      r0d}|j#                  | j%                  |||j6                               t        j                  dj                  |             |rt9        j:                  d       d}
t        j<                  | j
                        st>        j@                  jB                  jD                  jG                  d      }| j                  r}tI        jJ                         s4t-        jL                  tN        j                  | j
                  |            tI        jP                  tR        j                  | j
                  |            syt        jT                  | j
                  |       d}
|rRt        jV                  | j
                  ||jX                  | j                        }t        jZ                  |      | _.        nwt        j^                  | j
                  t>        j@                  jB                  jD                  jG                  d      t        j                  |            }|j`                  | _.        | j\                  st-        jL                  d      | jc                  |jd                        ry| j                  s|jf                  ji                         }|jj                  j#                  |jf                  jh                  jm                  | j\                  d             |jg                  |      }|jo                  | j
                  |      }|jq                  || j
                        }|jr                  ju                  |      }t        jv                  ||jX                         |
r&| jy                  | j
                  |jX                         |S )aB  Run 'endpoints services deploy'.

    Args:
      args: argparse.Namespace, The arguments that this command was invoked
          with.

    Returns:
      The response from the Update API call.

    Raises:
      BadFileExceptionn: if the provided service configuration files are
          invalid or cannot be read.
    NFr'   none)z.jsonz.yamlz.ymlz;Could not read JSON or YAML from service config file [{0}].swaggerhostzMalformed input. Found Swagger service config in file [{}], but no host was specified. Add a host specification to the config file.typezgoogle.api.ServicenamerK   zAmbiguous input. Found normalized service configuration in file [{0}], but received multiple input files. To upload normalized service config, please provide it separately from other input files to avoid ambiguity.zYThe --validate-only flag is not supported when using normalized service configs as input.zPUnable to parse Open API, or Google Service Configuration specification from {0}TzqCould not determine the content type of file [{0}]. Supported extensions are .json .yaml .yml .pb and .descriptorzSupport for uploading uncompiled .proto files is deprecated and will soon be removed. Use compiled descriptor sets (.pb) instead.
rc   )rn   rp   )validate_onlyz,Failed to retrieve Service Configuration Id.g      Y@)keyvalue)percentages)r   trafficPercentStrategy)rolloutr   )=r   r!   r"   r=   r>   rn   service_versionrx   IsSpecifiedr'   r   ReadServiceConfigFileFilenameMatchesExtensionLoadJsonOrYamlcalliope_exceptionsBadFileExceptiongetappendrI   OPEN_API_YAMLSERVICE_CONFIG_YAMLlenr   InvalidFlagErrorIsProtoDescriptorr?   
IsRawProto
PROTO_FILEr   rm   DoesServiceExistr   rf   rg   r    r%   r   	CanPromptInvalidConditionErrorVALIDATE_NEW_ERRORPromptContinueVALIDATE_NEW_PROMPTCreateServicePushMultipleServiceConfigFilesasync_0GetServiceConfigIdFromSubmitConfigSourceResponserV   !PushNormalizedGoogleServiceConfigidra   forceTrafficPercentStrategyPercentagesValueadditionalPropertiesAdditionalPropertyRollout.ServicemanagementServicesRolloutsCreateRequestservices_rolloutsCreateProcessOperationResultrq   )rD   argsr-   r.   rH   config_contentsconfig_filesgive_proto_deprecate_warningr   service_config_dictwas_service_createdrp   push_config_resultr{   traffic_percent_strategyr}   rollout_createrollout_operations                     r   Runz_BaseDeploy.Run   s$    ..0H,,.F$$<<JAEEDE,L++D $)  d&6&6x&@dk#77%;;<OPo		/	/
9
; ,::?K"#44v124 4 ++..%66 &'!)* *
 ""':'>'>v'F 3 7 7 ?D 

((:M)3)A)ACD !$$V,0DD""':'>'>v'F 3 7 7 ?D


((:M)3)G)GIJ ** ))*Q.%668 :@':)	* * --78 8 255f=$
,
#44'(./B(CE E **+>?&&8K'1'K'KM	N ##$78'+$&&8K'1'<'<>	? "22BCI6#D%& 	&Q  8Z $	kkPQ
  ))$*;*;<$$))1155t5Dj 
		##%001C1J1J,, 2K 2E F F((&&!..: ' GH !!$"3"3Z@ (GG


\4;;**, 
H
H " 
 )JJ






 
 
(
(
,
,d
,
;

&
&
79  244d!!,,
8: :
 TZZ( 33DDFk&&--**;;NN(( O 79 "*!@!@! "A "#  ''!9 ! <g  NN'' O n !2299.I**+<dkkJ	##D$5$5t{{Cr   c                    |r| j                   s{t        j                  j                  dj	                  | j
                  | j                               t        | j                        }t        j                  j                  d|z          y y y )Nz7Service Configuration [{0}] uploaded for service [{1}]
zTo manage your API, go to: )rx   r   ri   rj   r'   rV   rn   r1   )rD   resources_were_displayedmanagement_urls      r   Epilogz_BaseDeploy.Epilog  su      (:(:	jj *+16$2H2H262C2C,EF -T->->?n	jj4~EF );r   NF)__name__
__module____qualname____doc__staticmethodr8   rI   r   rm   r]   ra   rq   r   r   r_   r   r   r3   r3   ^   sE    84 40. CF++ (#TC*qf	Gr   r3   c                       e Zd ZdZy)Deploya[  Deploys a service configuration for the given service name.

     This command is used to deploy a service configuration for a service
     to Google Service Management. As input, it takes one or more paths
     to service configurations that should be uploaded. These configuration
     files can be Proto Descriptors, Open API (Swagger) specifications,
     or Google Service Configuration files in JSON or YAML formats.

     If a service name is present in multiple configuration files (given
     in the `host` field in OpenAPI specifications or the `name` field in
     Google Service Configuration files), the first one will take precedence.

     This command will block until deployment is complete unless the
     `--async` flag is passed.

     ## EXAMPLES
     To deploy a single Open API service configuration, run:

       $ {command} ~/my_app/openapi.json

     To run the deployment asynchronously (non-blocking), run:

       $ {command} ~/my_app/openapi.json --async

     To deploy a service config with a Proto, run:

       $ {command} ~/my_app/service-config.yaml ~/my_app/service-protos.pb
  N)r   r   r   r   r_   r   r   r   r     s    r   r   c                       e Zd ZdZddZy)DeployBetaAlphaa  Deploys a service configuration for the given service name.

     This command is used to deploy a service configuration for a service
     to Google Service Management. As input, it takes one or more paths
     to service configurations that should be uploaded. These configuration
     files can be Proto Descriptors, Open API (Swagger) specifications,
     or Google Service Configuration files in JSON or YAML formats.

     If a service name is present in multiple configuration files (given
     in the `host` field in OpenAPI specifications or the `name` field in
     Google Service Configuration files), the first one will take precedence.

     When deploying a new service configuration to an already-existing
     service, some safety checks will be made comparing the new configuration
     to the active configuration. If any actionable advice is provided, it
     will be printed out to the log, and the deployment will be halted. It is
     recommended that these warnings be addressed before proceeding, but they
     can be overridden with the --force flag.

     This command will block until deployment is complete unless the
     `--async` flag is passed.

     ## EXAMPLES
     To deploy a single Open API service configuration, run:

       $ {command} ~/my_app/openapi.json

     To run the deployment asynchronously (non-blocking), run:

       $ {command} ~/my_app/openapi.json --async

     To deploy a service config with a Proto, run:

       $ {command} ~/my_app/service-config.yaml ~/my_app/service-protos.pb
  c                    |rt         j                  nt         j                  }| j                  | j                  | j
                  |      }|dkD  r:|r |dj                  t                     y |dj                  t                     yy)a1  Run the Push Advisor and return whether the command should abort.

    Args:
      force: bool, if True, this method will return False even if warnings are
        generated.

    Returns:
      True if the deployment should be aborted due to warnings, otherwise
      False if it's safe to continue.
    r   z{0}
TF)	r   rm   errorr]   rn   rV   r'   FORCE_ADVICE_STRINGADVICE_STRING)rD   r   rW   num_advicess       r   ra   z DeployBetaAlpha.CheckPushAdvisor  sv     $s{{H''4118=KQ	'!!"567
  	'!!-01r   Nr   )r   r   r   r   ra   r_   r   r   r   r     s    "Jr   r   )*r   
__future__r   r   r   rA    googlecloudsdk.api_lib.endpointsr   r   r   googlecloudsdk.api_lib.servicesr	   rk   googlecloudsdk.callioper
   r   googlecloudsdk.corer   r   googlecloudsdk.core.consoler   googlecloudsdk.core.utilr   six.moves.urllib.parser(   r   r   r   r   rT   r   r1   objectr3   ReleaseTracksReleaseTrackGACommandr   ALPHABETAr   r_   r   r   <module>r      s      &  ' 	 < 7 : 6 M ( E # * 2 2 EI : . 
  	&>({G& {G|	 D%%(()[$,,  *F D%%++T->->-C-CD<k4<< < E<r   