We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Allow passing fsspec options to WebHDFS to enable Kerberos and https
After #6662 it is no longer possible to use custom hdfscli clients with WebHDFS, as a result we are no longer able to connect using Kerberos or HTTPS.

fsspec allows passing in options to enable kerberos and https, we simply need to pass them through and expose them in the DVC config file:
https://filesystem-spec.readthedocs.io/en/latest/_modules/fsspec/implementations/webhdfs.html

This would also be an opportunity to remove the no longer used hdfscli options.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `dvc/fs/webhdfs.py`
Content:
```
1 import threading
2 
3 from funcy import cached_property, wrap_prop
4 
5 from dvc.path_info import CloudURLInfo
6 from dvc.scheme import Schemes
7 
8 # pylint:disable=abstract-method
9 from .fsspec_wrapper import CallbackMixin, FSSpecWrapper
10 
11 
12 class WebHDFSFileSystem(CallbackMixin, FSSpecWrapper):
13     scheme = Schemes.WEBHDFS
14     PATH_CLS = CloudURLInfo
15     REQUIRES = {"fsspec": "fsspec"}
16     PARAM_CHECKSUM = "checksum"
17 
18     def _with_bucket(self, path):
19         if isinstance(path, self.PATH_CLS):
20             return f"/{path.path.rstrip('/')}"
21         return path
22 
23     @staticmethod
24     def _get_kwargs_from_urls(urlpath):
25         from fsspec.implementations.webhdfs import WebHDFS
26 
27         return (
28             WebHDFS._get_kwargs_from_urls(  # pylint:disable=protected-access
29                 urlpath
30             )
31         )
32 
33     def _prepare_credentials(self, **config):
34         if "webhdfs_token" in config:
35             config["token"] = config.pop("webhdfs_token")
36 
37         return config
38 
39     @wrap_prop(threading.Lock())
40     @cached_property
41     def fs(self):
42         from fsspec.implementations.webhdfs import WebHDFS
43 
44         return WebHDFS(**self.fs_args)
45 
46     def checksum(self, path_info):
47         path = self._with_bucket(path_info)
48         ukey = self.fs.ukey(path)
49         return ukey["bytes"]
50
```

Path: `dvc/config_schema.py`
Content:
```
1 import os
2 from urllib.parse import urlparse
3 
4 from funcy import walk_values
5 from voluptuous import (
6     All,
7     Any,
8     Coerce,
9     Invalid,
10     Lower,
11     Optional,
12     Range,
13     Schema,
14 )
15 
16 Bool = All(
17     Lower,
18     Any("true", "false"),
19     lambda v: v == "true",
20     msg="expected true or false",
21 )
22 
23 
24 def supported_cache_type(types):
25     """Checks if link type config option consists only of valid values.
26 
27     Args:
28         types (list/string): type(s) of links that dvc should try out.
29     """
30     if types is None:
31         return None
32     if isinstance(types, str):
33         types = [typ.strip() for typ in types.split(",")]
34 
35     unsupported = set(types) - {"reflink", "hardlink", "symlink", "copy"}
36     if unsupported:
37         raise Invalid(
38             "Unsupported cache type(s): {}".format(", ".join(unsupported))
39         )
40 
41     return types
42 
43 
44 def Choices(*choices):
45     """Checks that value belongs to the specified set of values
46 
47     Args:
48         *choices: pass allowed values as arguments, or pass a list or
49             tuple as a single argument
50     """
51     return Any(*choices, msg="expected one of {}".format(", ".join(choices)))
52 
53 
54 def ByUrl(mapping):
55     schemas = walk_values(Schema, mapping)
56 
57     def validate(data):
58         if "url" not in data:
59             raise Invalid("expected 'url'")
60 
61         parsed = urlparse(data["url"])
62         # Windows absolute paths should really have scheme == "" (local)
63         if os.name == "nt" and len(parsed.scheme) == 1 and parsed.netloc == "":
64             return schemas[""](data)
65         if parsed.scheme not in schemas:
66             raise Invalid(f"Unsupported URL type {parsed.scheme}://")
67 
68         return schemas[parsed.scheme](data)
69 
70     return validate
71 
72 
73 class RelPath(str):
74     pass
75 
76 
77 REMOTE_COMMON = {
78     "url": str,
79     "checksum_jobs": All(Coerce(int), Range(1)),
80     "jobs": All(Coerce(int), Range(1)),
81     Optional("no_traverse"): Bool,  # obsoleted
82     "verify": Bool,
83 }
84 LOCAL_COMMON = {
85     "type": supported_cache_type,
86     Optional("protected", default=False): Bool,  # obsoleted
87     "shared": All(Lower, Choices("group")),
88     Optional("slow_link_warning", default=True): Bool,
89 }
90 HTTP_COMMON = {
91     "auth": All(Lower, Choices("basic", "digest", "custom")),
92     "custom_auth_header": str,
93     "user": str,
94     "password": str,
95     "ask_password": Bool,
96     "ssl_verify": Any(Bool, str),
97     "method": str,
98 }
99 WEBDAV_COMMON = {
100     "user": str,
101     "password": str,
102     "ask_password": Bool,
103     "token": str,
104     "cert_path": str,
105     "key_path": str,
106     "timeout": Coerce(int),
107     "ssl_verify": Any(Bool, str),
108 }
109 
110 SCHEMA = {
111     "core": {
112         "remote": Lower,
113         "checksum_jobs": All(Coerce(int), Range(1)),
114         Optional("interactive", default=False): Bool,
115         Optional("analytics", default=True): Bool,
116         Optional("hardlink_lock", default=False): Bool,
117         Optional("no_scm", default=False): Bool,
118         Optional("autostage", default=False): Bool,
119         Optional("experiments"): Bool,  # obsoleted
120         Optional("check_update", default=True): Bool,
121         "machine": Lower,
122     },
123     "cache": {
124         "local": str,
125         "s3": str,
126         "gs": str,
127         "hdfs": str,
128         "webhdfs": str,
129         "ssh": str,
130         "azure": str,
131         # This is for default local cache
132         "dir": str,
133         **LOCAL_COMMON,
134     },
135     "remote": {
136         str: ByUrl(
137             {
138                 "": {**LOCAL_COMMON, **REMOTE_COMMON},
139                 "s3": {
140                     "region": str,
141                     "profile": str,
142                     "credentialpath": str,
143                     "configpath": str,
144                     "endpointurl": str,
145                     "access_key_id": str,
146                     "secret_access_key": str,
147                     "session_token": str,
148                     Optional("listobjects", default=False): Bool,  # obsoleted
149                     Optional("use_ssl", default=True): Bool,
150                     "ssl_verify": Any(Bool, str),
151                     "sse": str,
152                     "sse_kms_key_id": str,
153                     "acl": str,
154                     "grant_read": str,
155                     "grant_read_acp": str,
156                     "grant_write_acp": str,
157                     "grant_full_control": str,
158                     "cache_regions": bool,
159                     "read_timeout": Coerce(int),
160                     "connect_timeout": Coerce(int),
161                     **REMOTE_COMMON,
162                 },
163                 "gs": {
164                     "projectname": str,
165                     "credentialpath": str,
166                     **REMOTE_COMMON,
167                 },
168                 "ssh": {
169                     "type": supported_cache_type,
170                     "port": Coerce(int),
171                     "user": str,
172                     "password": str,
173                     "ask_password": Bool,
174                     "keyfile": str,
175                     "timeout": Coerce(int),
176                     "gss_auth": Bool,
177                     "allow_agent": Bool,
178                     **REMOTE_COMMON,
179                 },
180                 "hdfs": {"user": str, "kerb_ticket": str, **REMOTE_COMMON},
181                 "webhdfs": {
182                     "hdfscli_config": str,
183                     "webhdfs_token": str,
184                     "user": str,
185                     "webhdfs_alias": str,
186                     **REMOTE_COMMON,
187                 },
188                 "azure": {
189                     "connection_string": str,
190                     "sas_token": str,
191                     "account_name": str,
192                     "account_key": str,
193                     "tenant_id": str,
194                     "client_id": str,
195                     "client_secret": str,
196                     "allow_anonymous_login": Bool,
197                     "exclude_environment_credential": Bool,
198                     "exclude_visual_studio_code_credential": Bool,
199                     "exclude_shared_token_cache_credential": Bool,
200                     "exclude_managed_identity_credential": Bool,
201                     **REMOTE_COMMON,
202                 },
203                 "oss": {
204                     "oss_key_id": str,
205                     "oss_key_secret": str,
206                     "oss_endpoint": str,
207                     **REMOTE_COMMON,
208                 },
209                 "gdrive": {
210                     "gdrive_use_service_account": Bool,
211                     "gdrive_client_id": str,
212                     "gdrive_client_secret": str,
213                     "gdrive_user_credentials_file": str,
214                     "gdrive_service_account_user_email": str,
215                     "gdrive_service_account_json_file_path": str,
216                     Optional("gdrive_trash_only", default=False): Bool,
217                     **REMOTE_COMMON,
218                 },
219                 "http": {**HTTP_COMMON, **REMOTE_COMMON},
220                 "https": {**HTTP_COMMON, **REMOTE_COMMON},
221                 "webdav": {**WEBDAV_COMMON, **REMOTE_COMMON},
222                 "webdavs": {**WEBDAV_COMMON, **REMOTE_COMMON},
223                 "remote": {str: object},  # Any of the above options are valid
224             }
225         )
226     },
227     "state": {
228         "dir": str,
229         "row_limit": All(Coerce(int), Range(1)),  # obsoleted
230         "row_cleanup_quota": All(Coerce(int), Range(0, 100)),  # obsoleted
231     },
232     "index": {
233         "dir": str,
234     },
235     "machine": {
236         str: {
237             "cloud": All(Lower, Choices("aws", "azure")),
238             "region": All(
239                 Lower, Choices("us-west", "us-east", "eu-west", "eu-north")
240             ),
241             "image": str,
242             "name": str,
243             "spot": Bool,
244             "spot_price": Coerce(float),
245             "instance_hdd_size": Coerce(int),
246             "instance_type": Lower,
247             "instance_gpu": Lower,
248             "ssh_private": str,
249             "startup_script": str,
250         },
251     },
252     # section for experimental features
253     "feature": {
254         Optional("machine", default=False): Bool,
255         # enabled by default. It's of no use, kept for backward compatibility.
256         Optional("parametrization", default=True): Bool,
257     },
258     "plots": {"html_template": str},
259     "exp": {
260         "code": str,
261         "data": str,
262         "models": str,
263         "metrics": str,
264         "params": str,
265         "plots": str,
266         "live": str,
267     },
268 }
269
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/dvc/config_schema.py b/dvc/config_schema.py
--- a/dvc/config_schema.py
+++ b/dvc/config_schema.py
@@ -179,10 +179,12 @@
                 },
                 "hdfs": {"user": str, "kerb_ticket": str, **REMOTE_COMMON},
                 "webhdfs": {
-                    "hdfscli_config": str,
-                    "webhdfs_token": str,
-                    "user": str,
-                    "webhdfs_alias": str,
+                    "kerberos": Bool,
+                    "kerberos_principal": str,
+                    "proxy_to": str,
+                    "ssl_verify": Any(Bool, str),
+                    "token": str,
+                    "use_https": Bool,
                     **REMOTE_COMMON,
                 },
                 "azure": {
diff --git a/dvc/fs/webhdfs.py b/dvc/fs/webhdfs.py
--- a/dvc/fs/webhdfs.py
+++ b/dvc/fs/webhdfs.py
@@ -31,9 +31,10 @@
         )
 
     def _prepare_credentials(self, **config):
-        if "webhdfs_token" in config:
-            config["token"] = config.pop("webhdfs_token")
-
+        self._ssl_verify = config.pop("ssl_verify", True)
+        principal = config.pop("kerberos_principal", None)
+        if principal:
+            config["kerb_kwargs"] = {"principal": principal}
         return config
 
     @wrap_prop(threading.Lock())
@@ -41,7 +42,9 @@
     def fs(self):
         from fsspec.implementations.webhdfs import WebHDFS
 
-        return WebHDFS(**self.fs_args)
+        fs = WebHDFS(**self.fs_args)
+        fs.session.verify = self._ssl_verify
+        return fs
 
     def checksum(self, path_info):
         path = self._with_bucket(path_info)

{"golden_diff": "diff --git a/dvc/config_schema.py b/dvc/config_schema.py\n--- a/dvc/config_schema.py\n+++ b/dvc/config_schema.py\n@@ -179,10 +179,12 @@\n                 },\n                 \"hdfs\": {\"user\": str, \"kerb_ticket\": str, **REMOTE_COMMON},\n                 \"webhdfs\": {\n-                    \"hdfscli_config\": str,\n-                    \"webhdfs_token\": str,\n-                    \"user\": str,\n-                    \"webhdfs_alias\": str,\n+                    \"kerberos\": Bool,\n+                    \"kerberos_principal\": str,\n+                    \"proxy_to\": str,\n+                    \"ssl_verify\": Any(Bool, str),\n+                    \"token\": str,\n+                    \"use_https\": Bool,\n                     **REMOTE_COMMON,\n                 },\n                 \"azure\": {\ndiff --git a/dvc/fs/webhdfs.py b/dvc/fs/webhdfs.py\n--- a/dvc/fs/webhdfs.py\n+++ b/dvc/fs/webhdfs.py\n@@ -31,9 +31,10 @@\n         )\n \n     def _prepare_credentials(self, **config):\n-        if \"webhdfs_token\" in config:\n-            config[\"token\"] = config.pop(\"webhdfs_token\")\n-\n+        self._ssl_verify = config.pop(\"ssl_verify\", True)\n+        principal = config.pop(\"kerberos_principal\", None)\n+        if principal:\n+            config[\"kerb_kwargs\"] = {\"principal\": principal}\n         return config\n \n     @wrap_prop(threading.Lock())\n@@ -41,7 +42,9 @@\n     def fs(self):\n         from fsspec.implementations.webhdfs import WebHDFS\n \n-        return WebHDFS(**self.fs_args)\n+        fs = WebHDFS(**self.fs_args)\n+        fs.session.verify = self._ssl_verify\n+        return fs\n \n     def checksum(self, path_info):\n         path = self._with_bucket(path_info)\n", "issue": "Allow passing fsspec options to WebHDFS to enable Kerberos and https\nAfter #6662 it is no longer possible to use custom hdfscli clients with WebHDFS, as a result we are no longer able to connect using Kerberos or HTTPS.\r\n\r\nfsspec allows passing in options to enable kerberos and https, we simply need to pass them through and expose them in the DVC config file:\r\nhttps://filesystem-spec.readthedocs.io/en/latest/_modules/fsspec/implementations/webhdfs.html\r\n\r\nThis would also be an opportunity to remove the no longer used hdfscli options.\n", "before_files": [{"content": "import threading\n\nfrom funcy import cached_property, wrap_prop\n\nfrom dvc.path_info import CloudURLInfo\nfrom dvc.scheme import Schemes\n\n# pylint:disable=abstract-method\nfrom .fsspec_wrapper import CallbackMixin, FSSpecWrapper\n\n\nclass WebHDFSFileSystem(CallbackMixin, FSSpecWrapper):\n    scheme = Schemes.WEBHDFS\n    PATH_CLS = CloudURLInfo\n    REQUIRES = {\"fsspec\": \"fsspec\"}\n    PARAM_CHECKSUM = \"checksum\"\n\n    def _with_bucket(self, path):\n        if isinstance(path, self.PATH_CLS):\n            return f\"/{path.path.rstrip('/')}\"\n        return path\n\n    @staticmethod\n    def _get_kwargs_from_urls(urlpath):\n        from fsspec.implementations.webhdfs import WebHDFS\n\n        return (\n            WebHDFS._get_kwargs_from_urls(  # pylint:disable=protected-access\n                urlpath\n            )\n        )\n\n    def _prepare_credentials(self, **config):\n        if \"webhdfs_token\" in config:\n            config[\"token\"] = config.pop(\"webhdfs_token\")\n\n        return config\n\n    @wrap_prop(threading.Lock())\n    @cached_property\n    def fs(self):\n        from fsspec.implementations.webhdfs import WebHDFS\n\n        return WebHDFS(**self.fs_args)\n\n    def checksum(self, path_info):\n        path = self._with_bucket(path_info)\n        ukey = self.fs.ukey(path)\n        return ukey[\"bytes\"]\n", "path": "dvc/fs/webhdfs.py"}, {"content": "import os\nfrom urllib.parse import urlparse\n\nfrom funcy import walk_values\nfrom voluptuous import (\n    All,\n    Any,\n    Coerce,\n    Invalid,\n    Lower,\n    Optional,\n    Range,\n    Schema,\n)\n\nBool = All(\n    Lower,\n    Any(\"true\", \"false\"),\n    lambda v: v == \"true\",\n    msg=\"expected true or false\",\n)\n\n\ndef supported_cache_type(types):\n    \"\"\"Checks if link type config option consists only of valid values.\n\n    Args:\n        types (list/string): type(s) of links that dvc should try out.\n    \"\"\"\n    if types is None:\n        return None\n    if isinstance(types, str):\n        types = [typ.strip() for typ in types.split(\",\")]\n\n    unsupported = set(types) - {\"reflink\", \"hardlink\", \"symlink\", \"copy\"}\n    if unsupported:\n        raise Invalid(\n            \"Unsupported cache type(s): {}\".format(\", \".join(unsupported))\n        )\n\n    return types\n\n\ndef Choices(*choices):\n    \"\"\"Checks that value belongs to the specified set of values\n\n    Args:\n        *choices: pass allowed values as arguments, or pass a list or\n            tuple as a single argument\n    \"\"\"\n    return Any(*choices, msg=\"expected one of {}\".format(\", \".join(choices)))\n\n\ndef ByUrl(mapping):\n    schemas = walk_values(Schema, mapping)\n\n    def validate(data):\n        if \"url\" not in data:\n            raise Invalid(\"expected 'url'\")\n\n        parsed = urlparse(data[\"url\"])\n        # Windows absolute paths should really have scheme == \"\" (local)\n        if os.name == \"nt\" and len(parsed.scheme) == 1 and parsed.netloc == \"\":\n            return schemas[\"\"](data)\n        if parsed.scheme not in schemas:\n            raise Invalid(f\"Unsupported URL type {parsed.scheme}://\")\n\n        return schemas[parsed.scheme](data)\n\n    return validate\n\n\nclass RelPath(str):\n    pass\n\n\nREMOTE_COMMON = {\n    \"url\": str,\n    \"checksum_jobs\": All(Coerce(int), Range(1)),\n    \"jobs\": All(Coerce(int), Range(1)),\n    Optional(\"no_traverse\"): Bool,  # obsoleted\n    \"verify\": Bool,\n}\nLOCAL_COMMON = {\n    \"type\": supported_cache_type,\n    Optional(\"protected\", default=False): Bool,  # obsoleted\n    \"shared\": All(Lower, Choices(\"group\")),\n    Optional(\"slow_link_warning\", default=True): Bool,\n}\nHTTP_COMMON = {\n    \"auth\": All(Lower, Choices(\"basic\", \"digest\", \"custom\")),\n    \"custom_auth_header\": str,\n    \"user\": str,\n    \"password\": str,\n    \"ask_password\": Bool,\n    \"ssl_verify\": Any(Bool, str),\n    \"method\": str,\n}\nWEBDAV_COMMON = {\n    \"user\": str,\n    \"password\": str,\n    \"ask_password\": Bool,\n    \"token\": str,\n    \"cert_path\": str,\n    \"key_path\": str,\n    \"timeout\": Coerce(int),\n    \"ssl_verify\": Any(Bool, str),\n}\n\nSCHEMA = {\n    \"core\": {\n        \"remote\": Lower,\n        \"checksum_jobs\": All(Coerce(int), Range(1)),\n        Optional(\"interactive\", default=False): Bool,\n        Optional(\"analytics\", default=True): Bool,\n        Optional(\"hardlink_lock\", default=False): Bool,\n        Optional(\"no_scm\", default=False): Bool,\n        Optional(\"autostage\", default=False): Bool,\n        Optional(\"experiments\"): Bool,  # obsoleted\n        Optional(\"check_update\", default=True): Bool,\n        \"machine\": Lower,\n    },\n    \"cache\": {\n        \"local\": str,\n        \"s3\": str,\n        \"gs\": str,\n        \"hdfs\": str,\n        \"webhdfs\": str,\n        \"ssh\": str,\n        \"azure\": str,\n        # This is for default local cache\n        \"dir\": str,\n        **LOCAL_COMMON,\n    },\n    \"remote\": {\n        str: ByUrl(\n            {\n                \"\": {**LOCAL_COMMON, **REMOTE_COMMON},\n                \"s3\": {\n                    \"region\": str,\n                    \"profile\": str,\n                    \"credentialpath\": str,\n                    \"configpath\": str,\n                    \"endpointurl\": str,\n                    \"access_key_id\": str,\n                    \"secret_access_key\": str,\n                    \"session_token\": str,\n                    Optional(\"listobjects\", default=False): Bool,  # obsoleted\n                    Optional(\"use_ssl\", default=True): Bool,\n                    \"ssl_verify\": Any(Bool, str),\n                    \"sse\": str,\n                    \"sse_kms_key_id\": str,\n                    \"acl\": str,\n                    \"grant_read\": str,\n                    \"grant_read_acp\": str,\n                    \"grant_write_acp\": str,\n                    \"grant_full_control\": str,\n                    \"cache_regions\": bool,\n                    \"read_timeout\": Coerce(int),\n                    \"connect_timeout\": Coerce(int),\n                    **REMOTE_COMMON,\n                },\n                \"gs\": {\n                    \"projectname\": str,\n                    \"credentialpath\": str,\n                    **REMOTE_COMMON,\n                },\n                \"ssh\": {\n                    \"type\": supported_cache_type,\n                    \"port\": Coerce(int),\n                    \"user\": str,\n                    \"password\": str,\n                    \"ask_password\": Bool,\n                    \"keyfile\": str,\n                    \"timeout\": Coerce(int),\n                    \"gss_auth\": Bool,\n                    \"allow_agent\": Bool,\n                    **REMOTE_COMMON,\n                },\n                \"hdfs\": {\"user\": str, \"kerb_ticket\": str, **REMOTE_COMMON},\n                \"webhdfs\": {\n                    \"hdfscli_config\": str,\n                    \"webhdfs_token\": str,\n                    \"user\": str,\n                    \"webhdfs_alias\": str,\n                    **REMOTE_COMMON,\n                },\n                \"azure\": {\n                    \"connection_string\": str,\n                    \"sas_token\": str,\n                    \"account_name\": str,\n                    \"account_key\": str,\n                    \"tenant_id\": str,\n                    \"client_id\": str,\n                    \"client_secret\": str,\n                    \"allow_anonymous_login\": Bool,\n                    \"exclude_environment_credential\": Bool,\n                    \"exclude_visual_studio_code_credential\": Bool,\n                    \"exclude_shared_token_cache_credential\": Bool,\n                    \"exclude_managed_identity_credential\": Bool,\n                    **REMOTE_COMMON,\n                },\n                \"oss\": {\n                    \"oss_key_id\": str,\n                    \"oss_key_secret\": str,\n                    \"oss_endpoint\": str,\n                    **REMOTE_COMMON,\n                },\n                \"gdrive\": {\n                    \"gdrive_use_service_account\": Bool,\n                    \"gdrive_client_id\": str,\n                    \"gdrive_client_secret\": str,\n                    \"gdrive_user_credentials_file\": str,\n                    \"gdrive_service_account_user_email\": str,\n                    \"gdrive_service_account_json_file_path\": str,\n                    Optional(\"gdrive_trash_only\", default=False): Bool,\n                    **REMOTE_COMMON,\n                },\n                \"http\": {**HTTP_COMMON, **REMOTE_COMMON},\n                \"https\": {**HTTP_COMMON, **REMOTE_COMMON},\n                \"webdav\": {**WEBDAV_COMMON, **REMOTE_COMMON},\n                \"webdavs\": {**WEBDAV_COMMON, **REMOTE_COMMON},\n                \"remote\": {str: object},  # Any of the above options are valid\n            }\n        )\n    },\n    \"state\": {\n        \"dir\": str,\n        \"row_limit\": All(Coerce(int), Range(1)),  # obsoleted\n        \"row_cleanup_quota\": All(Coerce(int), Range(0, 100)),  # obsoleted\n    },\n    \"index\": {\n        \"dir\": str,\n    },\n    \"machine\": {\n        str: {\n            \"cloud\": All(Lower, Choices(\"aws\", \"azure\")),\n            \"region\": All(\n                Lower, Choices(\"us-west\", \"us-east\", \"eu-west\", \"eu-north\")\n            ),\n            \"image\": str,\n            \"name\": str,\n            \"spot\": Bool,\n            \"spot_price\": Coerce(float),\n            \"instance_hdd_size\": Coerce(int),\n            \"instance_type\": Lower,\n            \"instance_gpu\": Lower,\n            \"ssh_private\": str,\n            \"startup_script\": str,\n        },\n    },\n    # section for experimental features\n    \"feature\": {\n        Optional(\"machine\", default=False): Bool,\n        # enabled by default. It's of no use, kept for backward compatibility.\n        Optional(\"parametrization\", default=True): Bool,\n    },\n    \"plots\": {\"html_template\": str},\n    \"exp\": {\n        \"code\": str,\n        \"data\": str,\n        \"models\": str,\n        \"metrics\": str,\n        \"params\": str,\n        \"plots\": str,\n        \"live\": str,\n    },\n}\n", "path": "dvc/config_schema.py"}], "after_files": [{"content": "import threading\n\nfrom funcy import cached_property, wrap_prop\n\nfrom dvc.path_info import CloudURLInfo\nfrom dvc.scheme import Schemes\n\n# pylint:disable=abstract-method\nfrom .fsspec_wrapper import CallbackMixin, FSSpecWrapper\n\n\nclass WebHDFSFileSystem(CallbackMixin, FSSpecWrapper):\n    scheme = Schemes.WEBHDFS\n    PATH_CLS = CloudURLInfo\n    REQUIRES = {\"fsspec\": \"fsspec\"}\n    PARAM_CHECKSUM = \"checksum\"\n\n    def _with_bucket(self, path):\n        if isinstance(path, self.PATH_CLS):\n            return f\"/{path.path.rstrip('/')}\"\n        return path\n\n    @staticmethod\n    def _get_kwargs_from_urls(urlpath):\n        from fsspec.implementations.webhdfs import WebHDFS\n\n        return (\n            WebHDFS._get_kwargs_from_urls(  # pylint:disable=protected-access\n                urlpath\n            )\n        )\n\n    def _prepare_credentials(self, **config):\n        self._ssl_verify = config.pop(\"ssl_verify\", True)\n        principal = config.pop(\"kerberos_principal\", None)\n        if principal:\n            config[\"kerb_kwargs\"] = {\"principal\": principal}\n        return config\n\n    @wrap_prop(threading.Lock())\n    @cached_property\n    def fs(self):\n        from fsspec.implementations.webhdfs import WebHDFS\n\n        fs = WebHDFS(**self.fs_args)\n        fs.session.verify = self._ssl_verify\n        return fs\n\n    def checksum(self, path_info):\n        path = self._with_bucket(path_info)\n        ukey = self.fs.ukey(path)\n        return ukey[\"bytes\"]\n", "path": "dvc/fs/webhdfs.py"}, {"content": "import os\nfrom urllib.parse import urlparse\n\nfrom funcy import walk_values\nfrom voluptuous import (\n    All,\n    Any,\n    Coerce,\n    Invalid,\n    Lower,\n    Optional,\n    Range,\n    Schema,\n)\n\nBool = All(\n    Lower,\n    Any(\"true\", \"false\"),\n    lambda v: v == \"true\",\n    msg=\"expected true or false\",\n)\n\n\ndef supported_cache_type(types):\n    \"\"\"Checks if link type config option consists only of valid values.\n\n    Args:\n        types (list/string): type(s) of links that dvc should try out.\n    \"\"\"\n    if types is None:\n        return None\n    if isinstance(types, str):\n        types = [typ.strip() for typ in types.split(\",\")]\n\n    unsupported = set(types) - {\"reflink\", \"hardlink\", \"symlink\", \"copy\"}\n    if unsupported:\n        raise Invalid(\n            \"Unsupported cache type(s): {}\".format(\", \".join(unsupported))\n        )\n\n    return types\n\n\ndef Choices(*choices):\n    \"\"\"Checks that value belongs to the specified set of values\n\n    Args:\n        *choices: pass allowed values as arguments, or pass a list or\n            tuple as a single argument\n    \"\"\"\n    return Any(*choices, msg=\"expected one of {}\".format(\", \".join(choices)))\n\n\ndef ByUrl(mapping):\n    schemas = walk_values(Schema, mapping)\n\n    def validate(data):\n        if \"url\" not in data:\n            raise Invalid(\"expected 'url'\")\n\n        parsed = urlparse(data[\"url\"])\n        # Windows absolute paths should really have scheme == \"\" (local)\n        if os.name == \"nt\" and len(parsed.scheme) == 1 and parsed.netloc == \"\":\n            return schemas[\"\"](data)\n        if parsed.scheme not in schemas:\n            raise Invalid(f\"Unsupported URL type {parsed.scheme}://\")\n\n        return schemas[parsed.scheme](data)\n\n    return validate\n\n\nclass RelPath(str):\n    pass\n\n\nREMOTE_COMMON = {\n    \"url\": str,\n    \"checksum_jobs\": All(Coerce(int), Range(1)),\n    \"jobs\": All(Coerce(int), Range(1)),\n    Optional(\"no_traverse\"): Bool,  # obsoleted\n    \"verify\": Bool,\n}\nLOCAL_COMMON = {\n    \"type\": supported_cache_type,\n    Optional(\"protected\", default=False): Bool,  # obsoleted\n    \"shared\": All(Lower, Choices(\"group\")),\n    Optional(\"slow_link_warning\", default=True): Bool,\n}\nHTTP_COMMON = {\n    \"auth\": All(Lower, Choices(\"basic\", \"digest\", \"custom\")),\n    \"custom_auth_header\": str,\n    \"user\": str,\n    \"password\": str,\n    \"ask_password\": Bool,\n    \"ssl_verify\": Any(Bool, str),\n    \"method\": str,\n}\nWEBDAV_COMMON = {\n    \"user\": str,\n    \"password\": str,\n    \"ask_password\": Bool,\n    \"token\": str,\n    \"cert_path\": str,\n    \"key_path\": str,\n    \"timeout\": Coerce(int),\n    \"ssl_verify\": Any(Bool, str),\n}\n\nSCHEMA = {\n    \"core\": {\n        \"remote\": Lower,\n        \"checksum_jobs\": All(Coerce(int), Range(1)),\n        Optional(\"interactive\", default=False): Bool,\n        Optional(\"analytics\", default=True): Bool,\n        Optional(\"hardlink_lock\", default=False): Bool,\n        Optional(\"no_scm\", default=False): Bool,\n        Optional(\"autostage\", default=False): Bool,\n        Optional(\"experiments\"): Bool,  # obsoleted\n        Optional(\"check_update\", default=True): Bool,\n        \"machine\": Lower,\n    },\n    \"cache\": {\n        \"local\": str,\n        \"s3\": str,\n        \"gs\": str,\n        \"hdfs\": str,\n        \"webhdfs\": str,\n        \"ssh\": str,\n        \"azure\": str,\n        # This is for default local cache\n        \"dir\": str,\n        **LOCAL_COMMON,\n    },\n    \"remote\": {\n        str: ByUrl(\n            {\n                \"\": {**LOCAL_COMMON, **REMOTE_COMMON},\n                \"s3\": {\n                    \"region\": str,\n                    \"profile\": str,\n                    \"credentialpath\": str,\n                    \"configpath\": str,\n                    \"endpointurl\": str,\n                    \"access_key_id\": str,\n                    \"secret_access_key\": str,\n                    \"session_token\": str,\n                    Optional(\"listobjects\", default=False): Bool,  # obsoleted\n                    Optional(\"use_ssl\", default=True): Bool,\n                    \"ssl_verify\": Any(Bool, str),\n                    \"sse\": str,\n                    \"sse_kms_key_id\": str,\n                    \"acl\": str,\n                    \"grant_read\": str,\n                    \"grant_read_acp\": str,\n                    \"grant_write_acp\": str,\n                    \"grant_full_control\": str,\n                    \"cache_regions\": bool,\n                    \"read_timeout\": Coerce(int),\n                    \"connect_timeout\": Coerce(int),\n                    **REMOTE_COMMON,\n                },\n                \"gs\": {\n                    \"projectname\": str,\n                    \"credentialpath\": str,\n                    **REMOTE_COMMON,\n                },\n                \"ssh\": {\n                    \"type\": supported_cache_type,\n                    \"port\": Coerce(int),\n                    \"user\": str,\n                    \"password\": str,\n                    \"ask_password\": Bool,\n                    \"keyfile\": str,\n                    \"timeout\": Coerce(int),\n                    \"gss_auth\": Bool,\n                    \"allow_agent\": Bool,\n                    **REMOTE_COMMON,\n                },\n                \"hdfs\": {\"user\": str, \"kerb_ticket\": str, **REMOTE_COMMON},\n                \"webhdfs\": {\n                    \"kerberos\": Bool,\n                    \"kerberos_principal\": str,\n                    \"proxy_to\": str,\n                    \"ssl_verify\": Any(Bool, str),\n                    \"token\": str,\n                    \"use_https\": Bool,\n                    **REMOTE_COMMON,\n                },\n                \"azure\": {\n                    \"connection_string\": str,\n                    \"sas_token\": str,\n                    \"account_name\": str,\n                    \"account_key\": str,\n                    \"tenant_id\": str,\n                    \"client_id\": str,\n                    \"client_secret\": str,\n                    \"allow_anonymous_login\": Bool,\n                    \"exclude_environment_credential\": Bool,\n                    \"exclude_visual_studio_code_credential\": Bool,\n                    \"exclude_shared_token_cache_credential\": Bool,\n                    \"exclude_managed_identity_credential\": Bool,\n                    **REMOTE_COMMON,\n                },\n                \"oss\": {\n                    \"oss_key_id\": str,\n                    \"oss_key_secret\": str,\n                    \"oss_endpoint\": str,\n                    **REMOTE_COMMON,\n                },\n                \"gdrive\": {\n                    \"gdrive_use_service_account\": Bool,\n                    \"gdrive_client_id\": str,\n                    \"gdrive_client_secret\": str,\n                    \"gdrive_user_credentials_file\": str,\n                    \"gdrive_service_account_user_email\": str,\n                    \"gdrive_service_account_json_file_path\": str,\n                    Optional(\"gdrive_trash_only\", default=False): Bool,\n                    **REMOTE_COMMON,\n                },\n                \"http\": {**HTTP_COMMON, **REMOTE_COMMON},\n                \"https\": {**HTTP_COMMON, **REMOTE_COMMON},\n                \"webdav\": {**WEBDAV_COMMON, **REMOTE_COMMON},\n                \"webdavs\": {**WEBDAV_COMMON, **REMOTE_COMMON},\n                \"remote\": {str: object},  # Any of the above options are valid\n            }\n        )\n    },\n    \"state\": {\n        \"dir\": str,\n        \"row_limit\": All(Coerce(int), Range(1)),  # obsoleted\n        \"row_cleanup_quota\": All(Coerce(int), Range(0, 100)),  # obsoleted\n    },\n    \"index\": {\n        \"dir\": str,\n    },\n    \"machine\": {\n        str: {\n            \"cloud\": All(Lower, Choices(\"aws\", \"azure\")),\n            \"region\": All(\n                Lower, Choices(\"us-west\", \"us-east\", \"eu-west\", \"eu-north\")\n            ),\n            \"image\": str,\n            \"name\": str,\n            \"spot\": Bool,\n            \"spot_price\": Coerce(float),\n            \"instance_hdd_size\": Coerce(int),\n            \"instance_type\": Lower,\n            \"instance_gpu\": Lower,\n            \"ssh_private\": str,\n            \"startup_script\": str,\n        },\n    },\n    # section for experimental features\n    \"feature\": {\n        Optional(\"machine\", default=False): Bool,\n        # enabled by default. It's of no use, kept for backward compatibility.\n        Optional(\"parametrization\", default=True): Bool,\n    },\n    \"plots\": {\"html_template\": str},\n    \"exp\": {\n        \"code\": str,\n        \"data\": str,\n        \"models\": str,\n        \"metrics\": str,\n        \"params\": str,\n        \"plots\": str,\n        \"live\": str,\n    },\n}\n", "path": "dvc/config_schema.py"}]}