Repository: OpenKMIP/PyKMIP

Issue:
policy_path error when running server
I'm receiving the following error when attempting to run the PyKMIP server 0.5.0:
"kmip.core.exceptions.ConfigurationError: Setting 'policy_path' is missing from the configuration file."

I cannot find policy_path documented anywhere and have not found any guidance online.  I have attempted to insert a path statement in the config file the error then changes to:
"kmip.core.exceptions.ConfigurationError: The policy path value, if specified, must be a valid string path to a filesystem directory."   The path I used is a valid path with appropriate permissions but not knowing the format of the expected policy file I am unable to provide a suitable target. 

Any guidance would be appreciated. 

Discussion:
codecov-io: ## [Current coverage](https://codecov.io/gh/OpenKMIP/PyKMIP/pull/215?src=pr) is 86.79% (diff: 100%)
> Merging [#215](https://codecov.io/gh/OpenKMIP/PyKMIP/pull/215?src=pr) into [master](https://codecov.io/gh/OpenKMIP/PyKMIP/branch/master?src=pr) will decrease coverage by **<.01%**

```diff
@@             master       #215   diff @@
==========================================
  Files            64         64          
  Lines          8172       8171     -1   
  Methods           0          0          
  Messages          0          0          
  Branches          0          0          
==========================================
- Hits           7093       7092     -1   
  Misses         1079       1079          
  Partials          0          0          
```

> Powered by [Codecov](https://codecov.io?src=pr). Last update [023bb8f...8383f79](https://codecov.io/gh/OpenKMIP/PyKMIP/compare/023bb8fd04b1e61b127313f4a9a6313af07fb14a...8383f79c5f40a3ade027e4f75fce930e99eaf235?src=pr)
coveralls: 
[![Coverage Status](https://coveralls.io/builds/9028353/badge)](https://coveralls.io/builds/9028353)

Coverage decreased (-0.002%) to 86.795% when pulling **8383f79c5f40a3ade027e4f75fce930e99eaf235 on bug/fix-conf-policy-path** into **023bb8fd04b1e61b127313f4a9a6313af07fb14a on master**.


Patch:
diff --git a/kmip/services/server/config.py b/kmip/services/server/config.py
index 4687999..25bab5e 100644
--- a/kmip/services/server/config.py
+++ b/kmip/services/server/config.py
@@ -41,7 +41,9 @@ class KmipServerConfig(object):
             'certificate_path',
             'key_path',
             'ca_path',
-            'auth_suite',
+            'auth_suite'
+        ]
+        self._optional_settings = [
             'policy_path'
         ]
 
@@ -61,7 +63,7 @@ class KmipServerConfig(object):
             ConfigurationError: Raised if the setting is not supported or if
                 the setting value is invalid.
         """
-        if setting not in self._expected_settings:
+        if setting not in self._expected_settings + self._optional_settings:
             raise exceptions.ConfigurationError(
                 "Setting '{0}' is not supported.".format(setting)
             )
@@ -116,11 +118,11 @@ class KmipServerConfig(object):
             )
 
         settings = [x[0] for x in parser.items('server')]
-        for setting in settings:
-            if setting not in self._expected_settings:
+        for s in settings:
+            if s not in self._expected_settings + self._optional_settings:
                 raise exceptions.ConfigurationError(
                     "Setting '{0}' is not a supported setting. Please "
-                    "remove it from the configuration file.".format(setting)
+                    "remove it from the configuration file.".format(s)
                 )
         for setting in self._expected_settings:
             if setting not in settings:
@@ -231,16 +233,10 @@ class KmipServerConfig(object):
             self.settings['auth_suite'] = value
 
     def _set_policy_path(self, value):
-        if value is None:
+        if not value:
             self.settings['policy_path'] = None
         elif isinstance(value, six.string_types):
-            if os.path.exists(value):
-                self.settings['policy_path'] = value
-            else:
-                raise exceptions.ConfigurationError(
-                    "The policy path value, if specified, must be a valid "
-                    "string path to a filesystem directory."
-                )
+            self.settings['policy_path'] = value
         else:
             raise exceptions.ConfigurationError(
                 "The policy path, if specified, must be a valid string path "
diff --git a/kmip/services/server/engine.py b/kmip/services/server/engine.py
index 587d509..27e7341 100644
--- a/kmip/services/server/engine.py
+++ b/kmip/services/server/engine.py
@@ -134,9 +134,9 @@ class KmipEngine(object):
     def _load_operation_policies(self, policy_path):
         if (policy_path is None) or (not os.path.isdir(policy_path)):
             self._logger.warning(
-                "The specified operation policy directory ({0}) is not "
-                "valid. No user-defined policies will be loaded".format(
-                    policy_path
+                "The specified operation policy directory{0} is not "
+                "valid. No user-defined policies will be loaded.".format(
+                    " (" + policy_path + ")" if policy_path else ''
                 )
             )
             return dict()
@@ -151,7 +151,7 @@ class KmipEngine(object):
             file_path = os.path.join(policy_path, filename)
             if os.path.isfile(file_path):
                 self._logger.info(
-                    "Loading user_defined operation policies "
+                    "Loading user-defined operation policies "
                     "from file: {0}".format(file_path)
                 )
 
diff --git a/kmip/services/server/server.py b/kmip/services/server/server.py
index 32b6ea9..6cf11d3 100644
--- a/kmip/services/server/server.py
+++ b/kmip/services/server/server.py
@@ -51,7 +51,7 @@ class KmipServer(object):
             auth_suite=None,
             config_path='/etc/pykmip/server.conf',
             log_path='/var/log/pykmip/server.log',
-            policy_path='/etc/pykmip/policies'
+            policy_path=None
     ):
         """
         Create a KmipServer.
@@ -95,7 +95,7 @@ class KmipServer(object):
                 '/var/log/pykmip/server.log'.
             policy_path (string): The path to the filesystem directory
                 containing PyKMIP server operation policy JSON files.
-                Optional, defaults to '/etc/pykmip/policies'.
+                Optional, defaults to None.
         """
         self._logger = logging.getLogger('kmip.server')
         self._setup_logging(log_path)


Test patch:
diff --git a/kmip/tests/unit/services/server/test_config.py b/kmip/tests/unit/services/server/test_config.py
index 19bfb54..f9121dc 100644
--- a/kmip/tests/unit/services/server/test_config.py
+++ b/kmip/tests/unit/services/server/test_config.py
@@ -513,20 +513,10 @@ class TestKmipServerConfig(testtools.TestCase):
         # Test that a ConfigurationError is generated when setting the wrong
         # value.
         c._logger.reset_mock()
-        args = (0, )
+        args = (1, )
         self.assertRaises(
             exceptions.ConfigurationError,
             c._set_policy_path,
             *args
         )
-        self.assertNotEqual(0, c.settings.get('policy_path'))
-
-        args = ('/test/path/policies', )
-        with mock.patch('os.path.exists') as os_mock:
-            os_mock.return_value = False
-            self.assertRaises(
-                exceptions.ConfigurationError,
-                c._set_policy_path,
-                *args
-            )
-            self.assertNotEqual(0, c.settings.get('policy_path'))
+        self.assertNotEqual(1, c.settings.get('policy_path'))
diff --git a/kmip/tests/unit/services/server/test_engine.py b/kmip/tests/unit/services/server/test_engine.py
index 87956e7..23f3624 100644
--- a/kmip/tests/unit/services/server/test_engine.py
+++ b/kmip/tests/unit/services/server/test_engine.py
@@ -163,7 +163,7 @@ class TestKmipEngine(testtools.TestCase):
             )
         )
         e._logger.info.assert_any_call(
-            "Loading user_defined operation policies from file: {0}".format(
+            "Loading user-defined operation policies from file: {0}".format(
                 policy_file.name
             )
         )
@@ -203,7 +203,7 @@ class TestKmipEngine(testtools.TestCase):
             )
         )
         e._logger.info.assert_any_call(
-            "Loading user_defined operation policies from file: {0}".format(
+            "Loading user-defined operation policies from file: {0}".format(
                 policy_file.name
             )
         )
@@ -239,7 +239,7 @@ class TestKmipEngine(testtools.TestCase):
             )
         )
         e._logger.info.assert_any_call(
-            "Loading user_defined operation policies from file: {0}".format(
+            "Loading user-defined operation policies from file: {0}".format(
                 policy_file.name
             )
         )
@@ -283,12 +283,12 @@ class TestKmipEngine(testtools.TestCase):
             )
         )
         e._logger.info.assert_any_call(
-            "Loading user_defined operation policies from file: {0}".format(
+            "Loading user-defined operation policies from file: {0}".format(
                 policy_file_a.name
             )
         )
         e._logger.info.assert_any_call(
-            "Loading user_defined operation policies from file: {0}".format(
+            "Loading user-defined operation policies from file: {0}".format(
                 policy_file_b.name
             )
         )