Get rid of the oslo.serialization dependency

It was used to smoothen out the difference in handling bytes in
Python 2 and 3. Now that we only support Python 3, it can be
replaced.

A side effect of this change is that we no longer accept bytes
in JSON. JSON does not support bytes, but this problem has been
hidden due to oslo.serialization until now. The configdrive
handling has been updated to account for that.

Change-Id: I230b55db55bce08d46f5023ad7a3f6501c96d100
This commit is contained in:
Dmitry Tantsur 2020-04-28 12:54:56 +02:00
parent a44a77e6d3
commit 0242f8219a
7 changed files with 32 additions and 11 deletions

View File

@ -16,6 +16,7 @@
from distutils.version import StrictVersion
import functools
from http import client as http_client
import json
import logging
import re
import textwrap
@ -24,7 +25,6 @@ from urllib import parse as urlparse
from keystoneauth1 import adapter
from keystoneauth1 import exceptions as kexc
from oslo_serialization import jsonutils
from ironicclient.common import filecache
from ironicclient.common.i18n import _
@ -67,7 +67,7 @@ def _trim_endpoint_api_version(url):
def _extract_error_json(body):
"""Return error_message from the HTTP response body."""
try:
body_json = jsonutils.loads(body)
body_json = json.loads(body)
except ValueError:
return {}
@ -75,7 +75,7 @@ def _extract_error_json(body):
return {}
try:
error_json = jsonutils.loads(body_json['error_message'])
error_json = json.loads(body_json['error_message'])
except ValueError:
return body_json
@ -393,7 +393,7 @@ class SessionClient(VersionNegotiationMixin, adapter.LegacyJsonAdapter):
kwargs['headers'].setdefault('Accept', 'application/json')
if 'body' in kwargs:
kwargs['data'] = jsonutils.dump_as_bytes(kwargs.pop('body'))
kwargs['json'] = kwargs.pop('body')
resp = self._http_request(url, method, **kwargs)
body = resp.content

View File

@ -16,6 +16,7 @@
from __future__ import print_function
import argparse
import base64
import contextlib
import gzip
import json
@ -26,7 +27,6 @@ import sys
import tempfile
import time
from oslo_serialization import base64
from oslo_utils import strutils
from ironicclient.common.i18n import _
@ -296,7 +296,7 @@ def make_configdrive(path):
shutil.copyfileobj(tmpfile, gz_file)
tmpzipfile.seek(0)
return base64.encode_as_bytes(tmpzipfile.read())
return base64.b64encode(tmpzipfile.read())
def check_empty_arg(arg, arg_descriptor):

View File

@ -14,11 +14,11 @@
# under the License.
from http import client as http_client
import json
import time
from unittest import mock
from keystoneauth1 import exceptions as kexc
from oslo_serialization import jsonutils
from ironicclient.common import filecache
from ironicclient.common import http
@ -40,9 +40,9 @@ def _get_error_body(faultstring=None, debuginfo=None, description=None):
'faultstring': faultstring,
'debuginfo': debuginfo
}
raw_error_body = jsonutils.dump_as_bytes(error_body)
raw_error_body = json.dumps(error_body)
body = {'error_message': raw_error_body}
return jsonutils.dumps(body)
return json.dumps(body)
def _session_client(**kwargs):

View File

@ -1498,6 +1498,15 @@ class NodeManagerTest(testtools.TestCase):
]
self.assertEqual(expect, self.api.calls)
def test_node_set_provision_state_with_configdrive_invalid_bytes(self):
invalid_utf8 = b"\xc3\x28"
target_state = 'active'
self.assertRaisesRegex(ValueError,
'Config drive',
self.mgr.set_provision_state,
NODE1['uuid'], target_state,
configdrive=invalid_utf8)
def test_node_set_provision_state_with_configdrive_as_dict(self):
target_state = 'active'
self.mgr.set_provision_state(NODE1['uuid'], target_state,
@ -1518,7 +1527,8 @@ class NodeManagerTest(testtools.TestCase):
self.mgr.set_provision_state(NODE1['uuid'], target_state,
configdrive=f.name)
body = {'target': target_state, 'configdrive': file_content}
body = {'target': target_state,
'configdrive': file_content.decode('utf-8')}
expect = [
('PUT', '/v1/nodes/%s/states/provision' % NODE1['uuid'], {}, body),
]

View File

@ -557,6 +557,12 @@ class NodeManager(base.CreateManager):
if os.path.isdir(configdrive):
configdrive = utils.make_configdrive(configdrive)
if isinstance(configdrive, bytes):
try:
configdrive = configdrive.decode('utf-8')
except UnicodeError:
raise ValueError('Config drive must be a dictionary or '
'a base64 encoded string')
body['configdrive'] = configdrive
elif cleansteps:
body['clean_steps'] = cleansteps

View File

@ -0,0 +1,6 @@
---
upgrade:
- |
The Python API used to accepts byte arrays and other non-serializable in
JSON data types in a few places where strings are required. This is no
longer supported, an attempt to do it will result in an exception.

View File

@ -9,7 +9,6 @@ jsonschema>=2.6.0 # MIT
keystoneauth1>=3.4.0 # Apache-2.0
openstacksdk>=0.18.0 # Apache-2.0
osc-lib>=1.10.0 # Apache-2.0
oslo.serialization!=2.19.1,>=2.18.0 # Apache-2.0
oslo.utils>=3.33.0 # Apache-2.0
PyYAML>=3.12 # MIT
requests>=2.14.2 # Apache-2.0