[ keystone_policy.py ] Add yaml support

What:

Allow to read/write rules in json/yaml formats

Why:

1) Since Newton release oslo.policy supports both of the formats:
yaml and json.

2) oslopolicy-policy-generator produces an output only in yaml format
since the release, so yaml format expected as default.

3) Nova newton+ package has no any default policy.json file.
It has empty policy.yaml file, so we need to have ability to
manage the file from the module.

Change-Id: I39239ba5eebee39483607785698806c040937b4b
diff --git a/_modules/keystone_policy.py b/_modules/keystone_policy.py
index 05b9215..4e3ae6d 100644
--- a/_modules/keystone_policy.py
+++ b/_modules/keystone_policy.py
@@ -2,6 +2,8 @@
 import json
 import logging
 
+import yaml
+
 LOG = logging.getLogger(__name__)
 
 
@@ -12,10 +14,10 @@
 def rule_list(path, **kwargs):
     try:
         with io.open(path, 'r') as file_handle:
-            rules = json.loads(file_handle.read())
-        rules =  {str(k): str(v) for (k, v) in rules.items()}
+            rules = yaml.safe_load(file_handle) or {}
+        rules = {str(k): str(v) for (k, v) in rules.items()}
     except Exception as e:
-        msg = "Unable to load policy JSON %s: %s" % (path, repr(e))
+        msg = "Unable to load policy file %s: %s" % (path, repr(e))
         LOG.debug(msg)
         rules = {'Error': msg}
     return rules
@@ -30,9 +32,13 @@
         del rules[name]
         try:
             with io.open(path, 'w') as file_handle:
-                file_handle.write(unicode(json.dumps(rules, indent=4)))
+                if path.endswith('json'):
+                    serialized = json.dumps(rules, indent=4)
+                else:
+                    serialized = yaml.safe_dump(rules, indent=4)
+                file_handle.write(unicode(serialized))
         except Exception as e:
-            msg = "Unable to save policy json: %s" % repr(e)
+            msg = "Unable to save policy file: %s" % repr(e)
             LOG.error(msg)
             return {'Error': msg}
         ret = 'Rule {0} deleted'.format(name)
@@ -47,9 +53,13 @@
         rules.update({name: rule})
         try:
             with io.open(path, 'w') as file_handle:
-                file_handle.write(unicode(json.dumps(rules, indent=4)))
+                if path.endswith('json'):
+                    serialized = json.dumps(rules, indent=4)
+                else:
+                    serialized = yaml.safe_dump(rules, indent=4)
+                file_handle.write(unicode(serialized))
         except Exception as e:
-            msg = "Unable to save policy JSON %s: %s" % (path, repr(e))
+            msg = "Unable to save policy file %s: %s" % (path, repr(e))
             LOG.error(msg)
             return {'Error': msg}
         return rule_get(name, path, **kwargs)