diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | build/Makefile | 15 | ||||
-rw-r--r-- | build/nics-template.yaml.jinja2 | 21 | ||||
-rw-r--r-- | build/opnfv-apex-common.spec | 2 | ||||
-rwxr-xr-x | build/overcloud-full.sh | 17 | ||||
-rwxr-xr-x | build/overcloud-onos.sh | 4 | ||||
-rwxr-xr-x | build/undercloud.sh | 6 | ||||
-rw-r--r-- | build/variables.sh | 15 | ||||
-rwxr-xr-x | ci/deploy.sh | 17 | ||||
-rwxr-xr-x | ci/test.sh | 11 | ||||
-rw-r--r-- | lib/common-functions.sh | 2 | ||||
-rw-r--r-- | lib/python/apex/deploy_env.py | 53 | ||||
-rw-r--r-- | lib/python/apex/ip_utils.py | 41 | ||||
-rw-r--r-- | lib/python/apex/network_environment.py | 61 | ||||
-rw-r--r-- | lib/python/apex/network_settings.py | 9 | ||||
-rwxr-xr-x | lib/python/apex_python_utils.py (renamed from lib/python/apex-python-utils.py) | 34 | ||||
-rw-r--r-- | tests/test_apex_deploy_env.py | 17 | ||||
-rw-r--r-- | tests/test_apex_ip_utils.py | 9 | ||||
-rw-r--r-- | tests/test_apex_network_environment.py | 3 | ||||
-rw-r--r-- | tests/test_apex_python_utils_py.py | 80 |
20 files changed, 268 insertions, 151 deletions
@@ -1,5 +1,7 @@ *~ +*.pyc .*.sw? +.coverage /docs_build/ /docs_output/ /releng/ diff --git a/build/Makefile b/build/Makefile index 0763d361..84305618 100644 --- a/build/Makefile +++ b/build/Makefile @@ -66,12 +66,23 @@ $(RPMCOM): .PHONY: python-tests python-tests: + # clean previous coverage data + rm -rf ../tests/.coverage + rm -rf ../tests/htmlcov # run nose tests - cd ../tests && PYTHONPATH=../lib/python/ nosetests-3.4 . --with-coverage --cover-package apex + cd ../tests && PYTHONPATH=../lib/python/ nosetests-3.4 . --with-coverage --cover-package apex --cover-package apex_python_utils --cover-html --cover-min-percentage 85 + # generate reports - cd ../tests && coverage3 html --include '*lib/python/*' cd ../tests && coverage3 report --include '*lib/python/*' -m +####################### +# PYTHON PEP8 CHECK # +####################### + +.PHONY: python-pep8-check +python-pep8-check: + pep8 ../lib/python + pep8 ../tests ############### # UNDERCLOUD # diff --git a/build/nics-template.yaml.jinja2 b/build/nics-template.yaml.jinja2 index 1c51ab7f..455ae0f3 100644 --- a/build/nics-template.yaml.jinja2 +++ b/build/nics-template.yaml.jinja2 @@ -85,7 +85,7 @@ resources: os_net_config: network_config: - - {%- if vlans['private_network'] != 'native' or vlans['storage_network'] != 'native' or vlans['api_network'] != 'native' %} + {%- if vlans['private_network'] is number or vlans['storage_network'] is number or vlans['api_network'] is number %} type: ovs_bridge name: {get_input: bridge_name} members: @@ -94,7 +94,7 @@ resources: name: nic1 # force the MAC address of the bridge to this interface primary: true - {%- if 'public_network' in enabled_networks and vlans['private_network'] != 'native' %} + {%- if 'public_network' in enabled_networks and vlans['private_network'] is number %} - type: vlan vlan_id: {get_param: ExternalNetworkVlanID} @@ -106,7 +106,7 @@ resources: default: true next_hop: {get_param: ExternalInterfaceDefaultRoute} {%- endif %} - {%- if 'private_network' in enabled_networks and vlans['private_network'] != 'native' %} + {%- if 'private_network' in enabled_networks and vlans['private_network'] is number %} - type: vlan vlan_id: {get_param: TenantNetworkVlanID} @@ -114,7 +114,7 @@ resources: - ip_netmask: {get_param: TenantIpSubnet} {%- endif %} - {%- if 'storage_network' in enabled_networks and vlans['storage_network'] != 'native' %} + {%- if 'storage_network' in enabled_networks and vlans['storage_network'] is number %} - type: vlan vlan_id: {get_param: StorageNetworkVlanID} @@ -122,7 +122,7 @@ resources: - ip_netmask: {get_param: StorageIpSubnet} {%- endif %} - {%- if 'api_network' in enabled_networks and vlans['api_network'] != 'native' %} + {%- if 'api_network' in enabled_networks and vlans['api_network'] is number %} - type: vlan vlan_id: {get_param: InternalApiNetworkVlanID} @@ -212,6 +212,17 @@ resources: name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %} # force the MAC address of the bridge to this interface primary: true + {%- if role == 'controller' %} + dns_servers: {get_param: DnsServers} + addresses: + - + ip_netmask: {get_param: ExternalIpSubnet} + routes: + - + default: true + ip_netmask: 0.0.0.0/0 + next_hop: {get_param: ExternalInterfaceDefaultRoute} + {%- endif %} {%- endif %} {%- if 'storage_network' in enabled_networks and vlans['storage_network'] == 'native' %} - diff --git a/build/opnfv-apex-common.spec b/build/opnfv-apex-common.spec index d5532411..5abd4493 100644 --- a/build/opnfv-apex-common.spec +++ b/build/opnfv-apex-common.spec @@ -53,7 +53,7 @@ install config/network/network_settings_v6.yaml %{buildroot}%{_sysconfdir}/opnfv mkdir -p %{buildroot}%{_var}/opt/opnfv/lib/python/apex install lib/common-functions.sh %{buildroot}%{_var}/opt/opnfv/lib/ install lib/utility-functions.sh %{buildroot}%{_var}/opt/opnfv/lib/ -install lib/python/apex-python-utils.py %{buildroot}%{_var}/opt/opnfv/lib/python/ +install lib/python/apex_python_utils.py %{buildroot}%{_var}/opt/opnfv/lib/python/ mkdir -p %{buildroot}%{python3_sitelib}/apex/ install lib/python/apex/__init__.py %{buildroot}%{python3_sitelib}/apex/ install lib/python/apex/deploy_env.py %{buildroot}%{python3_sitelib}/apex/ diff --git a/build/overcloud-full.sh b/build/overcloud-full.sh index 777fa1c5..936decc3 100755 --- a/build/overcloud-full.sh +++ b/build/overcloud-full.sh @@ -13,6 +13,7 @@ source ./variables.sh source ./functions.sh populate_cache "$rdo_images_uri/overcloud-full.tar" +populate_cache "$openstack_congress" if [ ! -d images/ ]; then mkdir images; fi tar -xf cache/overcloud-full.tar -C images/ @@ -50,11 +51,23 @@ for package in ${dpdk_rpms[@]}; do dpdk_pkg_str+=" --upload $package:/root/dpdk_rpms" done +# tar up the congress puppet module +rm -rf puppet-congress +git clone https://github.com/radez/puppet-congress +pushd puppet-congress > /dev/null +git archive --format=tar.gz --prefix=congress/ origin/stable/mitaka > ../puppet-congress.tar.gz +popd > /dev/null + # installing forked opnfv-puppet-tripleo # enable connection tracking for protocal sctp # upload dpdk rpms but do not install +# enable connection tracking for protocal sctp +# install the congress rpms +# upload and explode the congress puppet module LIBGUESTFS_BACKEND=direct virt-customize \ --upload ../opnfv-puppet-tripleo.tar.gz:/etc/puppet/modules \ + --run-command "sed -i 's/^#UseDNS.*$/UseDNS no/' /etc/ssh/sshd_config" \ + --run-command "sed -i 's/^GSSAPIAuthentication.*$/GSSAPIAuthentication no/' /etc/ssh/sshd_config" \ --run-command "cd /etc/puppet/modules && rm -rf tripleo && tar xzf opnfv-puppet-tripleo.tar.gz" \ --run-command "echo 'nf_conntrack_proto_sctp' > /etc/modules-load.d/nf_conntrack_proto_sctp.conf" \ --run-command "mkdir /root/dpdk_rpms" \ @@ -64,6 +77,10 @@ LIBGUESTFS_BACKEND=direct virt-customize \ --run-command "yum remove -y qemu-system-x86" \ --upload ../os-net-config.tar.gz:/usr/lib/python2.7/site-packages \ --run-command "cd /usr/lib/python2.7/site-packages/ && rm -rf os_net_config && tar xzf os-net-config.tar.gz" \ + --install "$openstack_congress" \ + --install "python2-congressclient" \ + --upload puppet-congress.tar.gz:/etc/puppet/modules/ \ + --run-command "cd /etc/puppet/modules/ && tar xzf puppet-congress.tar.gz" \ -a overcloud-full_build.qcow2 mv -f overcloud-full_build.qcow2 overcloud-full.qcow2 diff --git a/build/overcloud-onos.sh b/build/overcloud-onos.sh index 72f3a681..d59be0a3 100755 --- a/build/overcloud-onos.sh +++ b/build/overcloud-onos.sh @@ -19,7 +19,7 @@ cp -f overcloud-full.qcow2 overcloud-full-onos_build.qcow2 ####################################### # upgrade ovs into ovs 2.5.90 with NSH function -curl -O "$onos_artifacts_uri"package_ovs_rpm.tar.gz +curl -L -O ${onos_ovs_uri}/package_ovs_rpm.tar.gz tar -xzf package_ovs_rpm.tar.gz LIBGUESTFS_BACKEND=direct virt-customize --upload openvswitch-kmod-2.5.90-1.el7.centos.x86_64.rpm:/root/ \ --run-command "yum install -y /root/openvswitch-kmod-2.5.90-1.el7.centos.x86_64.rpm" \ @@ -31,7 +31,7 @@ LIBGUESTFS_BACKEND=direct virt-customize --upload openvswitch-kmod-2.5.90-1.el7. # get the onos files rm -rf puppet-onos populate_cache "$onos_release_uri/$onos_release_file" -populate_cache "$onos_artifacts_uri/jdk-8u51-linux-x64.tar.gz" +populate_cache "$onos_jdk_uri/jdk-8u51-linux-x64.tar.gz" LIBGUESTFS_BACKEND=direct virt-customize --upload $CACHE_DIR/$onos_release_file:/opt/ \ --run-command "mkdir /opt/onos && cd /opt/ && tar -xzf $onos_release_file -C /opt/onos --strip-components=1" \ diff --git a/build/undercloud.sh b/build/undercloud.sh index c1d7c3ab..9873c177 100755 --- a/build/undercloud.sh +++ b/build/undercloud.sh @@ -27,6 +27,7 @@ pushd images > /dev/null # enabling ceph OSDs to live on the controller # OpenWSMan package update supports the AMT Ironic driver for the TealBox # seeding configuration files specific to OPNFV +# add congress password to python-triploclient LIBGUESTFS_BACKEND=direct virt-customize \ --upload ../opnfv-tht.tar.gz:/usr/share \ --run-command "cd /usr/share && rm -rf openstack-tripleo-heat-templates && tar xzf opnfv-tht.tar.gz" \ @@ -37,6 +38,11 @@ LIBGUESTFS_BACKEND=direct virt-customize \ --run-command "cp /usr/share/instack-undercloud/undercloud.conf.sample /home/stack/undercloud.conf && chown stack:stack /home/stack/undercloud.conf" \ --upload ../opnfv-environment.yaml:/home/stack/ \ --upload ../virtual-environment.yaml:/home/stack/ \ + --install "python2-congressclient" \ + --run-command "sed -i '/SERVICE_LIST/a\\ \x27congress\x27: {\x27password_field\x27: \x27OVERCLOUD_CONGRESS_PASSWORD\x27},' /usr/lib/python2.7/site-packages/tripleoclient/constants.py" \ + --run-command "sed -i '/PASSWORD_NAMES =/a\\ \"OVERCLOUD_CONGRESS_PASSWORD\",' /usr/lib/python2.7/site-packages/tripleoclient/utils.py" \ + --run-command "sed -i '/AodhPassword/a\\ parameters\[\x27CongressPassword\x27\] = passwords\[\x27OVERCLOUD_CONGRESS_PASSWORD\x27\]' /usr/lib/python2.7/site-packages/tripleoclient/v1/overcloud_deploy.py" \ + --run-command "sed -i '/^SERVICES/a\ \x27congress\x27: {\x27description\x27: \x27Congress Service\x27, \x27type\x27: \x27policy\x27, \x27path\x27: \x27/\x27, \x27port\x27: 1789 },' /usr/lib/python2.7/site-packages/os_cloud_config/keystone.py" \ -a undercloud_build.qcow2 # Add custom IPA to allow kernel params diff --git a/build/variables.sh b/build/variables.sh index 19294ce5..ccd1add5 100644 --- a/build/variables.sh +++ b/build/variables.sh @@ -11,14 +11,15 @@ rdo_images_uri=https://ci.centos.org/artifacts/rdo/images/mitaka/delorean/stable/ onos_release_uri=https://downloads.onosproject.org/nightly/ onos_release_file=onos-1.6.0-rc2.tar.gz -onos_artifacts_uri=http://205.177.226.237:9999/onosfw/ - +onos_jdk_uri=https://www.dropbox.com/s/qyujpib8zyhzeev +onos_ovs_uri=https://www.dropbox.com/s/gm6o6k80l56pf0o +openstack_congress=https://radez.fedorapeople.org/openstack-congress-2016.1-1.fc24.noarch.rpm dpdk_uri_base=http://artifacts.opnfv.org/ovsnfv dpdk_rpms=( -'ovs4opnfv-dpdk-16.04.0-2.el7.centos.x86_64.rpm' -'ovs4opnfv-dpdk-devel-16.04.0-2.el7.centos.x86_64.rpm' -'ovs4opnfv-dpdk-examples-16.04.0-2.el7.centos.x86_64.rpm' -'ovs4opnfv-dpdk-tools-16.04.0-2.el7.centos.x86_64.rpm' -'ovs4opnfv-openvswitch-2.5.90-0.12060.git46ed1382.1.el7.centos.x86_64.rpm' +'ovs4opnfv-32930523-dpdk-16.04.0-1.el7.centos.x86_64.rpm' +'ovs4opnfv-32930523-dpdk-devel-16.04.0-1.el7.centos.x86_64.rpm' +'ovs4opnfv-32930523-dpdk-examples-16.04.0-1.el7.centos.x86_64.rpm' +'ovs4opnfv-32930523-dpdk-tools-16.04.0-1.el7.centos.x86_64.rpm' +'ovs4opnfv-32930523-openvswitch-2.5.90-0.12032.gitc61e93d6.1.el7.centos.x86_64.rpm' ) diff --git a/ci/deploy.sh b/ci/deploy.sh index 663e9f6c..bcd8a6bb 100755 --- a/ci/deploy.sh +++ b/ci/deploy.sh @@ -124,7 +124,7 @@ parse_setting_value() { ##parses network settings yaml into globals parse_network_settings() { local output - if output=$(python3.4 -B $LIB/python/apex-python-utils.py parse-net-settings -s $NETSETS -i $net_isolation_enabled -e $CONFIG/network-environment.yaml); then + if output=$(python3.4 -B $LIB/python/apex_python_utils.py parse-net-settings -s $NETSETS -i $net_isolation_enabled -e $CONFIG/network-environment.yaml); then echo -e "${blue}${output}${reset}" eval "$output" else @@ -136,7 +136,7 @@ parse_network_settings() { ##parses deploy settings yaml into globals parse_deploy_settings() { local output - if output=$(python3.4 -B $LIB/python/apex-python-utils.py parse-deploy-settings -f $DEPLOY_SETTINGS_FILE); then + if output=$(python3.4 -B $LIB/python/apex_python_utils.py parse-deploy-settings -f $DEPLOY_SETTINGS_FILE); then echo -e "${blue}${output}${reset}" eval "$output" else @@ -664,12 +664,12 @@ function configure_undercloud { ovs_dpdk_bridge='' fi - if ! controller_nic_template=$(python3.4 -B $LIB/python/apex-python-utils.py nic-template -r controller -s $NETSETS -i $net_isolation_enabled -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e $ext_net_type -af $ip_addr_family); then + if ! controller_nic_template=$(python3.4 -B $LIB/python/apex_python_utils.py nic-template -r controller -s $NETSETS -i $net_isolation_enabled -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e "br-ex" -af $ip_addr_family); then echo -e "${red}ERROR: Failed to generate controller NIC heat template ${reset}" exit 1 fi - if ! compute_nic_template=$(python3.4 -B $LIB/python/apex-python-utils.py nic-template -r compute -s $NETSETS -i $net_isolation_enabled -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e $ext_net_type -af $ip_addr_family -d "$ovs_dpdk_bridge"); then + if ! compute_nic_template=$(python3.4 -B $LIB/python/apex_python_utils.py nic-template -r compute -s $NETSETS -i $net_isolation_enabled -t $CONFIG/nics-template.yaml.jinja2 -n "$enabled_network_list" -e $ext_net_type -af $ip_addr_family -d "$ovs_dpdk_bridge"); then echo -e "${red}ERROR: Failed to generate compute NIC heat template ${reset}" exit 1 fi @@ -1115,6 +1115,15 @@ swift_endpoint_id=\$(openstack endpoint list | grep swift | cut -d ' ' -f 2) openstack endpoint delete \$swift_endpoint_id openstack service delete \$swift_service_id +if [ "${deploy_options_array['congress']}" == 'True' ]; then + for s in nova neutronv2 ceilometer cinder glancev2 keystone; do + openstack congress datasource create \$s "\$s" \\ + --config username=\$OS_USERNAME \\ + --config tenant_name=\$OS_TENANT_NAME \\ + --config password=\$OS_PASSWORD \\ + --config auth_url=\$OS_AUTH_URL + done +fi EOI echo -e "${blue}INFO: Checking if OVS bridges have IP addresses...${reset}" @@ -11,7 +11,7 @@ set -e # Make sure python dependencies are installed -for pkg in epel-release python34-devel python34-nose; do +for pkg in epel-release python34-devel python34-nose python-pep8; do if ! rpm -q ${pkg} > /dev/null; then if ! sudo yum install -y ${pkg}; then echo "Failed to install ${pkg} package..." @@ -25,12 +25,5 @@ if ! python3 -c "import coverage" &> /dev/null; then sudo easy_install-3.4 cover pushd ../build/ > /dev/null make python-tests -popd > /dev/null -pushd ../tests/ > /dev/null -percent=$(coverage3 report --include '*lib/python/*' -m | grep TOTAL | tr -s ' ' | awk '{ print $4 }' | cut -d % -f 1) -if [[ percent -lt 80 ]]; then - echo "Python Coverage: $percent" - echo "Does not meet 80% requirement" - exit 1 -fi +make python-pep8-check popd > /dev/null diff --git a/lib/common-functions.sh b/lib/common-functions.sh index 6b259ac1..079b0886 100644 --- a/lib/common-functions.sh +++ b/lib/common-functions.sh @@ -18,7 +18,7 @@ function find_ip { return 1 fi - python3.4 -B $LIB/python/apex-python-utils.py find-ip -i $1 + python3.4 -B $LIB/python/apex_python_utils.py find-ip -i $1 } ##attach interface to OVS and set the network config correctly diff --git a/lib/python/apex/deploy_env.py b/lib/python/apex/deploy_env.py index 4c71b54f..1fe137e4 100644 --- a/lib/python/apex/deploy_env.py +++ b/lib/python/apex/deploy_env.py @@ -24,8 +24,9 @@ REQ_DEPLOY_SETTINGS = ['sdn_controller', OPT_DEPLOY_SETTINGS = ['performance'] VALID_ROLES = ['Controller', 'Compute', 'ObjectStorage'] -VALID_PERF_OPTS = ['kernel','nova'] -VALID_DATAPLANES = ['ovs','ovs_dpdk','fdio'] +VALID_PERF_OPTS = ['kernel', 'nova'] +VALID_DATAPLANES = ['ovs', 'ovs_dpdk', 'fdio'] + class DeploySettings: """ @@ -65,9 +66,9 @@ class DeploySettings: if setting == 'dataplane': if value not in VALID_DATAPLANES: planes = ' '.join(VALID_DATAPLANES) - raise DeploySettingsException("Invalid dataplane {} " - "specified. Valid dataplanes:" - " {}".format(value,planes)) + raise DeploySettingsException( + "Invalid dataplane {} specified. Valid dataplanes:" + " {}".format(value, planes)) for req_set in REQ_DEPLOY_SETTINGS: if req_set not in deploy_options: @@ -80,37 +81,43 @@ class DeploySettings: if not isinstance(deploy_options['performance'], dict): raise DeploySettingsException("Performance deploy_option" "must be a dictionary.") - for role,role_perf_sets in deploy_options['performance'].items(): + for role, role_perf_sets in deploy_options['performance'].items(): if role not in VALID_ROLES: raise DeploySettingsException("Performance role {}" "is not valid, choose" "from {}".format( - role," ".join(VALID_ROLES) + role, + " ".join(VALID_ROLES) )) for key in role_perf_sets: if key not in VALID_PERF_OPTS: - raise DeploySettingsException("Performance option {}" + raise DeploySettingsException("Performance option {} " "is not valid, choose" "from {}".format( - key," ".join( - VALID_PERF_OPTS))) - + key, + " ".join( + VALID_PERF_OPTS) + )) def _dump_performance(self): """ Creates performance settings string for bash consumption. - Output will be in the form of a list that can be iterated over in bash, - with each string being the direct input to the performance setting script - in the form <role> <category> <key> <value> to facilitate modification of the - correct image. + Output will be in the form of a list that can be iterated over in + bash, with each string being the direct input to the performance + setting script in the form <role> <category> <key> <value> to + facilitate modification of the correct image. """ bash_str = 'performance_options=(\n' - for role,settings in self.deploy_settings['deploy_options']['performance'].items(): - for category,options in settings.items(): - for key,value in options.items(): - bash_str += "\"{} {} {} {}\"\n".format(role, category, key, value) + deploy_options = self.deploy_settings['deploy_options'] + for role, settings in deploy_options['performance'].items(): + for category, options in settings.items(): + for key, value in options.items(): + bash_str += "\"{} {} {} {}\"\n".format(role, + category, + key, + value) bash_str += ')\n' bash_str += '\n' bash_str += 'performance_roles=(\n' @@ -126,11 +133,13 @@ class DeploySettings: Creates deploy settings array in bash syntax. """ bash_str = '' - for key,value in self.deploy_settings['deploy_options'].items(): + for key, value in self.deploy_settings['deploy_options'].items(): if not isinstance(value, bool): - bash_str += "deploy_options_array[{}]=\"{}\"\n".format(key, value) + bash_str += "deploy_options_array[{}]=\"{}\"\n".format(key, + value) else: - bash_str += "deploy_options_array[{}]={}\n".format(key, value) + bash_str += "deploy_options_array[{}]={}\n".format(key, + value) return bash_str def dump_bash(self, path=None): diff --git a/lib/python/apex/ip_utils.py b/lib/python/apex/ip_utils.py index f51f227a..b039e26b 100644 --- a/lib/python/apex/ip_utils.py +++ b/lib/python/apex/ip_utils.py @@ -34,11 +34,11 @@ def get_ip_range(start_offset=None, count=None, end_offset=None, space, and end_offset will be calculated from the interface IP. 2 of start_offset, end_offset and count options must be provided: - - If start_offset and end_offset are provided, a range from start_offset - to end_offset will be returned. - - If count is provided, a range from either start_offset to (start_offset - +count) or (end_offset-count) to end_offset will be returned. The - IP range returned will be of size <count>. + - If start_offset and end_offset are provided, a range from + start_offset to end_offset will be returned. + - If count is provided, a range from either start_offset to + (start_offset+count) or (end_offset-count) to end_offset will be + returned. The IP range returned will be of size <count>. Both start_offset and end_offset must be greater than 0. Returns IP range in the format of "first_addr,second_addr" or exception @@ -47,7 +47,7 @@ def get_ip_range(start_offset=None, count=None, end_offset=None, if cidr: if count and start_offset and not end_offset: start_index = start_offset - end_index = start_offset + count -1 + end_index = start_offset + count - 1 elif count and end_offset and not start_offset: end_index = -1 - end_offset start_index = -1 - end_index - count + 1 @@ -81,7 +81,7 @@ def get_ip_range(start_offset=None, count=None, end_offset=None, else: if count and start_offset and not end_offset: start_ip = network[start_offset] - end_ip = start_ip + count -1 + end_ip = start_ip + count - 1 elif count and end_offset and not start_offset: end_ip = interface.ip - end_offset start_ip = end_ip - count + 1 @@ -135,27 +135,6 @@ def get_ip(offset, cidr=None, interface=None): return str(ip) -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 get_interface(nic, address_family=4): """ Returns interface object for a given NIC name in the system @@ -183,7 +162,7 @@ def get_interface(nic, address_family=4): return ipaddress.ip_interface(match.group()) else: logging.info("interface ip not found! ip address output:\n{}" - .format(output)) + .format(output)) return None @@ -228,8 +207,8 @@ def _validate_ip_range(start_ip, end_ip, cidr): """ ip_range = "{},{}".format(start_ip, end_ip) if end_ip <= start_ip: - logging.warning("IP range {} is invalid: end_ip should be greater than " - "starting ip".format(ip_range)) + logging.warning("IP range {} is invalid: end_ip should be greater " + "than starting ip".format(ip_range)) return False if start_ip not in ipaddress.ip_network(cidr): logging.warning('start_ip {} is not in network {}' diff --git a/lib/python/apex/network_environment.py b/lib/python/apex/network_environment.py index fd6f5286..fec6299d 100644 --- a/lib/python/apex/network_environment.py +++ b/lib/python/apex/network_environment.py @@ -9,7 +9,11 @@ import yaml import re -from .common import constants +from .common.constants import ADMIN_NETWORK +from .common.constants import PRIVATE_NETWORK +from .common.constants import STORAGE_NETWORK +from .common.constants import PUBLIC_NETWORK +from .common.constants import API_NETWORK PORTS = '/ports' # Resources defined by <resource name>: <prefix> @@ -70,27 +74,27 @@ class NetworkEnvironment: if not tht_dir: raise NetworkEnvException('Unable to parse THT Directory') - admin_cidr = net_settings[constants.ADMIN_NETWORK]['cidr'] + admin_cidr = net_settings[ADMIN_NETWORK]['cidr'] admin_prefix = str(admin_cidr.prefixlen) self.netenv_obj[param_def]['ControlPlaneSubnetCidr'] = admin_prefix self.netenv_obj[param_def]['ControlPlaneDefaultRoute'] = \ - net_settings[constants.ADMIN_NETWORK]['provisioner_ip'] - public_cidr = net_settings[constants.PUBLIC_NETWORK]['cidr'] + net_settings[ADMIN_NETWORK]['provisioner_ip'] + public_cidr = net_settings[PUBLIC_NETWORK]['cidr'] self.netenv_obj[param_def]['ExternalNetCidr'] = str(public_cidr) - if net_settings[constants.PUBLIC_NETWORK]['vlan'] != 'native': + if net_settings[PUBLIC_NETWORK]['vlan'] != 'native': self.netenv_obj[param_def]['ExternalNetworkVlanID'] = \ - net_settings[constants.PUBLIC_NETWORK]['vlan'] - public_range = net_settings[constants.PUBLIC_NETWORK][ - 'usable_ip_range'].split(',') + net_settings[PUBLIC_NETWORK]['vlan'] + public_range = \ + net_settings[PUBLIC_NETWORK]['usable_ip_range'].split(',') self.netenv_obj[param_def]['ExternalAllocationPools'] = \ [{'start': public_range[0], 'end': public_range[1] }] self.netenv_obj[param_def]['ExternalInterfaceDefaultRoute'] = \ - net_settings[constants.PUBLIC_NETWORK]['gateway'] + net_settings[PUBLIC_NETWORK]['gateway'] self.netenv_obj[param_def]['EC2MetadataIp'] = \ - net_settings[constants.ADMIN_NETWORK]['provisioner_ip'] + net_settings[ADMIN_NETWORK]['provisioner_ip'] self.netenv_obj[param_def]['DnsServers'] = net_settings['dns_servers'] if public_cidr.version == 6: @@ -103,24 +107,23 @@ class NetworkEnvironment: prefix = '' self.netenv_obj[reg][key] = tht_dir + prefix + postfix - - if constants.PRIVATE_NETWORK in enabled_networks: - priv_range = net_settings[constants.PRIVATE_NETWORK][ + if PRIVATE_NETWORK in enabled_networks: + priv_range = net_settings[PRIVATE_NETWORK][ 'usable_ip_range'].split(',') self.netenv_obj[param_def]['TenantAllocationPools'] = \ [{'start': priv_range[0], 'end': priv_range[1] }] - priv_cidr = net_settings[constants.PRIVATE_NETWORK]['cidr'] + priv_cidr = net_settings[PRIVATE_NETWORK]['cidr'] self.netenv_obj[param_def]['TenantNetCidr'] = str(priv_cidr) if priv_cidr.version == 6: postfix = '/tenant_v6.yaml' else: postfix = '/tenant.yaml' - if net_settings[constants.PRIVATE_NETWORK]['vlan'] != 'native': + if net_settings[PRIVATE_NETWORK]['vlan'] != 'native': self.netenv_obj[param_def]['TenantNetworkVlanID'] = \ - net_settings[constants.PRIVATE_NETWORK]['vlan'] + net_settings[PRIVATE_NETWORK]['vlan'] else: postfix = '/noop.yaml' @@ -129,8 +132,8 @@ class NetworkEnvironment: prefix = '' self.netenv_obj[reg][key] = tht_dir + prefix + postfix - if constants.STORAGE_NETWORK in enabled_networks: - storage_range = net_settings[constants.STORAGE_NETWORK][ + if STORAGE_NETWORK in enabled_networks: + storage_range = net_settings[STORAGE_NETWORK][ 'usable_ip_range'].split(',') self.netenv_obj[param_def]['StorageAllocationPools'] = \ [{'start': @@ -138,15 +141,15 @@ class NetworkEnvironment: 'end': storage_range[1] }] - storage_cidr = net_settings[constants.STORAGE_NETWORK]['cidr'] + storage_cidr = net_settings[STORAGE_NETWORK]['cidr'] self.netenv_obj[param_def]['StorageNetCidr'] = str(storage_cidr) if storage_cidr.version == 6: postfix = '/storage_v6.yaml' else: postfix = '/storage.yaml' - if net_settings[constants.STORAGE_NETWORK]['vlan'] != 'native': + if net_settings[STORAGE_NETWORK]['vlan'] != 'native': self.netenv_obj[param_def]['StorageNetworkVlanID'] = \ - net_settings[constants.STORAGE_NETWORK]['vlan'] + net_settings[STORAGE_NETWORK]['vlan'] else: postfix = '/noop.yaml' @@ -155,24 +158,22 @@ class NetworkEnvironment: prefix = '' self.netenv_obj[reg][key] = tht_dir + prefix + postfix - if constants.API_NETWORK in enabled_networks: - api_range = net_settings[constants.API_NETWORK][ + if API_NETWORK in enabled_networks: + api_range = net_settings[API_NETWORK][ 'usable_ip_range'].split(',') self.netenv_obj[param_def]['InternalApiAllocationPools'] = \ - [{'start': - api_range[0], - 'end': - api_range[1] + [{'start': api_range[0], + 'end': api_range[1] }] - api_cidr = net_settings[constants.API_NETWORK]['cidr'] + api_cidr = net_settings[API_NETWORK]['cidr'] self.netenv_obj[param_def]['InternalApiNetCidr'] = str(api_cidr) if api_cidr.version == 6: postfix = '/internal_api_v6.yaml' else: postfix = '/internal_api.yaml' - if net_settings[constants.API_NETWORK]['vlan'] != 'native': + if net_settings[API_NETWORK]['vlan'] != 'native': self.netenv_obj[param_def]['InternalApiNetworkVlanID'] = \ - net_settings[constants.API_NETWORK]['vlan'] + net_settings[API_NETWORK]['vlan'] else: postfix = '/noop.yaml' diff --git a/lib/python/apex/network_settings.py b/lib/python/apex/network_settings.py index 475082df..50dd15c3 100644 --- a/lib/python/apex/network_settings.py +++ b/lib/python/apex/network_settings.py @@ -19,8 +19,8 @@ class NetworkSettings: This class parses APEX network settings yaml file into an object. It generates or detects all missing fields for deployment. - The resulting object will be used later to generate network environment file - as well as configuring post deployment networks. + The resulting object will be used later to generate network environment + file as well as configuring post deployment networks. Currently the parsed object is dumped into a bash global definition file for deploy.sh consumption. This object will later be used directly as @@ -41,7 +41,7 @@ class NetworkSettings: """ if constants.ADMIN_NETWORK not in self.settings_obj or \ not utils.str2bool(self.settings_obj[constants.ADMIN_NETWORK].get( - 'enabled')): + 'enabled')): raise NetworkSettingsException("You must enable admin_network " "and configure it explicitly or " "use auto-detection") @@ -274,6 +274,3 @@ class NetworkSettingsException(Exception): def __str__(self): return self.value - - - diff --git a/lib/python/apex-python-utils.py b/lib/python/apex_python_utils.py index 01e6b03b..1a3cb159 100755 --- a/lib/python/apex-python-utils.py +++ b/lib/python/apex_python_utils.py @@ -105,16 +105,15 @@ def build_nic_template(args): vlans_vals = map(lambda x: settings[x]['vlan'], net_list) vlans = dict(zip(net_list, vlans_vals)) - print(template.render( - enabled_networks=args.enabled_networks, - role=args.role, - vlans=vlans, - external_net_type=args.ext_net_type, - external_net_af=args.address_family, - ovs_dpdk_bridge=args.ovs_dpdk_bridge)) + print(template.render(enabled_networks=args.enabled_networks, + role=args.role, + vlans=vlans, + external_net_type=args.ext_net_type, + external_net_af=args.address_family, + ovs_dpdk_bridge=args.ovs_dpdk_bridge)) -def parse_args(): +def get_parser(): parser = argparse.ArgumentParser() parser.add_argument('--debug', action='store_true', default=False, help="Turn on debug messages") @@ -176,11 +175,17 @@ def parse_args(): nic_template.set_defaults(func=build_nic_template) deploy_settings = subparsers.add_parser('parse-deploy-settings', - help='Parse deploy settings file') - deploy_settings.add_argument('-f', '--file', default='deploy_settings.yaml', - help='path to deploy settings file') + help='Parse deploy settings file') + deploy_settings.add_argument('-f', '--file', + default='deploy_settings.yaml', + help='path to deploy settings file') deploy_settings.set_defaults(func=parse_deploy_settings) + return parser + + +def main(): + parser = get_parser() args = parser.parse_args(sys.argv[1:]) if args.debug: logging.basicConfig(level=logging.DEBUG) @@ -191,10 +196,6 @@ def parse_args(): format='%(asctime)s %(levelname)s: %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', level=logging.DEBUG) - return parser, args - - -def main(parser, args): if hasattr(args, 'func'): args.func(args) else: @@ -202,5 +203,4 @@ def main(parser, args): exit(1) if __name__ == "__main__": - parser, args = parse_args() - main(parser, args) + main() diff --git a/tests/test_apex_deploy_env.py b/tests/test_apex_deploy_env.py index 0cd144ef..648923d0 100644 --- a/tests/test_apex_deploy_env.py +++ b/tests/test_apex_deploy_env.py @@ -30,23 +30,23 @@ deploy_files = ('deploy_settings.yaml', 'os-onos-nofeature-ha.yaml') test_deploy_content = ( -'global_params:', -'deploy_options: string', -"""deploy_options: string + 'global_params:', + 'deploy_options: string', + """deploy_options: string global_params:""", -"""global_params: + """global_params: deploy_options: error: error """, -"""global_params: + """global_params: deploy_options: performance: string """, -"""global_params: + """global_params: deploy_options: dataplane: invalid """, -"""global_params: + """global_params: deploy_options: performance: Controller: @@ -78,7 +78,8 @@ class TestIpUtils(object): f = open('/tmp/apex_deploy_test_file', 'w') f.write(c) f.close() - assert_raises(DeploySettingsException, DeploySettings, '/tmp/apex_deploy_test_file') + assert_raises(DeploySettingsException, + DeploySettings, '/tmp/apex_deploy_test_file') def test_dump_bash(self): # the performance file has the most use of the function diff --git a/tests/test_apex_ip_utils.py b/tests/test_apex_ip_utils.py index dc3aadf7..60c8b2b8 100644 --- a/tests/test_apex_ip_utils.py +++ b/tests/test_apex_ip_utils.py @@ -60,9 +60,9 @@ class TestIpUtils(object): def test_get_interface(self): assert_equal(get_interface(''), None) assert_equal(get_interface('notreal'), None) - assert_is_instance(get_interface( - self.iface_name, - address_family=4), IPv4Address) + assert_is_instance(get_interface(self.iface_name, + address_family=4), + IPv4Address) # assert_is_instance(get_interface( # self.iface_name, # address_family=6), IPv6Address) @@ -93,8 +93,7 @@ class TestIpUtils(object): assert_regexp_matches(get_ip_range(interface=self.iface, end_offset=20, count=10), ip4_range_pattern) - @staticmethod - def test_get_ip_range_with_cidr(): + def test_get_ip_range_with_cidr(self): cidr = ip_network('10.10.10.0/24') assert_raises(IPUtilsException, get_ip_range, cidr=cidr) assert_regexp_matches(get_ip_range(cidr=cidr, start_offset=1, diff --git a/tests/test_apex_network_environment.py b/tests/test_apex_network_environment.py index 90c89073..2a8438fa 100644 --- a/tests/test_apex_network_environment.py +++ b/tests/test_apex_network_environment.py @@ -33,7 +33,8 @@ class TestNetworkEnvironment(object): """This method is run once after _each_ test method is executed""" def test_init(self): - assert_raises(NetworkEnvException, NetworkEnvironment, None, '../build/network-environment.yaml') + assert_raises(NetworkEnvException, NetworkEnvironment, + None, '../build/network-environment.yaml') def test_get_netenv_settings(self): ns = NetworkSettings('../config/network/network_settings.yaml', True) diff --git a/tests/test_apex_python_utils_py.py b/tests/test_apex_python_utils_py.py new file mode 100644 index 00000000..47c10092 --- /dev/null +++ b/tests/test_apex_python_utils_py.py @@ -0,0 +1,80 @@ +############################################################################## +# Copyright (c) 2016 Dan Radez (Red Hat) +# +# 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 sys + +from test_apex_ip_utils import get_default_gateway_linux +from apex_python_utils import main +from apex_python_utils import get_parser +from apex_python_utils import parse_net_settings +from apex_python_utils import parse_deploy_settings +from apex_python_utils import find_ip +from apex_python_utils import build_nic_template + +from nose.tools import assert_equal +from nose.tools import assert_raises + + +net_sets = '../config/network/network_settings.yaml' +net_env = '../build/network-environment.yaml' +deploy_sets = '../config/deploy/deploy_settings.yaml' +nic_template = '../build/nics-template.yaml.jinja2' + + +class TestCommonUtils(object): + @classmethod + def setup_class(klass): + """This method is run once for each class before any tests are run""" + klass.parser = get_parser() + klass.iface_name = get_default_gateway_linux() + + @classmethod + def teardown_class(klass): + """This method is run once for each class _after_ all tests are run""" + + def setUp(self): + """This method is run once before _each_ test method is executed""" + + def teardown(self): + """This method is run once after _each_ test method is executed""" + + def test_main(self): + sys.argv = ['apex_python_utils', '-l', '/dev/null'] + assert_raises(SystemExit, main) + sys.argv = ['apex_python_utils', '--debug', '-l', '/dev/null'] + assert_raises(SystemExit, main) + sys.argv = ['apex_python_utils', '-l', '/dev/null', + 'parse-deploy-settings', + '-f', deploy_sets] + assert_equal(main(), None) + + def test_parse_net_settings(self): + args = self.parser.parse_args(['parse-net-settings', + '-s', net_sets, + '-i', 'True', + '-e', net_env]) + assert_equal(parse_net_settings(args), None) + + def test_parse_deploy_settings(self): + args = self.parser.parse_args(['parse-deploy-settings', + '-f', deploy_sets]) + assert_equal(parse_deploy_settings(args), None) + + def test_find_ip(self): + args = self.parser.parse_args(['find-ip', + '-i', self.iface_name]) + assert_equal(find_ip(args), None) + + def test_build_nic_template(self): + args = self.parser.parse_args(['nic-template', + '-s', net_sets, + '-r', 'compute', + '-t', nic_template, + '-n', 'admin_network']) + assert_equal(build_nic_template(args), None) |