package org.ovirt.engine.core.bll.network;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.ovirt.engine.core.utils.MockConfigRule.mockConfig;
import java.util.Collection;
import java.util.Map;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.ovirt.engine.core.bll.context.CommandContext;
import org.ovirt.engine.core.bll.interfaces.BackendInternal;
import org.ovirt.engine.core.bll.network.NetworkConfigurator.NetworkConfiguratorException;
import org.ovirt.engine.core.bll.network.cluster.ManagementNetworkUtil;
import org.ovirt.engine.core.common.AuditLogType;
import org.ovirt.engine.core.common.action.HostSetupNetworksParameters;
import org.ovirt.engine.core.common.action.VdcActionType;
import org.ovirt.engine.core.common.action.VdcReturnValueBase;
import org.ovirt.engine.core.common.action.VdsActionParameters;
import org.ovirt.engine.core.common.businessentities.VDS;
import org.ovirt.engine.core.common.businessentities.network.IPv4Address;
import org.ovirt.engine.core.common.businessentities.network.IpConfiguration;
import org.ovirt.engine.core.common.businessentities.network.IpV6Address;
import org.ovirt.engine.core.common.businessentities.network.Ipv4BootProtocol;
import org.ovirt.engine.core.common.businessentities.network.Ipv6BootProtocol;
import org.ovirt.engine.core.common.businessentities.network.Network;
import org.ovirt.engine.core.common.businessentities.network.VdsNetworkInterface;
import org.ovirt.engine.core.common.config.ConfigValues;
import org.ovirt.engine.core.compat.Guid;
import org.ovirt.engine.core.compat.Version;
import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogable;
import org.ovirt.engine.core.di.InjectorRule;
import org.ovirt.engine.core.utils.MockConfigRule;
@RunWith(MockitoJUnitRunner.class)
public class NetworkConfiguratorTest {
private static final String NETWORK_NAME1 = "networkName";
private static final String NETWORK_NAME2 = "not" + NETWORK_NAME1;
private static final String IPV4_ADDRESS = "ipv4 address";
private static final String IPV4_GATEWAY = "ipv4 gateway";
private static final String IPV4_SUBNET = "ipv4 subnet";
private static final String IPV6_ADDRESS = "ipv6 address";
private static final String IPV6_GATEWAY = "ipv6 gateway";
private static final int IPV6_PREFIX = 666;
private static final CommandContext COMMAND_CONTEXT = CommandContext.createContext("context");
private static final Guid MANAGEMENT_NETWORK_ID = Guid.newGuid();
private static final Guid CLUSTER_ID = Guid.newGuid();
private static final String NIC_NAME = "nic name";
private static final String MANAGEMENT_NETWORK_NAME = "management network name";
private static final int NIC_VLAN_ID = 666;
private static final int MANAGMENT_NETWORK_VLAN_ID = 777;
private static final String HOST_NAME = "host name";
@Rule
public InjectorRule injectorRule = new InjectorRule();
@Rule
public MockConfigRule mcr = new MockConfigRule(
mockConfig(ConfigValues.Ipv6Supported, Version.v3_6, false),
mockConfig(ConfigValues.Ipv6Supported, Version.v4_0, true));
@Mock
private ManagementNetworkUtil mockManagementNetworkUtil;
@Mock
private BackendInternal backend;
@Mock
private AuditLogDirector auditLogDirector;
@Captor
private ArgumentCaptor<AuditLogable> auditLogableArgumentCaptor;
private VDS host;
private VdsNetworkInterface nic = new VdsNetworkInterface();
private Network managementNetwork = new Network();
private NetworkConfigurator underTest;
@Before
public void setUp() {
injectorRule.bind(ManagementNetworkUtil.class, mockManagementNetworkUtil);
managementNetwork.setId(MANAGEMENT_NETWORK_ID);
managementNetwork.setName(MANAGEMENT_NETWORK_NAME);
when(mockManagementNetworkUtil.getManagementNetwork(CLUSTER_ID)).thenReturn(managementNetwork);
nic.setNetworkName(NETWORK_NAME1);
nic.setName(NIC_NAME);
host = new VDS();
host.setVdsName(HOST_NAME);
host.setClusterId(CLUSTER_ID);
host.setClusterCompatibilityVersion(Version.v4_0);
host.getInterfaces().add(nic);
underTest = new NetworkConfigurator(host, COMMAND_CONTEXT, auditLogDirector);
}
@Test
public void getIpv4AddressOfNetwork() {
setIpv4Details(nic);
assertThat(underTest.getIpv4AddressOfNetwork(NETWORK_NAME1), is(IPV4_ADDRESS));
}
@Test
public void getIpv6AddressOfNetwork() {
setIpv6Details(nic);
assertThat(underTest.getIpv6AddressOfNetwork(NETWORK_NAME1), is(IPV6_ADDRESS));
}
@Test
public void getIpv4AddressOfNetworkReturnsNullWhenThereIsNoIpSet() {
assertThat(underTest.getIpv4AddressOfNetwork(NETWORK_NAME1), nullValue());
}
@Test
public void getIpv6AddressOfNetworkReturnsNullWhenThereIsNoIpSet() {
assertThat(underTest.getIpv6AddressOfNetwork(NETWORK_NAME1), nullValue());
}
@Test
public void getIpv4AddressOfNetworkReturnsNullWhenThereIsNoNetworkOfGivenName() {
nic.setIpv4Address(IPV4_ADDRESS);
assertThat(underTest.getIpv4AddressOfNetwork(NETWORK_NAME2), nullValue());
}
@Test
public void getIpv6AddressOfNetworkReturnsNullWhenThereIsNoNetworkOfGivenName() {
nic.setIpv6Address(IPV6_ADDRESS);
assertThat(underTest.getIpv6AddressOfNetwork(NETWORK_NAME2), nullValue());
}
@Test
public void createSetupNetworkParamsInLegacyCluster() {
createSetupNetworkParamsTest(Version.v3_6, empty());
}
@Test
public void createSetupNetworkParamsInNewCluster() {
final IpConfiguration actual =
createSetupNetworkParamsTest(Version.v4_0, hasSize(1));
assertIpv6Details(actual);
}
@Test
public void testCreateManagementNetworkIfRequiredFailedOnSetupNetworks() {
host.setActiveNic(NIC_NAME);
final NetworkConfigurator spiedUnderTest = spy(underTest);
doReturn(backend).when(spiedUnderTest).getBackend();
when(backend.runInternalAction(
eq(VdcActionType.HostSetupNetworks),
any(HostSetupNetworksParameters.class),
any(CommandContext.class)))
.thenReturn(createReturnValue(false));
verifyAuditLoggableBaseFilledProperly(
spiedUnderTest,
AuditLogType.SETUP_NETWORK_FAILED_FOR_MANAGEMENT_NETWORK_CONFIGURATION);
}
@Test
public void testCreateManagementNetworkIfRequiredFailedOnCommitNetworkChanges() {
host.setActiveNic(NIC_NAME);
final NetworkConfigurator spiedUnderTest = spy(underTest);
doReturn(backend).when(spiedUnderTest).getBackend();
when(backend.runInternalAction(
eq(VdcActionType.HostSetupNetworks),
any(HostSetupNetworksParameters.class),
any(CommandContext.class)))
.thenReturn(createReturnValue(true));
when(backend.runInternalAction(
eq(VdcActionType.CommitNetworkChanges),
any(VdsActionParameters.class),
any(CommandContext.class)))
.thenReturn(createReturnValue(false));
verifyAuditLoggableBaseFilledProperly(
spiedUnderTest,
AuditLogType.PERSIST_NETWORK_FAILED_FOR_MANAGEMENT_NETWORK);
}
@Test
public void testCreateManagementNetworkIfRequiredFailsOnDifferentVlanId() {
host.setActiveNic(NIC_NAME);
nic.setVlanId(NIC_VLAN_ID);
managementNetwork.setVlanId(MANAGMENT_NETWORK_VLAN_ID);
final Map<String, String> capturedCustomValues = verifyAuditLoggableBaseFilledProperly(
underTest,
AuditLogType.VLAN_ID_MISMATCH_FOR_MANAGEMENT_NETWORK_CONFIGURATION);
assertThat(capturedCustomValues, allOf(
hasEntry("vlanid", String.valueOf(NIC_VLAN_ID)),
hasEntry("mgmtvlanid", String.valueOf(MANAGMENT_NETWORK_VLAN_ID)),
hasEntry("interfacename", NIC_NAME)));
}
private Map<String, String> verifyAuditLoggableBaseFilledProperly(NetworkConfigurator underTest, AuditLogType auditLogType) {
try {
underTest.createManagementNetworkIfRequired();
} catch (NetworkConfiguratorException e) {
verify(auditLogDirector).log(
auditLogableArgumentCaptor.capture(),
eq(auditLogType));
final AuditLogable capturedEvent = auditLogableArgumentCaptor.getValue();
assertThat(capturedEvent.getVdsName(), is(HOST_NAME));
return capturedEvent.getCustomValues();
}
fail("The test should lead to NetworkConfiguratorException");
return null;
}
private VdcReturnValueBase createReturnValue(boolean succeed) {
final VdcReturnValueBase setupNetsReturnValue = new VdcReturnValueBase();
setupNetsReturnValue.setSucceeded(succeed);
return setupNetsReturnValue;
}
private IpConfiguration createSetupNetworkParamsTest(
Version clusterVersion,
Matcher<Collection<? extends IpV6Address>> ipv6AddressMatcher) {
setIpDetails(nic);
host.setClusterCompatibilityVersion(clusterVersion);
final HostSetupNetworksParameters actual = underTest.createSetupNetworkParams(nic);
assertThat(actual.getNetworkAttachments(), hasSize(1));
final IpConfiguration ipConfiguration = actual.getNetworkAttachments().get(0).getIpConfiguration();
assertIpv4Details(ipConfiguration);
assertThat(ipConfiguration.getIpV6Addresses(), ipv6AddressMatcher);
return ipConfiguration;
}
private void assertIpv4Details(IpConfiguration ipConfiguration) {
assertThat(ipConfiguration.getIPv4Addresses(), hasSize(1));
final IPv4Address ipv4Address = ipConfiguration.getIPv4Addresses().get(0);
assertThat(ipv4Address.getAddress(), is(IPV4_ADDRESS));
assertThat(ipv4Address.getBootProtocol(), is(Ipv4BootProtocol.STATIC_IP));
assertThat(ipv4Address.getAddress(), is(IPV4_ADDRESS));
}
private void assertIpv6Details(IpConfiguration ipConfiguration) {
assertThat(ipConfiguration.getIpV6Addresses(), hasSize(1));
final IpV6Address ipv6Address = ipConfiguration.getIpV6Addresses().get(0);
assertThat(ipv6Address.getAddress(), is(IPV6_ADDRESS));
assertThat(ipv6Address.getBootProtocol(), is(Ipv6BootProtocol.STATIC_IP));
assertThat(ipv6Address.getAddress(), is(IPV6_ADDRESS));
}
private void setIpDetails(VdsNetworkInterface nic) {
setIpv4Details(nic);
setIpv6Details(nic);
}
private void setIpv4Details(VdsNetworkInterface nic) {
nic.setIpv4Address(IPV4_ADDRESS);
nic.setIpv4BootProtocol(Ipv4BootProtocol.STATIC_IP);
nic.setIpv4Gateway(IPV4_GATEWAY);
nic.setIpv4Subnet(IPV4_SUBNET);
}
private void setIpv6Details(VdsNetworkInterface nic) {
nic.setIpv6Address(IPV6_ADDRESS);
nic.setIpv6BootProtocol(Ipv6BootProtocol.STATIC_IP);
nic.setIpv6Gateway(IPV6_GATEWAY);
nic.setIpv6Prefix(IPV6_PREFIX);
}
}