18 changed files with 291 additions and 123 deletions
@ -0,0 +1,96 @@
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
# implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
# generate_baremetal_macs method ripped from |
||||
# openstack/tripleo-incubator/scripts/configure-vm |
||||
|
||||
import math |
||||
import random |
||||
import sys |
||||
import fnmatch |
||||
import os |
||||
import socket |
||||
import struct |
||||
from itertools import chain |
||||
import json |
||||
import netaddr |
||||
DOCUMENTATION = ''' |
||||
--- |
||||
module: ipam |
||||
version_added: "1.0" |
||||
short_description: Help with IPAM allocation |
||||
description: |
||||
- Generate IPs for instances, ensuring they're unique on every node |
||||
''' |
||||
# we don't support specifying subnet_bridge or instances yet |
||||
def allocate_ips(nodes, physical_primary_ip, physical_node_count=1, subnet_bridge='192.168.0.0/24', subnet_instances='192.168.4.0/22'): |
||||
"""Return IP assignments""" |
||||
# calculate some stuff |
||||
vm_instance_count = len(nodes) |
||||
last_octet = physical_primary_ip.split('.')[-1] |
||||
node_index = int(last_octet) % int(physical_node_count) |
||||
bridge_ip = netaddr.IPNetwork(subnet_bridge)[node_index+1] |
||||
# generate an ip for every vm in the entire environment |
||||
ip_buckets=[None] * physical_node_count |
||||
vm_ip_list = list(netaddr.IPNetwork(subnet_instances)) |
||||
vm_ip_list.reverse() |
||||
|
||||
# throw away 0, .1, .2, .3 - assumes we won't exceed .255 |
||||
vm_ip_list.pop() |
||||
vm_ip_list.pop() |
||||
vm_ip_list.pop() |
||||
vm_ip_list.pop() |
||||
|
||||
# now take IPs from this list - enough for all the VMs |
||||
# we need to create and place them into groups |
||||
# one for each physical node |
||||
for physnode in range(0, physical_node_count): |
||||
ip_buckets[physnode] = {} |
||||
ip_list = [] |
||||
for vmidx in range(0, vm_instance_count): |
||||
ip_list.append(vm_ip_list.pop().__str__()) |
||||
ip_buckets[physnode] = ip_list |
||||
|
||||
bridge_subnet_netmask = cidr_to_netmask(subnet_bridge) |
||||
return { |
||||
'node_index': node_index, |
||||
'bridge_ip': bridge_ip.__str__(), |
||||
'instance_ips': ip_buckets[node_index], |
||||
'bridge_subnet_netmask': bridge_subnet_netmask, |
||||
} |
||||
|
||||
def cidr_to_netmask(cidr): |
||||
_, net_bits = cidr.split('/') |
||||
host_bits = 32 - int(net_bits) |
||||
netmask = socket.inet_ntoa(struct.pack('!I', (1 << 32) - (1 << host_bits))) |
||||
return netmask |
||||
|
||||
def main(): |
||||
module = AnsibleModule( |
||||
argument_spec=dict( |
||||
nodes=dict(required=True, type='list'), |
||||
physical_node_count=dict(required=True, type='int'), |
||||
primary_ipaddress=dict(required=True, type='str'), |
||||
subnet_bridge=dict(required=True, type='str'), |
||||
subnet_instances=dict(required=True, type='str'), |
||||
) |
||||
) |
||||
result = allocate_ips(module.params["nodes"], |
||||
module.params["primary_ipaddress"], |
||||
module.params["physical_node_count"], |
||||
module.params["subnet_bridge"], |
||||
module.params["subnet_instances"]) |
||||
module.exit_json(**result) |
||||
# see http://docs.ansible.com/developing_modules.html#common-module-boilerplate |
||||
from ansible.module_utils.basic import AnsibleModule # noqa |
||||
if __name__ == '__main__': |
||||
main() |
@ -0,0 +1,38 @@
|
||||
|
||||
################################################## |
||||
# REMOVE ONCE OPERATOR IS SUPPLYING THIS DATA ## |
||||
################################################## |
||||
- name: initialize ipam |
||||
set_fact: |
||||
ipam: {} |
||||
# get the subnet in yaml - the network named 'management' |
||||
# is special |
||||
|
||||
- name: discover management subnet from network definitions |
||||
set_fact: |
||||
management_subnet: "{{ item }}" |
||||
when: item.name == 'management' |
||||
loop: "{{ networks }}" |
||||
|
||||
- name: print value of management subnet |
||||
debug: |
||||
msg: "Value of management subnet is {{ management_subnet }}" |
||||
# get our ip from admin interface which is always our default route |
||||
|
||||
- name: discover assigned address of this machines management interface |
||||
set_fact: |
||||
primary_ip: "{{ ansible_default_ipv4.address|default(ansible_all_ipv4_addresses[0]) }}" |
||||
|
||||
- name: ipam allocation |
||||
ipam: |
||||
nodes: "{{ domains }}" |
||||
primary_ipaddress: "{{ primary_ip }}" |
||||
physical_node_count: "{{ nodeCount | int }}" |
||||
subnet_bridge: "{{ management_subnet.subnet }}" |
||||
subnet_instances: "{{ management_subnet.instanceSubnet }}" |
||||
register: ipam |
||||
when: domains |
||||
|
||||
- name: debug ipam result |
||||
debug: |
||||
msg: "IPAM Result {{ ipam }}" |
@ -1 +1,2 @@
|
||||
libvirt_uri: qemu:///system |
||||
libvirt_uri: qemu:///system |
||||
node_core_map: {} |
Loading…
Reference in new issue