From 3d56d3211e2ddee0825e79174cfdfbcda70cd20b Mon Sep 17 00:00:00 2001 From: Feng Pan Date: Fri, 15 Apr 2016 11:43:34 -0400 Subject: Adds python IP utility library 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 --- build/opnfv-apex-common.spec | 12 ++++++-- ci/build.sh | 9 ++++++ lib/common-functions.sh | 65 ++++++++++++++------------------------------ lib/python/apex/__init__.py | 9 ++++++ lib/python/apex/ip_utils.py | 54 ++++++++++++++++++++++++++++++++++++ 5 files changed, 103 insertions(+), 46 deletions(-) create mode 100644 lib/python/apex/__init__.py create mode 100644 lib/python/apex/ip_utils.py diff --git a/build/opnfv-apex-common.spec b/build/opnfv-apex-common.spec index e618ff0f..89fb4030 100644 --- a/build/opnfv-apex-common.spec +++ b/build/opnfv-apex-common.spec @@ -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 - 3.0-2 +- Adds python ip utility lib. * Mon Apr 11 2016 Tim Rozet - 3.0-1 - adding opnfv-util * Mon Apr 04 2016 Dan Radez - 3.0-0 diff --git a/ci/build.sh b/ci/build.sh index 2fd8c26d..26cdf7a0 100755 --- a/ci/build.sh +++ b/ci/build.sh @@ -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 diff --git a/lib/common-functions.sh b/lib/common-functions.sh index af9b7103..32ee6bcc 100644 --- a/lib/common-functions.sh +++ b/lib/common-functions.sh @@ -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 index 00000000..0c0ae6c6 --- /dev/null +++ b/lib/python/apex/__init__.py @@ -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 index 00000000..680ce7e0 --- /dev/null +++ b/lib/python/apex/ip_utils.py @@ -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() + -- cgit 1.2.3-korg