Skip to content

Commit

Permalink
Add support for Cisco Nexus 9000v platform (#60)
Browse files Browse the repository at this point in the history
  • Loading branch information
glennmatthews committed Feb 13, 2017
1 parent 6d9ce37 commit 15ea8b7
Show file tree
Hide file tree
Showing 6 changed files with 214 additions and 1 deletion.
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This project adheres to `Semantic Versioning`_.

- Support for Python 3.6
- Support for `brew` package manager (`#55`_).
- Support for Cisco Nexus 9000v (NX-OSv 9000) platform (`#60`_).

**Fixed**

Expand Down Expand Up @@ -610,6 +611,7 @@ Initial public release.
.. _#57: https://github.com/glennmatthews/cot/issues/57
.. _#58: https://github.com/glennmatthews/cot/issues/58
.. _#59: https://github.com/glennmatthews/cot/issues/59
.. _#60: https://github.com/glennmatthews/cot/issues/60

.. _Semantic Versioning: http://semver.org/
.. _`PEP 8`: https://www.python.org/dev/peps/pep-0008/
Expand Down
23 changes: 22 additions & 1 deletion COT/platforms/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# October 2013, Glenn F. Matthews
# Copyright (c) 2013-2016 the COT project developers.
# Copyright (c) 2013-2017 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
Expand Down Expand Up @@ -40,6 +40,7 @@
COT.platforms.cisco_iosv
COT.platforms.cisco_iosxrv
COT.platforms.cisco_iosxrv_9000
COT.platforms.cisco_nexus_9000v
COT.platforms.cisco_nxosv
"""

Expand All @@ -50,6 +51,7 @@
from .cisco_iosv import IOSv
from .cisco_iosxrv import IOSXRv, IOSXRvRP, IOSXRvLC
from .cisco_iosxrv_9000 import IOSXRv9000
from .cisco_nexus_9000v import Nexus9000v
from .cisco_nxosv import NXOSv

logger = logging.getLogger(__name__)
Expand All @@ -58,6 +60,7 @@
PRODUCT_PLATFORM_MAP = {
'com.cisco.csr1000v': CSR1000V,
'com.cisco.iosv': IOSv,
'com.cisco.n9k': Nexus9000v,
'com.cisco.nx-osv': NXOSv,
'com.cisco.ios-xrv': IOSXRv,
'com.cisco.ios-xrv.rp': IOSXRvRP,
Expand All @@ -78,6 +81,14 @@ def is_known_product_class(product_class):
Returns:
bool: Whether product_class is known.
Examples:
::
>>> is_known_product_class("com.cisco.n9k")
True
>>> is_known_product_class("foobar")
False
"""
return product_class in PRODUCT_PLATFORM_MAP

Expand All @@ -90,6 +101,16 @@ def platform_from_product_class(product_class):
Returns:
class: GenericPlatform or a subclass of it
Examples:
::
>>> platform_from_product_class("com.cisco.n9k")
<class 'COT.platforms.cisco_nexus_9000v.Nexus9000v'>
>>> platform_from_product_class(None)
<class 'COT.platforms.generic.GenericPlatform'>
>>> platform_from_product_class("frobozz")
<class 'COT.platforms.generic.GenericPlatform'>
"""
if product_class is None:
return GenericPlatform
Expand Down
102 changes: 102 additions & 0 deletions COT/platforms/cisco_nexus_9000v.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# January 2017, Glenn F. Matthews
# Copyright (c) 2013-2017 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
# This file is part of the Common OVF Tool (COT) project.
# It is subject to the license terms in the LICENSE.txt file found in the
# top-level directory of this distribution and at
# https://github.com/glennmatthews/cot/blob/master/LICENSE.txt. No part
# of COT, including this file, may be copied, modified, propagated, or
# distributed except according to the terms contained in the LICENSE.txt file.

"""Platform logic for the Cisco Nexus 9000v virtual switch."""

import logging

from COT.platforms.generic import GenericPlatform
from COT.data_validation import (
ValueTooLowError, validate_int,
)

logger = logging.getLogger(__name__)


class Nexus9000v(GenericPlatform):
"""Platform-specific logic for Cisco Nexus 9000v."""

PLATFORM_NAME = "Cisco Nexus 9000v"

CONFIG_TEXT_FILE = 'nxos_config.txt'
LITERAL_CLI_STRING = None
SUPPORTED_NIC_TYPES = ["E1000", "VMXNET3"]

@classmethod
def guess_nic_name(cls, nic_number):
"""The Nexus 9000v has a management NIC and some number of data NICs.
Args:
nic_number (int): Nth NIC to name.
Returns:
* mgmt0
* Ethernet1/1
* Ethernet1/2
* ...
"""
if nic_number == 1:
return "mgmt0"
else:
return "Ethernet1/{0}".format(nic_number - 1)

@classmethod
def validate_cpu_count(cls, cpus):
"""The Nexus 9000v requires 1-4 vCPUs.
Args:
cpus (int): Number of vCPUs
Raises:
ValueTooLowError: if ``cpus`` is less than 1
ValueTooHighError: if ``cpus`` is more than 4
"""
validate_int(cpus, 1, 4, "CPUs")

@classmethod
def validate_memory_amount(cls, mebibytes):
"""The Nexus 9000v requires at least 8 GiB of RAM.
Args:
mebibytes (int): RAM, in MiB.
Raises:
ValueTooLowError: if ``mebibytes`` is less than 8192
"""
if mebibytes < 8192:
raise ValueTooLowError("RAM", str(mebibytes) + " MiB", "8 GiB")

@classmethod
def validate_nic_count(cls, count):
"""The Nexus 9000v requires at least 1 and supports at most 65 NICs.
Args:
count (int): Number of NICs.
Raises:
ValueTooLowError: if ``count`` is less than 1
ValueTooHighError: if ``count`` is more than 65
"""
validate_int(count, 1, 65, "NICs")

@classmethod
def validate_serial_count(cls, count):
"""The Nexus 9000v requires exactly 1 serial port.
Args:
count (int): Number of serial ports.
Raises:
ValueTooLowError: if ``count`` is less than 1
ValueTooHighError: if ``count`` is more than 1
"""
validate_int(count, 1, 1, "serial ports")
77 changes: 77 additions & 0 deletions COT/platforms/tests/test_cisco_nexus_9000v.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# test_cisco_nxosv.py - Unit test cases for Cisco Nexus 9000v platform
#
# January 2017, Glenn F. Matthews
# Copyright (c) 2014-2017 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
# This file is part of the Common OVF Tool (COT) project.
# It is subject to the license terms in the LICENSE.txt file found in the
# top-level directory of this distribution and at
# https://github.com/glennmatthews/cot/blob/master/LICENSE.txt. No part
# of COT, including this file, may be copied, modified, propagated, or
# distributed except according to the terms contained in the LICENSE.txt file.

"""Unit test cases for Nexus 9000v platform."""

import unittest
from COT.platforms.cisco_nexus_9000v import Nexus9000v
from COT.data_validation import (
ValueUnsupportedError, ValueTooLowError, ValueTooHighError
)


class TestNexus9000v(unittest.TestCase):
"""Test cases for Cisco Nexus 9000v platform handling."""

cls = Nexus9000v

def test_nic_name(self):
"""Test NIC name construction."""
self.assertEqual(self.cls.guess_nic_name(1),
"mgmt0")
self.assertEqual(self.cls.guess_nic_name(2),
"Ethernet1/1")
self.assertEqual(self.cls.guess_nic_name(3),
"Ethernet1/2")
self.assertEqual(self.cls.guess_nic_name(4),
"Ethernet1/3")

def test_cpu_count(self):
"""Test CPU count limits."""
self.assertRaises(ValueTooLowError, self.cls.validate_cpu_count, 0)
self.cls.validate_cpu_count(1)
self.cls.validate_cpu_count(4)
self.assertRaises(ValueTooHighError, self.cls.validate_cpu_count, 5)

def test_memory_amount(self):
"""Test RAM allocation limits."""
self.assertRaises(ValueTooLowError,
self.cls.validate_memory_amount, 8191)
self.cls.validate_memory_amount(8192)
self.cls.validate_memory_amount(16384)
# No upper bound known at present

def test_nic_count(self):
"""Test NIC range limits."""
self.assertRaises(ValueTooLowError, self.cls.validate_nic_count, 0)
self.cls.validate_nic_count(1)
self.cls.validate_nic_count(65)
self.assertRaises(ValueTooHighError, self.cls.validate_nic_count, 66)

def test_nic_type(self):
"""Test NIC valid and invalid types."""
self.assertRaises(ValueUnsupportedError,
self.cls.validate_nic_type, "E1000e")
self.cls.validate_nic_type("E1000")
self.assertRaises(ValueUnsupportedError,
self.cls.validate_nic_type, "PCNet32")
self.assertRaises(ValueUnsupportedError,
self.cls.validate_nic_type, "virtio")
self.cls.validate_nic_type("VMXNET3")

def test_serial_count(self):
"""Test serial port range limits."""
self.assertRaises(ValueTooLowError, self.cls.validate_serial_count, 0)
self.cls.validate_serial_count(1)
self.assertRaises(ValueTooHighError, self.cls.validate_serial_count, 2)
7 changes: 7 additions & 0 deletions COT/tests/test_doctests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@

"""Test runner for COT doctest tests."""

import logging

from doctest import DocTestSuite
from unittest import TestSuite

from COT.tests.ut import NullHandler

logging.getLogger('COT').addHandler(NullHandler())


def load_tests(*_):
"""Load doctests as unittest test suite.
Expand All @@ -33,4 +39,5 @@ def load_tests(*_):
suite.addTests(DocTestSuite('COT.edit_hardware'))
suite.addTests(DocTestSuite('COT.edit_properties'))
suite.addTests(DocTestSuite('COT.file_reference'))
suite.addTests(DocTestSuite('COT.platforms'))
return suite
4 changes: 4 additions & 0 deletions docs/COT.platforms.cisco_nexus_9000v.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
``COT.platforms.cisco_nexus_9000v`` module
==========================================

.. automodule:: COT.platforms.cisco_nexus_9000v

0 comments on commit 15ea8b7

Please sign in to comment.