Interdiff:

diff --git a/lib/utils/security.py b/lib/utils/security.py
index 221b587..10d515a 100644
--- a/lib/utils/security.py
+++ b/lib/utils/security.py
@@ -48,7 +48,7 @@ def AddNodeToCandidateCerts(node_uuid, cert_digest,
candidate_certs,
     old_cert_digest = candidate_certs[node_uuid]
     if old_cert_digest == cert_digest:
       info_fn("Certificate digest for node %s already in config."
-              "Not doing anything.")
+              "Not doing anything." % node_uuid)
       return
     else:
       warn_fn("Overriding differing certificate digest for node %s"
@@ -71,6 +71,6 @@ def RemoveNodeFromCandidateCerts(node_uuid,
candidate_certs,
   """
   if node_uuid not in candidate_certs:
     warn_fn("Cannot remove certifcate for node %s, because it's not in the"
-            "candidate map.")
+            "candidate map." % node_uuid)
     return
   del candidate_certs[node_uuid]



On Thu, Dec 19, 2013 at 4:44 PM, Helga Velroyen <[email protected]> wrote:

>
>
>
> On Thu, Dec 19, 2013 at 4:23 PM, Hrvoje Ribicic <[email protected]> wrote:
>
>>
>>
>> On Thu, Dec 19, 2013 at 3:49 PM, Helga Velroyen <[email protected]>wrote:
>>
>>> This patch adds a couple of utility functions to manipulate
>>> the map of master candidate SSL certificate digests.
>>>
>>> Signed-off-by: Helga Velroyen <[email protected]>
>>> ---
>>>  Makefile.am                               |  2 +
>>>  lib/utils/security.py                     | 76
>>> +++++++++++++++++++++++++++++++
>>>  test/py/ganeti.utils.security_unittest.py | 74
>>> ++++++++++++++++++++++++++++++
>>>  3 files changed, 152 insertions(+)
>>>  create mode 100644 lib/utils/security.py
>>>  create mode 100755 test/py/ganeti.utils.security_unittest.py
>>>
>>> diff --git a/Makefile.am b/Makefile.am
>>> index e74f58b..96e1284 100644
>>> --- a/Makefile.am
>>> +++ b/Makefile.am
>>> @@ -490,6 +490,7 @@ utils_PYTHON = \
>>>         lib/utils/nodesetup.py \
>>>         lib/utils/process.py \
>>>         lib/utils/retry.py \
>>> +       lib/utils/security.py \
>>>         lib/utils/storage.py \
>>>         lib/utils/text.py \
>>>         lib/utils/version.py \
>>> @@ -1473,6 +1474,7 @@ python_tests = \
>>>         test/py/ganeti.utils.nodesetup_unittest.py \
>>>         test/py/ganeti.utils.process_unittest.py \
>>>         test/py/ganeti.utils.retry_unittest.py \
>>> +       test/py/ganeti.utils.security_unittest.py \
>>>         test/py/ganeti.utils.storage_unittest.py \
>>>         test/py/ganeti.utils.text_unittest.py \
>>>         test/py/ganeti.utils.version_unittest.py \
>>> diff --git a/lib/utils/security.py b/lib/utils/security.py
>>> new file mode 100644
>>> index 0000000..221b587
>>> --- /dev/null
>>> +++ b/lib/utils/security.py
>>> @@ -0,0 +1,76 @@
>>> +#
>>> +#
>>> +
>>> +# Copyright (C) 2013 Google Inc.
>>> +#
>>> +# This program is free software; you can redistribute it and/or modify
>>> +# it under the terms of the GNU General Public License as published by
>>> +# the Free Software Foundation; either version 2 of the License, or
>>> +# (at your option) any later version.
>>> +#
>>> +# This program is distributed in the hope that it will be useful, but
>>> +# WITHOUT ANY WARRANTY; without even the implied warranty of
>>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> +# General Public License for more details.
>>> +#
>>> +# You should have received a copy of the GNU General Public License
>>> +# along with this program; if not, write to the Free Software
>>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>>> +# 02110-1301, USA.
>>> +
>>> +"""Utility functions for security features of Ganeti.
>>> +
>>> +"""
>>> +
>>> +import logging
>>> +
>>> +
>>> +def AddNodeToCandidateCerts(node_uuid, cert_digest, candidate_certs,
>>> +                            info_fn=logging.info,
>>> warn_fn=logging.warn):
>>> +  """Adds an entry to the candidate certificate map.
>>> +
>>> +  @type node_uuid: string
>>> +  @param node_uuid: the node's UUID
>>> +  @type cert_digest: string
>>> +  @param cert_digest: the digest of the node's client SSL certificate
>>> +  @type candidate_certs: dict of strings to strings
>>> +  @param candidate_certs: map of node UUIDs to the digests of their
>>> client
>>> +      SSL certificates, will be manipulated in this function
>>> +  @type info_fn: function
>>> +  @param info_fn: logging function for information messages
>>> +  @type warn_fn: function
>>> +  @param warn_fn: logging function for warning messages
>>> +
>>> +  """
>>> +  assert candidate_certs is not None
>>> +
>>> +  if node_uuid in candidate_certs:
>>> +    old_cert_digest = candidate_certs[node_uuid]
>>> +    if old_cert_digest == cert_digest:
>>> +      info_fn("Certificate digest for node %s already in config."
>>> +              "Not doing anything.")
>>>
>>
>> The node identifier is not injected into the logging message here.
>>
>
> Right, thanks for noticing.
>
>
>>
>>
>>> +      return
>>> +    else:
>>> +      warn_fn("Overriding differing certificate digest for node %s"
>>> +              % node_uuid)
>>>
>>
>> Regarding the node_uuid, a more general question:
>> Do we have some standards regarding what goes into a log?
>> A node uuid will identify the node, but I guess a node name is more
>> useful to the user.
>> If this is what we do elsewhere, then let it be :)
>>
>
> I don't know what the standard is in general, but while working on it, I
> found it highly practical to have the node UUIDs instead of the name,
> because when debugging this it is kind of crucial to distinguish two nodes
> that have the same host name at some point in time, for example a node can
> be removed and a different node can be added using the same name and there
> it should actually be the case that the UUID differs. Hence related to this
> SSL certificate handling, I found it highly beneficial to have the UUID,
> because otherwise you don't know which host of that name has the
> certificate.
>
>
>>
>>
>>> +  candidate_certs[node_uuid] = cert_digest
>>> +
>>> +
>>> +def RemoveNodeFromCandidateCerts(node_uuid, candidate_certs,
>>> +                                 warn_fn=logging.warn):
>>> +  """Removes the entry of the given node in the certificate map.
>>> +
>>> +  @type node_uuid: string
>>> +  @param node_uuid: the node's UUID
>>> +  @type candidate_certs: dict of strings to strings
>>> +  @param candidate_certs: map of node UUIDs to the digests of their
>>> client
>>> +      SSL certificates, will be manipulated in this function
>>> +  @type warn_fn: function
>>> +  @param warn_fn: logging function for warning messages
>>> +
>>> +  """
>>> +  if node_uuid not in candidate_certs:
>>> +    warn_fn("Cannot remove certifcate for node %s, because it's not in
>>> the"
>>> +            "candidate map.")
>>>
>>
>> Again, missing identifier, and a typo: s/certifcate/certificate/
>>
>
> Thx, will send an interdiff.
>
>
>>
>>
>>> +    return
>>> +  del candidate_certs[node_uuid]
>>> diff --git a/test/py/ganeti.utils.security_unittest.py b/test/py/
>>> ganeti.utils.security_unittest.py
>>> new file mode 100755
>>> index 0000000..08c6b58
>>> --- /dev/null
>>> +++ b/test/py/ganeti.utils.security_unittest.py
>>> @@ -0,0 +1,74 @@
>>> +#!/usr/bin/python
>>> +#
>>> +
>>> +# Copyright (C) 2013 Google Inc.
>>> +#
>>> +# This program is free software; you can redistribute it and/or modify
>>> +# it under the terms of the GNU General Public License as published by
>>> +# the Free Software Foundation; either version 2 of the License, or
>>> +# (at your option) any later version.
>>> +#
>>> +# This program is distributed in the hope that it will be useful, but
>>> +# WITHOUT ANY WARRANTY; without even the implied warranty of
>>> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>>> +# General Public License for more details.
>>> +#
>>> +# You should have received a copy of the GNU General Public License
>>> +# along with this program; if not, write to the Free Software
>>> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>>> +# 02110-1301, USA.
>>> +
>>> +
>>> +"""Script for unittesting the ganeti.utils.storage module"""
>>> +
>>> +import mock
>>> +import unittest
>>> +
>>> +from ganeti.utils import security
>>> +
>>> +import testutils
>>> +
>>> +
>>> +class TestCandidateCerts(unittest.TestCase):
>>> +
>>> +  def setUp(self):
>>> +    self._warn_fn = mock.Mock()
>>> +    self._info_fn = mock.Mock()
>>> +    self._candidate_certs = {}
>>> +
>>> +  def testAddAndRemoveCerts(self):
>>> +    self.assertEqual(0, len(self._candidate_certs))
>>> +
>>> +    node_uuid = "1234"
>>> +    cert_digest = "foobar"
>>> +    security.AddNodeToCandidateCerts(node_uuid, cert_digest,
>>> +      self._candidate_certs, warn_fn=self._warn_fn,
>>> info_fn=self._info_fn)
>>> +    self.assertEqual(1, len(self._candidate_certs))
>>> +
>>> +    # Try adding the same cert again
>>> +    security.AddNodeToCandidateCerts(node_uuid, cert_digest,
>>> +      self._candidate_certs, warn_fn=self._warn_fn,
>>> info_fn=self._info_fn)
>>> +    self.assertEqual(1, len(self._candidate_certs))
>>> +    self.assertTrue(self._candidate_certs[node_uuid] == cert_digest)
>>> +
>>> +    # Overriding cert
>>> +    other_digest = "barfoo"
>>> +    security.AddNodeToCandidateCerts(node_uuid, other_digest,
>>> +      self._candidate_certs, warn_fn=self._warn_fn,
>>> info_fn=self._info_fn)
>>> +    self.assertEqual(1, len(self._candidate_certs))
>>> +    self.assertTrue(self._candidate_certs[node_uuid] == other_digest)
>>> +
>>> +    # Try removing a certificate from a node that is not in the list
>>> +    other_node_uuid = "5678"
>>> +    security.RemoveNodeFromCandidateCerts(
>>> +      other_node_uuid, self._candidate_certs, warn_fn=self._warn_fn)
>>> +    self.assertEqual(1, len(self._candidate_certs))
>>> +
>>> +    # Remove a certificate from a node that is in the list
>>> +    security.RemoveNodeFromCandidateCerts(
>>> +      node_uuid, self._candidate_certs, warn_fn=self._warn_fn)
>>> +    self.assertEqual(0, len(self._candidate_certs))
>>> +
>>> +
>>> +if __name__ == "__main__":
>>> +  testutils.GanetiTestProgram()
>>> --
>>> 1.8.5.1
>>>
>>>
>>
>
>
> --
> --
> Helga Velroyen | Software Engineer | [email protected] |
>
> Google Germany GmbH
> Dienerstr. 12
> 80331 München
>
> Registergericht und -nummer: Hamburg, HRB 86891
> Sitz der Gesellschaft: Hamburg
> Geschäftsführer: Graham Law, Christine Elizabeth Flores
>



-- 
-- 
Helga Velroyen | Software Engineer | [email protected] |

Google Germany GmbH
Dienerstr. 12
80331 München

Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg
Geschäftsführer: Graham Law, Christine Elizabeth Flores

Reply via email to