diff --git a/vmware_nsxlib/tests/unit/v3/test_client.py b/vmware_nsxlib/tests/unit/v3/test_client.py index 95ae314f..f132d859 100644 --- a/vmware_nsxlib/tests/unit/v3/test_client.py +++ b/vmware_nsxlib/tests/unit/v3/test_client.py @@ -282,6 +282,22 @@ class NsxV3JSONClientTestCase(nsxlib_testcase.NsxClientTestCase): self.assertEqual(resp, {'result': {'ok': 200}}) + def test_mask_password(self): + pwds = ('my!pwd0#', 'some0therlong$pwd', 'pwd') + body = {'name_pwd': 'name1', + 'password': pwds[0], + 'some_list': {'name_password': 'name2', + 'password': pwds[1]}, + 'password': pwds[2]} + + cl = client.RESTClient(None) + json_body = jsonutils.dumps(body) + masked_body = cl._mask_password(json_body) + for pwd in pwds: + json_body = json_body.replace('"' + pwd + '"', '"********"') + + self.assertEqual(json_body, masked_body) + class NsxV3APIClientTestCase(nsxlib_testcase.NsxClientTestCase): diff --git a/vmware_nsxlib/v3/client.py b/vmware_nsxlib/v3/client.py index 202f02a5..69122fa1 100644 --- a/vmware_nsxlib/v3/client.py +++ b/vmware_nsxlib/v3/client.py @@ -13,6 +13,7 @@ # License for the specific language governing permissions and limitations # under the License. # +import re import requests import six.moves.urllib.parse as urlparse @@ -161,6 +162,14 @@ class RESTClient(object): uri = "%s://%s" % (prefix.scheme, uri) return uri + def _mask_password(self, json): + '''Mask password value in json format''' + if not json: + return json + + pattern = r'\"password\": [^,}]*' + return re.sub(pattern, '"password": "********"', json) + def _rest_call(self, url, method='GET', body=None, headers=None, silent=False): request_headers = headers.copy() if headers else {} @@ -169,8 +178,10 @@ class RESTClient(object): do_request = getattr(self._conn, method.lower()) if not silent: + LOG.debug("REST call: %s %s. Headers: %s. Body: %s", - method, request_url, request_headers, body) + method, request_url, request_headers, + self._mask_password(body)) result = do_request( request_url,