text: # -*- coding: utf-8 -*- #
  # Copyright 2017 Google LLC. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the "License");
  # you may not use this file except in compliance with the License.
  # You may obtain a copy of the License at
  #
  #    http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing, software
  # distributed under the License is distributed on an "AS IS" BASIS,
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  # See the License for the specific language governing permissions and
  # limitations under the License.
  
  """Register gcloud as a Docker credential helper."""
  
  from __future__ import absolute_import
  from __future__ import division
  from __future__ import unicode_literals
  
  import json
  
  from googlecloudsdk.calliope import base
  from googlecloudsdk.core import exceptions
  from googlecloudsdk.core import log
  from googlecloudsdk.core.console import console_io
  from googlecloudsdk.core.docker import credential_utils as cred_utils
  from googlecloudsdk.core.util import files as file_utils
  
  
  class ConfigureDockerError(exceptions.Error):
    """General command error class."""
  
  
  @base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA,
                      base.ReleaseTrack.GA)
  class ConfigureDockerBeta(base.Command):
    # pylint: disable=line-too-long
    r"""Register `gcloud` as a Docker credential helper.
  
    {command} adds the Docker `credHelper` entry to Docker's configuration file,
    or creates the file if it doesn't exist. This will register `gcloud` as the
    credential helper for all Google-supported Docker registries. If the Docker
    configuration already contains a `credHelper` entry, it will be overwritten.
  
    Note, `docker` and `gcloud` need to be on the same system `PATH` to work
    correctly.
  
    For more details on Docker credential helpers, see
    [](https://docs.docker.com/engine/reference/commandline/login/#credential-helpers).
  
    For more details on the Google Container Registry's Docker credential helper,
    see [](https://github.com/GoogleCloudPlatform/docker-credential-gcr).
    """
    # pylint: enable=line-too-long
  
    def DockerCredentialGcloudExists(self):
      return file_utils.SearchForExecutableOnPath(
          'docker-credential-gcloud') or file_utils.SearchForExecutableOnPath(
              'docker-credential-gcloud.cmd')
  
    def DockerExists(self):
      return file_utils.SearchForExecutableOnPath(
          'docker') or file_utils.SearchForExecutableOnPath('docker.exe')
  
    @staticmethod
    def Args(parser):
      """Set args for configure-docker."""
      parser.add_argument(
          'registries',
          nargs='?',
          help='The comma-separated list of registries to configure the credential helper for.'
      )
  
    def Run(self, args):
      """Run the configure-docker command."""
      if not self.DockerCredentialGcloudExists():
        log.warning('`docker-credential-gcloud` not in system PATH.\n'
                    'gcloud\'s Docker credential helper can be configured but '
                    'it will not work until this is corrected.')
  
      current_config = cred_utils.Configuration.ReadFromDisk()
  
      if self.DockerExists():
        if not current_config.SupportsRegistryHelpers():
          raise ConfigureDockerError(
              'Invalid Docker version: The version of your Docker client is '
              '[{}]; version [{}] or higher is required to support Docker '
              'credential helpers.'.format(
                  current_config.DockerVersion(),
                  cred_utils.MIN_DOCKER_CONFIG_HELPER_VERSION))
      else:
        log.warning(
            '`docker` not in system PATH.\n'
            '`docker` and `docker-credential-gcloud` need to be in the same PATH '
            'in order to work correctly together.\n'
            'gcloud\'s Docker credential helper can be configured but '
            'it will not work until this is corrected.')
  
      current_helpers = current_config.GetRegisteredCredentialHelpers()
      current_helper_map = {}
      if current_helpers:
        log.warning('Your config file at [{0}] contains these credential helper '
                    'entries:\n\n{1}'.format(
                        current_config.path,
                        json.dumps(current_helpers, indent=2)))
        current_helper_map = current_helpers[cred_utils.CREDENTIAL_HELPER_KEY]
  
      # Use the value from the argument, otherwise the default list.
      if args.registries:
        log.status.Print('Adding credentials for: {0}'.format(args.registries))
        registries = filter(self.CheckValidRegistry, args.registries.split(','))
        new_helpers = cred_utils.GetGcloudCredentialHelperConfig(registries)
      else:
        log.status.Print('Adding credentials for all GCR repositories.')
        log.warning('A long list of credential helpers may cause delays running '
                    '\'docker build\'. We recommend passing the registry name to '
                    'configure only the registry you are using.')
        new_helpers = cred_utils.GetGcloudCredentialHelperConfig()
  
      # Merge in the new settings so that existing configs are preserved.
      merged_helper_map = current_helper_map.copy()
      merged_helper_map.update(new_helpers[cred_utils.CREDENTIAL_HELPER_KEY])
  
      if current_helper_map == merged_helper_map:
        log.status.Print(
            'gcloud credential helpers already registered correctly.')
        return
  
      merged_helpers = {cred_utils.CREDENTIAL_HELPER_KEY: merged_helper_map}
      console_io.PromptContinue(
          message='After update, the following will be written to your Docker '
          'config file located at [{0}]:\n {1}'.format(
              current_config.path, json.dumps(merged_helpers, indent=2)),
          cancel_on_no=True)
  
      current_config.RegisterCredentialHelpers(merged_helper_map)
      log.status.Print('Docker configuration file updated.')
  
    def CheckValidRegistry(self, registry):
      if registry not in cred_utils.SupportedRegistries():
        log.warning('{0} is not a supported registry'.format(registry))
        return False
      return True
  