adding metal3 vm verifier
[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 math
19 import random
20
21 DOCUMENTATION = '''
22 ---
23 module: generate_macs
24 version_added: "2.0"
25 short_description: Generate a list of Ethernet MAC addresses
26 description:
27    - Generate a list of Ethernet MAC addresses suitable for baremetal testing.
28 '''
29
30 MAX_NUM_MACS = math.trunc(0xff / 2)
31
32
33 def generate_baremetal_macs(nodes, networks):
34     """Generate an Ethernet MAC address suitable for baremetal testing."""
35     # NOTE(dprince): We generate our own bare metal MAC address's here
36     # instead of relying on libvirt so that we can ensure the
37     # locally administered bit is set low. (The libvirt default is
38     # to set the 2nd MSB high.) This effectively allows our
39     # fake baremetal VMs to more accurately behave like real hardware
40     # and fixes issues with bridge/DHCP configurations which rely
41     # on the fact that bridges assume the MAC address of the lowest
42     # attached NIC.
43     # MACs generated for a given machine will also be in sequential
44     # order, which matches how most BM machines are laid out as well.
45     # Additionally we increment each MAC by two places.
46     macs = []
47     count = len(nodes) * len(networks)
48
49     if count > MAX_NUM_MACS:
50         raise ValueError("The MAX num of MACS supported is %i  "
51                          "(you specified %i)." % (MAX_NUM_MACS, count))
52
53     base_nums = [0x00,
54                  random.randint(0x00, 0xff),
55                  random.randint(0x00, 0xff),
56                  random.randint(0x00, 0xff),
57                  random.randint(0x00, 0xff)]
58     base_mac = ':'.join(map(lambda x: "%02x" % x, base_nums))
59
60     start = random.randint(0x00, 0xff)
61     if (start + (count * 2)) > 0xff:
62         # leave room to generate macs in sequence
63         start = 0xff - count * 2
64     for num in range(0, count * 2, 2):
65         mac = start + num
66         macs.append(base_mac + ":" + ("%02x" % mac))
67
68     result = {}
69     for node in nodes:
70         result[node['name']] = {}
71         for network in networks:
72             result[node['name']][network['name']] = macs.pop(0)
73
74     return result
75
76
77 def main():
78     module = AnsibleModule(
79         argument_spec=dict(
80             nodes=dict(required=True, type='list'),
81             networks=dict(required=True, type='list')
82         )
83     )
84     result = generate_baremetal_macs(module.params["nodes"],
85                                      module.params["networks"])
86     module.exit_json(**result)
87
88 # see http://docs.ansible.com/developing_modules.html#common-module-boilerplate
89 from ansible.module_utils.basic import AnsibleModule  # noqa
90
91
92 if __name__ == '__main__':
93     main()