Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for flexible config (via env var) for the pipline service and UI, fix broken links (pointed to API vs UI service) #1293

Merged
merged 9 commits into from
Jul 16, 2019

Conversation

yaronha
Copy link
Contributor

@yaronha yaronha commented May 7, 2019

provide a client SDK mechanism to override pipline API & UI service endpoint URLs via environment var
also fixes an issue of broken ui link when not using the default host (host is API ep and link is a UI ep)

this addresses issue #1235


This change is Reviewable

… and UI, fix broken links (pointed to API vs UI service)
@googlebot
Copy link
Collaborator

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@k8s-ci-robot
Copy link
Contributor

Hi @yaronha. Thanks for your PR.

I'm waiting for a kubeflow member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

1 similar comment
@k8s-ci-robot
Copy link
Contributor

Hi @yaronha. Thanks for your PR.

I'm waiting for a kubeflow member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository.

@yaronha
Copy link
Contributor Author

yaronha commented May 7, 2019

I signed it!

@googlebot
Copy link
Collaborator

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@yaronha
Copy link
Contributor Author

yaronha commented May 7, 2019

/assign @gaoning777

@yaronha
Copy link
Contributor Author

yaronha commented May 12, 2019

@gaoning777 @Ark-kun any update on this (tiny) PR ?

@Ark-kun
Copy link
Contributor

Ark-kun commented May 14, 2019

any update on this (tiny) PR ?

Sorry. We'll try to review it soon. @kevinbache WDYT?

@yaronha
Copy link
Contributor Author

yaronha commented May 26, 2019

@Ark-kun any updates on it? waiting for ~20 days on a rather simple patch

@gaoning777
Copy link
Contributor

/ok-to-test

@gaoning777
Copy link
Contributor

Would you mind resolving the conflicts? There seems to be a recent PR that is in conflict with this PR.

@Ark-kun
Copy link
Contributor

Ark-kun commented Jun 5, 2019

/lgtm

@k8s-ci-robot k8s-ci-robot removed the lgtm label Jun 5, 2019
@yaronha
Copy link
Contributor Author

yaronha commented Jun 5, 2019

@Ark-kun @gaoning777 test failed, but seem to be related to some CI/infra issue not in my code, can u give it a look?

@gaoning777
Copy link
Contributor

/test kubeflow-pipeline-e2e-test

@gaoning777
Copy link
Contributor

THe KFP also runs a sample test in the background, which shows "run-notebook-tfx-tests: AttributeError: 'Client' object has no attribute '_uihost'"

detailed logs are: https://prow.k8s.io/view/gcs/kubernetes-jenkins/pr-logs/pull/kubeflow_pipelines/1293/kubeflow-pipeline-sample-test/1136281786020532224

Copy link
Contributor

@hongye-sun hongye-sun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @yaronha, I recently added support to parameterize the namespace in the sdk in #1443. Other than the namespace, is there any other use case that you want to customize the API host by env var?

@@ -52,21 +55,23 @@ def __init__(self, host=None, client_id=None, namespace='kubeflow'):
"""

self._host = host
self._uihost = os.environ.get(KF_PIPELINES_UI_ENDPOINT_ENV, '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can default value be host? Otherwise, it will break currently local notebook + port forward use case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun i'm trying to make the UI and API ports configurable from the environment variables, this way we dont have to use proxy server when there is a proper API/UI gateway.

i wasnt clear about the port forward case, are you forwarding the UI port or the API port, currently the it seems like host and config.host identifies the API port and the current code is broken, im one place you have:

     if in_cluster:
      config.host = Client.IN_CLUSTER_DNS_NAME.format(namespace)
      return config

(i.e. host == API port)

in another:

    if config.host:
      config.host = os.path.join(config.host, Client.KUBE_PROXY_PATH.format(namespace))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yaronha, it makes sense to have API and UI addresses as separate configurations. We have a wiki to guide user to local port-forward on ambassador (https://www.kubeflow.org/docs/other-guides/accessing-uis/), which is the gateway for both API and UIs. We also have a notebook tutorial (https://github.com/amygdala/examples/blob/cookbook/cookbook/pipelines/notebooks/kfp_remote_deploy-no-IAP.ipynb) to guide user to use the SDK with local port forward and I think the UI link is working at this time. IAP guide (https://github.com/amygdala/examples/blob/cookbook/cookbook/pipelines/notebooks/kfp_remote_deploy.ipynb) should probably work, too. I think we should make the existing tutorial continues working, which assumes API and UI are both from the same host. That's why I suggest to keep the host as uihost if the env var is missing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun the examples above fall into two categories, using Proxy and using proprietary Google API gateway (IAP), we or others may have our own UI/API gateway with strong identity management (like IAP) so need a way to specify the the path to it.

The API and UI can be different hosts, since the API can be an internal cluster/DNS name, while the UI is accessed from a remote browser and need a publicly exposed URL.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yaronha, thanks for letting me know your use cases. let's keep both host and uihost. The only thing missing in the PR is that it changes the behavior for uihost if user doesn't provide env var, which might cause existing tutorial break. Could you make sure that in case of env var is missing, the uihost equals to host, just like today?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, i will update

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun did u review my changes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay. One more comment.

@@ -52,21 +55,23 @@ def __init__(self, host=None, client_id=None, namespace='kubeflow'):
"""

self._host = host
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host or os.environ.get(KF_PIPELINES_ENDPOINT_ENV)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

its a simple/standard way to say host if host else os.env...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean if we should set _host to be the value from env var if it's missing? Either it's from parameter or env var, it should be the same thing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun i consolidated self._host and self._uihost since _host wasnt used, now if no env var and host is provided it will use host (still not clear, how host will open up the browser on the UI if its the remote API endpoint)

@@ -52,21 +55,23 @@ def __init__(self, host=None, client_id=None, namespace='kubeflow'):
"""

self._host = host
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably change the name to _api_host

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// I think host is can be misleading here as people think they do not need the https:// schema. endpoint or uri might be more appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun it seems like self._host is not used anymore so maybe we should only keep one, once we clarify the use of API vs UI (above)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need two one for API and one for UI. API endpoint can be passed as parameter or env var. UI endpoint can only be customized via env var. The default value of UI endpoint if env var is missing is same as API host. This is useful if the endpoint is from ambassador use case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, sorry. API endpoint, might not need env var support as we support namespace customization.

@Ark-kun
Copy link
Contributor

Ark-kun commented Jun 5, 2019

/test kubeflow-pipeline-e2e-test

@Ark-kun
Copy link
Contributor

Ark-kun commented Jun 6, 2019

/test kubeflow-pipeline-e2e-test

@Ark-kun Ark-kun requested a review from IronPan June 7, 2019 01:01
config = self._load_config(host, client_id, namespace)
api_client = kfp_server_api.api_client.ApiClient(config)
self._run_api = kfp_server_api.api.run_service_api.RunServiceApi(api_client)
self._experiment_api = kfp_server_api.api.experiment_service_api.ExperimentServiceApi(api_client)

def _load_config(self, host, client_id, namespace):
config = kfp_server_api.configuration.Configuration()
config.host = config.host or os.environ.get(KF_PIPELINES_ENDPOINT_ENV)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

host = host or os.environ.get(KF_PIPELINES_ENDPOINT_ENV, None)

Otherwise, the code will fail if no host and env var are provided.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun i don't think get fails, will just return None
just try this: print('' or os.environ.get('SOMEKEY')) on your laptop

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you are right on the environ.get. You still need to change the config.host to host or you should change rest of the method body to check against config.host instead of host.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun you can see the line below, (if host: config.host = host), host will take precedence over the env var, i'm not clear why it doesnt address the case ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to go with test cases:

For example, (host=None, os.environ.get(KF_PIPELINES_ENDPOINT_ENV)='https://iap-endpoint/', client_id=''), in ln 70, iap token won't be fetched.

Another example, (host=None, os.environ.get(KF_PIPELINES_ENDPOINT_ENV)='https://iap-endpoint/', client_id=None), in ln 79, it will ignore config.host and override it with either incluster DNS or the default kubu config's endpoint.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@hongye-sun ok, got u, switched to host, make more sense

@yaronha
Copy link
Contributor Author

yaronha commented Jun 17, 2019

@IronPan @gaoning777 can u look into this PR?

@yaronha
Copy link
Contributor Author

yaronha commented Jun 18, 2019

/retest

@gaoning777
Copy link
Contributor

gaoning777 commented Jun 25, 2019

/ok-to-test

@gaoning777
Copy link
Contributor

/lgtm

@gaoning777
Copy link
Contributor

Could you resolve the conflicts? Sorry for the delay, I was OOO.

@k8s-ci-robot k8s-ci-robot removed the lgtm label Jul 16, 2019
@yaronha
Copy link
Contributor Author

yaronha commented Jul 16, 2019

@IronPan @gaoning777 i resolved the conflict, please review this before doing more changes on that file so i wont need to do the merge for the 4th time

@IronPan
Copy link
Member

IronPan commented Jul 16, 2019

/lgtm
/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: IronPan

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@yaronha
Copy link
Contributor Author

yaronha commented Jul 16, 2019

/retest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants