Hi,

I wrote a small plugin that I would like to share..

It allows cobbler to auto-allocate IP from a pool, rather than user
explicitly specifying the IP at host creation time. This is mostly
useful for VMs with statically assigned IP, where you don't care too
much what the IP is (other than it is not used in that VLAN).

How to use?
In the /etc/cobbler/settings you configure a pool for each VLAN..
ip_auto_alloc: true
ip_pool:
    vlan100: 10.10.100.20 - 10.10.100.250
    vlan101: 10.10.101.20 - 10.10.101.250

There is only one pool allowed on each vlan. Pool name must match the
vlan/bridge name (from --virt-bridge option).
Then you can create a VM as follows..

cobbler system add --name $host --hostname $host --profile
Fedora14-kvm --gateway=10.10.100.1
cobbler system edit --name $host --interface=eth0 --virt-bridge=vlan100 \
    --ip=0.0.0.0 --subnet=255.255.255.0 --dns-name=${host}.example.com
--static=yes
cobbler system edit --name $host --interface=eth1 --virt-bridge=vlan101 \
    --ip=0.0.0.0 --subnet=255.255.255.0
--dns-name=${host}-mgmt.example.com --static=yes

The code above can be wrapped into a script, which will allow you to
add VM just by specifying the hostname.

How it works?
When the new host/interface is added to cobbler, plugin is triggered.
If it finds an IP address 0.0.0.0 on an interface, it will select a
pool associated with the interface's VLAN (--virt-bridge). Then it
finds the first unused IP in the pool. The check if the IP is used is
made against Cobbler DB, therefore Cobbler must be the only authority
to assign IP from that pool. Lastly, the dummy IP 0.0.0.0 is replaced
with real IP.

To install..
Install package python-IPy (yum install python-IPy)
Copy the attached file "system_post_ip_alloc.py" to
/usr/lib/pythonX.X/site-packages/cobbler/modules/.
Add the config snippet from above to /etc/cobbler/settings.
Restart cobblerd

I have also attached the same plugin in a form of a patch file against
stable branch.

Regards,

BranoZ
"""
This module allow Cobbler to auto-allocate IP to newly created hosts.
If the IP address is set to '0.0.0.0' by user, then Cobbler will choose
the first unallocated IP from the pool. VLAN name (from --virt-bridge)
will determine which pool to allocate from.

Example:
/etc/cobbler/settings:
ip_auto_alloc: true
ip_pool:
    vlan100: 10.10.100.20 - 10.10.100.250
    vlan101: 10.10.101.20 - 10.10.101.250

cobbler system add --name $host --hostname $host --profile Fedora14-kvm --gateway=10.10.100.1
cobbler system edit --name $host --interface=eth0 --virt-bridge=vlan100 \
    --ip=0.0.0.0 --subnet=255.255.255.0 --dns-name=${host}.example.com --static=yes
cobbler system edit --name $host --interface=eth1 --virt-bridge=vlan101 \
    --ip=0.0.0.0 --subnet=255.255.255.0 --dns-name=${host}-mgmt.example.com --static=yes

"""

# this module is loaded only if IP alloc is needed (provided by 'python-IPy' package)
#import IPy

from cobbler.cexceptions import CX

def register():
   # this string determines, what type of plugin this is.."
   return '/var/lib/cobbler/triggers/add/system/post/*'

def already_assigned_ips(api):
    """return a set of all IPs used in Cobbler DB"""
    import IPy

    assigned_ips = set()
    for s in api.systems():
        for (name, interface) in s.interfaces.iteritems():
            ip = interface['ip_address']
            if len(ip) > 0:
                assigned_ips.add(IPy.IP(ip).ip)

    return assigned_ips

def alloc_ip(api, vlan):
    """find and return an unsued IP in a pool designated by 'vlan'"""

    try:
        import IPy
    except ImportError:
        raise CX('Python module "IPy" not found, please install "python-IPy" package')

    # take ip_pool entry (from settings) corresponding to 'vlan'
    ip_pool = api.settings().ip_pool
    if vlan not in ip_pool:
        raise CX('No pool is defined for vlan %s (/etc/cobbler/settings)' % vlan)

    pool_str = ip_pool[vlan]
    try:
        # parse pool entry, expected format "X.X.X.X - Y.Y.Y.Y" (both must be valid IPs)
        (start_ip, end_ip) = pool_str.replace(' ', '').split('-')
        start_num = IPy.IP(start_ip).ip
        end_num = IPy.IP(end_ip).ip
    except Exception, e:
        raise CX('Error parsing the pool "%s" for vlan %s' % (pool_str, vlan))

    assigned_ips = already_assigned_ips(api)

    # iterate over all IPs in the pool, find first one that's unsued
    for i in range(start_num, end_num+1):
        if i not in assigned_ips:
            return str(IPy.IP(i))
    else:
        raise CX('No free IP available in pool for VLAN %s' % vlan)

def run(api, args, logger):

    # skip plugin if disabled
    settings = api.settings()
    if not str(settings.ip_auto_alloc).lower() in ['1', 'yes', 'y', 'true']:
        return 0

    hostname = args[0]
    system = api.find_system(hostname)

    # find any interace of 'this' host with IP == '0.0.0.0'
    for (name, interface) in system.interfaces.iteritems():
        if interface['ip_address'] == '0.0.0.0':
            vlan = interface.get('virt_bridge', '')
            if vlan == '':
                raise CX('Cannot allocate IP, vlan is not set for interface %s' % name)

            newip = alloc_ip(api, vlan)
            system.set_ip_address(newip, name)
            api.serialize()         # make sure that the change is saved to JSON config file

    return 0

From cbe55e5dd3d38e00025985c6fff248ace8f0f326 Mon Sep 17 00:00:00 2001
From: Brano Zarnovican <[email protected]>
Date: Fri, 6 May 2011 16:34:57 +0100
Subject: [PATCH] added system_post_ip_alloc.py plugin to auto-allocate IPs by cobbler

---
 cobbler/modules/system_post_ip_alloc.py |   97 +++++++++++++++++++++++++++++++
 cobbler/settings.py                     |    1 +
 installer_templates/settings.template   |   11 ++++
 3 files changed, 109 insertions(+), 0 deletions(-)
 create mode 100644 cobbler/modules/system_post_ip_alloc.py

diff --git a/cobbler/modules/system_post_ip_alloc.py b/cobbler/modules/system_post_ip_alloc.py
new file mode 100644
index 0000000..7c48ee6
--- /dev/null
+++ b/cobbler/modules/system_post_ip_alloc.py
@@ -0,0 +1,97 @@
+"""
+This module allow Cobbler to auto-allocate IP to newly created hosts.
+If the IP address is set to '0.0.0.0' by user, then Cobbler will choose
+the first unallocated IP from the pool. VLAN name (from --virt-bridge)
+will determine which pool to allocate from.
+
+Example:
+/etc/cobbler/settings:
+ip_auto_alloc: true
+ip_pool:
+    vlan100: 10.10.100.20 - 10.10.100.250
+    vlan101: 10.10.101.20 - 10.10.101.250
+
+cobbler system add --name $host --hostname $host --profile Fedora14-kvm --gateway=10.10.100.1
+cobbler system edit --name $host --interface=eth0 --virt-bridge=vlan100 \
+    --ip=0.0.0.0 --subnet=255.255.255.0 --dns-name=${host}.example.com --static=yes
+cobbler system edit --name $host --interface=eth1 --virt-bridge=vlan101 \
+    --ip=0.0.0.0 --subnet=255.255.255.0 --dns-name=${host}-mgmt.example.com --static=yes
+
+"""
+
+# this module is loaded only if IP alloc is needed (provided by 'python-IPy' package)
+#import IPy
+
+from cobbler.cexceptions import CX
+
+def register():
+   # this string determines, what type of plugin this is.."
+   return '/var/lib/cobbler/triggers/add/system/post/*'
+
+def already_assigned_ips(api):
+    """return a set of all IPs used in Cobbler DB"""
+    import IPy
+
+    assigned_ips = set()
+    for s in api.systems():
+        for (name, interface) in s.interfaces.iteritems():
+            ip = interface['ip_address']
+            if len(ip) > 0:
+                assigned_ips.add(IPy.IP(ip).ip)
+
+    return assigned_ips
+
+def alloc_ip(api, vlan):
+    """find and return an unsued IP in a pool designated by 'vlan'"""
+
+    try:
+        import IPy
+    except ImportError:
+        raise CX('Python module "IPy" not found, please install "python-IPy" package')
+
+    # take ip_pool entry (from settings) corresponding to 'vlan'
+    ip_pool = api.settings().ip_pool
+    if vlan not in ip_pool:
+        raise CX('No pool is defined for vlan %s (/etc/cobbler/settings)' % vlan)
+
+    pool_str = ip_pool[vlan]
+    try:
+        # parse pool entry, expected format "X.X.X.X - Y.Y.Y.Y" (both must be valid IPs)
+        (start_ip, end_ip) = pool_str.replace(' ', '').split('-')
+        start_num = IPy.IP(start_ip).ip
+        end_num = IPy.IP(end_ip).ip
+    except Exception, e:
+        raise CX('Error parsing the pool "%s" for vlan %s' % (pool_str, vlan))
+
+    assigned_ips = already_assigned_ips(api)
+
+    # iterate over all IPs in the pool, find first one that's unsued
+    for i in range(start_num, end_num+1):
+        if i not in assigned_ips:
+            return str(IPy.IP(i))
+    else:
+        raise CX('No free IP available in pool for VLAN %s' % vlan)
+
+def run(api, args, logger):
+
+    # skip plugin if disabled
+    settings = api.settings()
+    if not str(settings.ip_auto_alloc).lower() in ['1', 'yes', 'y', 'true']:
+        return 0
+
+    hostname = args[0]
+    system = api.find_system(hostname)
+
+    # find any interace of 'this' host with IP == '0.0.0.0'
+    for (name, interface) in system.interfaces.iteritems():
+        if interface['ip_address'] == '0.0.0.0':
+            vlan = interface.get('virt_bridge', '')
+            if vlan == '':
+                raise CX('Cannot allocate IP, vlan is not set for interface %s' % name)
+
+            newip = alloc_ip(api, vlan)
+            system.set_ip_address(newip, name)
+            api.serialize()         # make sure that the change is saved to JSON config file
+
+    return 0
+
diff --git a/cobbler/settings.py b/cobbler/settings.py
index 2216a9e..0ea33f3 100644
--- a/cobbler/settings.py
+++ b/cobbler/settings.py
@@ -54,6 +54,7 @@ DEFAULTS = {
     "func_master"                 : "overlord.example.org",
     "func_auto_setup"             : 0,
     "http_port"                   : "80",
+    "ip_auto_alloc"               : "false",
     "isc_set_host_name"           : 0,
     "ldap_server"                 : "grimlock.devel.redhat.com",
     "ldap_base_dn"                : "DC=devel,DC=redhat,DC=com",
diff --git a/installer_templates/settings.template b/installer_templates/settings.template
index 335c320..70ddc8b 100644
--- a/installer_templates/settings.template
+++ b/installer_templates/settings.template
@@ -414,3 +414,14 @@ safe_templating_whitelist:
    - silent
    - slurp
    - raw
+
+# Allow Cobbler to auto-allocate IP to newly created hosts.
+# If the IP address is set to '0.0.0.0' by user, then Cobbler will choose
+# the first unallocated IP from the pool below. VLAN name (from --virt-bridge)
+# will determine which pool to allocate from.
+
+#ip_auto_alloc: true
+#ip_pool:
+#    vlan100: 10.10.100.20 - 10.10.100.250
+#    vlan101: 10.10.101.20 - 10.10.101.250
+
-- 
1.6.4.4

_______________________________________________
cobbler mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/cobbler

Reply via email to