示例#1
0
def ValidateInstanceID(value, param_name):
  """Performs syntax check on an instance ID; doesn't check whether it exists.

  Args:
    value: str, the instance ID to check
    param_name: str, the parameter's name; included in the exception's message

  Raises:
    exceptions.Error: if value is an invalid instance ID
  """
  if not value:
    raise exceptions.Error('Missing required parameter ' + param_name)

  if re.match(r'^\d+$', value):
    return

  raise exceptions.Error(
      'Invalid value `{value}` for parameter {param_name}. '
      'For details on valid instance IDs, refer to the criteria '
      'documented under the field `id` at: {url}'.format(
          value=value,
          param_name=param_name,
          url='https://cloud.google.com/compute/docs/reference/rest/v1/instances'
      ))
def _RetrieveWorkloadServiceAccount(workload_manifest):
    """Retrieve the service account used for the workload."""
    if not workload_manifest:
        raise WorkloadError('Cannot verify an empty workload from the cluster')

    try:
        workload_data = yaml.load(workload_manifest)
    except yaml.Error as e:
        raise exceptions.Error(
            'Invalid workload from the cluster {}'.format(workload_manifest),
            e)

    service_account = _GetNestedKeyFromManifest(workload_data, 'spec',
                                                'template', 'serviceAccount')
    return service_account
示例#3
0
    def GetMembershipOwnerID(self):
        """Looks up the owner id field in the Membership resource."""
        if not self.MembershipCRDExists():
            return None

        out, err = self._RunKubectl([
            'get', 'membership', 'membership', '-o',
            'jsonpath={.spec.owner.id}'
        ], None)
        if err:
            if 'NotFound' in err:
                return None
            raise exceptions.Error(
                'Error retrieving membership id: {}'.format(err))
        return out
示例#4
0
def ValidateUpdateMask(args, complex_type_dict):
    """Validate the update mask in update complex type requests."""
    update_masks = list(args.update_mask.split(','))
    for mask in update_masks:
        # walk the path in the dictionary to ensure it's correct
        mask_path = mask.split('.')
        mask_path_index = 0
        complex_type_walker = complex_type_dict
        while mask_path_index < len(mask_path):
            if mask_path[mask_path_index] not in complex_type_walker:
                raise exceptions.Error(
                    'unrecognized field in update_mask: {0}.'.format(mask))
            complex_type_walker = complex_type_walker[
                mask_path[mask_path_index]]
            mask_path_index += 1
示例#5
0
    def _get_feature(self, project):
        """Fetch the Config Management Feature.

    Args:
      project: project id

    Returns:
      configManagementFeature
    """
        try:
            name = 'projects/{0}/locations/global/features/{1}'.format(
                project, self.FEATURE_NAME)
            response = base.GetFeature(name)
        except apitools_exceptions.HttpUnauthorizedError as e:
            raise exceptions.Error(
                'You are not authorized to see the status of {} '
                'Feature from project [{}]. Underlying error: {}'.format(
                    self.FEATURE_DISPLAY_NAME, project, e))
        except apitools_exceptions.HttpNotFoundError as e:
            raise exceptions.Error(
                '{} Feature for project [{}] is not enabled'.format(
                    self.FEATURE_DISPLAY_NAME, project))

        return response
示例#6
0
    def IdentityProviderCRExists(self):
        """Verifies if the google Identity Provider CR exists."""
        if not self._IdentityProviderCRDExists():
            return None

        _, err = self._RunKubectl(
            ['get', 'identityproviders.security.cloud.google.com', 'google'],
            None)
        if err:
            if 'NotFound' in err:
                return False
            raise exceptions.Error(
                'Error retrieving the google Identity Provider CR: {}'.format(
                    err))
        return True
示例#7
0
    def Update(self):
        """Updates this operation with the latest state of the agent pod."""
        out, err = self.kube_client.GetPodField(self.namespace,
                                                self.agent_pod_name,
                                                '.status.phase')
        if err:
            self.done = True
            self.succeeded = False
            self.error = err
            return

        # The .status.phase field contains one of five values. They map to the
        # staus of this operation as follows:
        #   - "Pending": operation is ongoing
        #   - "Running": operation is ongoing
        #   - "Succeeded": operation is complete, successfully
        #   - "Failed": operation is complete, unsuccessfully
        #   - "Unknown": operation is complete, unsuccessfully
        # The JSONPath expression above prints the value of the .status.phase field
        # (i.e., one of these five strings) to stdout
        if out == 'Pending' or out == 'Running':
            return

        self.done = True
        if out == 'Failed':
            self.succeeded = False
            # TODO(b/130295119): Is there a way to get a failure message?
            self.error = exceptions.Error('Connect agent pod failed.')
            return
        if out == 'Unknown':
            self.succeeded = False
            self.error = exceptions.Error(
                'Connect agent pod in an unknown state.')
            return

        self.succeeded = True
示例#8
0
def _WriteTempFile(data):
  """Write a new temporary file and register for cleanup at program exit.

  Args:
    data: data to write to the file

  Returns:
    string: the path to the new temporary file

  Raises:
    Error: if the write failed
  """
  try:
    _, f = tempfile.mkstemp()
  except Exception as e:  # pylint: disable=broad-except
    raise exceptions.Error('failed to create temp file: {}'.format(e))

  try:
    files.WriteFileContents(f, data, private=True)
    atexit.register(lambda: os.remove(f))
    return f
  except Exception as e:  # pylint: disable=broad-except
    os.remove(f)
    raise exceptions.Error('failed to write temp file {}: {}'.format(f, e))
示例#9
0
  def _ClusterRequest(self, method, url, headers=None):
    """Internal method to make requests against the target cluster.

    Args:
      method: request method, e.g. GET
      url: request URL
      headers: dictionary of request headers

    Returns:
      Response body as a string.

    Raises:
      Error: If the response has a status code >= 400.
    """
    r = self.cluster_pool_manager.request(method, url, headers=headers)
    if not r:
      raise exceptions.Error('null response')
    elif r.status >= 400:
      raise exceptions.Error(
          'status: {}, reason: {}'.format(r.status, r.reason))
    elif not hasattr(r, 'data'):
      raise exceptions.Error('missing response data: {}'.format(r))

    return r.data.decode('utf-8')
    def Run(self, args):
        memberships = base.ListMemberships()
        if not memberships:
            raise exceptions.Error('No Memberships available in the fleet.')
        # User should choose an existing membership if not provide one
        if not args.membership:
            index = console_io.PromptChoice(
                options=memberships,
                message='Please specify a membership to '
                'unmanage in configmanagement:\n')
            membership = memberships[index]
        else:
            membership = args.membership
            if membership not in memberships:
                raise exceptions.Error(
                    'Membership {} is not in the fleet.'.format(membership))

        # Setup a patch to set the MembershipSpec to the empty proto ("delete").
        membership_key = self.MembershipResourceName(membership)
        specs = {membership_key: self.messages.MembershipFeatureSpec()}
        patch = self.messages.Feature(
            membershipSpecs=self.hubclient.ToMembershipSpecs(specs))

        self.Update(['membership_specs'], patch)
示例#11
0
  def Run(self, args):
    """This is what gets called when the user runs this command.

    Args:
      args: an argparse namespace. All the arguments that were provided to this
        command invocation.

    Returns:
      Some value that we want to have printed later.
    """
    repository_arg = args.repository
    if not repository_arg:
      repository_arg = 'gcr.io/{0}'.format(
          properties.VALUES.core.project.Get(required=True))

    # Throws if invalid.
    repository = util.ValidateRepositoryPath(repository_arg)

    def _DisplayName(c):
      """Display the fully-qualified name."""
      return '{0}/{1}'.format(repository, c)

    http_obj = http.Http()
    with docker_image.FromRegistry(basic_creds=util.CredentialProvider(),
                                   name=repository,
                                   transport=http_obj) as r:
      try:
        images = [{'name': _DisplayName(c)} for c in r.children()]
        return images
      except docker_http.V2DiagnosticException as err:
        if err.http_status_code == 403:
          raise exceptions.Error('Access denied: {0}'.format(repository))
        elif err.http_status_code == 404:
          raise exceptions.Error('Not found: {0}'.format(repository))
        else:
          raise
示例#12
0
def CreateWorkloadIdentityBucket(project, issuer_url, openid_config_json,
                                 openid_keyset_json):
    """Creates a storage bucket to serve the issuer's discovery information.

  Creates a bucket named after the first path segment of issuer_url,
  configures it as a public bucket, and uploads the provided OpenID Provider
  Configuration and JSON Web Key Set to the bucket.

  Args:
    project: The same project as this cluster's Hub membership.
    issuer_url: The issuer URL that uniquely identifies a cluster as an
                OpenID Provider.
    openid_config_json: The JSON OpenID Provider Configuration response from
                        the cluster's built-in OIDC discovery endpoint.
    openid_keyset_json: The OpenID Provider JSON Web Key Set response from the
                        cluster's built-in JWKS endpoint.

  Raises:
    exceptions.Error: If it fails to create, configure, and populate
                      the bucket.
  """
    try:
        issuer_name = _ParseBucketIssuerURL(issuer_url)

        storage_client = _StorageClient()
        _CreateBucketIfNotExists(storage_client, issuer_name, project)
        _SetPublicBucket(storage_client, issuer_name)

        # Do NOT add leading slash, doing so nests the bucket path inside a subdir
        # named "".
        config_name = '.well-known/openid-configuration'
        keyset_name = 'openid/v1/jwks'

        # TODO(b/151111297): This is the hardcoded Cache-Control value in K8s
        # clusters, but if the bucket approach makes it to beta (which it should
        # not, it's a temporary solution until Google can serve the keys), we should
        # read it out of the header from the cluster's response.
        cache_control = 'public, max-age=3600'
        config_content_type = 'application/json'
        keyset_content_type = 'application/jwk-set+json'

        _UploadToBucket(storage_client, issuer_name, config_name,
                        openid_config_json, config_content_type, cache_control)
        _UploadToBucket(storage_client, issuer_name, keyset_name,
                        openid_keyset_json, keyset_content_type, cache_control)
    except Exception as e:
        raise exceptions.Error('Failed to configure bucket for '
                               'Workload Identity: {}'.format(e))
示例#13
0
    def testDeleteWIMembershipContextManageBucketDeleteException(self):
        self.mock_kubernetes_client.GetNamespaceUID.return_value = 'fake-uid'
        self.mock_kubernetes_client.DeleteNamespace.return_value = None
        self.mock_kubernetes_client.CheckClusterAdminPermissions.return_value = True
        self.mock_kubernetes_client.NamespacesWithLabelSelector.return_value = [
            'gke-connect-12321'
        ]
        self.StartObjectPatch(kube_util, 'IsGKECluster', return_value=False)
        mock_delete_membership = self.StartObjectPatch(api_util,
                                                       'DeleteMembership')
        mock_delete_membership_resource = self.StartObjectPatch(
            exclusivity_util, 'DeleteMembershipResources')
        mock_delete_connect_namespace = self.StartObjectPatch(
            agent_util, 'DeleteConnectNamespace')
        self.StartObjectPatch(p_util, 'GetProjectNumber', return_value=12321)
        self.StartObjectPatch(exclusivity_util,
                              'GetMembershipCROwnerID',
                              return_value=None)

        self.mock_kubernetes_client.GetOpenIDConfiguration.return_value = json.dumps(
            {'issuer': TEST_BUCKET_ISSUER_URL})
        mock_delete_bucket = self.StartObjectPatch(
            api_util, 'DeleteWorkloadIdentityBucket')
        mock_delete_bucket.side_effect = exceptions.Error('Oops!')
        mock_get_membership = self.StartObjectPatch(api_util, 'GetMembership')
        membership = self._MakeMembership(description='my-cluster',
                                          external_id='fake-uid')
        mock_get_membership.return_value = membership
        self.mockValidateExclusivitySucceed()

        # Test that the command works and only bucket deletion is skipped.
        self.RunCommand([
            'my-cluster',
            '--kubeconfig=' + self.kubeconfig,
            '--context=test-context',
            '--project=fake-project',
            '--manage-workload-identity-bucket',
        ])

        self.mock_kubernetes_client.GetOpenIDConfiguration.assert_called_once_with(
        )
        mock_delete_bucket.assert_called_with(TEST_BUCKET_ISSUER_URL)

        mock_delete_connect_namespace.assert_called_once()
        mock_delete_membership.assert_called_with(
            'projects/fake-project/locations/global/memberships/my-cluster',
            self.track)
        mock_delete_membership_resource.assert_called_once()
  def Run(self, args):
    """This is what gets called when the user runs this command.

    Args:
      args: an argparse namespace. All the arguments that were provided to this
        command invocation.

    Returns:
      Some value that we want to have printed later.
    """

    wp_region = args.region

    release_track = self.ReleaseTrack()
    client = cloudbuild_util.GetClientInstance(release_track)
    messages = cloudbuild_util.GetMessagesModule(release_track)

    parent = properties.VALUES.core.project.Get(required=True)

    wp_name = args.WORKER_POOL

    # Get the workerpool ref
    wp_resource = resources.REGISTRY.Parse(
        None,
        collection='cloudbuild.projects.locations.workerPools',
        api_version=cloudbuild_util.RELEASE_TRACK_TO_API_VERSION[release_track],
        params={
            'projectsId': parent,
            'locationsId': wp_region,
            'workerPoolsId': wp_name,
        })

    # Send the Get request
    wp = client.projects_locations_workerPools.Get(
        messages.CloudbuildProjectsLocationsWorkerPoolsGetRequest(
            name=wp_resource.RelativeName()))

    if release_track != base.ReleaseTrack.ALPHA:
      if wp.hybridPoolConfig is not None:
        raise exceptions.Error('NOT_FOUND: Requested entity was not found.')

    # Format the workerpool name for display
    try:
      wp.name = cloudbuild_util.WorkerPoolShortName(wp.name)
    except ValueError:
      pass  # Must be an old version.

    return wp
示例#15
0
def _Run(args, legacy_output=False, schema=None, message_encoding=None):
    """Creates one or more topics."""
    client = topics.TopicsClient()

    labels = labels_util.ParseCreateArgs(args,
                                         client.messages.Topic.LabelsValue)

    kms_key = None
    kms_ref = args.CONCEPTS.kms_key.Parse()
    if kms_ref:
        kms_key = kms_ref.RelativeName()
    else:
        # Did user supply any topic-encryption-key flags?
        for keyword in [
                'topic-encryption-key', 'topic-encryption-key-project',
                'topic-encryption-key-location', 'topic-encryption-key-keyring'
        ]:
            if args.IsSpecified(keyword.replace('-', '_')):
                raise core_exceptions.Error(
                    '--topic-encryption-key was not fully specified.')

    message_storage_policy_allowed_regions = args.message_storage_policy_allowed_regions

    failed = []
    for topic_ref in args.CONCEPTS.topic.Parse():
        try:
            result = client.Create(topic_ref,
                                   labels=labels,
                                   kms_key=kms_key,
                                   message_storage_policy_allowed_regions=
                                   message_storage_policy_allowed_regions,
                                   schema=schema,
                                   message_encoding=message_encoding)
        except api_ex.HttpError as error:
            exc = exceptions.HttpException(error)
            log.CreatedResource(topic_ref.RelativeName(),
                                kind='topic',
                                failed=exc.payload.status_message)
            failed.append(topic_ref.topicsId)
            continue

        if legacy_output:
            result = util.TopicDisplayDict(result)
        log.CreatedResource(topic_ref.RelativeName(), kind='topic')
        yield result

    if failed:
        raise util.RequestsFailedError(failed, 'create')
示例#16
0
def UpdateDockerCredentials(server):
  """Updates the docker config to have fresh credentials."""
  # Loading credentials will ensure that we're logged in.
  # And prompt/abort to 'run gcloud auth login' otherwise.
  cred = c_store.Load()

  # Ensure our credential has a valid access token,
  # which has the full duration available.
  c_store.Refresh(cred)
  if not cred.access_token:
    raise exceptions.Error('No access token could be obtained '
                           'from the current credentials.')

  # Update the docker configuration file passing the access token
  # as a password, and a benign value as the username.
  _UpdateDockerConfig(server, USERNAME, cred.access_token)
示例#17
0
  def Run(self, args):
    """Run 'services identity create'.

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

    Returns:
      Nothing.
    """
    project = properties.VALUES.core.project.Get(required=True)
    email, _ = serviceusage.GenerateServiceIdentity(project, args.service)
    if not email:
      raise exceptions.Error('Service identity not created successfully')
    else:
      log.status.Print('Service identity created: {0}'.format(email))
示例#18
0
def _CreateBucketIfNotExists(storage_client, bucket_name, project):
    """Create a GCS bucket if it does not exist.

  The bucket will be created with a Uniform Bucket Level Access policy, so that
  access can be configured with IAM.

  Does not raise any exceptions if the bucket already exists. Note that
  ownership is not checked by this method (an existing bucket could belong to a
  malicious user, so callers should either check that the bucket is contained in
  the project, or ensure that the bucket name can't be guessed and claimed of
  time).

  Args:
    storage_client: v1 storage client
    bucket_name: string, the name of the bucket to create
    project: string, the project to create the bucket in

  Raises:
    Error: If unable to create the bucket, and the bucket does not already
           exist.
  """
    m = storage_client.MESSAGES_MODULE
    # TODO(b/150317886): Bucket location default seems to be US (multiple region).
    # Unclear if this is based on request origin, gcloud settings, or just the
    # overall default. We might consider letting customers set a location, but
    # since we're also exploring having Gaia serve the keys, it's just as likely
    # we will move away from the GCS bucket approach before our beta.
    request = m.StorageBucketsInsertRequest(bucket=m.Bucket(
        iamConfiguration=m.Bucket.IamConfigurationValue(
            uniformBucketLevelAccess=m.Bucket.IamConfigurationValue.
            UniformBucketLevelAccessValue(enabled=True)),
        name=bucket_name),
                                            project=project)

    try:
        log.status.Print('Creating bucket {}'.format(bucket_name))
        storage_client.buckets.Insert(request)
        log.status.Print('Successfully created bucket {}'.format(bucket_name))
    except apitools_exceptions.HttpConflictError:
        # Bucket likely already exists, get the bucket to be sure.
        request = m.StorageBucketsGetRequest(bucket=bucket_name)
        storage_client.buckets.Get(request)
        log.status.Print('Bucket {} already exists. '
                         'Skipping creation.'.format(bucket_name))
    except Exception as e:
        raise exceptions.Error('Unable to create bucket {}: '
                               '{}'.format(bucket_name, e))
    def Run(self, args):
        """Run the helper command."""

        if args.method == DockerHelper.LIST:
            return {
                # This tells Docker that the secret will be an access token, not a
                # username/password.
                # Docker normally expects a prefixed 'https://' for auth configs.
                ('https://' + url): '_dcgcloud_token'
                for url in credential_utils.DefaultAuthenticatedRegistries()
            }

        elif args.method == DockerHelper.GET:
            # docker credential helper protocol expects that error is printed to
            # stdout.
            try:
                cred = c_store.Load(use_google_auth=True)
            except creds_exceptions.NoActiveAccountException:
                log.Print(
                    'You do not currently have an active account selected. '
                    'See https://cloud.google.com/sdk/docs/authorizing for more '
                    'information.')
                sys.exit(1)

            c_store.RefreshIfExpireWithinWindow(cred,
                                                window=TOKEN_MIN_LIFETIME)
            url = sys.stdin.read().strip()
            if (url.replace('https://', '', 1)
                    not in credential_utils.SupportedRegistries()):
                raise exceptions.Error(
                    'Repository url [{url}] is not supported'.format(url=url))
            # Putting an actual username in the response doesn't work. Docker will
            # then prompt for a password instead of using the access token.
            token = (cred.token if c_creds.IsGoogleAuthCredentials(cred) else
                     cred.access_token)

            return {
                'Secret': token,
                'Username': '******',
            }

        # Don't print anything if we are not supporting the given action.
        # The credential helper protocol also support 'store' and 'erase' actions
        # that don't apply here. The full spec can be found here:
        # https://github.com/docker/docker-credential-helpers#development
        args.GetDisplayInfo().AddFormat('none')
        return None
    def CleanUpRbacPolicy(self, membership, role, project_id, user,
                          anthos_support):
        """Get the RBAC cluster role binding policy."""
        # TODO(b/200192930): Remove the regex in next change.
        cluster_pattern = re.compile('^clusterrole/')
        namespace_pattern = re.compile('^role/')

        rbac_to_check = [('clusterrole',
                          self.RbacPolicyName('impersonate', project_id,
                                              membership, user)),
                         ('clusterrolebinding',
                          self.RbacPolicyName('impersonate', project_id,
                                              membership, user))]
        # Check anthos-support permission policy when '--anthos-support' specified.
        if anthos_support:
            rbac_to_check.append(('clusterrolebinding',
                                  self.RbacPolicyName('anthos', project_id,
                                                      membership, user)))
        # Check namespace permission policy when role is specified as
        # 'role/namespace/namespace-permission'.
        elif cluster_pattern.match(role.lower()):
            rbac_to_check.append(('clusterrolebinding',
                                  self.RbacPolicyName('permission', project_id,
                                                      membership, user)))
        # Check RBAC permission policy for general clusterrole.
        elif namespace_pattern.match(role.lower()):
            rbac_to_check.append(('rolebinding',
                                  self.RbacPolicyName('permission', project_id,
                                                      membership, user)))

        for rbac_policy_pair in rbac_to_check:
            rbac_type = rbac_policy_pair[0]
            rbac_name = rbac_policy_pair[1]
            out, err = self._RunKubectl(['delete', rbac_type, rbac_name], None)
            if err:
                if 'NotFound' in err:
                    log.status.Print(
                        '{} for RBAC policy: {} not exist.'.format(
                            rbac_type, rbac_name))
                    continue
                else:
                    raise exceptions.Error(
                        'Error deleting RBAC policy: {}'.format(err))
            else:
                log.status.Print('{}'.format(out))
        return True
def ParseYearlyPrice(api_version, price_string):
  """Parses money string as type Money."""
  if not price_string:
    return None
  try:
    units, cents, currency = _ParseMoney(price_string)
  except ValueError:
    raise exceptions.Error(
        ('Yearly price \'{}\' is invalid. Please specify the amount followed '
         'by the currency code.').format(price_string))

  if currency == '$':
    currency = 'USD'

  messages = registrations.GetMessagesModule(api_version)
  return messages.Money(
      units=int(units), nanos=cents * 10**7, currencyCode=currency)
示例#22
0
    def _GetSchedulerJobLocation(self):
        messages = apis.GetMessagesModule('cloudscheduler', 'v1')
        client = apis.GetClientInstance('cloudscheduler', 'v1')
        project = properties.VALUES.core.project.Get(required=True)

        try:
            locations_res = client.projects_locations.List(
                messages.CloudschedulerProjectsLocationsListRequest(
                    name='projects/' + project))
        except HttpNotFoundError:
            raise core_exceptions.Error(
                'You must create an App Engine application in your project to use '
                'Cloud Scheduler. Visit '
                'https://console.developers.google.com/appengine?project={} to '
                'add an App Engine application.'.format(project))

        return locations_res.locations[0].labels.additionalProperties[0].value
示例#23
0
def ParseYearlyPrice(price_string):
    """Parses money string as type Money."""
    if not price_string:
        return None
    try:
        units, cents, currency = _ParseMoney(price_string)
    except ValueError:
        raise exceptions.Error(
            'Yearly price \'{}\' is not valid.'.format(price_string))

    if currency == '$':
        currency = 'USD'

    messages = registrations.GetMessagesModule()
    return messages.Money(units=int(units),
                          nanos=cents * 10**7,
                          currencyCode=currency)
示例#24
0
    def Run(self, args):
        # pylint: disable=missing-docstring
        def Push(image, dest_name, creds, http_obj, src_name,
                 session_push_type):
            with session_push_type(dest_name, creds, http_obj) as push:
                push.upload(image)
                log.CreatedResource(dest_name)
            log.UpdatedResource(src_name)

        http_obj = http.Http()

        src_name = util.GetDockerImageFromTagOrDigest(args.src_image)
        dest_name = docker_name.Tag(args.dest_image)

        if '/' not in dest_name.repository:
            raise exceptions.Error(
                'Pushing to project root-level images is disabled. '
                'Please designate an image within a project, '
                'e.g. gcr.io/project-id/my-image:tag')

        console_io.PromptContinue('This will tag {0} with {1}'.format(
            src_name, dest_name),
                                  default=True,
                                  cancel_on_no=True)
        creds = util.CredentialProvider()
        with util.WrapExpectedDockerlessErrors():
            with docker_image_list.FromRegistry(src_name, creds,
                                                http_obj) as manifest_list:
                if manifest_list.exists():
                    Push(manifest_list, dest_name, creds, http_obj, src_name,
                         v2_2_session.Push)
                    return

            with v2_2_image.FromRegistry(src_name,
                                         creds,
                                         http_obj,
                                         accepted_mimes=docker_http.
                                         SUPPORTED_MANIFEST_MIMES) as v2_2_img:
                if v2_2_img.exists():
                    Push(v2_2_img, dest_name, creds, http_obj, src_name,
                         v2_2_session.Push)
                    return

            with v2_image.FromRegistry(src_name, creds, http_obj) as v2_img:
                Push(v2_img, dest_name, creds, http_obj, src_name,
                     v2_session.Push)
示例#25
0
文件: udp.py 项目: barber223/AudioApp
    def Modify(self, client, args, existing_check):
        """Returns a modified HealthCheck message."""
        # We do not support using 'update udp' with a health check of a
        # different protocol.
        if (existing_check.type !=
                client.messages.HealthCheck.TypeValueValuesEnum.UDP):
            raise core_exceptions.Error(
                'update udp subcommand applied to health check with protocol '
                + existing_check.type.name)

        # Description and PortName are the only attributes that can be cleared by
        # passing in an empty string (but we don't want to set it to empty string).
        if args.description:
            description = args.description
        elif args.description is None:
            description = existing_check.description
        else:
            description = None

        if args.port_name:
            port_name = args.port_name
        elif args.port_name is None:
            port_name = existing_check.udpHealthCheck.portName
        else:
            port_name = None

        new_health_check = client.messages.HealthCheck(
            name=existing_check.name,
            description=description,
            type=client.messages.HealthCheck.TypeValueValuesEnum.UDP,
            udpHealthCheck=client.messages.UDPHealthCheck(
                request=args.request or existing_check.udpHealthCheck.request,
                response=args.response
                or existing_check.udpHealthCheck.response,
                port=args.port or existing_check.udpHealthCheck.port,
                portName=port_name),
            checkIntervalSec=(args.check_interval
                              or existing_check.checkIntervalSec),
            timeoutSec=args.timeout or existing_check.timeoutSec,
            healthyThreshold=(args.healthy_threshold
                              or existing_check.healthyThreshold),
            unhealthyThreshold=(args.unhealthy_threshold
                                or existing_check.unhealthyThreshold),
        )
        return new_health_check
示例#26
0
def UpdateDockerCredentials(server, refresh=True):
    """Updates the docker config to have fresh credentials.

  This reads the current contents of Docker's keyring, and extends it with
  a fresh entry for the provided 'server', based on the active gcloud
  credential.  If a credential exists for 'server' this replaces it.

  Args:
    server: The hostname of the registry for which we're freshening
       the credential.
    refresh: Whether to force a token refresh on the active credential.

  Raises:
    core.credentials.exceptions.Error: There was an error loading the
      credentials.
  """

    if refresh:
        access_token = store.GetFreshAccessToken()
    else:
        access_token = store.GetAccessToken()

    if not access_token:
        raise exceptions.Error(
            'No access token could be obtained from the current credentials.')

    if _CredentialStoreConfigured():
        try:
            # Update the credentials stored by docker, passing the sentinel username
            # and access token.
            DockerLogin(server, _USERNAME, access_token)
        except client_lib.DockerError as e:
            # Only catch docker-not-found error
            if six.text_type(e) != client_lib.DOCKER_NOT_FOUND_ERROR:
                raise

            # Fall back to the previous manual .dockercfg manipulation
            # in order to support gcloud app's docker-binaryless use case.
            _UpdateDockerConfig(server, _USERNAME, access_token)
            log.warning(
                "'docker' was not discovered on the path. Credentials have been "
                'stored, but are not guaranteed to work with the Docker client '
                ' if an external credential store is configured.')
    else:
        _UpdateDockerConfig(server, _USERNAME, access_token)
示例#27
0
def Fingerprint(path, params):
    """Check for a Ruby app.

  Args:
    path: (str) Application path.
    params: (fingerprinting.Params) Parameters passed through to the
      fingerprinters.

  Returns:
    (RubyConfigurator or None) Returns a configurator if the path contains a
    Ruby app, or None if not.
  """
    appinfo = params.appinfo
    entrypoint = None
    is_explicit_runtime = False
    if appinfo:
        if appinfo.GetEffectiveRuntime() != 'ruby':
            return None
        is_explicit_runtime = True

        if appinfo.entrypoint:
            entrypoint = appinfo.entrypoint

    log.info('Checking for Ruby.')

    gemfile_path = os.path.join(path, 'Gemfile')
    if not os.path.isfile(gemfile_path):
        if is_explicit_runtime:
            raise exceptions.Error('Gemfile required for Ruby runtime')
        else:
            return None

    _CheckFiles(path)

    gems = _DetectGems()
    ruby_version = _DetectRubyInterpreter(path)
    packages = _DetectNeededPackages(gems)

    if not entrypoint:
        default_entrypoint = _DetectDefaultEntrypoint(path, gems)
        entrypoint = _ChooseEntrypoint(default_entrypoint, appinfo)
        if not entrypoint:
            return None

    return RubyConfigurator(path, params, ruby_version, entrypoint, packages)
    def GetRbacPolicy(self, membership, role, project_id, user,
                      anthos_support):
        """Get the RBAC cluster role binding policy."""
        not_found = False
        # TODO(b/200192930): Remove the regex in next change.
        cluster_pattern = re.compile('^clusterrole/')
        namespace_pattern = re.compile('^role/')

        rbac_to_check = [('clusterrole',
                          self.RbacPolicyName('impersonate', project_id,
                                              membership, user)),
                         ('clusterrolebinding',
                          self.RbacPolicyName('impersonate', project_id,
                                              membership, user))]
        # Check anthos-support permission policy when '--anthos-support' specified.
        if anthos_support:
            rbac_to_check.append(('clusterrolebinding',
                                  self.RbacPolicyName('anthos', project_id,
                                                      membership, user)))
        # Check namespace permission policy when role is specified as
        # 'role/namespace/namespace-permission'.
        elif cluster_pattern.match(role.lower()):
            rbac_to_check.append(('clusterrolebinding',
                                  self.RbacPolicyName('permission', project_id,
                                                      membership, user)))
        # Check RBAC permission policy for general clusterrole.
        elif namespace_pattern.match(role.lower()):
            rbac_to_check.append(('rolebinding',
                                  self.RbacPolicyName('permission', project_id,
                                                      membership, user)))

        for rbac_policy_pair in rbac_to_check:
            rbac_type = rbac_policy_pair[0]
            rbac_name = rbac_policy_pair[1]
            _, err = self._RunKubectl(['get', rbac_type, rbac_name])
            if err:
                if 'NotFound' in err:
                    not_found = True
                else:
                    raise exceptions.Error(
                        'Error retrieving RBAC policy: {}'.format(err))
            else:
                return False
        if not_found:
            return True
示例#29
0
def _UploadToBucket(storage_client, bucket_name, obj_name, str_data,
                    content_type, cache_control):
    """Uploads an object to a storage bucket.

  Args:
    storage_client: v1 storage client
    bucket_name: string, name of the bucket to upload the object to
    obj_name: string, name the object should be uploaded as (path in bucket)
    str_data: string, the string that comprises the object data to upload
    content_type: string, the Content-Type header the bucket will serve for the
                  uploaded object.
    cache_control: string, the Cache-Control header the bucket will serve for
                   the uploaded object.

  Raises:
    Error: If unable to upload the object to the bucket.
  """
    m = storage_client.MESSAGES_MODULE

    stream = six.StringIO(str_data)
    upload = transfer.Upload.FromStream(
        stream,
        mime_type=content_type,
        # Use apitools default (1048576 B).
        # GCS requires a multiple of 256 KiB.
        chunksize=None)
    request = m.StorageObjectsInsertRequest(bucket=bucket_name,
                                            name=obj_name,
                                            object=m.Object(
                                                contentType=content_type,
                                                cacheControl=cache_control))
    try:
        log.status.Print('Uploading object {} to bucket {}'.format(
            obj_name, bucket_name))
        # Uploading again just overwrites the object, so we don't have to worry
        # about conflicts with pre-existing objects.
        storage_client.objects.Insert(request, upload=upload)
        log.status.Print('Successfully uploaded object {} to bucket {}'.format(
            obj_name, bucket_name))
    except Exception as e:
        raise exceptions.Error('Unable to upload object to bucket {} at {}: '
                               '{}'.format(bucket_name, obj_name, e))
    finally:
        # apitools doesn't automatically close the stream.
        upload.stream.close()
示例#30
0
 def Run(self, args):
   project = properties.VALUES.core.project.GetOrFail()
   if not args.config_membership:
     memberships = base.ListMemberships(project)
     if not memberships:
       raise exceptions.Error('No Memberships available in Hub.')
     index = console_io.PromptChoice(
         options=memberships,
         message='Please specify a config membership:\n')
     config_membership = memberships[index]
   else:
     config_membership = args.config_membership
   config_membership = ('projects/{0}/locations/global/memberships/{1}'
                        .format(project,
                                os.path.basename(config_membership)))
   self.RunCommand(args, multiclusteringressFeatureSpec=(
       base.CreateMultiClusterIngressFeatureSpec(
           config_membership)))