summaryrefslogtreecommitdiffstats
path: root/vstf/vstf/controller/env_build/cfg_intent_parse.py
blob: 8c7c10b8bf6f9790d42d8f32793129e2ef0b3246 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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))