Browse Source

Updating naming conventions and documenting a Python API

- renamed the class that calls ansible_runner to NetworkingAnsible
- added documentation

Change-Id: Ia1819d54469acdcb66bf2e40f6cb750574a4ea30
changes/27/601327/6
Dan Radez 3 years ago
parent
commit
095c86e015
  1. 30
      README.rst
  2. 1
      doc/source/contributor/index.rst
  3. 4
      doc/source/install/configure.rst
  4. 9
      doc/source/install/index.rst
  5. 6
      doc/source/install/install.rst
  6. 6
      doc/source/install/next-steps.rst
  7. 12
      doc/source/install/prerequisites.rst
  8. 4
      doc/source/install/verify.rst
  9. 46
      doc/source/user/api.rst
  10. 38
      doc/source/user/index.rst
  11. 42
      doc/source/user/ironic.rst
  12. 1
      networking_ansible/__init__.py
  13. 2
      networking_ansible/api.py
  14. 10
      networking_ansible/ml2/mech_driver.py
  15. 4
      networking_ansible/tests/unit/base.py
  16. 14
      networking_ansible/tests/unit/ml2/test_mech_driver.py
  17. 14
      networking_ansible/tests/unit/test_api.py
  18. 5
      requirements.txt

30
README.rst

@ -4,12 +4,12 @@ Networking-Ansible ML2 Driver
Overview
--------
Networking-Ansible is a Neutron ML2 driver that abstracts the management and
interaction with switching hardware to Ansible Networking. This driver is not
Networking-Ansible is a python library that abstracts management and
interaction with switching hardware to Ansible Networking. This library is not
tested with all the modules included with Ansible Networking. In theory it
should work with any switch that has compatible modules included with Ansible
Networking if the provider tasks are added to the Ansible openstack-ml2 role
included with this driver. See the contributor documentation for more information
Networking if the provider tasks are added to this library's Ansible role.
See the contributor documentation for more information
about adding support for an Ansible Networking driver to the openstack-ml2
Ansible role.
@ -20,21 +20,31 @@ Ansible role.
Components
----------
The Networking-Ansible ML2 Driver consists of the following components:
The Networking-Ansible library consists of the following components:
``networking_ansible`` ML2 Driver
Invoked by neutron to configure L2 networking for tenant networks.
``ML2 Mechanism Driver``
Invoked by neutron to configure L2 networking for OpenStack tenant networks.
``Python API``
Imported directly by python.
Use Cases
---------
``Ironic Baremetal Guest Deployment``
``OpenStack Ironic Baremetal Guest Deployment``
Ironic uses Networking-Ansible to configure the switch ports for the baremetal guests.
Ironic needs to swap the port a baremetal guest is connected to between the
Ironic provisioning network and the tenant VLAN that the guest is assigned.
``Python API``
Any python application could need the ability to communicate with a switch
to perform a task that networking-ansible is able to complete. The interaction
with ansible is designed in a library style that will allow direct import and
invocation in python independant of a running OpenStack deployment.
Features
--------
* On create network a vlan can be defined
* On port update will assign a vlan to an access port
* Create and delete VLANs
* Configure a port in access mode and assign a it to a VLAN

1
doc/source/contributor/index.rst

@ -7,4 +7,3 @@
contributing
provider

4
doc/source/install/configure.rst

@ -1,7 +1,7 @@
.. _configure:
Configure
~~~~~~~~~
ML2 Configuriation
~~~~~~~~~~~~~~~~~~
This section decribes how to configure Neutron configuration files to enable
the networking-ansible ML2 driver and configure switch devices that will be

9
doc/source/install/index.rst

@ -4,7 +4,9 @@ Install and configure
This section describes how to install and configure the networking-ansible
ML2 Driver, code-named networking-ansible, on the controller node.
This section assumes that you already have a working OpenStack
environment with Neutron server included.
environment with Neutron server included. For guides to assist in installing
and deploying OpenStack visit
`OpenStack Docs <https://docs.openstack.org/>`_.
Perform installation configuration steps on each controller node that has a Neutron server running.
@ -20,8 +22,3 @@ Perform installation configuration steps on each controller node that has a Neut
.. note::
Installation and configuration may vary by distribution.
This chapter assumes a working setup of OpenStack that includes Neutron server.
For guides to assist in installing and deploying OpenStack visit
`OpenStack Docs <https://docs.openstack.org/>`_.

6
doc/source/install/install.rst

@ -4,9 +4,9 @@ Install
~~~~~~~
This section describes how to install and configure the Networking-Ansible
Driver, code-named networking_ansible, on the controller node. This section
assumes that you already have a working OpenStack environment with Neutron
configured to provide VLAN tenant networking.
library, code-named networking_ansible. If you plan to use the library as an
ML2 driver in OpenStack, this section assumes that you already have a working
OpenStack environment with Neutron configured to provide VLAN tenant networking.
.. note::

6
doc/source/install/next-steps.rst

@ -3,6 +3,10 @@
Next steps
~~~~~~~~~~
Your OpenStack environment now includes the networking-ansible ML2 Driver.
If you have installed and configured Networking-Ansible as an ML2 driver, your
OpenStack environment now includes the networking-ansible ML2 Driver.
To add additional services, see https://docs.openstack.org/.
If you plan to use Networking-Ansible as a Python API the module can now be
imported and instatiated. See :ref:`api`.

12
doc/source/install/prerequisites.rst

@ -1,9 +1,9 @@
Prerequisites
-------------
To successfully install and configure the Networking-Ansible ML2 Driver, you
will need a few prerequisites. Collecting this information and ensuring these
resources are available will ensure a successful installation.
To successfully install and configure the Networking-Ansible library, you
will possibly need a few prerequisites. Collecting this information and ensuring
these resources are available will ensure a successful installation.
#. Switch credentials that allow configuration changes to the ports that the
deployed baremetal guests are connected to.
@ -16,9 +16,13 @@ resources are available will ensure a successful installation.
a VLAN to that port. It will optionally need access to create VLANs if
you choose not to predefine the VLANs that will be used.
#. OpenStack must be installed with Neutron configured to provide VLAN tenant
#. If you plan to configure networking-ansible as an ML2 driver in OpenStack,
OpenStack must be installed with Neutron configured to provide VLAN tenant
networking.
This prerequisite is currently outside the scope of this document. Please
refer to Neutron's documentation or other guides to provide VLAN tenant
networking.
For guides to assist in installing and deploying OpenStack visit
`OpenStack Docs <https://docs.openstack.org/>`_.

4
doc/source/install/verify.rst

@ -1,7 +1,7 @@
.. _verify:
Verify operation
~~~~~~~~~~~~~~~~
Verify ML2 operation
~~~~~~~~~~~~~~~~~~~~
Verify operation of the networking-ansible ML2 Driver service.

46
doc/source/user/api.rst

@ -0,0 +1,46 @@
.. _api:
==========
Python API
==========
Networking-Ansible can be called directly via python API. This method does not
require a running OpenStack, with neutron.
In this section, this use case will be exercised in a set of example commands to
show how end users could import the networking-ansible API and call it to
execute switch level network configuration.
#. In a python environment import the networking-ansible class.
.. code-block:: console
from networking_ansible.api import NetworkingAnsible
#. Instantiate the NetworkingAnsible class. This requires a dictionary that
represents an Ansible Inventory data structure. This data structure could be
read from a file or built dynamically by the code that is instantiating the
class. This example will statically assign the data structure to a variable
to show the expected data structure.
.. code-block:: console
inventory = {'all':
{'hosts':
{'examplehost':
{'ansible_network_os': 'openswitch',
'ansible_host': '5.6.7.8',
'ansible_user': 'ansible',
'ansible_ssh_pass': 'password',
}
}
}
}
net_ans = NetworkingAnsible(inventory)
#. Call functions to configure the inventory.
.. code-block:: console
vlan = 37
net_ans.create_network(vlan)

38
doc/source/user/index.rst

@ -2,38 +2,10 @@
Users guide
===========
Networking-Ansible is currently tested with one use case, Ironic Baremetal Guests.
In this section this use case will be exercised in a set of example commands to
show how end users would use ironic to provision baremetal nodes. Provisioning
baremetal nodes using ironic with networking-ansible would use networking-ansible
to manage the guest's switch level network configuration. Networking-Ansible is used by
ironic to first assign a baremetal guest's switchport to the Ironic provisoning
network to provision the baremetal guest. After provisoning, the baremetal
guest's switchport is assigned to the VLAN assigned by Neutron to guest's tenant network.
Networking-Ansible is able to be used in two possible senarios.
The example shown here mirrors a user's expereience deploying a guest with
Ironic. The end user's experience using networking-ansible is via Neutron and
Nova. Nova will select a baremetal node as its target when a properly configured
baremetal flavor is provided to the OpenStack server create command.
.. toctree::
:maxdepth: 2
#. An administrator will provide Ironic node(s) that are available for
provisioning and a baremetal flavor.
.. code-block:: console
openstack baremetal node list
openstack flavor list
#. Create a tenant VLAN network and subnet that uses the physical network the guest is attached to.
.. code-block:: console
openstack network create --provider-network-type vlan --provider-physical-network datacentre my-tenant-net
openstack subnet create --network tenant-net --subnet-range 192.168.3.0/24 --allocation-pool start=192.168.3.10,end=192.168.3.20 tenant-subnet
#. Execute server create using the tenant network just created. This assumes
disk images and keypairs are already created and available.
.. code-block:: console
openstack server create --image a-baremetal-image --flavor baremetal --nic net-id={my-tenant-net uuid} --key-name my-keypair bm-instance
ironic
api

42
doc/source/user/ironic.rst

@ -0,0 +1,42 @@
======================
Ironic Baremetal Guest
======================
Networking-Ansible can be used as the ML2 driver that communicates with the
switch that baremetal guests are cabled to. These guests need to have their
port configuration updated depending on their deployment status.
In this section, this use case will be exercised in a set of example commands to
show how end users would use ironic to provision baremetal nodes. Provisioning
baremetal nodes using ironic with networking-ansible would use networking-ansible
to manage the guest's switch level network configuration. Networking-Ansible is used by
ironic to first assign a baremetal guest's switchport to the Ironic provisoning
network to provision the baremetal guest. After provisoning, the baremetal
guest's switchport is assigned to the VLAN assigned by Neutron to guest's tenant network.
The example shown here mirrors a user's expereience deploying a guest with
Ironic. The end user's experience using networking-ansible is via Neutron and
Nova. Nova will select a baremetal node as its target when a properly configured
baremetal flavor is provided to the OpenStack server create command.
#. An administrator will provide Ironic node(s) that are available for
provisioning and a baremetal flavor.
.. code-block:: console
openstack baremetal node list
openstack flavor list
#. Create a tenant VLAN network and subnet that uses the physical network the guest is attached to.
.. code-block:: console
openstack network create --provider-network-type vlan --provider-physical-network datacentre my-tenant-net
openstack subnet create --network tenant-net --subnet-range 192.168.3.0/24 --allocation-pool start=192.168.3.10,end=192.168.3.20 tenant-subnet
#. Execute server create using the tenant network just created. This assumes
disk images and keypairs are already created and available.
.. code-block:: console
openstack server create --image a-baremetal-image --flavor baremetal --nic net-id={my-tenant-net uuid} --key-name my-keypair bm-instance

1
networking_ansible/__init__.py

@ -14,6 +14,5 @@
import pbr.version
__version__ = pbr.version.VersionInfo(
'networking-ansible').version_string()

2
networking_ansible/ansible_networking.py → networking_ansible/api.py

@ -21,7 +21,7 @@ from networking_ansible import exceptions
LOG = logging.getLogger(__name__)
class AnsibleNetworking(object):
class NetworkingAnsible(object):
"""Object to invoke ansible_runner to call Ansible Networking
Hold inventory and provide an interface for calling

10
networking_ansible/ml2/mech_driver.py

@ -17,10 +17,10 @@ from neutron.db import provisioning_blocks
from neutron.plugins.ml2.common import exceptions as ml2_exc
from neutron_lib.api.definitions import portbindings
from neutron_lib.callbacks import resources
from neutron_lib.plugins.ml2 import api
from neutron_lib.plugins.ml2 import api as ml2api
from oslo_log import log as logging
from networking_ansible import ansible_networking
from networking_ansible import api
from networking_ansible import config
LOG = logging.getLogger(__name__)
@ -28,7 +28,7 @@ LOG = logging.getLogger(__name__)
ANSIBLE_NETWORKING_ENTITY = 'ANSIBLENETWORKING'
class AnsibleMechanismDriver(api.MechanismDriver):
class AnsibleMechanismDriver(ml2api.MechanismDriver):
"""ML2 Mechanism Driver for Ansible Networking
https://www.ansible.com/integrations/networks
@ -38,7 +38,7 @@ class AnsibleMechanismDriver(api.MechanismDriver):
LOG.debug("Initializing Ansible ML2 driver")
inventory = config.build_ansible_inventory()
self.ansnet = ansible_networking.AnsibleNetworking(inventory)
self.ansnet = api.NetworkingAnsible(inventory)
def create_network_postcommit(self, context):
"""Create a network.
@ -228,7 +228,7 @@ class AnsibleMechanismDriver(api.MechanismDriver):
# Assign port to network
self.ansnet.vlan_access_port('assign', context.current,
context.network.current)
context.set_binding(segments[0][api.ID],
context.set_binding(segments[0][ml2api.ID],
portbindings.VIF_TYPE_OTHER, {})
@staticmethod

4
networking_ansible/tests/unit/base.py

@ -19,7 +19,7 @@ from oslo_config import cfg
from oslotest import base
import pbr
from networking_ansible import ansible_networking
from networking_ansible import api
from networking_ansible import config
from networking_ansible.ml2 import mech_driver
@ -108,4 +108,4 @@ class NetworkingAnsibleTestCase(BaseTestCase):
self.mock_port_context.network.current
]
self.mech.ansnet = ansible_networking.AnsibleNetworking(self.inventory)
self.mech.ansnet = api.NetworkingAnsible(self.inventory)

14
networking_ansible/tests/unit/ml2/test_mech_driver.py

@ -25,7 +25,7 @@ from neutron_lib.api.definitions import portbindings
from neutron_lib.api.definitions import provider_net
import webob.exc
from networking_ansible import ansible_networking as anet
from networking_ansible import api
from networking_ansible import exceptions
from networking_ansible.tests.unit import base
@ -49,7 +49,7 @@ class NetAnsibleML2Base(test_plugin.Ml2PluginV2TestCase):
super(NetAnsibleML2Base, self).setUp()
@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
@mock.patch.object(api.NetworkingAnsible, 'vlan_access_port')
@mock.patch('networking_ansible.ml2.mech_driver.provisioning_blocks',
autospec=True)
class TestBindPort(base.NetworkingAnsibleTestCase):
@ -106,7 +106,7 @@ class TestIsPortBound(base.NetworkingAnsibleTestCase):
self.mech._is_port_bound(self.mock_port_context.current))
@mock.patch.object(anet.AnsibleNetworking, 'create_network')
@mock.patch.object(api.NetworkingAnsible, 'create_network')
class TestCreateNetworkPostCommit(base.NetworkingAnsibleTestCase):
def test_create_network_postcommit(self, mock_create_network):
self.mech.create_network_postcommit(self.mock_net_context)
@ -137,7 +137,7 @@ class TestCreateNetworkPostCommit(base.NetworkingAnsibleTestCase):
mock_create_netwrk.assert_not_called()
@mock.patch.object(anet.AnsibleNetworking, 'delete_network')
@mock.patch.object(api.NetworkingAnsible, 'delete_network')
class TestDeleteNetworkPostCommit(base.NetworkingAnsibleTestCase):
def test_delete_network_postcommit(self, mock_delete_network):
self.mech.delete_network_postcommit(self.mock_net_context)
@ -168,7 +168,7 @@ class TestDeleteNetworkPostCommit(base.NetworkingAnsibleTestCase):
@mock.patch('networking_ansible.ml2.mech_driver.'
'AnsibleMechanismDriver._is_port_bound')
@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
@mock.patch.object(api.NetworkingAnsible, 'vlan_access_port')
class TestDeletePortPostCommit(base.NetworkingAnsibleTestCase):
def test_delete_port_postcommit_current(self,
mock_vlan_access,
@ -196,7 +196,7 @@ class TestInit(base.NetworkingAnsibleTestCase):
@mock.patch('networking_ansible.ml2.mech_driver.'
'AnsibleMechanismDriver._is_port_bound')
@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
@mock.patch.object(api.NetworkingAnsible, 'vlan_access_port')
@mock.patch('networking_ansible.ml2.mech_driver.provisioning_blocks',
autospec=True)
class TestUpdatePortPostCommit(base.NetworkingAnsibleTestCase):
@ -224,7 +224,7 @@ class TestUpdatePortPostCommit(base.NetworkingAnsibleTestCase):
mock_vlan_access.assert_not_called()
@mock.patch.object(anet.AnsibleNetworking, '_run_task')
@mock.patch.object(api.NetworkingAnsible, '_run_task')
class TestML2PluginIntegration(NetAnsibleML2Base):
_mechanism_drivers = ['ansible']
HOSTS = ['testinghost', 'otherhost']

14
networking_ansible/tests/unit/test_ansible_networking.py → networking_ansible/tests/unit/test_api.py

@ -21,16 +21,16 @@ from networking_ansible.tests.unit import base
class TestCreateDeleteNetwork(base.NetworkingAnsibleTestCase):
@mock.patch('networking_ansible.ansible_networking'
'.AnsibleNetworking._run_task')
@mock.patch('networking_ansible.api'
'.NetworkingAnsible._run_task')
def test_create_network(self, mock_run_task):
self.mech.ansnet.create_network(self.testhost, self.testsegid)
mock_run_task.assert_called_once_with('create_network',
self.testhost,
self.testsegid)
@mock.patch('networking_ansible.ansible_networking'
'.AnsibleNetworking._run_task')
@mock.patch('networking_ansible.api'
'.NetworkingAnsible._run_task')
def test_delete_network(self, mock_run_task):
self.mech.ansnet.delete_network(self.testhost, self.testsegid)
mock_run_task.assert_called_once_with('delete_network',
@ -38,7 +38,7 @@ class TestCreateDeleteNetwork(base.NetworkingAnsibleTestCase):
self.testsegid)
@mock.patch('networking_ansible.ansible_networking.ansible_runner')
@mock.patch('networking_ansible.api.ansible_runner')
class TestRunTask(base.NetworkingAnsibleTestCase):
def test_run_task_no_switchport(self, mock_ans_runner):
mock_result = mock_ans_runner.run.return_value
@ -86,8 +86,8 @@ class TestRunTask(base.NetworkingAnsibleTestCase):
'fake_switchport')
@mock.patch('networking_ansible.ansible_networking'
'.AnsibleNetworking._run_task')
@mock.patch('networking_ansible.api'
'.NetworkingAnsible._run_task')
class TestVlanAccessPort(base.NetworkingAnsibleTestCase):
def test_assign_vlan_access_port(self, mock_run_task):

5
requirements.txt

@ -6,3 +6,8 @@ ansible-runner>=1.0.5 # Apache-2.0
neutron>=13.0.0.0b1 # Apache-2.0
neutron-lib>=1.18.0 # Apache-2.0
pbr>=2.0 # Apache-2.0
# these are explictly defined for python API support
# oslo-log is ont in openstack-requirements
# TODO(radez) figure out how to handle logging
# oslo-log

Loading…
Cancel
Save