Skip to content

Commit

Permalink
BUGFIX: Do interface validation of set interface commands in a case…
Browse files Browse the repository at this point in the history
…-insensitive manor, to match the DB.
  • Loading branch information
caladd authored and masonkatz committed Apr 29, 2019
1 parent be77681 commit a8e38ee
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,48 @@ class command(stack.commands.set.host.command):
def validate(self, hosts, interface=None, mac=None, network=None):
"""
Validated that the provided interface, mac, and/or network
exist for the hosts, or raise an error.
exist for the hosts, or raise an error. The validation needs to
be done in a case-insensitive manor, to match the DB behavior.
"""

# Construct our host data to check against
host_data = defaultdict(lambda: defaultdict(set))
for row in self.call('list.host.interface', hosts):
combo = []
if row['interface']:
host_data[row['host']]['interfaces'].add(row['interface'])
combo.append(row['interface'])
host_data[row['host']]['interfaces'].add(row['interface'].lower())
combo.append(row['interface'].lower())

if row['mac']:
host_data[row['host']]['macs'].add(row['mac'])
combo.append(row['mac'])
host_data[row['host']]['macs'].add(row['mac'].lower())
combo.append(row['mac'].lower())

if row['network']:
host_data[row['host']]['networks'].add(row['network'])
combo.append(row['network'])
host_data[row['host']]['networks'].add(row['network'].lower())
combo.append(row['network'].lower())

if len(combo) > 1:
host_data[row['host']]['combos'].add(tuple(combo))

# Our combination the user asked for
combo = tuple(filter(None, (interface, mac, network)))
combo = []
if interface:
combo.append(interface.lower())
if mac:
combo.append(mac.lower())
if network:
combo.append(network.lower())
combo = tuple(combo)

# Check the provided arguements against the host data
for host in hosts:
if interface and interface not in host_data[host]['interfaces']:
if interface and interface.lower() not in host_data[host]['interfaces']:
raise CommandError(self, f'interface "{interface}" does not exist for host "{host}"')

if mac and mac not in host_data[host]['macs']:
if mac and mac.lower() not in host_data[host]['macs']:
raise CommandError(self, f'mac "{mac}" does not exist for host "{host}"')

if network and network not in host_data[host]['networks']:
if network and network.lower() not in host_data[host]['networks']:
raise CommandError(self, f'network "{network}" does not exist for host "{host}"')

if len(combo) > 1 and combo not in host_data[host]['combos']:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,35 @@ def test_all_parameters(self, host, add_host, add_network):
'vlan': None
}]

def test_all_parameters_insensitive(self, host, add_host, add_network):
# Add an interface with a mac and network to our test host
result = host.run('stack add host interface backend-0-0 mac=aa:bb:cc:dd:ee:ff network=test')
assert result.rc == 0

# Set the default host interface
result = host.run(
'stack set host interface interface backend-0-0 interface=eth0 '
'mac=AA:BB:CC:DD:EE:FF network=TEST'
)
assert result.rc == 0

# Check that it made it into the database
result = host.run('stack list host interface backend-0-0 output-format=json')
assert result.rc == 0
assert json.loads(result.stdout) == [{
'channel': None,
'default': None,
'host': 'backend-0-0',
'interface': 'eth0',
'ip': None,
'mac': 'aa:bb:cc:dd:ee:ff',
'module': None,
'name': None,
'network': 'test',
'options': None,
'vlan': None
}]

def test_multiple_hosts(self, host, add_host, add_network):
# Add an interface with a MAC and network
result = host.run('stack add host interface backend-0-0 mac=00:11:22:33:44:55 network=test')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,35 @@ def test_all_parameters(self, host, add_host, add_network):
'vlan': None
}]

def test_all_parameters_insensitive(self, host, add_host, add_network):
# Add an interface with a interface device and network to our test host
result = host.run('stack add host interface backend-0-0 interface=eth0 network=test')
assert result.rc == 0

# Set the host interface mac
result = host.run(
'stack set host interface mac backend-0-0 interface=ETH0 '
'mac=aa:bb:cc:dd:ee:ff network=TEST'
)
assert result.rc == 0

# Check that it made it into the database
result = host.run('stack list host interface backend-0-0 output-format=json')
assert result.rc == 0
assert json.loads(result.stdout) == [{
'channel': None,
'default': None,
'host': 'backend-0-0',
'interface': 'eth0',
'ip': None,
'mac': 'aa:bb:cc:dd:ee:ff',
'module': None,
'name': None,
'network': 'test',
'options': None,
'vlan': None
}]

def test_multiple_hosts(self, host, add_host):
# Add a second test backend
add_host('backend-0-1', '0', '1', 'backend')
Expand Down

0 comments on commit a8e38ee

Please sign in to comment.