Use Vagrantfile to build virtual site
[icn.git] / deploy / metal3-vm / vm-setup / library / generate_macs.py
1 #!/usr/bin/python
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 #
6 #    http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11 # implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # generate_baremetal_macs method ripped from
16 # openstack/tripleo-incubator/scripts/configure-vm
17
18 import marshal
19 import math
20 import random
21
22 DOCUMENTATION = '''
23 ---
24 module: generate_macs
25 version_added: "2.0"
26 short_description: Generate a list of Ethernet MAC addresses
27 description:
28    - Generate a list of Ethernet MAC addresses suitable for baremetal testing.
29 '''
30
31 MAX_NUM_MACS = math.trunc(0xff / 2)
32
33
34 def generate_baremetal_macs(nodes, networks):
35     """Generate an Ethernet MAC address suitable for baremetal testing."""
36     # NOTE(dprince): We generate our own bare metal MAC address's here
37     # instead of relying on libvirt so that we can ensure the
38     # locally administered bit is set low. (The libvirt default is
39     # to set the 2nd MSB high.) This effectively allows our
40     # fake baremetal VMs to more accurately behave like real hardware
41     # and fixes issues with bridge/DHCP configurations which rely
42     # on the fact that bridges assume the MAC address of the lowest
43     # attached NIC.
44     # MACs generated for a given machine will also be in sequential
45     # order, which matches how most BM machines are laid out as well.
46     # Additionally we increment each MAC by two places.
47     macs = []
48     count = len(nodes) * len(networks)
49
50     if count > MAX_NUM_MACS:
51         raise ValueError("The MAX num of MACS supported is %i  "
52                          "(you specified %i)." % (MAX_NUM_MACS, count))
53
54     # See the random number generator with the input so that MAC
55     # generation is idempotent.
56     random.seed(marshal.dumps(nodes + networks))
57
58     base_nums = [0x00,
59                  random.randint(0x00, 0xff),
60                  random.randint(0x00, 0xff),
61                  random.randint(0x00, 0xff),
62                  random.randint(0x00, 0xff)]
63     base_mac = ':'.join(map(lambda x: "%02x" % x, base_nums))
64
65     start = random.randint(0x00, 0xff)
66     if (start + (count * 2)) > 0xff:
67         # leave room to generate macs in sequence
68         start = 0xff - count * 2
69     for num in range(0, count * 2, 2):
70         mac = start + num
71         macs.append(base_mac + ":" + ("%02x" % mac))
72
73     result = {}
74     for node in nodes:
75         result[node['name']] = {}
76         for network in networks:
77             result[node['name']][network['name']] = macs.pop(0)
78
79     return result
80
81
82 def main():
83     module = AnsibleModule(
84         argument_spec=dict(
85             nodes=dict(required=True, type='list'),
86             networks=dict(required=True, type='list')
87         )
88     )
89     result = generate_baremetal_macs(module.params["nodes"],
90                                      module.params["networks"])
91     module.exit_json(**result)
92
93 # see http://docs.ansible.com/developing_modules.html#common-module-boilerplate
94 from ansible.module_utils.basic import AnsibleModule  # noqa
95
96
97 if __name__ == '__main__':
98     main()