Adds python IP utility library 69/12369/7
authorFeng Pan <fpan@redhat.com>
Fri, 15 Apr 2016 15:43:34 +0000 (11:43 -0400)
committerFeng Pan <fpan@redhat.com>
Thu, 21 Apr 2016 13:37:20 +0000 (09:37 -0400)
Changes include:
 - IP utility library in python 3 that supports both IPv4 and IPv6
   address generation. This library currently includes a single
   function of generating IP ranges or single IP for a given CIDR.
   More functionality will be added at a later time to support
   features such as IP address calculation.
 - Updated common-function.sh to use python library to generate IP
   ranges. All existing bash functions are preserved, so any
   callers will get identical IP ranges as before.
 - Add dependency to python3 for opnfv-apex-common package.
 - Add python dependency to build.sh

No change is made to interface related functions.

Change-Id: Idc6998754f9f3c7a3868ec5b5768f3bb5f78cd90
Signed-off-by: Feng Pan <fpan@redhat.com>
build/opnfv-apex-common.spec
ci/build.sh
lib/common-functions.sh
lib/python/apex/__init__.py [new file with mode: 0644]
lib/python/apex/ip_utils.py [new file with mode: 0644]

index e618ff0..89fb403 100644 (file)
@@ -9,9 +9,9 @@ URL:            https://gerrit.opnfv.org/gerrit/apex.git
 Source0:       opnfv-apex-common.tar.gz
 
 BuildArch:     noarch
-BuildRequires: python-docutils
+BuildRequires: python-docutils python34-devel
 Requires:      openstack-tripleo opnfv-apex-sdn opnfv-apex-undercloud openvswitch qemu-kvm bridge-utils libguestfs-tools
-Requires:      initscripts net-tools iputils iproute iptables
+Requires:      initscripts net-tools iputils iproute iptables python34
 
 %description
 Scripts for OPNFV deployment using RDO Manager
@@ -42,6 +42,9 @@ install config/network/network_settings.yaml %{buildroot}%{_sysconfdir}/opnfv-ap
 mkdir -p %{buildroot}%{_var}/opt/opnfv/lib/
 install lib/common-functions.sh %{buildroot}%{_var}/opt/opnfv/lib/
 install lib/utility-functions.sh %{buildroot}%{_var}/opt/opnfv/lib/
+mkdir -p %{buildroot}%{python3_sitelib}/apex/
+install lib/python/apex/__init__.py %{buildroot}%{python3_sitelib}/apex/
+install lib/python/apex/ip_utils.py %{buildroot}%{python3_sitelib}/apex/
 mkdir -p %{buildroot}%{_var}/opt/opnfv/lib/installer/onos/
 install lib/installer/onos/onos_gw_mac_update.sh %{buildroot}%{_var}/opt/opnfv/lib/installer/onos/
 
@@ -61,6 +64,9 @@ install config/inventory/pod_example_settings.yaml %{buildroot}%{_docdir}/opnfv/
 %attr(755,root,root) %{_bindir}/opnfv-util
 %{_var}/opt/opnfv/lib/common-functions.sh
 %{_var}/opt/opnfv/lib/utility-functions.sh
+%{python3_sitelib}/apex/ip_utils.py
+%{python3_sitelib}/apex/__init__.py
+%{python3_sitelib}/apex/__pycache__/*
 %{_var}/opt/opnfv/lib/installer/onos/onos_gw_mac_update.sh
 %{_sysconfdir}/opnfv-apex/os-nosdn-nofeature-ha.yaml
 %{_sysconfdir}/opnfv-apex/os-odl_l2-nofeature-ha.yaml
@@ -78,6 +84,8 @@ install config/inventory/pod_example_settings.yaml %{buildroot}%{_docdir}/opnfv/
 %doc %{_docdir}/opnfv/inventory.yaml.example
 
 %changelog
+* Fri Apr 15 2016 Feng Pan <fpan@redhat.com> - 3.0-2
+- Adds python ip utility lib.
 * Mon Apr 11 2016 Tim Rozet <trozet@redhat.com> - 3.0-1
 - adding opnfv-util
 * Mon Apr 04 2016 Dan Radez <dradez@redhat.com> - 3.0-0
index 2fd8c26..26cdf7a 100755 (executable)
@@ -128,6 +128,15 @@ if [[ "$MAKE_TARGETS" == "images" ]]; then
     fi
 fi
 
+# Make sure python is installed
+if ! rpm -q python34-devel > /dev/null; then
+    sudo yum install -y epel-release
+    if ! sudo yum install -y python34-devel; then
+        echo "Failed to install python34-devel package..."
+        exit 1
+    fi
+fi
+
 # Execute make against targets
 for t in $MAKE_TARGETS; do
     run_make $t
index af9b710..32ee6bc 100644 (file)
@@ -2,6 +2,9 @@
 # Common Functions used by  OPNFV Apex
 # author: Tim Rozet (trozet@redhat.com)
 
+#python ip_gen command
+ip_gen="python3.4 -B -m apex.ip_utils generate_ip_range"
+
 ##converts subnet mask to prefix
 ##params: subnet mask
 function prefix2mask {
@@ -212,25 +215,19 @@ function find_usable_ip_range {
 }
 
 ##generates usable IP range in correct format based on CIDR
-##assumes the first 20 IPs are used (by undercloud or otherwise)
+##A block of 20 IP addresses are reserved at beginning of address space.
+##A block of 22 IP addresses are reserved at end of address space, this includes
+##the broadcast IP address.
+##In a /24 IPv4 CIDR, this results in .1-20 as as .234-255 being excluded.
 ##params: cidr
 function generate_usable_ip_range {
-  local first_ip first_block_ip last_block_ip
-  #first_ip=$(ipcalc  -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  first_ip=$(increment_ip ${first_ip} 1)
-  first_block_ip=$(increment_ip ${first_ip} 20)
-  #last_block_ip=$(ipcalc  -nb $1 | grep HostMax: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  last_block_ip=$(ipcalc -nmpb $1 | grep BROADCAST= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  last_block_ip=$(subtract_ip ${last_block_ip} 1)
-  if [[ -z "$first_block_ip" || -z "$last_block_ip" ]]; then
+  if [ -z "$1" ]; then
     return 1
-  else
-    last_block_ip=$(subtract_ip ${last_block_ip} 21)
-    echo "${first_block_ip},${last_block_ip}"
   fi
+  echo $($ip_gen $1 21 -23)
 }
 
+
 ##find the undercloud IP address
 ##finds first usable IP on subnet
 ##params: interface
@@ -249,16 +246,13 @@ function find_provisioner_ip {
 ##generates undercloud IP address based on CIDR
 ##params: cidr
 function generate_provisioner_ip {
-  local provisioner_ip
-  #provisioner_ip=$(ipcalc  -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  provisioner_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  if [ -z "$provisioner_ip" ]; then
+  if [ -z "$1" ]; then
     return 1
   fi
-  provisioner_ip=$(increment_ip ${provisioner_ip} 1)
-  echo "$provisioner_ip"
+  echo $($ip_gen $1 1 1)
 }
 
+
 ##finds the dhcp range available via interface
 ##uses first 8 IPs, after 2nd IP
 ##params: interface
@@ -280,16 +274,10 @@ function find_dhcp_range {
 ##uses first 8 IPs, after 1st IP
 ##params: cidr
 function generate_dhcp_range {
-  local dhcp_range_start dhcp_range_end first_ip
-  #first_ip=$(ipcalc  -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  if [ -z "$first_ip" ]; then
+  if [ -z "$1" ]; then
     return 1
   fi
-  first_ip=$(increment_ip ${first_ip} 1)
-  dhcp_range_start=$(increment_ip ${first_ip} 1)
-  dhcp_range_end=$(increment_ip ${dhcp_range_start} 8)
-  echo "${dhcp_range_start},${dhcp_range_end}"
+  echo $($ip_gen $1 2 10)
 }
 
 ##finds the introspection range available via interface
@@ -313,16 +301,10 @@ function find_introspection_range {
 ##uses 8 IPs, after the first 10 IPs
 ##params: cidr
 function generate_introspection_range {
-  local inspect_range_start inspect_range_end first_ip
-  #first_ip=$(ipcalc  -nb $1 | grep HostMin: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  first_ip=$(ipcalc -nmpb $1 | grep NETWORK= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  if [ -z "$first_ip" ]; then
+  if [ -z "$1" ]; then
     return 1
   fi
-  first_ip=$(increment_ip ${first_ip} 1)
-  inspect_range_start=$(increment_ip ${first_ip} 10)
-  inspect_range_end=$(increment_ip ${inspect_range_start} 8)
-  echo "${inspect_range_start},${inspect_range_end}"
+  echo $($ip_gen $1 11 19)
 }
 
 ##finds the floating ip range available via interface
@@ -345,19 +327,14 @@ function find_floating_ip_range {
 }
 
 ##generate the floating range available via CIDR
-##uses last 20 IPs of subnet, minus last IP
+##uses last 20 IPs of subnet, minus last 2 IPs.
+##In a /24 IPv4 CIDR, this would result in floating ip range of .234-253
 ##params: cidr
 function generate_floating_ip_range {
-  local float_range_start float_range_end last_ip
-  #last_ip=$(ipcalc  -nb $1 | grep HostMax: | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  last_ip=$(ipcalc -nmpb $1 | grep BROADCAST= | grep -Eo "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")
-  if [ -z "$last_ip" ]; then
+  if [ -z "$1" ]; then
     return 1
   fi
-  last_ip=$(subtract_ip ${last_ip} 2)
-  float_range_start=$(subtract_ip ${last_ip} 19)
-  float_range_end=${last_ip}
-  echo "${float_range_start},${float_range_end}"
+  echo $($ip_gen $1 -22 -3)
 }
 
 ##attach interface to OVS and set the network config correctly
diff --git a/lib/python/apex/__init__.py b/lib/python/apex/__init__.py
new file mode 100644 (file)
index 0000000..0c0ae6c
--- /dev/null
@@ -0,0 +1,9 @@
+##############################################################################
+# Copyright (c) 2016 Feng Pan (fpan@redhat.com) and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
diff --git a/lib/python/apex/ip_utils.py b/lib/python/apex/ip_utils.py
new file mode 100644 (file)
index 0000000..680ce7e
--- /dev/null
@@ -0,0 +1,54 @@
+
+##############################################################################
+# Copyright (c) 2016 Feng Pan (fpan@redhat.com) and others.
+#
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+
+import ipaddress
+
+
+def generate_ip_range(args):
+    """
+    Generate IP range in string format for given CIDR.
+    This function works for both IPv4 and IPv6.
+
+    args is expected to contain the following members:
+    CIDR: any valid CIDR representation.
+    start_position: starting index, default to first address in subnet (1)
+    end_position:  ending index, default to last address in subnet (-1)
+
+    Returns IP range in string format. A single IP is returned if start and end IPs are identical.
+    """
+    cidr = ipaddress.ip_network(args.CIDR)
+    (start_index, end_index) = (args.start_position, args.end_position)
+    if cidr[start_index] == cidr[end_index]:
+        return str(cidr[start_index])
+    else:
+        return ','.join(sorted([str(cidr[start_index]), str(cidr[end_index])]))
+
+
+def main():
+    import argparse
+    import sys
+
+    parser = argparse.ArgumentParser()
+    subparsers = parser.add_subparsers()
+
+    parser_gen_ip_range = subparsers.add_parser('generate_ip_range', help='Generate IP Range given CIDR')
+    parser_gen_ip_range.add_argument('CIDR', help='Network in CIDR notation')
+    parser_gen_ip_range.add_argument('start_position', type=int, help='Starting index')
+    parser_gen_ip_range.add_argument('end_position', type=int, help='Ending index')
+    parser_gen_ip_range.set_defaults(func=generate_ip_range)
+
+    args = parser.parse_args(sys.argv[1:])
+    print(args.func(args))
+
+
+if __name__ == '__main__':
+    main()
+