Allows specifying nic order for overcloud nodes in network settings 07/17007/4
authorTim Rozet <trozet@redhat.com>
Sat, 16 Jul 2016 02:04:24 +0000 (22:04 -0400)
committerTim Rozet <trozet@redhat.com>
Mon, 18 Jul 2016 20:35:00 +0000 (16:35 -0400)
Currently there is no way to specify logically or physically the nic
order to be used on overcloud nodes.  We always hardcode to use nic1 for
admin network, nic2 for private, etc.  This patch allows a user to not
only decide which logical nics to use for which network, but also
specify physical interface names if they need to.

This is done on a per role basis, due to tripleO limitation.  So a user
is able to specify nic order/names for compute and controller roles
separately.

If a user specifies nic order, they must specify it for all networks
other than admin network.  We assume if admin network is unspecified it
uses "nic1", so that name is reserved in this case.  A user is also
allowed to specify a mixture of logical and physical names, for example
"nic2" and "eth3" on another network.

JIRA: APEX-151

Change-Id: Ie9d4abb463cf8f8788913cb4bcf9486830adc449
Signed-off-by: Tim Rozet <trozet@redhat.com>
build/nics-template.yaml.jinja2
config/network/network_settings.yaml
lib/python/apex/common/constants.py
lib/python/apex/network_settings.py
lib/python/apex_python_utils.py
tests/config/network_settings_duplicate_nic.yaml [new file with mode: 0644]
tests/config/network_settings_missing_required_nic.yaml [new file with mode: 0644]
tests/config/network_settings_nic1_reserved.yaml [new file with mode: 0644]
tests/config/network_settings_nics_not_specified.yaml [new file with mode: 0644]
tests/test_apex_network_settings.py

index 91d0c47..53290e4 100644 (file)
@@ -91,7 +91,7 @@ resources:
               members:
                 -
                   type: interface
-                  name: nic1
+                  name: {{ nics[role]['admin_network'] }}
                   # force the MAC address of the bridge to this interface
                   primary: true
                 {%- if 'public_network' in enabled_networks and vlans['public_network'] is number %}
@@ -132,7 +132,7 @@ resources:
                 {%- endif %}
             {%- else %}
               type: interface
-              name: nic1
+              name: {{ nics[role]['admin_network'] }}
             {%- endif %}
               use_dhcp: false
               dns_servers: {get_param: DnsServers}
@@ -153,7 +153,6 @@ resources:
                   next_hop: {get_param: ControlPlaneDefaultRoute}
                 {%- endif %}
 
-            {%- set nic_index = 2 %}
             {%- if 'private_network' in enabled_networks and vlans['private_network'] == 'native' %}
             {%- if ovs_dpdk_bridge == 'br-phy' and role == 'compute' %}
             -
@@ -166,7 +165,7 @@ resources:
               members:
                 -
                   type: interface
-                  name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+                  name: {{ nics[role]['private_network'] }}
                   # force the MAC address of the bridge to this interface
                   primary: true
             -
@@ -176,7 +175,7 @@ resources:
             {%- else %}
             -
               type: interface
-              name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+              name: {{ nics[role]['private_network'] }}
               use_dhcp: false
               addresses:
                 -
@@ -186,7 +185,7 @@ resources:
             {%- if 'public_network' in enabled_networks and external_net_type == 'interface' and vlans['public_network'] == 'native' %}
             -
               type: interface
-              name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+              name: {{ nics[role]['public_network'] }}
               {%- if role == 'controller' %}
               dns_servers: {get_param: DnsServers}
               {%- endif %}
@@ -209,7 +208,7 @@ resources:
               members:
                 -
                   type: interface
-                  name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+                  name: {{ nics[role]['public_network'] }}
                   # force the MAC address of the bridge to this interface
                   primary: true
               {%- if role == 'controller' %}
@@ -227,7 +226,7 @@ resources:
             {%- if 'storage_network' in enabled_networks and vlans['storage_network'] == 'native' %}
             -
               type: interface
-              name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+              name: {{ nics[role]['storage_network'] }}
               use_dhcp: false
               addresses:
                 -
@@ -236,7 +235,7 @@ resources:
             {%- if 'api_network' in enabled_networks and vlans['api_network'] == 'native' %}
             -
               type: interface
-              name: nic{{ nic_index }}{% set nic_index = nic_index + 1 %}
+              name: {{ nics[role]['api_network'] }}
               use_dhcp: false
               addresses:
                 -
index 793c10d..7c0f501 100644 (file)
@@ -34,6 +34,8 @@ admin_network:
   network_type: bridged
   bridged_interface: ''
   bond_interfaces: ''
+  compute_interface: nic1
+  controller_interface: nic1
   usable_ip_range: 192.0.2.11,192.0.2.99
   gateway: 192.0.2.1
   provisioner_ip: 192.0.2.1
@@ -50,6 +52,8 @@ private_network:
   enabled: true
   vlan: native
   cidr: 11.0.0.0/24
+  compute_interface: nic2
+  controller_interface: nic2
 
 # "public" network is used for external connectivity.
 # The external network provides Internet access for virtual
@@ -62,6 +66,8 @@ public_network:
   enabled: true
   network_type: ''
   bridged_interface: ''
+  compute_interface: nic3
+  controller_interface: nic3
   vlan: native
   cidr: 192.168.37.0/24
   gateway: 192.168.37.1
@@ -77,12 +83,16 @@ storage_network:
   enabled: true
   vlan: native
   cidr: 12.0.0.0/24
+  compute_interface: nic4
+  controller_interface: nic4
 
 #admin_network:
 #  enabled: true
 #  network_type: bridged                             #Indicates if this network will be bridged to an interface, or to a bond
 #  bridged_interface: ''                             #Interface to bridge to for installer VM
 #  bond_interfaces: ''                               #Interfaces to create bond with for installer VM
+#  compute_interface: nic4                           #Interface used for this network on the compute node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  controller_interface: nic4                        #Interface used for this network on the controller node.  Can either be logical nic name like "nic1" or real name like "eth1"
 #  vlan: native                                      #VLAN tag to use, native means none
 #  usable_ip_range: 192.0.2.11,192.0.2.99            #Usable ip range, if empty entire range is usable, ex. 192.168.1.10,192.168.1.20
 #  gateway: 192.0.2.1                                #Gateway (only needed when public_network is disabled), if empty it is auto-detected
index 8ed49ff..dfed33f 100644 (file)
@@ -15,3 +15,4 @@ API_NETWORK = 'api_network'
 OPNFV_NETWORK_TYPES = [ADMIN_NETWORK, PRIVATE_NETWORK, PUBLIC_NETWORK,
                        STORAGE_NETWORK, API_NETWORK]
 DNS_SERVERS = ["8.8.8.8", "8.8.4.4"]
+ROLES = ['compute', 'controller']
index 50dd15c..fd6c145 100644 (file)
@@ -31,6 +31,8 @@ class NetworkSettings:
             self.settings_obj = yaml.load(network_settings_file)
             self.network_isolation = network_isolation
             self.enabled_network_list = []
+            self.nics = {'compute': dict(), 'controller': dict()}
+            self.nics_specified = {'compute': False, 'controller': False}
             self._validate_input()
 
     def _validate_input(self):
@@ -63,6 +65,7 @@ class NetworkSettings:
                                           start_offset=21, end_offset=21)
                     self._config_optional_settings(network)
                     self.enabled_network_list.append(network)
+                    self._validate_overcloud_nic_order(network)
                 else:
                     logging.info("{} disabled, will collapse with "
                                  "admin_network".format(network))
@@ -73,6 +76,51 @@ class NetworkSettings:
         self.settings_obj['dns_servers'] = self.settings_obj.get(
             'dns_servers', constants.DNS_SERVERS)
 
+    def _validate_overcloud_nic_order(self, network):
+        """
+        Detects if nic order is specified per profile (compute/controller)
+        for network
+
+        If nic order is specified in a network for a profile, it should be
+        specified for every network with that profile other than admin_network
+
+        Duplicate nic names are also not allowed across different networks
+
+        :param network: network to detect if nic order present
+        :return: None
+        """
+
+        for role in constants.ROLES:
+            interface = role+'_interface'
+            nic_index = self.get_enabled_networks().index(network) + 1
+            if interface in self.settings_obj[network]:
+                if any(y == self.settings_obj[network][interface] for x, y in
+                       self.nics[role].items()):
+                    raise NetworkSettingsException("Duplicate {} already "
+                                                   "specified for "
+                                                   "another network"
+                                                   .format(self.settings_obj
+                                                           [network]
+                                                           [interface]))
+                self.nics[role][network] = self.settings_obj[network][
+                    interface]
+                self.nics_specified[role] = True
+                logging.info("{} nic order specified for network {"
+                             "}".format(role, network))
+            elif self.nics_specified[role]:
+                logging.error("{} nic order not specified for network {"
+                              "}".format(role, network))
+                raise NetworkSettingsException("Must specify {} for all "
+                                               "enabled networks (other than "
+                                               " admin) or not specify it for "
+                                               "any".format(interface))
+            else:
+                logging.info("{} nic order not specified for network {"
+                             "}. Will use logical default "
+                             "nic{}".format(interface, network, nic_index))
+                self.nics[role][network] = 'nic' + str(nic_index)
+                nic_index += 1
+
     def _config_required_settings(self, network):
         """
         Configures either CIDR or bridged_interface setting
index 1a3cb15..bc9bc56 100755 (executable)
@@ -22,7 +22,6 @@ from apex import NetworkSettings
 from apex import NetworkEnvironment
 from apex import DeploySettings
 from apex import ip_utils
-from apex.common.constants import OPNFV_NETWORK_TYPES
 from apex.common.constants import ADMIN_NETWORK
 
 
@@ -94,8 +93,9 @@ def build_nic_template(args):
     """
     template_dir, template = args.template.rsplit('/', 1)
 
-    settings = NetworkSettings(args.net_settings_file,
-                               args.network_isolation).settings_obj
+    network_settings = NetworkSettings(args.net_settings_file,
+                                       args.network_isolation)
+    settings = network_settings.settings_obj
     env = Environment(loader=FileSystemLoader(template_dir))
     template = env.get_template(template)
 
@@ -104,13 +104,15 @@ def build_nic_template(args):
     net_list.remove(ADMIN_NETWORK)
     vlans_vals = map(lambda x: settings[x]['vlan'], net_list)
     vlans = dict(zip(net_list, vlans_vals))
+    nics = network_settings.nics
 
     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))
+                          ovs_dpdk_bridge=args.ovs_dpdk_bridge,
+                          nics=nics))
 
 
 def get_parser():
diff --git a/tests/config/network_settings_duplicate_nic.yaml b/tests/config/network_settings_duplicate_nic.yaml
new file mode 100644 (file)
index 0000000..24dd5ca
--- /dev/null
@@ -0,0 +1,115 @@
+# This configuration file defines Network Environment for a
+# Baremetal Deployment of OPNFV. It contains default values
+# for 4 following networks:
+#
+# - admin
+# - private*
+# - public
+# - storage*
+#
+# *) optional networks
+#
+# Any values missing from this configuration file will be
+# auto-detected by deployment script from the existing network
+# configuration of the jumphost.
+#
+# Optional networks will be consolidated with the admin network
+# if not explicitely configured.
+#
+# See short description of the networks in the comments below.
+#
+
+# DNS Servers for all nodes, comma delimited list
+dns_servers: ["8.8.8.8", "8.8.4.4"]
+
+# "admin" is the short name for Control Plane Network.
+# During OPNFV deployment it is used for node provisioning so
+# PXE boot should be enabled for the related interfaces on all
+# the nodes in the OPNFV cluster. After the deployment this
+# network is used as the OpenStack management network which
+# carries e.g. communication between its internal components.
+#
+admin_network:
+  enabled: true
+  network_type: bridged
+  bridged_interface: ''
+  bond_interfaces: ''
+  compute_interface: eth1
+  controller_interface: eth2
+  usable_ip_range: 192.0.2.11,192.0.2.99
+  gateway: 192.0.2.1
+  provisioner_ip: 192.0.2.1
+  cidr: 192.0.2.0/24
+  dhcp_range: 192.0.2.2,192.0.2.10
+  introspection_range: 192.0.2.100,192.0.2.120
+
+# "private" is an optional network used as underlying physical
+# network for virtual provider and tenant networks created by
+# users. Traffic between virtual machines is carried by this
+# network.
+#
+private_network:
+  enabled: true
+  vlan: native
+  cidr: 11.0.0.0/24
+  compute_interface: enp0s4
+  controller_interface: nic3
+
+# "public" network is used for external connectivity.
+# The external network provides Internet access for virtual
+# machines. If floating IP range is defined for this network,
+# floating IP addresses can be used for accessing virtual
+# machines from outside of OPNFV cluster. Also external REST
+# API calls use this network.
+#
+public_network:
+  enabled: true
+  network_type: ''
+  bridged_interface: ''
+  compute_interface: eth1
+  controller_interface: enp0s3
+  vlan: native
+  cidr: 192.168.37.0/24
+  gateway: 192.168.37.1
+  floating_ip_range: 192.168.37.200,192.168.37.220
+  usable_ip_range: 192.168.37.10,192.168.37.199
+  provisioner_ip: 192.168.37.1
+
+# "storage" is an optional network used by storage backends.
+# You can configure this network in order to reduce load on
+# Control Plane Network.
+#
+storage_network:
+  enabled: true
+  vlan: native
+  cidr: 12.0.0.0/24
+  compute_interface: eth5
+  controller_interface: eth6
+
+#admin_network:
+#  enabled: true
+#  network_type: bridged                             #Indicates if this network will be bridged to an interface, or to a bond
+#  bridged_interface: ''                             #Interface to bridge to for installer VM
+#  bond_interfaces: ''                               #Interfaces to create bond with for installer VM
+#  compute_interface: nic4                           #Interface used for this network on the compute node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  controller_interface: nic4                        #Interface used for this network on the controller node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  vlan: native                                      #VLAN tag to use, native means none
+#  usable_ip_range: 192.0.2.11,192.0.2.99            #Usable ip range, if empty entire range is usable, ex. 192.168.1.10,192.168.1.20
+#  gateway: 192.0.2.1                                #Gateway (only needed when public_network is disabled), if empty it is auto-detected
+#  provisioner_ip: 192.0.2.1                         #installer VM IP, if empty it is the next available IP in the admin subnet
+#  cidr: 192.0.2.0/24                                #subnet in CIDR format 192.168.1.0/24, if empty it will be auto-detected
+#  dhcp_range: 192.0.2.2,192.0.2.10                  #dhcp range for the admin network, if empty it will be automatically provisioned
+#  introspection_range: 192.0.2.100,192.0.2.120      #Range used for introspection phase (examining nodes)
+#private_network:
+#  enabled: false                                    #If disabled, internal api traffic will collapse to admin_network
+#public_network:
+#  enabled: true                                     #If disabled, public_network traffic will collapse to admin network
+#  network_type: ''
+#  bridged_interface: ''
+#  cidr: 192.168.37.0/24
+#  gateway: 192.168.37.1
+#  floating_ip_range: 192.168.37.200,192.168.37.220  #Range to allocate to floating IPs for the public network with Neutron
+#  usable_ip_range: 192.168.37.10,192.168.37.199     #Usable IP range on the public network, usually this is a shared subnet
+#  provisioner_ip: 192.168.37.1
+#storage_network:
+#  enabled: false                                    #If disabled, storage_network traffic will collapse to admin network
diff --git a/tests/config/network_settings_missing_required_nic.yaml b/tests/config/network_settings_missing_required_nic.yaml
new file mode 100644 (file)
index 0000000..1888627
--- /dev/null
@@ -0,0 +1,113 @@
+# This configuration file defines Network Environment for a
+# Baremetal Deployment of OPNFV. It contains default values
+# for 4 following networks:
+#
+# - admin
+# - private*
+# - public
+# - storage*
+#
+# *) optional networks
+#
+# Any values missing from this configuration file will be
+# auto-detected by deployment script from the existing network
+# configuration of the jumphost.
+#
+# Optional networks will be consolidated with the admin network
+# if not explicitely configured.
+#
+# See short description of the networks in the comments below.
+#
+
+# DNS Servers for all nodes, comma delimited list
+dns_servers: ["8.8.8.8", "8.8.4.4"]
+
+# "admin" is the short name for Control Plane Network.
+# During OPNFV deployment it is used for node provisioning so
+# PXE boot should be enabled for the related interfaces on all
+# the nodes in the OPNFV cluster. After the deployment this
+# network is used as the OpenStack management network which
+# carries e.g. communication between its internal components.
+#
+admin_network:
+  enabled: true
+  network_type: bridged
+  bridged_interface: ''
+  bond_interfaces: ''
+  compute_interface: eth1
+  controller_interface: eth2
+  usable_ip_range: 192.0.2.11,192.0.2.99
+  gateway: 192.0.2.1
+  provisioner_ip: 192.0.2.1
+  cidr: 192.0.2.0/24
+  dhcp_range: 192.0.2.2,192.0.2.10
+  introspection_range: 192.0.2.100,192.0.2.120
+
+# "private" is an optional network used as underlying physical
+# network for virtual provider and tenant networks created by
+# users. Traffic between virtual machines is carried by this
+# network.
+#
+private_network:
+  enabled: true
+  vlan: native
+  cidr: 11.0.0.0/24
+  compute_interface: enp0s4
+  controller_interface: nic3
+
+# "public" network is used for external connectivity.
+# The external network provides Internet access for virtual
+# machines. If floating IP range is defined for this network,
+# floating IP addresses can be used for accessing virtual
+# machines from outside of OPNFV cluster. Also external REST
+# API calls use this network.
+#
+public_network:
+  enabled: true
+  network_type: ''
+  bridged_interface: ''
+  vlan: native
+  cidr: 192.168.37.0/24
+  gateway: 192.168.37.1
+  floating_ip_range: 192.168.37.200,192.168.37.220
+  usable_ip_range: 192.168.37.10,192.168.37.199
+  provisioner_ip: 192.168.37.1
+
+# "storage" is an optional network used by storage backends.
+# You can configure this network in order to reduce load on
+# Control Plane Network.
+#
+storage_network:
+  enabled: true
+  vlan: native
+  cidr: 12.0.0.0/24
+  compute_interface: eth5
+  controller_interface: eth6
+
+#admin_network:
+#  enabled: true
+#  network_type: bridged                             #Indicates if this network will be bridged to an interface, or to a bond
+#  bridged_interface: ''                             #Interface to bridge to for installer VM
+#  bond_interfaces: ''                               #Interfaces to create bond with for installer VM
+#  compute_interface: nic4                 #Interface used for this network on the compute node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  controller_interface: nic4              #Interface used for this network on the controller node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  vlan: native                                      #VLAN tag to use, native means none
+#  usable_ip_range: 192.0.2.11,192.0.2.99            #Usable ip range, if empty entire range is usable, ex. 192.168.1.10,192.168.1.20
+#  gateway: 192.0.2.1                                #Gateway (only needed when public_network is disabled), if empty it is auto-detected
+#  provisioner_ip: 192.0.2.1                         #installer VM IP, if empty it is the next available IP in the admin subnet
+#  cidr: 192.0.2.0/24                                #subnet in CIDR format 192.168.1.0/24, if empty it will be auto-detected
+#  dhcp_range: 192.0.2.2,192.0.2.10                  #dhcp range for the admin network, if empty it will be automatically provisioned
+#  introspection_range: 192.0.2.100,192.0.2.120      #Range used for introspection phase (examining nodes)
+#private_network:
+#  enabled: false                                    #If disabled, internal api traffic will collapse to admin_network
+#public_network:
+#  enabled: true                                     #If disabled, public_network traffic will collapse to admin network
+#  network_type: ''
+#  bridged_interface: ''
+#  cidr: 192.168.37.0/24
+#  gateway: 192.168.37.1
+#  floating_ip_range: 192.168.37.200,192.168.37.220  #Range to allocate to floating IPs for the public network with Neutron
+#  usable_ip_range: 192.168.37.10,192.168.37.199     #Usable IP range on the public network, usually this is a shared subnet
+#  provisioner_ip: 192.168.37.1
+#storage_network:
+#  enabled: false                                    #If disabled, storage_network traffic will collapse to admin network
diff --git a/tests/config/network_settings_nic1_reserved.yaml b/tests/config/network_settings_nic1_reserved.yaml
new file mode 100644 (file)
index 0000000..8abcfc8
--- /dev/null
@@ -0,0 +1,113 @@
+# This configuration file defines Network Environment for a
+# Baremetal Deployment of OPNFV. It contains default values
+# for 4 following networks:
+#
+# - admin
+# - private*
+# - public
+# - storage*
+#
+# *) optional networks
+#
+# Any values missing from this configuration file will be
+# auto-detected by deployment script from the existing network
+# configuration of the jumphost.
+#
+# Optional networks will be consolidated with the admin network
+# if not explicitely configured.
+#
+# See short description of the networks in the comments below.
+#
+
+# DNS Servers for all nodes, comma delimited list
+dns_servers: ["8.8.8.8", "8.8.4.4"]
+
+# "admin" is the short name for Control Plane Network.
+# During OPNFV deployment it is used for node provisioning so
+# PXE boot should be enabled for the related interfaces on all
+# the nodes in the OPNFV cluster. After the deployment this
+# network is used as the OpenStack management network which
+# carries e.g. communication between its internal components.
+#
+admin_network:
+  enabled: true
+  network_type: bridged
+  bridged_interface: ''
+  bond_interfaces: ''
+  usable_ip_range: 192.0.2.11,192.0.2.99
+  gateway: 192.0.2.1
+  provisioner_ip: 192.0.2.1
+  cidr: 192.0.2.0/24
+  dhcp_range: 192.0.2.2,192.0.2.10
+  introspection_range: 192.0.2.100,192.0.2.120
+
+# "private" is an optional network used as underlying physical
+# network for virtual provider and tenant networks created by
+# users. Traffic between virtual machines is carried by this
+# network.
+#
+private_network:
+  enabled: true
+  vlan: native
+  cidr: 11.0.0.0/24
+  compute_interface: enp0s4
+  controller_interface: nic3
+
+# "public" network is used for external connectivity.
+# The external network provides Internet access for virtual
+# machines. If floating IP range is defined for this network,
+# floating IP addresses can be used for accessing virtual
+# machines from outside of OPNFV cluster. Also external REST
+# API calls use this network.
+#
+public_network:
+  enabled: true
+  network_type: ''
+  bridged_interface: ''
+  compute_interface: nic1
+  controller_interface: enp0s3
+  vlan: native
+  cidr: 192.168.37.0/24
+  gateway: 192.168.37.1
+  floating_ip_range: 192.168.37.200,192.168.37.220
+  usable_ip_range: 192.168.37.10,192.168.37.199
+  provisioner_ip: 192.168.37.1
+
+# "storage" is an optional network used by storage backends.
+# You can configure this network in order to reduce load on
+# Control Plane Network.
+#
+storage_network:
+  enabled: true
+  vlan: native
+  cidr: 12.0.0.0/24
+  compute_interface: eth5
+  controller_interface: eth6
+
+#admin_network:
+#  enabled: true
+#  network_type: bridged                             #Indicates if this network will be bridged to an interface, or to a bond
+#  bridged_interface: ''                             #Interface to bridge to for installer VM
+#  bond_interfaces: ''                               #Interfaces to create bond with for installer VM
+#  overcloud_compute_interface: nic4                 #Interface used for this network on the compute node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  overcloud_controller_interface: nic4              #Interface used for this network on the controller node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  vlan: native                                      #VLAN tag to use, native means none
+#  usable_ip_range: 192.0.2.11,192.0.2.99            #Usable ip range, if empty entire range is usable, ex. 192.168.1.10,192.168.1.20
+#  gateway: 192.0.2.1                                #Gateway (only needed when public_network is disabled), if empty it is auto-detected
+#  provisioner_ip: 192.0.2.1                         #installer VM IP, if empty it is the next available IP in the admin subnet
+#  cidr: 192.0.2.0/24                                #subnet in CIDR format 192.168.1.0/24, if empty it will be auto-detected
+#  dhcp_range: 192.0.2.2,192.0.2.10                  #dhcp range for the admin network, if empty it will be automatically provisioned
+#  introspection_range: 192.0.2.100,192.0.2.120      #Range used for introspection phase (examining nodes)
+#private_network:
+#  enabled: false                                    #If disabled, internal api traffic will collapse to admin_network
+#public_network:
+#  enabled: true                                     #If disabled, public_network traffic will collapse to admin network
+#  network_type: ''
+#  bridged_interface: ''
+#  cidr: 192.168.37.0/24
+#  gateway: 192.168.37.1
+#  floating_ip_range: 192.168.37.200,192.168.37.220  #Range to allocate to floating IPs for the public network with Neutron
+#  usable_ip_range: 192.168.37.10,192.168.37.199     #Usable IP range on the public network, usually this is a shared subnet
+#  provisioner_ip: 192.168.37.1
+#storage_network:
+#  enabled: false                                    #If disabled, storage_network traffic will collapse to admin network
diff --git a/tests/config/network_settings_nics_not_specified.yaml b/tests/config/network_settings_nics_not_specified.yaml
new file mode 100644 (file)
index 0000000..e508943
--- /dev/null
@@ -0,0 +1,107 @@
+# This configuration file defines Network Environment for a
+# Baremetal Deployment of OPNFV. It contains default values
+# for 4 following networks:
+#
+# - admin
+# - private*
+# - public
+# - storage*
+#
+# *) optional networks
+#
+# Any values missing from this configuration file will be
+# auto-detected by deployment script from the existing network
+# configuration of the jumphost.
+#
+# Optional networks will be consolidated with the admin network
+# if not explicitely configured.
+#
+# See short description of the networks in the comments below.
+#
+
+# DNS Servers for all nodes, comma delimited list
+dns_servers: ["8.8.8.8", "8.8.4.4"]
+
+# "admin" is the short name for Control Plane Network.
+# During OPNFV deployment it is used for node provisioning so
+# PXE boot should be enabled for the related interfaces on all
+# the nodes in the OPNFV cluster. After the deployment this
+# network is used as the OpenStack management network which
+# carries e.g. communication between its internal components.
+#
+admin_network:
+  enabled: true
+  network_type: bridged
+  bridged_interface: ''
+  bond_interfaces: ''
+  usable_ip_range: 192.0.2.11,192.0.2.99
+  gateway: 192.0.2.1
+  provisioner_ip: 192.0.2.1
+  cidr: 192.0.2.0/24
+  dhcp_range: 192.0.2.2,192.0.2.10
+  introspection_range: 192.0.2.100,192.0.2.120
+
+# "private" is an optional network used as underlying physical
+# network for virtual provider and tenant networks created by
+# users. Traffic between virtual machines is carried by this
+# network.
+#
+private_network:
+  enabled: true
+  vlan: native
+  cidr: 11.0.0.0/24
+
+# "public" network is used for external connectivity.
+# The external network provides Internet access for virtual
+# machines. If floating IP range is defined for this network,
+# floating IP addresses can be used for accessing virtual
+# machines from outside of OPNFV cluster. Also external REST
+# API calls use this network.
+#
+public_network:
+  enabled: true
+  network_type: ''
+  bridged_interface: ''
+  vlan: native
+  cidr: 192.168.37.0/24
+  gateway: 192.168.37.1
+  floating_ip_range: 192.168.37.200,192.168.37.220
+  usable_ip_range: 192.168.37.10,192.168.37.199
+  provisioner_ip: 192.168.37.1
+
+# "storage" is an optional network used by storage backends.
+# You can configure this network in order to reduce load on
+# Control Plane Network.
+#
+storage_network:
+  enabled: true
+  vlan: native
+  cidr: 12.0.0.0/24
+
+#admin_network:
+#  enabled: true
+#  network_type: bridged                             #Indicates if this network will be bridged to an interface, or to a bond
+#  bridged_interface: ''                             #Interface to bridge to for installer VM
+#  bond_interfaces: ''                               #Interfaces to create bond with for installer VM
+#  compute_interface: nic4                           #Interface used for this network on the compute node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  controller_interface: nic4                        #Interface used for this network on the controller node.  Can either be logical nic name like "nic1" or real name like "eth1"
+#  vlan: native                                      #VLAN tag to use, native means none
+#  usable_ip_range: 192.0.2.11,192.0.2.99            #Usable ip range, if empty entire range is usable, ex. 192.168.1.10,192.168.1.20
+#  gateway: 192.0.2.1                                #Gateway (only needed when public_network is disabled), if empty it is auto-detected
+#  provisioner_ip: 192.0.2.1                         #installer VM IP, if empty it is the next available IP in the admin subnet
+#  cidr: 192.0.2.0/24                                #subnet in CIDR format 192.168.1.0/24, if empty it will be auto-detected
+#  dhcp_range: 192.0.2.2,192.0.2.10                  #dhcp range for the admin network, if empty it will be automatically provisioned
+#  introspection_range: 192.0.2.100,192.0.2.120      #Range used for introspection phase (examining nodes)
+#private_network:
+#  enabled: false                                    #If disabled, internal api traffic will collapse to admin_network
+#public_network:
+#  enabled: true                                     #If disabled, public_network traffic will collapse to admin network
+#  network_type: ''
+#  bridged_interface: ''
+#  cidr: 192.168.37.0/24
+#  gateway: 192.168.37.1
+#  floating_ip_range: 192.168.37.200,192.168.37.220  #Range to allocate to floating IPs for the public network with Neutron
+#  usable_ip_range: 192.168.37.10,192.168.37.199     #Usable IP range on the public network, usually this is a shared subnet
+#  provisioner_ip: 192.168.37.1
+#storage_network:
+#  enabled: false                                    #If disabled, storage_network traffic will collapse to admin network
index a891473..45c26ed 100644 (file)
@@ -7,10 +7,16 @@
 # http://www.apache.org/licenses/LICENSE-2.0
 ##############################################################################
 
-from apex.network_settings import NetworkSettings
+from apex.network_settings import (
+    NetworkSettings,
+    NetworkSettingsException,
+)
 
-from nose.tools import assert_equal
-from nose.tools import assert_is_instance
+from nose.tools import (
+    assert_equal,
+    assert_is_instance,
+    assert_raises
+)
 
 
 class TestNetworkSettings(object):
@@ -29,7 +35,7 @@ class TestNetworkSettings(object):
         """This method is run once after _each_ test method is executed"""
 
     def test_init(self):
-        ns = NetworkSettings('../config/network/network_settings.yaml', True)
+        NetworkSettings('../config/network/network_settings.yaml', True)
 
     def test_dump_bash(self):
         ns = NetworkSettings('../config/network/network_settings.yaml', True)
@@ -39,7 +45,38 @@ class TestNetworkSettings(object):
     def test_get_network_settings(self):
         ns = NetworkSettings('../config/network/network_settings.yaml', True)
         assert_is_instance(ns.get_network_settings(), dict)
+        for role in ['controller', 'compute']:
+            nic_index = 1
+            for network in ['admin_network', 'private_network',
+                            'public_network', 'storage_network']:
+                nic = 'nic' + str(nic_index)
+                assert_equal(ns.nics[role][network], nic)
+                nic_index += 1
+
+    def test_get_network_settings_unspecified_nics(self):
+        ns = NetworkSettings(
+            '../tests/config/network_settings_nics_not_specified.yaml',
+            True)
+        assert_is_instance(ns.get_network_settings(), dict)
+        for role in ['controller', 'compute']:
+            nic_index = 1
+            for network in ['admin_network', 'private_network',
+                            'public_network', 'storage_network']:
+                nic = 'nic' + str(nic_index)
+                assert_equal(ns.nics[role][network], nic)
+                nic_index += 1
 
     def test_get_enabled_networks(self):
         ns = NetworkSettings('../config/network/network_settings.yaml', True)
         assert_is_instance(ns.get_enabled_networks(), list)
+
+    def test_negative_network_settings(self):
+        assert_raises(NetworkSettingsException, NetworkSettings,
+                      '../tests/config/network_settings_duplicate_nic.yaml',
+                      True)
+        assert_raises(NetworkSettingsException, NetworkSettings,
+                      '../tests/config/network_settings_nic1_reserved.yaml',
+                      True)
+        assert_raises(NetworkSettingsException, NetworkSettings,
+                      '../tests/config/network_settings_missing_required_nic'
+                      '.yaml', True)