fuel-web/nailgun/nailgun/test/integration/test_node_nic_handlers_w_bo...

312 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Copyright 2013 Mirantis, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import json
from nailgun.consts import NETWORK_INTERFACE_TYPES
from nailgun.consts import OVS_BOND_MODES
from nailgun.test.base import BaseIntegrationTest
from nailgun.test.base import reverse
class TestNodeNICsBonding(BaseIntegrationTest):
def setUp(self):
super(TestNodeNICsBonding, self).setUp()
meta = self.env.default_metadata()
self.env.set_interfaces_in_meta(meta, [
{"name": "eth0", "mac": "00:00:00:00:00:66"},
{"name": "eth1", "mac": "00:00:00:00:00:77"},
{"name": "eth2", "mac": "00:00:00:00:00:88"}])
self.env.create(
cluster_kwargs={
"net_provider": "neutron",
"net_segment_type": "gre"
},
nodes_kwargs=[
{"api": True,
"pending_addition": True,
"meta": meta}
]
)
self.get_node_nics_info()
def get_node_nics_info(self):
resp = self.app.get(
reverse("NodeNICsHandler",
kwargs={"node_id": self.env.nodes[0]["id"]}),
headers=self.default_headers)
self.assertEquals(resp.status_code, 200)
self.data = json.loads(resp.body)
self.admin_nic, self.other_nic, self.empty_nic = None, None, None
for nic in self.data:
net_names = [n["name"] for n in nic["assigned_networks"]]
if "fuelweb_admin" in net_names:
self.admin_nic = nic
elif net_names:
self.other_nic = nic
else:
self.empty_nic = nic
self.assertTrue(self.admin_nic and self.other_nic and self.empty_nic)
def put_single(self):
return self.env.node_nics_put(self.env.nodes[0]["id"], self.data,
expect_errors=True)
def put_collection(self):
nodes_list = [{"id": self.env.nodes[0]["id"],
"interfaces": self.data}]
return self.env.node_collection_nics_put(nodes_list,
expect_errors=True)
def node_nics_put_check_error(self, message):
for put_func in (self.put_single, self.put_collection):
resp = put_func()
self.assertEquals(resp.status_code, 400)
self.assertEquals(resp.body, message)
def nics_bond_create(self, put_func):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
resp = put_func()
self.assertEquals(resp.status_code, 200)
resp = self.env.node_nics_get(self.env.nodes[0]["id"])
self.assertEquals(resp.status_code, 200)
data = json.loads(resp.body)
bonds = filter(
lambda iface: iface["type"] == NETWORK_INTERFACE_TYPES.bond,
data)
self.assertEquals(len(bonds), 1)
self.assertEqual(bonds[0]["name"], 'ovs-bond0')
def nics_bond_remove(self, put_func):
resp = self.env.node_nics_get(self.env.nodes[0]["id"])
self.assertEquals(resp.status_code, 200)
self.data = json.loads(resp.body)
for nic in self.data:
if nic["type"] == NETWORK_INTERFACE_TYPES.bond:
bond = nic
break
else:
raise Exception("No bond was found unexpectedly")
for nic in self.data:
if nic["name"] == bond["slaves"][0]["name"]:
nic["assigned_networks"] = bond["assigned_networks"]
break
else:
raise Exception("NIC from bond wasn't found unexpectedly")
self.data.remove(bond)
resp = put_func()
self.assertEquals(resp.status_code, 200)
def test_nics_bond_delete(self):
for put_func in (self.put_single, self.put_collection):
self.get_node_nics_info()
self.nics_bond_create(put_func)
self.nics_bond_remove(put_func)
resp = self.env.node_nics_get(self.env.nodes[0]["id"])
self.assertEquals(resp.status_code, 200)
data = json.loads(resp.body)
for nic in data:
self.assertNotEqual(nic["type"], NETWORK_INTERFACE_TYPES.bond)
def test_nics_bond_create_failed_no_type(self):
self.data.append({
"name": 'ovs-bond0'
})
self.node_nics_put_check_error(
"Node '{0}': each interface must have a "
"type".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_not_have_enough_data(self):
self.data.append({
"type": NETWORK_INTERFACE_TYPES.bond
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': each bond interface must have "
"name".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_unknown_mode(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": "unknown",
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': bond interface 'ovs-bond0' has unknown mode "
"'unknown'".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_no_mode(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': each bond interface must have "
"mode".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_no_slaves(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': each bond interface must have "
"two or more slaves".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_one_slave(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': each bond interface must have "
"two or more slaves".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_no_assigned_networks(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}', interface 'ovs-bond0': there is no "
"'assigned_networks' list".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_nic_is_used_twice(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.other_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': interface '{1}' is used in bonds more "
"than once".format(self.env.nodes[0]["id"], self.other_nic["id"]))
def test_nics_bond_create_failed_duplicated_assigned_networks(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.node_nics_put_check_error(
"Node '{0}': there is a duplicated network '{1}' in "
"assigned networks (second occurrence is in interface "
"'ovs-bond0')".format(
self.env.nodes[0]["id"],
self.other_nic["assigned_networks"][0]["id"]))
def test_nics_bond_create_failed_unknown_interface(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": "some_nic"}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}': there is no interface 'some_nic' found for bond "
"'ovs-bond0' in DB".format(self.env.nodes[0]["id"]))
def test_nics_bond_create_failed_slave_has_assigned_networks(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"name": self.empty_nic["name"]}],
"assigned_networks": []
})
self.node_nics_put_check_error(
"Node '{0}': interface '{1}' cannot have assigned networks as it "
"is used in bond".format(self.env.nodes[0]["id"],
self.other_nic["id"]))
def test_nics_bond_create_failed_slave_has_no_name(self):
self.data.append({
"name": 'ovs-bond0',
"type": NETWORK_INTERFACE_TYPES.bond,
"mode": OVS_BOND_MODES.balance_slb,
"slaves": [
{"name": self.other_nic["name"]},
{"nic": self.empty_nic["name"]}],
"assigned_networks": self.other_nic["assigned_networks"]
})
self.other_nic["assigned_networks"] = []
self.node_nics_put_check_error(
"Node '{0}', interface 'ovs-bond0': each bond slave "
"must have name".format(self.env.nodes[0]["id"]))