utils: move publisher-only utils functions in publisher
Change-Id: Ia110b6ee4e087a3b987d160594d5d6e7958228b2
This commit is contained in:
parent
5f2cc46b02
commit
72095eb352
ceilometer
@ -22,7 +22,6 @@ from oslo_config import cfg
|
||||
from oslo_utils import secretutils
|
||||
import six
|
||||
|
||||
from ceilometer import utils
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('telemetry_secret',
|
||||
@ -40,6 +39,42 @@ OPTS = [
|
||||
]
|
||||
|
||||
|
||||
def decode_unicode(input):
|
||||
"""Decode the unicode of the message, and encode it into utf-8."""
|
||||
if isinstance(input, dict):
|
||||
temp = {}
|
||||
# If the input data is a dict, create an equivalent dict with a
|
||||
# predictable insertion order to avoid inconsistencies in the
|
||||
# message signature computation for equivalent payloads modulo
|
||||
# ordering
|
||||
for key, value in sorted(six.iteritems(input)):
|
||||
temp[decode_unicode(key)] = decode_unicode(value)
|
||||
return temp
|
||||
elif isinstance(input, (tuple, list)):
|
||||
# When doing a pair of JSON encode/decode operations to the tuple,
|
||||
# the tuple would become list. So we have to generate the value as
|
||||
# list here.
|
||||
return [decode_unicode(element) for element in input]
|
||||
elif isinstance(input, six.text_type):
|
||||
return input.encode('utf-8')
|
||||
elif six.PY3 and isinstance(input, six.binary_type):
|
||||
return input.decode('utf-8')
|
||||
else:
|
||||
return input
|
||||
|
||||
|
||||
def recursive_keypairs(d, separator=':'):
|
||||
"""Generator that produces sequence of keypairs for nested dictionaries."""
|
||||
for name, value in sorted(six.iteritems(d)):
|
||||
if isinstance(value, dict):
|
||||
for subname, subvalue in recursive_keypairs(value, separator):
|
||||
yield ('%s%s%s' % (name, separator, subname), subvalue)
|
||||
elif isinstance(value, (tuple, list)):
|
||||
yield name, decode_unicode(value)
|
||||
else:
|
||||
yield name, value
|
||||
|
||||
|
||||
def compute_signature(message, secret):
|
||||
"""Return the signature for a message dictionary."""
|
||||
if not secret:
|
||||
@ -48,7 +83,7 @@ def compute_signature(message, secret):
|
||||
if isinstance(secret, six.text_type):
|
||||
secret = secret.encode('utf-8')
|
||||
digest_maker = hmac.new(secret, b'', hashlib.sha256)
|
||||
for name, value in utils.recursive_keypairs(message):
|
||||
for name, value in recursive_keypairs(message):
|
||||
if name == 'message_signature':
|
||||
# Skip any existing signature value, which would not have
|
||||
# been part of the original message.
|
||||
|
@ -121,3 +121,48 @@ class TestSignature(base.BaseTestCase):
|
||||
def test_verify_no_secret(self):
|
||||
data = {'a': 'A', 'b': 'B'}
|
||||
self.assertTrue(utils.verify_signature(data, ''))
|
||||
|
||||
|
||||
class TestUtils(base.BaseTestCase):
|
||||
def test_recursive_keypairs(self):
|
||||
data = {'a': 'A', 'b': 'B',
|
||||
'nested': {'a': 'A', 'b': 'B'}}
|
||||
pairs = list(utils.recursive_keypairs(data))
|
||||
self.assertEqual([('a', 'A'), ('b', 'B'),
|
||||
('nested:a', 'A'), ('nested:b', 'B')],
|
||||
pairs)
|
||||
|
||||
def test_recursive_keypairs_with_separator(self):
|
||||
data = {'a': 'A',
|
||||
'b': 'B',
|
||||
'nested': {'a': 'A',
|
||||
'b': 'B',
|
||||
},
|
||||
}
|
||||
separator = '.'
|
||||
pairs = list(utils.recursive_keypairs(data, separator))
|
||||
self.assertEqual([('a', 'A'),
|
||||
('b', 'B'),
|
||||
('nested.a', 'A'),
|
||||
('nested.b', 'B')],
|
||||
pairs)
|
||||
|
||||
def test_recursive_keypairs_with_list_of_dict(self):
|
||||
small = 1
|
||||
big = 1 << 64
|
||||
expected = [('a', 'A'),
|
||||
('b', 'B'),
|
||||
('nested:list', [{small: 99, big: 42}])]
|
||||
data = {'a': 'A',
|
||||
'b': 'B',
|
||||
'nested': {'list': [{small: 99, big: 42}]}}
|
||||
pairs = list(utils.recursive_keypairs(data))
|
||||
self.assertEqual(len(expected), len(pairs))
|
||||
for k, v in pairs:
|
||||
# the keys 1 and 1<<64 cause a hash collision on 64bit platforms
|
||||
if k == 'nested:list':
|
||||
self.assertIn(v,
|
||||
[[{small: 99, big: 42}],
|
||||
[{big: 42, small: 99}]])
|
||||
else:
|
||||
self.assertIn((k, v), expected)
|
||||
|
@ -22,49 +22,6 @@ from ceilometer import utils
|
||||
|
||||
class TestUtils(base.BaseTestCase):
|
||||
|
||||
def test_recursive_keypairs(self):
|
||||
data = {'a': 'A', 'b': 'B',
|
||||
'nested': {'a': 'A', 'b': 'B'}}
|
||||
pairs = list(utils.recursive_keypairs(data))
|
||||
self.assertEqual([('a', 'A'), ('b', 'B'),
|
||||
('nested:a', 'A'), ('nested:b', 'B')],
|
||||
pairs)
|
||||
|
||||
def test_recursive_keypairs_with_separator(self):
|
||||
data = {'a': 'A',
|
||||
'b': 'B',
|
||||
'nested': {'a': 'A',
|
||||
'b': 'B',
|
||||
},
|
||||
}
|
||||
separator = '.'
|
||||
pairs = list(utils.recursive_keypairs(data, separator))
|
||||
self.assertEqual([('a', 'A'),
|
||||
('b', 'B'),
|
||||
('nested.a', 'A'),
|
||||
('nested.b', 'B')],
|
||||
pairs)
|
||||
|
||||
def test_recursive_keypairs_with_list_of_dict(self):
|
||||
small = 1
|
||||
big = 1 << 64
|
||||
expected = [('a', 'A'),
|
||||
('b', 'B'),
|
||||
('nested:list', [{small: 99, big: 42}])]
|
||||
data = {'a': 'A',
|
||||
'b': 'B',
|
||||
'nested': {'list': [{small: 99, big: 42}]}}
|
||||
pairs = list(utils.recursive_keypairs(data))
|
||||
self.assertEqual(len(expected), len(pairs))
|
||||
for k, v in pairs:
|
||||
# the keys 1 and 1<<64 cause a hash collision on 64bit platforms
|
||||
if k == 'nested:list':
|
||||
self.assertIn(v,
|
||||
[[{small: 99, big: 42}],
|
||||
[{big: 42, small: 99}]])
|
||||
else:
|
||||
self.assertIn((k, v), expected)
|
||||
|
||||
def test_hash_of_set(self):
|
||||
x = ['a', 'b']
|
||||
y = ['a', 'b', 'a']
|
||||
|
@ -22,7 +22,6 @@ import threading
|
||||
|
||||
from oslo_concurrency import processutils
|
||||
from oslo_config import cfg
|
||||
import six
|
||||
|
||||
ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
|
||||
|
||||
@ -51,42 +50,6 @@ def execute(*cmd, **kwargs):
|
||||
return processutils.execute(*cmd, **kwargs)
|
||||
|
||||
|
||||
def decode_unicode(input):
|
||||
"""Decode the unicode of the message, and encode it into utf-8."""
|
||||
if isinstance(input, dict):
|
||||
temp = {}
|
||||
# If the input data is a dict, create an equivalent dict with a
|
||||
# predictable insertion order to avoid inconsistencies in the
|
||||
# message signature computation for equivalent payloads modulo
|
||||
# ordering
|
||||
for key, value in sorted(six.iteritems(input)):
|
||||
temp[decode_unicode(key)] = decode_unicode(value)
|
||||
return temp
|
||||
elif isinstance(input, (tuple, list)):
|
||||
# When doing a pair of JSON encode/decode operations to the tuple,
|
||||
# the tuple would become list. So we have to generate the value as
|
||||
# list here.
|
||||
return [decode_unicode(element) for element in input]
|
||||
elif isinstance(input, six.text_type):
|
||||
return input.encode('utf-8')
|
||||
elif six.PY3 and isinstance(input, six.binary_type):
|
||||
return input.decode('utf-8')
|
||||
else:
|
||||
return input
|
||||
|
||||
|
||||
def recursive_keypairs(d, separator=':'):
|
||||
"""Generator that produces sequence of keypairs for nested dictionaries."""
|
||||
for name, value in sorted(six.iteritems(d)):
|
||||
if isinstance(value, dict):
|
||||
for subname, subvalue in recursive_keypairs(value, separator):
|
||||
yield ('%s%s%s' % (name, separator, subname), subvalue)
|
||||
elif isinstance(value, (tuple, list)):
|
||||
yield name, decode_unicode(value)
|
||||
else:
|
||||
yield name, value
|
||||
|
||||
|
||||
def hash_of_set(s):
|
||||
return str(hash(frozenset(s)))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user