Merge "Refactor grain code to remove string handling using bash"
diff --git a/_grains/ceph.py b/_grains/ceph.py
index 45652e8..54bc97e 100644
--- a/_grains/ceph.py
+++ b/_grains/ceph.py
@@ -6,6 +6,7 @@
     from subprocess import check_output
     from subprocess import CalledProcessError
     import shlex
+    import json
     import os
     import re
 
@@ -28,44 +29,60 @@
 
         # osd
         if os.path.exists('/var/lib/ceph/osd'):
-            mount_path = check_output("df -h | awk '{print $6}' | grep ceph | grep -v lockbox | sed 's/-[0-9]*//g' | awk 'NR==1{print $1}'", shell=True).rstrip()
-            sed = 'sed \'s#{0}-##g\''.format(mount_path)
-            cmd = "lsblk -rp | awk '{print $1,$6,$7}' | grep -v lockbox | grep ceph | " + sed
+            cmd = "ceph-volume lvm list --format json"
             osd_output = check_output(cmd, shell=True)
+            osd_output = json.loads(osd_output)
+            dev_id = ''
+            devices = {}
             if osd_output:
+                for osd, params in osd_output.iteritems():
+                    dev_id = osd
+                    devices[dev_id] = {}
+                    devices[dev_id]['dev'] = params[0]['devices'][0]
+                    devices[dev_id]['path'] = params[0]['path']
+                    devices[dev_id]['uuid'] = params[0]['tags']['ceph.osd_fsid']
+
+                cmd = "ceph osd tree --format json"
+                osd_tree_output = check_output(cmd, shell=True)
+                osd_tree_output = json.loads(osd_tree_output)
+                for osd in osd_tree_output['nodes']:
+                    if 'type_id' in osd.keys():
+                        if str(osd['type_id']) == '0':
+                            for dev_id in devices.keys():
+                                if str(osd['id']) == str(dev_id):
+                                    devices[dev_id]['weight'] = osd['crush_weight']
+                                    devices[dev_id]['class'] = osd['device_class']
+                grain["ceph"]["ceph_volume"] = devices
+            else:
+                cmd = "ceph-disk list --format json"
+                osd_output = check_output(cmd, shell=True).decode("utf-8")
+                osd_output = json.loads(osd_output)
+                dev_id = ''
                 devices = {}
-                for line in osd_output.splitlines():
-                    device = line.split()
-                    encrypted = False
-                    if "crypt" in device[1]:
-                        output = check_output("lsblk -rp | grep -B1 " + device[0], shell=True)
-                        for l in output.splitlines():
-                            d = l.split()
-                            dev = re.sub("\d+", "", device[0])
-                            encrypted = True
-                            break
-                    else:
-                        dev = device[0].replace('1','')
-                        dev = re.sub("\d+", "", device[0])
-                    device[0] = device[2]
-                    try:
-                        devices[device[0]] = {}
-                        devices[device[0]]['dev'] = dev
-                        if encrypted:
-                            devices[device[0]]['dmcrypt'] = 'true'
-                        tline = check_output("ceph -c " + conf_file + " osd tree | awk '{print $1,$2,$3,$4}' | grep -w 'osd." + device[0] + "'", shell=True)
-                        osd = tline.split()
-                        if "osd" not in osd[2]:
-                            crush_class = osd[1]
-                            crush_weight = osd[2]
-                            devices[device[0]]['class'] = crush_class
-                            devices[device[0]]['weight'] = crush_weight
-                        else:
-                            crush_weight = osd[1]
-                            devices[device[0]]['weight'] = crush_weight
-                    except CalledProcessError:
-                        continue
-                grain["ceph"]["ceph_disk"] = devices
+                if osd_output:
+                    for line in osd_output:
+                        if "is_partition" not in line.keys():
+                            dev = line["path"]
+                            parts = line["partitions"]
+                            for p in parts:
+                                if "mount" in p.keys() and "ceph" in p["mount"]:
+                                    dev_id = p["whoami"]
+                                    devices[dev_id] = {}
+                                    devices[dev_id]['dev'] = dev
+                                    if len(p["dmcrypt"]) > 0:
+                                        devices[dev_id]['dmcrypt'] = 'true'
+
+                    cmd = "ceph osd tree --format json"
+                    osd_tree_output = check_output(cmd, shell=True).decode("utf-8")
+                    osd_tree_output = json.loads(osd_tree_output)
+                    for osd in osd_tree_output['nodes']:
+                        if 'type_id' in osd.keys():
+                            if str(osd['type_id']) == '0':
+                                for dev_id in devices.keys():
+                                    if str(osd['id']) == str(dev_id):
+                                        devices[dev_id]['weight'] = osd['crush_weight']
+                                        devices[dev_id]['class'] = osd['device_class']
+                    grain["ceph"]["ceph_disk"] = devices
 
         # keyrings
         directory = '/etc/ceph/'