mirror of
https://github.com/clearml/clearml
synced 2025-05-08 14:54:28 +00:00
Fix Jupyter password might not be used in some protected Jupyterlab instances
This commit is contained in:
parent
3012837bf3
commit
3377efe738
@ -700,28 +700,13 @@ class ScriptInfo(object):
|
||||
cookies = None
|
||||
password = None
|
||||
if server_info and server_info.get("password"):
|
||||
# we need to get the password
|
||||
from ....config import config
|
||||
|
||||
password = config.get("development.jupyter_server_password", "")
|
||||
password, cookies = cls._authenticate_jupyter(server_info)
|
||||
if not password:
|
||||
cls._get_logger().warning(
|
||||
"Password protected Jupyter Notebook server was found! "
|
||||
"Add `sdk.development.jupyter_server_password=<jupyter_password>` to ~/clearml.conf"
|
||||
)
|
||||
return os.path.join(os.getcwd(), "error_notebook_not_found.py")
|
||||
|
||||
r = requests.get(url=server_info["url"] + "login")
|
||||
cookies = {"_xsrf": r.cookies.get("_xsrf", "")}
|
||||
r = requests.post(
|
||||
server_info["url"] + "login?next",
|
||||
cookies=cookies,
|
||||
data={"_xsrf": cookies["_xsrf"], "password": password},
|
||||
)
|
||||
cookies.update(r.cookies)
|
||||
|
||||
# get api token from ENV - if not defined then from server info
|
||||
auth_token = os.getenv("JUPYTERHUB_API_TOKEN") or server_info.get("token") or ""
|
||||
verify = True
|
||||
try:
|
||||
r = requests.get(
|
||||
url=server_info["url"] + "api/sessions",
|
||||
@ -729,8 +714,10 @@ class ScriptInfo(object):
|
||||
headers={
|
||||
"Authorization": "token {}".format(auth_token),
|
||||
},
|
||||
verify=verify
|
||||
)
|
||||
except requests.exceptions.SSLError:
|
||||
verify = False
|
||||
# disable SSL check warning
|
||||
from urllib3.exceptions import InsecureRequestWarning
|
||||
|
||||
@ -743,13 +730,28 @@ class ScriptInfo(object):
|
||||
headers={
|
||||
"Authorization": "token {}".format(auth_token),
|
||||
},
|
||||
verify=False,
|
||||
verify=verify,
|
||||
)
|
||||
# enable SSL check warning
|
||||
import warnings
|
||||
|
||||
warnings.simplefilter("default", InsecureRequestWarning)
|
||||
|
||||
if r.status_code == 403 and server_info.get("password", False) is False:
|
||||
# server info json might set password=False even tho that is not the case
|
||||
# retry the request
|
||||
password, cookies = cls._authenticate_jupyter(server_info)
|
||||
if not password:
|
||||
return os.path.join(os.getcwd(), "error_notebook_not_found.py")
|
||||
r = requests.get(
|
||||
url=server_info["url"] + "api/sessions",
|
||||
cookies=cookies,
|
||||
headers={
|
||||
"Authorization": "token {}".format(auth_token),
|
||||
},
|
||||
verify=verify
|
||||
)
|
||||
|
||||
# send request to the jupyter server
|
||||
try:
|
||||
r.raise_for_status()
|
||||
@ -853,8 +855,47 @@ class ScriptInfo(object):
|
||||
|
||||
return script_entry_point
|
||||
except Exception:
|
||||
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def _authenticate_jupyter(cls, server_info):
|
||||
"""
|
||||
Authenticate to the Jupyter server using a password.
|
||||
The password is fetched from `CLEARML_JUPYTER_PASSWORD` env var or the
|
||||
`sdk.development.jupyter_server_password` configuration entry. The env var
|
||||
has a higher priority than the configuration entry.
|
||||
|
||||
:param server_info: A dictionary containing Jupyter server information
|
||||
|
||||
:return: If the authentication succeded, return a tuple contain the password used
|
||||
for authentication and the cookies obtained after authenticating. Otherwise,
|
||||
return a tuple of Nones
|
||||
"""
|
||||
cookies = None
|
||||
password = None
|
||||
# we need to get the password
|
||||
from ....config import config
|
||||
from ....config.defs import JUPYTER_PASSWORD
|
||||
|
||||
password = JUPYTER_PASSWORD.get(default=config.get("development.jupyter_server_password", ""))
|
||||
if not password:
|
||||
cls._get_logger().warning(
|
||||
"Password protected Jupyter Notebook server was found! "
|
||||
"Add `sdk.development.jupyter_server_password=<jupyter_password>` to ~/clearml.conf"
|
||||
)
|
||||
return None, None
|
||||
|
||||
r = requests.get(url=server_info["url"] + "login")
|
||||
cookies = {"_xsrf": r.cookies.get("_xsrf", "")}
|
||||
r = requests.post(
|
||||
server_info["url"] + "login?next",
|
||||
cookies=cookies,
|
||||
data={"_xsrf": cookies["_xsrf"], "password": password},
|
||||
)
|
||||
cookies.update(r.cookies)
|
||||
return password, cookies
|
||||
|
||||
@classmethod
|
||||
def is_sagemaker(cls):
|
||||
return Path(cls._sagemaker_metadata_path).is_file()
|
||||
|
@ -28,6 +28,8 @@ SUPPRESS_UPDATE_MESSAGE_ENV_VAR = EnvEntry("CLEARML_SUPPRESS_UPDATE_MESSAGE", "T
|
||||
|
||||
MAX_SERIES_PER_METRIC = EnvEntry("CLEARML_MAX_SERIES_PER_METRIC", default=100, type=int)
|
||||
|
||||
JUPYTER_PASSWORD = EnvEntry("CLEARML_JUPYTER_PASSWORD")
|
||||
|
||||
# Repository detection
|
||||
VCS_REPO_TYPE = EnvEntry("CLEARML_VCS_REPO_TYPE", "TRAINS_VCS_REPO_TYPE", default="git")
|
||||
VCS_REPOSITORY_URL = EnvEntry("CLEARML_VCS_REPO_URL", "TRAINS_VCS_REPO_URL")
|
||||
|
Loading…
Reference in New Issue
Block a user