mirror of
https://github.com/clearml/clearml
synced 2025-06-26 18:16:07 +00:00
Fix unsafe Google Storage delete object
This commit is contained in:
parent
63c3e446a3
commit
6e15349b76
@ -14,3 +14,4 @@ ENV_HOST_VERIFY_CERT = EnvEntry("CLEARML_API_HOST_VERIFY_CERT", "TRAINS_API_HOST
|
|||||||
ENV_OFFLINE_MODE = EnvEntry("CLEARML_OFFLINE_MODE", "TRAINS_OFFLINE_MODE", type=bool, converter=safe_text_to_bool)
|
ENV_OFFLINE_MODE = EnvEntry("CLEARML_OFFLINE_MODE", "TRAINS_OFFLINE_MODE", type=bool, converter=safe_text_to_bool)
|
||||||
ENV_CLEARML_NO_DEFAULT_SERVER = EnvEntry("CLEARML_NO_DEFAULT_SERVER", "TRAINS_NO_DEFAULT_SERVER",
|
ENV_CLEARML_NO_DEFAULT_SERVER = EnvEntry("CLEARML_NO_DEFAULT_SERVER", "TRAINS_NO_DEFAULT_SERVER",
|
||||||
converter=safe_text_to_bool, type=bool, default=True)
|
converter=safe_text_to_bool, type=bool, default=True)
|
||||||
|
ENV_DISABLE_VAULT_SUPPORT = EnvEntry('CLEARML_DISABLE_VAULT_SUPPORT', type=bool)
|
||||||
|
@ -12,14 +12,23 @@ from six.moves.urllib.parse import urlparse, urlunparse
|
|||||||
|
|
||||||
from .callresult import CallResult
|
from .callresult import CallResult
|
||||||
from .defs import (
|
from .defs import (
|
||||||
ENV_VERBOSE, ENV_HOST, ENV_ACCESS_KEY, ENV_SECRET_KEY, ENV_WEB_HOST,
|
ENV_VERBOSE,
|
||||||
ENV_FILES_HOST, ENV_OFFLINE_MODE, ENV_CLEARML_NO_DEFAULT_SERVER, ENV_AUTH_TOKEN, )
|
ENV_HOST,
|
||||||
|
ENV_ACCESS_KEY,
|
||||||
|
ENV_SECRET_KEY,
|
||||||
|
ENV_WEB_HOST,
|
||||||
|
ENV_FILES_HOST,
|
||||||
|
ENV_OFFLINE_MODE,
|
||||||
|
ENV_CLEARML_NO_DEFAULT_SERVER,
|
||||||
|
ENV_AUTH_TOKEN,
|
||||||
|
ENV_DISABLE_VAULT_SUPPORT,
|
||||||
|
)
|
||||||
from .request import Request, BatchRequest # noqa: F401
|
from .request import Request, BatchRequest # noqa: F401
|
||||||
from .token_manager import TokenManager
|
from .token_manager import TokenManager
|
||||||
from ..config import load
|
from ..config import load
|
||||||
from ..utils import get_http_session_with_retry, urllib_log_warning_setup
|
from ..utils import get_http_session_with_retry, urllib_log_warning_setup
|
||||||
from ...debugging import get_logger
|
from ...debugging import get_logger
|
||||||
from ...utilities.pyhocon import ConfigTree
|
from ...utilities.pyhocon import ConfigTree, ConfigFactory
|
||||||
from ...version import __version__
|
from ...version import __version__
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -59,6 +68,7 @@ class Session(TokenManager):
|
|||||||
|
|
||||||
api_version = '2.1'
|
api_version = '2.1'
|
||||||
max_api_version = '2.1'
|
max_api_version = '2.1'
|
||||||
|
feature_set = 'basic'
|
||||||
default_demo_host = "https://demoapi.demo.clear.ml"
|
default_demo_host = "https://demoapi.demo.clear.ml"
|
||||||
default_host = default_demo_host
|
default_host = default_demo_host
|
||||||
default_web = "https://demoapp.demo.clear.ml"
|
default_web = "https://demoapp.demo.clear.ml"
|
||||||
@ -198,6 +208,7 @@ class Session(TokenManager):
|
|||||||
Session._client.append(('clearml-server', token_dict.get('server_version'), ))
|
Session._client.append(('clearml-server', token_dict.get('server_version'), ))
|
||||||
|
|
||||||
Session.max_api_version = Session.api_version = str(api_version)
|
Session.max_api_version = Session.api_version = str(api_version)
|
||||||
|
Session.feature_set = str(token_dict.get('feature_set', self.feature_set) or "basic")
|
||||||
except (jwt.DecodeError, ValueError):
|
except (jwt.DecodeError, ValueError):
|
||||||
(self._logger or get_logger()).warning(
|
(self._logger or get_logger()).warning(
|
||||||
"Failed parsing server API level, defaulting to {}".format(Session.api_version))
|
"Failed parsing server API level, defaulting to {}".format(Session.api_version))
|
||||||
@ -212,6 +223,38 @@ class Session(TokenManager):
|
|||||||
if self.force_max_api_version and self.check_min_api_version(self.force_max_api_version):
|
if self.force_max_api_version and self.check_min_api_version(self.force_max_api_version):
|
||||||
Session.max_api_version = Session.api_version = str(self.force_max_api_version)
|
Session.max_api_version = Session.api_version = str(self.force_max_api_version)
|
||||||
|
|
||||||
|
def _load_vaults(self):
|
||||||
|
if not self.check_min_api_version("2.15") or self.feature_set == "basic":
|
||||||
|
return
|
||||||
|
|
||||||
|
if ENV_DISABLE_VAULT_SUPPORT.get():
|
||||||
|
print("Vault support is disabled")
|
||||||
|
return
|
||||||
|
|
||||||
|
def parse(vault):
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
|
d = vault.get('data', None)
|
||||||
|
if d:
|
||||||
|
r = ConfigFactory.parse_string(d)
|
||||||
|
if isinstance(r, (ConfigTree, dict)):
|
||||||
|
return r
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed parsing vault {}: {}".format(vault.get("description", "<unknown>"), e))
|
||||||
|
|
||||||
|
# noinspection PyBroadException
|
||||||
|
try:
|
||||||
|
res = self.send_request("users", "get_vaults", json={"enabled": True, "types": ["config"]})
|
||||||
|
if res.ok:
|
||||||
|
vaults = res.json().get("data", {}).get("vaults", [])
|
||||||
|
data = list(filter(None, map(parse, vaults)))
|
||||||
|
if data:
|
||||||
|
self.config.set_overrides(*data)
|
||||||
|
elif res.status_code != 404:
|
||||||
|
raise Exception(res.json().get("meta", {}).get("result_msg", res.text))
|
||||||
|
except Exception as ex:
|
||||||
|
print("Failed getting vaults: {}".format(ex))
|
||||||
|
|
||||||
def _send_request(
|
def _send_request(
|
||||||
self,
|
self,
|
||||||
service,
|
service,
|
||||||
|
@ -86,6 +86,7 @@ class Config(object):
|
|||||||
self._env = env or os.environ.get("CLEARML_ENV", os.environ.get("TRAINS_ENV", Environment.default))
|
self._env = env or os.environ.get("CLEARML_ENV", os.environ.get("TRAINS_ENV", Environment.default))
|
||||||
self.config_paths = set()
|
self.config_paths = set()
|
||||||
self.is_server = is_server
|
self.is_server = is_server
|
||||||
|
self._overrides_configs = None
|
||||||
|
|
||||||
if self._verbose:
|
if self._verbose:
|
||||||
print("Config env:%s" % str(self._env))
|
print("Config env:%s" % str(self._env))
|
||||||
@ -177,6 +178,15 @@ class Config(object):
|
|||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if self._overrides_configs:
|
||||||
|
config = functools.reduce(
|
||||||
|
lambda cfg, override: ConfigTree.merge_configs(
|
||||||
|
cfg, override, copy_trees=True
|
||||||
|
),
|
||||||
|
self._overrides_configs,
|
||||||
|
config,
|
||||||
|
)
|
||||||
|
|
||||||
config["env"] = env
|
config["env"] = env
|
||||||
return config
|
return config
|
||||||
|
|
||||||
@ -401,3 +411,10 @@ class Config(object):
|
|||||||
bucket=bucket,
|
bucket=bucket,
|
||||||
host=host,
|
host=host,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def set_overrides(self, *dicts):
|
||||||
|
""" Set several override dictionaries or ConfigTree objects which should be merged onto the configuration """
|
||||||
|
self._overrides_configs = [
|
||||||
|
d if isinstance(d, ConfigTree) else ConfigFactory.from_dict(d) for d in dicts
|
||||||
|
]
|
||||||
|
self.reload()
|
||||||
|
@ -1543,7 +1543,19 @@ class _GoogleCloudStorageDriver(_Driver):
|
|||||||
return list(container.bucket.list_blobs())
|
return list(container.bucket.list_blobs())
|
||||||
|
|
||||||
def delete_object(self, object, **kwargs):
|
def delete_object(self, object, **kwargs):
|
||||||
object.delete()
|
try:
|
||||||
|
object.delete()
|
||||||
|
except Exception as ex:
|
||||||
|
try:
|
||||||
|
from google.cloud.exceptions import NotFound
|
||||||
|
if isinstance(ex, NotFound):
|
||||||
|
return False
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
name = getattr(object, "name", "")
|
||||||
|
log.warning("Failed deleting object {}: {}".format(name, ex))
|
||||||
|
return False
|
||||||
|
|
||||||
return not object.exists()
|
return not object.exists()
|
||||||
|
|
||||||
def get_object(self, container_name, object_name, *args, **kwargs):
|
def get_object(self, container_name, object_name, *args, **kwargs):
|
||||||
|
Loading…
Reference in New Issue
Block a user