Upload the contribution of vstf as bottleneck network framework.
[bottlenecks.git] / vstf / vstf / controller / env_build / cfg_intent_parse.py
diff --git a/vstf/vstf/controller/env_build/cfg_intent_parse.py b/vstf/vstf/controller/env_build/cfg_intent_parse.py
new file mode 100755 (executable)
index 0000000..8c7c10b
--- /dev/null
@@ -0,0 +1,130 @@
+"""
+Created on 2015-10-13
+
+@author: y00228926
+"""
+import json
+import logging
+from vstf.common.utils import randomMAC
+
+LOG = logging.getLogger(__name__)
+
+
+class IntentParser(object):
+    def __init__(self, cfg_file):
+        self.cfg_file = cfg_file
+        with file(cfg_file) as fp:
+            self.cfg_intent = json.load(fp)
+
+    def parse_cfg_file(self):
+        self.set_default()
+        self.parse_br_type()
+        self.parse_vms_cfg()
+        return self.cfg_intent
+
+    def set_default(self):
+        for host_cfg in self.cfg_intent['env-build']:
+            host_cfg.setdefault("scheme", 'libvirt')
+            host_cfg.setdefault("drivers", [])
+            host_cfg.setdefault("vms", [])
+            host_cfg.setdefault("bridges", [])
+            for vm_cfg in host_cfg["vms"]:
+                vm_cfg.setdefault("init_config", {})
+                vm_cfg["init_config"].setdefault('amqp_port', 5672)
+                vm_cfg["init_config"].setdefault('amqp_user', "guest")
+                vm_cfg["init_config"].setdefault('amqp_passwd', "guest")
+                vm_cfg["init_config"].setdefault('amqp_id', "")
+
+    def _nomornize_boolean(self, flag):
+        if isinstance(flag, bool):
+            return flag
+        lflag = flag.lower()
+        if lflag == 'true':
+            return True
+        if lflag == 'false':
+            return False
+        raise Exception("flag %s cannot be nomonized to bool value" % flag)
+
+    def parse_br_type(self):
+        for host_cfg in self.cfg_intent['env-build']:
+            br_cfgs = host_cfg['bridges']
+            br_type_set = set()
+            for br_cfg in br_cfgs:
+                br_type_set.add(br_cfg["type"])
+            for vm_cfg in host_cfg['vms']:
+                for tap_cfg in vm_cfg['taps']:
+                    br_type_set.add(tap_cfg["br_type"])
+            if len(br_type_set) > 1:
+                raise Exception("specified more than one type of vswitchfor host:%s" % host_cfg['ip'])
+            if len(br_type_set) > 0:
+                br_type = br_type_set.pop()
+                host_cfg['br_type'] = br_type
+
+    def parse_vms_cfg(self):
+        for host_cfg in self.cfg_intent['env-build']:
+            vm_cfgs = host_cfg["vms"]
+            self._parse_vm_init_cfg(vm_cfgs)
+            self._parse_vm_ctrl_cfg(vm_cfgs)
+            for vm_cfg in vm_cfgs:
+                self._parse_taps_cfg(vm_cfg['taps'])
+
+    def _parse_taps_cfg(self, tap_cfgs):
+        tap_name_set = set()
+        tap_mac_set = set()
+        count = 0
+        for tap_cfg in tap_cfgs:
+            count += 1
+            tap_name_set.add(tap_cfg["tap_mac"])
+            tap_mac_set.add(tap_cfg["tap_name"])
+        if len(tap_mac_set) != len(tap_name_set) != count:
+            raise Exception('config same tap_mac/tap_name for different taps')
+        LOG.info("tap_name_set: %s", tap_name_set)
+        LOG.info("tap_mac_set: %s", tap_mac_set)
+
+    def _parse_vm_init_cfg(self, vm_cfgs):
+        count = 0
+        ip_set = set()
+        gw_set = set()
+        required_options = {"ctrl_ip_setting", "ctrl_gw", "amqp_server"}
+        for vm_cfg in vm_cfgs:
+            init_cfg = vm_cfg["init_config"]
+            sub = required_options - set(init_cfg.keys())
+            if sub:
+                raise Exception("unset required options:%s" % sub)
+            count += 1
+            ip_set.add(init_cfg["ctrl_ip_setting"])
+            gw_set.add(init_cfg["ctrl_gw"])
+        if len(gw_set) > 1:
+            raise Exception("cannot config more than one gw for vm")
+        if len(ip_set) < count:
+            raise Exception("config same ip for different vm")
+        LOG.info("ip_set: %s", ip_set)
+        LOG.info("gw_set: %s", gw_set)
+
+    def _parse_vm_ctrl_cfg(self, vm_cfgs):
+        count = 0
+        ctrl_mac_set = set()
+        ctrl_br_set = set()
+        for vm_cfg in vm_cfgs:
+            count += 1
+            vm_cfg.setdefault("ctrl_mac", randomMAC())
+            vm_cfg.setdefault("ctrl_br", 'br0')
+            ctrl_mac_set.add(vm_cfg['ctrl_mac'])
+            ctrl_br_set.add(vm_cfg['ctrl_br'])
+        if len(ctrl_br_set) > 1:
+            raise Exception("cannot config more than one ctrl_br_set.")
+        if len(ctrl_mac_set) < count:
+            raise Exception("config same ctrl_mac_set for different vm.")
+        LOG.info("ctrl_mac_set: %s", ctrl_mac_set)
+        LOG.info("ctrl_br_set: %s", ctrl_br_set)
+
+
+if __name__ == '__main__':
+    import argparse
+
+    parser = argparse.ArgumentParser()
+    parser.add_argument('--config', help='config file to parse')
+    args = parser.parse_args()
+    logging.basicConfig(level=logging.INFO)
+    p = IntentParser(args.config)
+    LOG.info(json.dumps(p.parse_cfg_file(), indent=4))