Repository: kubeflow/pipelines

Issue:
IAP host shouldn't be restricted to a cloud endpoint url
In https://github.com/kubeflow/pipelines/commit/8d5ec83f5e26312ee6cecabe647e79f3c7bf1e9b#diff-1f65a44a2187458da0f00e0ebbe730e5R142-R145, the logic for `self._is_iap_host` uses a regex to ensure that the host name is of the form `https://<deployment>.endpoints.<project>.cloud.goog/pipeline`. This breaks for us, because we use a different hostname, and thus when trying to connect via IAP an auth token is not generated.

We are able to workaround this by overriding the client and `def _is_iap_host(self, host, client_id)`, but just wanted to raise this issue here.




Discussion:
/cc @IronPan @jessiezcc 
/cc @chensun 
Assigning to Renmin for triage
/assign @chensun 


/unassign @rmgogogo 

Resolving patch:
diff --git a/sdk/python/kfp/_auth.py b/sdk/python/kfp/_auth.py
--- a/sdk/python/kfp/_auth.py
+++ b/sdk/python/kfp/_auth.py
@@ -36,9 +36,14 @@ def get_gcp_access_token():
     Credentials. If not set, returns None. For more information, see
     https://cloud.google.com/sdk/gcloud/reference/auth/application-default/print-access-token
     """
+    token = None
     args = ['gcloud', 'auth', 'print-access-token']
-    # Casting to string to accommodate API server request schema.
-    return subprocess.check_output(args).rstrip().decode("utf-8")
+    try:
+      # Casting to string to accommodate API server request schema.
+      token = subprocess.check_output(args).rstrip().decode("utf-8")
+    except subprocess.CalledProcessError as e:
+      logging.warning('Failed to get GCP access token: %s', e)
+    return token
 
 def get_auth_token(client_id, other_client_id, other_client_secret):
     """Gets auth token from default service account or user account."""
diff --git a/sdk/python/kfp/_client.py b/sdk/python/kfp/_client.py
--- a/sdk/python/kfp/_client.py
+++ b/sdk/python/kfp/_client.py
@@ -116,11 +116,12 @@ def _load_config(self, host, client_id, namespace, other_client_id, other_client
 
     token = None
 
-    # Obtain the tokens if it is inverse proxy or IAP.
-    if self._is_inverse_proxy_host(host):
-      token = get_gcp_access_token()
-    if self._is_iap_host(host,client_id):
+    # Obtain the tokens if it is IAP or inverse proxy.
+    # client_id is only used for IAP, so when the value is provided, we assume it's IAP.
+    if client_id:
       token = get_auth_token(client_id, other_client_id, other_client_secret)
+    elif self._is_inverse_proxy_host(host):
+      token = get_gcp_access_token()
 
     if token:
       config.api_key['authorization'] = token
@@ -153,13 +154,6 @@ def _load_config(self, host, client_id, namespace, other_client_id, other_client
       config.host = config.host + '/' + Client.KUBE_PROXY_PATH.format(namespace)
     return config
 
-  def _is_iap_host(self, host, client_id):
-    if host and client_id:
-      if re.match(r'\S+.endpoints.\S+.cloud.goog/{0,1}$', host):
-        warnings.warn('Suffix /pipeline is not ignorable for IAP host.')
-      return re.match(r'\S+.endpoints.\S+.cloud.goog/pipeline', host)
-    return False
-
   def _is_inverse_proxy_host(self, host):
     if host:
       return re.match(r'\S+.googleusercontent.com/{0,1}$', host)


Test patch: