Skip to content

Commit

Permalink
Merge pull request #225 from lindycoder/transport_aware_eapi_factory
Browse files Browse the repository at this point in the history
Push the transport decision in the factory
  • Loading branch information
stephanerobert committed Oct 26, 2018
2 parents 26345c1 + 2e561e2 commit e900610
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 58 deletions.
27 changes: 20 additions & 7 deletions netman/adapters/switches/arista.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
import warnings

import pyeapi
from netaddr import IPNetwork
Expand All @@ -11,24 +12,36 @@
from netman.core.objects.vlan import Vlan


def eapi_http(switch_descriptor):
return Arista(switch_descriptor, transport="http")


def eapi_https(switch_descriptor):
return Arista(switch_descriptor, transport="https")


def eapi(switch_descriptor):
return Arista(switch_descriptor=switch_descriptor)
warnings.warn("Use either the _http or _https driver", DeprecationWarning)

m = re.match('^(https?):\/\/(.*)$', switch_descriptor.hostname.lower())
transport, hostname = (m.group(1), m.group(2)) if m else ('https', switch_descriptor.hostname)

switch_descriptor.hostname = hostname
return Arista(switch_descriptor, transport=transport)


class Arista(SwitchBase):
def __init__(self, switch_descriptor):
def __init__(self, switch_descriptor, transport):
super(Arista, self).__init__(switch_descriptor)
self.switch_descriptor = switch_descriptor
self.transport = transport

def _connect(self):
m = re.match('^(https?):\/\/(.*)$', self.switch_descriptor.hostname.lower())
transport, hostname = (m.group(1), m.group(2)) if m else ('https', self.switch_descriptor.hostname)

self.node = pyeapi.connect(host=hostname,
self.node = pyeapi.connect(host=self.switch_descriptor.hostname,
username=self.switch_descriptor.username,
password=self.switch_descriptor.password,
port=self.switch_descriptor.port,
transport=transport,
transport=self.transport,
return_node=True)

def _disconnect(self):
Expand Down
2 changes: 2 additions & 0 deletions netman/core/switch_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

factories = {
"arista": arista.eapi,
"arista_http": arista.eapi_http,
"arista_https": arista.eapi_https,
"cisco": cisco.ssh,
"brocade": brocade.ssh,
"brocade_ssh": brocade.ssh,
Expand Down
2 changes: 1 addition & 1 deletion tests/adapters/compliance_tests/add_ip_to_vlan_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


class AddIpToVlanTest(ComplianceTestCase):
_dev_sample = "arista"
_dev_sample = "arista_http"

def setUp(self):
super(AddIpToVlanTest, self).setUp()
Expand Down
2 changes: 1 addition & 1 deletion tests/adapters/compliance_tests/add_vlan_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@


class AddVlanTest(ComplianceTestCase):
_dev_sample = "arista"
_dev_sample = "arista_http"

def test_creates_an_empty_vlan(self):
self.client.add_vlan(1000)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@


class RemoveIpFromVlanTest(ComplianceTestCase):
_dev_sample = "arista"
_dev_sample = "arista_http"

def setUp(self):
super(RemoveIpFromVlanTest, self).setUp()
Expand Down
4 changes: 2 additions & 2 deletions tests/adapters/model_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
available_models = [
{
"switch_descriptor": SwitchDescriptor(
model="arista",
hostname="http://127.0.0.1",
model="arista_http",
hostname="127.0.0.1",
port=11015,
username="root",
password="root",
Expand Down
96 changes: 73 additions & 23 deletions tests/adapters/switches/arista_test.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,30 @@
import unittest

import mock
import pyeapi
from flexmock import flexmock, flexmock_teardown
from hamcrest import assert_that, has_length, equal_to, is_, contains_string
from netaddr import IPNetwork
from pyeapi.client import Node
from pyeapi.eapilib import CommandError

from netman.adapters.switches import arista
from netman.adapters.switches.arista import Arista
from netman.core.objects.exceptions import BadVlanNumber, VlanAlreadyExist, BadVlanName, UnknownVlan, \
UnknownIP, IPNotAvailable, IPAlreadySet, UnknownInterface
from netman.core.objects.switch_descriptor import SwitchDescriptor
from netman.core.objects.vlan import Vlan
from tests import ignore_deprecation_warnings
from tests.fixtures.arista import vlan_data, result_payload, interface_vlan_data, show_interfaces, interface_address


class AristaTest(unittest.TestCase):

def setUp(self):
self.switch = Arista(SwitchDescriptor(model='arista', hostname="my.hostname"))
self.switch = Arista(SwitchDescriptor(model='arista', hostname="my.hostname"), transport="Eytch tea tea pee")
self.switch.node = flexmock()

def tearDown(self):
flexmock_teardown()

def test_arista_instance_with_proper_transport_http(self):
arista_eapi = flexmock(pyeapi)
arista_eapi.should_receive('connect').with_args(host="127.0.0.1", transport="http",
username=None, return_node=True,
password=None, port=None).once() \
.and_return(flexmock(Node(connection=None)))

switch = Arista(SwitchDescriptor(model='arista', hostname="http://127.0.0.1"))
switch._connect()

def test_arista_instance_with_proper_default_transport(self):
arista_eapi = flexmock(pyeapi)
arista_eapi.should_receive('connect').with_args(host="127.0.0.1", transport="https",
username=None, return_node=True,
password=None, port=None).once() \
.and_return(flexmock(Node(connection=None)))

switch = Arista(SwitchDescriptor(model='arista', hostname="127.0.0.1"))
switch._connect()

def test_get_vlans(self):
vlans_payload = {'vlans': {'1': vlan_data(name='default'),
'123': vlan_data(name='VLAN0123'),
Expand Down Expand Up @@ -329,3 +310,72 @@ def test_transactions_commit_write_memory(self):
self.switch.node.should_receive("enable").with_args("write memory").once()

self.switch.commit_transaction()


class AristaFactoryTest(unittest.TestCase):
def tearDown(self):
flexmock_teardown()

def test_arista_instance_with_proper_transport(self):
pyeapi_client_node = mock.sentinel

flexmock(pyeapi).should_receive('connect').once() \
.with_args(host="1.2.3.4",
username="you sir name",
password="paw sword",
port=8888,
transport="trololo",
return_node=True) \
.and_return(pyeapi_client_node)

switch = Arista(
SwitchDescriptor(model='arista',
hostname="1.2.3.4",
username="you sir name",
password="paw sword",
port=8888),
transport="trololo"
)

switch._connect()

assert_that(switch.node, is_(pyeapi_client_node))

@ignore_deprecation_warnings
def test_factory_transport_auto_detection_http(self):
switch_descriptor = SwitchDescriptor(model="arista", hostname='http://hostname')

instance = mock.sentinel
flexmock(arista).should_receive("Arista").once() \
.with_args(switch_descriptor, transport="http") \
.and_return(mock.sentinel)

assert_that(arista.eapi(switch_descriptor), is_(instance))

assert_that(switch_descriptor.hostname, is_("hostname"))

@ignore_deprecation_warnings
def test_factory_transport_auto_detection_https(self):
switch_descriptor = SwitchDescriptor(model="arista", hostname='https://hostname')

instance = mock.sentinel
flexmock(arista).should_receive("Arista").once() \
.with_args(switch_descriptor, transport="https") \
.and_return(mock.sentinel)

assert_that(arista.eapi(switch_descriptor), is_(instance))

assert_that(switch_descriptor.hostname, is_("hostname"))

@ignore_deprecation_warnings
def test_factory_transport_auto_detection_assumes_https_if_not_specified(self):
switch_descriptor = SwitchDescriptor(model="arista", hostname='hostname')

instance = mock.sentinel
flexmock(arista).should_receive("Arista").once() \
.with_args(switch_descriptor, transport="https") \
.and_return(mock.sentinel)

assert_that(arista.eapi(switch_descriptor), is_(instance))

assert_that(switch_descriptor.hostname, is_("hostname"))
2 changes: 1 addition & 1 deletion tests/adapters/unified_tests/bond_management_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class BondManagementTest(ConfiguredTestCase):
__test__ = False

@skip_on_switches("cisco", "brocade", "brocade_telnet", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista")
@skip_on_switches("cisco", "brocade", "brocade_telnet", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista_http")
def test_creating_deleting_a_bond(self):
self.client.add_bond(3)

Expand Down
2 changes: 1 addition & 1 deletion tests/adapters/unified_tests/dhcp_relay_server_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
class DhcpRelayServerTest(ConfiguredTestCase):
__test__ = False

@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "arista_http")
def test_add_and_get_and_delete_dhcp_relay_server(self):
try:
self.client.add_vlan(2999, name="my-test-vlan")
Expand Down
10 changes: 5 additions & 5 deletions tests/adapters/unified_tests/interface_management_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,22 @@
class InterfaceManagementTest(ConfiguredTestCase):
__test__ = False

@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "arista_http")
def test_set_interface_state_off(self):
self.client.set_interface_state(self.test_port, OFF)

@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "juniper_mx", "arista_http")
def test_set_interface_state_on(self):
self.client.set_interface_state(self.test_port, ON)

@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista")
@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista_http")
def test_edit_spanning_tree(self):
self.client.edit_interface_spanning_tree(self.test_port, edge=True)

@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista")
@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista_http")
def test_set_interface_lldp_state(self):
self.client.set_interface_lldp_state(self.test_port, enabled=True)

@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista")
@skip_on_switches("cisco", "brocade", "brocade_telnet", "juniper_mx", "arista_http")
def test_disable_lldp(self):
self.client.set_interface_lldp_state(self.test_port, enabled=False)
6 changes: 3 additions & 3 deletions tests/adapters/unified_tests/ip_management_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
class IpManagementTest(ConfiguredTestCase):
__test__ = False

@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista_http")
def test_adding_and_removing_ip_basic(self):
self.client.add_vlan(2345)

Expand Down Expand Up @@ -58,7 +58,7 @@ def test_adding_and_removing_ip_basic(self):

self.client.remove_vlan(2345)

@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista_http")
def test_adding_unavailable_ips_and_various_errors(self):
self.client.add_vlan(2345)

Expand Down Expand Up @@ -91,7 +91,7 @@ def test_adding_unavailable_ips_and_various_errors(self):

self.client.remove_vlan(2345)

@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista")
@skip_on_switches("juniper", "juniper_qfx_copper", "dell", "dell_telnet", "dell10g", "dell10g_telnet", "juniper_mx", "arista_http")
def test_handling_access_groups(self):
self.client.add_vlan(2345)

Expand Down

0 comments on commit e900610

Please sign in to comment.