diff --git a/pyeapi/api/interfaces.py b/pyeapi/api/interfaces.py index d2b0aae..aeddec5 100644 --- a/pyeapi/api/interfaces.py +++ b/pyeapi/api/interfaces.py @@ -601,19 +601,31 @@ def set_members(self, name, members, mode=None): member interfaces mode(str): The LACP mode to configure the member interfaces to. - Valid values are 'on, 'passive', 'active' + Valid values are 'on, 'passive', 'active'. When there are + existing channel-group members and their lacp mode differs + from this attribute, all of those members will be removed and + then re-added using the specified lacp mode. If this attribute + is omitted, the existing lacp mode will be used for new + member additions. Returns: True if the operation succeeds otherwise False """ + commands = list() + grpid = re.search(r'(\d+)', name).group() current_members = self.get_members(name) - if mode: + lacp_mode = self.get_lacp_mode(name) + if mode and mode != lacp_mode: lacp_mode = mode - else: - lacp_mode = self.get_lacp_mode(name) - grpid = re.search(r'(\d+)', name).group() - - commands = list() + # remove all members from the current port-channel interface + # so that we can change the mode below + for member in current_members: + commands.append('interface %s' % member) + commands.append('no channel-group %s' % grpid) + # add all members back with the specified lacp_mode + for member in current_members: + commands.append('interface %s' % member) + commands.append('channel-group %s mode %s' % (grpid, lacp_mode)) # remove members from the current port-channel interface for member in set(current_members).difference(members): diff --git a/test/system/test_api_interfaces.py b/test/system/test_api_interfaces.py index 337e760..7f3c638 100644 --- a/test/system/test_api_interfaces.py +++ b/test/system/test_api_interfaces.py @@ -242,6 +242,38 @@ def test_set_members(self): config[0]['output'], 'dut=%s' % dut) + def test_set_members_with_mode(self): + for dut in self.duts: + et1 = random_interface(dut) + et2 = random_interface(dut, exclude=[et1]) + et3 = random_interface(dut, exclude=[et1, et2]) + + dut.config(['no interface Port-Channel1', + 'default interface %s' % et1, + 'interface %s' % et1, + 'channel-group 1 mode on', + 'default interface %s' % et2, + 'interface %s' % et2, + 'channel-group 1 mode on', + 'default interface %s' % et3]) + + api = dut.api('interfaces') + result = api.set_members('Port-Channel1', [et1, et3], mode='active') + self.assertTrue(result, 'dut=%s' % dut) + + cmd = 'show running-config interfaces %s' + + # check to make sure et1 is still in the lag and et3 was + # added to the lag + for interface in [et1, et3]: + config = dut.run_commands(cmd % interface, 'text') + self.assertIn('channel-group 1 mode active', + config[0]['output'], 'dut=%s' % dut) + + # checks to make sure et2 was remvoved form the lag + config = dut.run_commands(cmd % et2, 'text') + self.assertNotIn('channel-group 1 mode on', + config[0]['output'], 'dut=%s' % dut) def test_minimum_links_valid(self):