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
|
from oslo_utils import secretutils
|
||||||
import six
|
import six
|
||||||
|
|
||||||
from ceilometer import utils
|
|
||||||
|
|
||||||
OPTS = [
|
OPTS = [
|
||||||
cfg.StrOpt('telemetry_secret',
|
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):
|
def compute_signature(message, secret):
|
||||||
"""Return the signature for a message dictionary."""
|
"""Return the signature for a message dictionary."""
|
||||||
if not secret:
|
if not secret:
|
||||||
@ -48,7 +83,7 @@ def compute_signature(message, secret):
|
|||||||
if isinstance(secret, six.text_type):
|
if isinstance(secret, six.text_type):
|
||||||
secret = secret.encode('utf-8')
|
secret = secret.encode('utf-8')
|
||||||
digest_maker = hmac.new(secret, b'', hashlib.sha256)
|
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':
|
if name == 'message_signature':
|
||||||
# Skip any existing signature value, which would not have
|
# Skip any existing signature value, which would not have
|
||||||
# been part of the original message.
|
# been part of the original message.
|
||||||
|
@ -121,3 +121,48 @@ class TestSignature(base.BaseTestCase):
|
|||||||
def test_verify_no_secret(self):
|
def test_verify_no_secret(self):
|
||||||
data = {'a': 'A', 'b': 'B'}
|
data = {'a': 'A', 'b': 'B'}
|
||||||
self.assertTrue(utils.verify_signature(data, ''))
|
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):
|
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):
|
def test_hash_of_set(self):
|
||||||
x = ['a', 'b']
|
x = ['a', 'b']
|
||||||
y = ['a', 'b', 'a']
|
y = ['a', 'b', 'a']
|
||||||
|
@ -22,7 +22,6 @@ import threading
|
|||||||
|
|
||||||
from oslo_concurrency import processutils
|
from oslo_concurrency import processutils
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
import six
|
|
||||||
|
|
||||||
ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
|
ROOTWRAP_CONF = "/etc/ceilometer/rootwrap.conf"
|
||||||
|
|
||||||
@ -51,42 +50,6 @@ def execute(*cmd, **kwargs):
|
|||||||
return processutils.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):
|
def hash_of_set(s):
|
||||||
return str(hash(frozenset(s)))
|
return str(hash(frozenset(s)))
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user