예제 #1
0
def GKEClusterSelfLink(kube_client):
  """Returns the selfLink of a cluster, if it is a GKE cluster.

  There is no straightforward way to obtain this information from the cluster
  API server directly. This method uses metadata on the Kubernetes nodes to
  determine the instance ID and project ID of a GCE VM, whose metadata is used
  to find the location of the cluster and its name.

  Args:
    kube_client: A Kubernetes client for the cluster to be registered.

  Returns:
    the full OnePlatform resource path of a GKE cluster, e.g.,
    //container.googleapis.com/project/p/location/l/cluster/c. If the cluster is
    not a GKE cluster, returns None.

  Raises:
    exceptions.Error: if there is an error fetching metadata from the cluster
      nodes
    calliope_exceptions.MinimumArgumentException: if a kubeconfig file
      cannot be deduced from the command line flags or environment
    <others?>
  """

  # Get the instance ID and provider ID of some VM. Since all of the VMs should
  # have the same cluster name, arbitrarily choose the first one that is
  # returned from kubectl.

  # The instance ID field is unique to GKE clusters: Kubernetes-on-GCE clusters
  # do not have this field.
  vm_instance_id, err = kube_client.GetResourceField(
      None, 'nodes',
      '.items[0].metadata.annotations.container\\.googleapis\\.com/instance_id')
  # If we cannot determine this is a GKE cluster, no resource link will be
  # attached.
  if err or (not vm_instance_id):
    return None

  # The provider ID field exists on both GKE-on-GCP and Kubernetes-on-GCP
  # clusters. Therefore, even though it contains all of the necessary
  # information, it's presence does not guarantee that this is a GKE cluster.
  vm_provider_id, err = kube_client.GetResourceField(
      None, 'nodes', '.items[0].spec.providerID')
  if err or not vm_provider_id:
    raise exceptions.Error(
        'Error retrieving VM provider ID for cluster node: {}'.format(
            err or 'field does not exist on object'))

  # Parse the providerID to determine the project ID and VM zone.
  matches = re.match(r'^gce://([^/]+?)/([^/]+?)/.+', vm_provider_id)
  if not matches or matches.lastindex != 2:
    raise exceptions.Error(
        'Error parsing project ID and VM zone from provider ID: unexpected format "{}" for provider ID'
        .format(vm_provider_id))
  project_id = matches.group(1)
  vm_zone = matches.group(2)

  # Call the compute API to get the VM instance with this instance ID.
  compute_client = _ComputeClient()
  request = compute_client.MESSAGES_MODULE.ComputeInstancesGetRequest(
      instance=vm_instance_id, project=project_id, zone=vm_zone)
  instance = compute_client.instances.Get(request)
  if not instance:
    raise exceptions.Error('Empty GCE instance returned from compute API.')
  if not instance.metadata:
    raise exceptions.Error(
        'GCE instance with empty metadata returned from compute API.')

  # Read the cluster name and location from the VM instance's metadata.

  # Convert the metadata message to a Python dict.
  metadata = {}
  for item in instance.metadata.items:
    metadata[item.key] = item.value

  cluster_name = metadata.get('cluster-name')
  cluster_location = metadata.get('cluster-location')

  if not cluster_name:
    raise exceptions.Error('Could not determine cluster name from instance.')
  if not cluster_location:
    raise exceptions.Error(
        'Could not determine cluster location from instance.')

  # Trim http prefix.
  container_endpoint = core_apis.GetEffectiveApiEndpoint(
      'container', 'v1').replace('https://', '', 1).replace('http://', '', 1)
  if container_endpoint.endswith('/'):
    container_endpoint = container_endpoint[:-1]
  return '//{}/projects/{}/locations/{}/clusters/{}'.format(
      container_endpoint, project_id, cluster_location, cluster_name)
예제 #2
0
 def Connect(self):
     global_endpoint = apis.GetEffectiveApiEndpoint(
         global_methods.SERVERLESS_API_NAME, self._version)
     self.endpoint = DeriveRegionalEndpoint(global_endpoint, self.region)
     with _OverrideEndpointOverrides(self.endpoint):
         yield self
예제 #3
0
def GetEffectiveMlEndpoint(region):
  """Returns regional ML Endpoint, or global if region not set."""
  endpoint = apis.GetEffectiveApiEndpoint(ML_API_NAME, ML_API_VERSION)
  if region and region != 'global':
    return DeriveMLRegionalEndpoint(endpoint, region)
  return endpoint
예제 #4
0
def MakeAnalyzeIamPolicyHttpRequests(args, api_version=V1P4ALPHA1_API_VERSION):
    """Manually make the analyze IAM policy request."""
    http_client = http.Http()

    if api_version == V1P4ALPHA1_API_VERSION:
        folder = None
        project = None
    else:
        folder = args.folder
        project = args.project

    parent = asset_utils.GetParentNameForAnalyzeIamPolicy(
        args.organization, project, folder)
    endpoint = apis.GetEffectiveApiEndpoint(API_NAME, api_version)
    url = '{0}{1}/{2}:{3}'.format(endpoint, api_version, parent,
                                  'analyzeIamPolicy')

    params = []
    if args.IsSpecified('full_resource_name'):
        params.extend([(
            _IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['resource_selector']
            + '.fullResourceName', args.full_resource_name)])

    if args.IsSpecified('identity'):
        params.extend([(
            _IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['identity_selector']
            + '.identity', args.identity)])

    if args.IsSpecified('roles'):
        params.extend([(
            _IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['access_selector'] +
            '.roles', r) for r in args.roles])
    if args.IsSpecified('permissions'):
        params.extend([(
            _IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['access_selector'] +
            '.permissions', p) for p in args.permissions])

    if args.expand_groups:
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.expandGroups', args.expand_groups)
        ])
    if args.expand_resources:
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.expandResources', args.expand_resources)
        ])
    if args.expand_roles:
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.expandRoles', args.expand_roles)
        ])

    if args.output_resource_edges:
        if (api_version == V1P4BETA1_API_VERSION or api_version
                == DEFAULT_API_VERSION) and (not args.show_response):
            raise gcloud_exceptions.InvalidArgumentException(
                '--output-resource-edges',
                'Must be set together with --show-response to take effect.')
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.outputResourceEdges', args.output_resource_edges)
        ])
    if args.output_group_edges:
        if (api_version == V1P4BETA1_API_VERSION or api_version
                == DEFAULT_API_VERSION) and (not args.show_response):
            raise gcloud_exceptions.InvalidArgumentException(
                '--output-group-edges',
                'Must be set together with --show-response to take effect.')
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.outputGroupEdges', args.output_group_edges)
        ])
    if api_version == V1P4ALPHA1_API_VERSION and args.IsSpecified(
            'output_partial_result_before_timeout'):
        params.extend([('options.outputPartialResultBeforeTimeout',
                        args.output_partial_result_before_timeout)])
    if (api_version == V1P4BETA1_API_VERSION or api_version
            == DEFAULT_API_VERSION) and args.IsSpecified('execution_timeout'):
        params.extend([(_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]
                        ['execution_timeout'],
                        six.text_type(args.execution_timeout) + 's')])

    if (api_version == V1P4BETA1_API_VERSION
            or api_version == DEFAULT_API_VERSION
        ) and args.analyze_service_account_impersonation:
        params.extend([
            (_IAM_POLICY_ANALYZER_VERSION_DICT[api_version]['options'] +
             '.analyzeServiceAccountImpersonation',
             args.analyze_service_account_impersonation)
        ])

    encoded_params = six.moves.urllib.parse.urlencode(params)
    response, raw_content = http_client.request(uri=url,
                                                headers=_HEADERS,
                                                method='POST',
                                                body=encoded_params)

    content = core_encoding.Decode(raw_content)

    if int(response['status']) != httplib.OK:
        http_error = api_exceptions.HttpError(response, content, url)
        raise exceptions.HttpException(http_error)

    response_message_class = GetMessages(api_version).AnalyzeIamPolicyResponse
    try:
        response = encoding.JsonToMessage(response_message_class, content)
        if (api_version == V1P4BETA1_API_VERSION or api_version
                == DEFAULT_API_VERSION) and (not args.show_response):
            return _RenderResponseforAnalyzeIamPolicy(
                response, args.analyze_service_account_impersonation)
        else:
            return response
    except ValueError as e:
        err_msg = ('Failed receiving proper response from server, cannot'
                   'parse received assets. Error details: ' + six.text_type(e))
        raise MessageDecodeError(err_msg)
예제 #5
0
def GetServiceName(api_version=DEFAULT_API_VERSION):
    """Gets the service name based on the configured API endpoint."""
    endpoint = apis.GetEffectiveApiEndpoint('privateca', api_version)
    return six.moves.urllib.parse.urlparse(endpoint).hostname
예제 #6
0
 def Connect(self):
     global_endpoint = apis.GetEffectiveApiEndpoint(self._api_name,
                                                    self._version)
     self.endpoint = DeriveRegionalEndpoint(global_endpoint, self.region)
     with _OverrideEndpointOverrides(self._api_name, self.endpoint):
         yield self
def _GetEffectiveEndpoint(location, track=base.ReleaseTrack.GA):
  """Returns regional GKE Multi-cloud Endpoint."""
  endpoint = apis.GetEffectiveApiEndpoint(
      api_util.MODULE_NAME, api_util.GetApiVersionForTrack(track))
  return _AppendLocation(endpoint, location)