2 * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.utils.netvirt.it.utils;
11 import java.io.IOException;
12 import java.util.HashMap;
14 import java.util.UUID;
15 import org.junit.Assert;
16 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
17 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSubnet;
20 import org.opendaylight.netvirt.utils.neutron.utils.NeutronUtils;
21 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
22 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25 * A utility class used in integration tests that need to create neutron networks with some ports.
26 * Please see NetvirtIT#testNeutronNet for an example of how this class is used
28 public class NeutronNetItUtil {
30 public final String tenantId;
31 public final String id;
32 public final String subnetId;
33 public NeutronNetwork neutronNetwork;
34 public NeutronSubnet neutronSubnet;
35 public String segId = "100";
40 public SouthboundUtils southboundUtils;
41 public NeutronUtils neutronUtils;
44 * Information about a port created using createPort() - fields should be pretty self explanatory
46 public class PortInfo {
47 public PortInfo(String name, long ofPort) {
50 this.ip = ipFor(ofPort);
51 this.mac = macFor(ofPort);
55 public NeutronPort neutronPort;
62 * Maps port names (the ones you pass in to createPort() to their PortInfo objects
64 public Map<String, PortInfo> portInfoByName = new HashMap<>();
67 * Construct a new NeutronNetItUtil.
68 * @param southboundUtils used to create termination points
69 * @param tenantId tenant ID
71 public NeutronNetItUtil(SouthboundUtils southboundUtils, String tenantId) {
72 this(southboundUtils, tenantId, "101", "f4:00:00:0f:00:", "10.0.0.", "10.0.0.0/24");
76 * Construct a new NeutronNetItUtil.
77 * @param southboundUtils used to create termination points
78 * @param tenantId tenant ID
79 * @param segId the segmentation id to use for the neutron network
80 * @param macPfx the first characters of the mac addresses generated for ports. Format is "f7:00:00:0f:00:"
81 * @param ipPfx the first characters of the ip addresses generated for ports. Format is "10.0.0."
82 * @param cidr the cidr for this network, e.g., "10.0.0.0/24"
84 public NeutronNetItUtil(SouthboundUtils southboundUtils, String tenantId,
85 String segId, String macPfx, String ipPfx, String cidr) {
86 this.tenantId = tenantId;
92 this.id = UUID.randomUUID().toString();
93 this.subnetId = UUID.randomUUID().toString();
95 this.southboundUtils = southboundUtils;
96 neutronUtils = new NeutronUtils();
97 neutronNetwork = null;
102 * Create the network and subnet.
104 public void create() {
105 neutronNetwork = neutronUtils.createNeutronNetwork(id, tenantId, "vxlan", segId);
106 neutronSubnet = neutronUtils.createNeutronSubnet(subnetId, tenantId, id, "10.0.0.0/24");
110 * Clean up all created neutron objects.
112 public void destroy() {
113 for (PortInfo portInfo : portInfoByName.values()) {
114 neutronUtils.removeNeutronPort(portInfo.neutronPort.getID());
116 //TODO: probably more polite to clean up everything else as well...
117 //TODO: for now just assume that the docker image will be recreated
118 //TODO: before each test
119 portInfoByName.clear();
121 if (neutronSubnet != null) {
122 neutronUtils.removeNeutronSubnet(neutronSubnet.getID());
123 neutronSubnet = null;
126 if (neutronNetwork != null) {
127 neutronUtils.removeNeutronNetwork(neutronNetwork.getID());
128 neutronNetwork = null;
133 * Create a port on the network. The deviceOwner will be set to "compute:None".
134 * @param bridge bridge where the port will be created on OVS
135 * @param portName name for this port
136 * @throws InterruptedException if we're interrupted while waiting for objects to be created
138 public void createPort(Node bridge, String portName) throws InterruptedException, IOException {
139 createPort(bridge, portName, "compute:None");
143 * Create a port on the network. The deviceOwner will be set to "compute:None".
144 * @param bridge bridge where the port will be created on OVS
145 * @param portName name for this port
146 * @param owner deviceOwner, e.g., "network:dhcp"
147 * @param secGroups Optional NeutronSecurityGroup objects see NeutronUtils.createNeutronSecurityGroup()
148 * @throws InterruptedException if we're interrupted while waiting for objects to be created
150 public void createPort(Node bridge, String portName, String owner, NeutronSecurityGroup... secGroups)
151 throws InterruptedException, IOException {
152 PortInfo portInfo = buildPortInfo(portName);
153 doCreatePort(bridge, portInfo, owner, "internal", secGroups);
156 protected PortInfo buildPortInfo(String portName) {
157 Assert.assertFalse("Can't have two ports with the same name", portInfoByName.containsKey(portName));
159 long idx = portInfoByName.size() + 1;
160 Assert.assertTrue(idx < 256);
161 return new PortInfo(portName, idx);
164 protected void doCreatePort(Node bridge, PortInfo portInfo, String owner,
165 String portType, NeutronSecurityGroup ... secGroups) throws InterruptedException {
167 String portId = UUID.randomUUID().toString();
168 portInfo.neutronPort = neutronUtils.createNeutronPort(
169 id, subnetId, portId, owner, portInfo.ip, portInfo.mac, secGroups);
171 //TBD: Use NotifyingDataChangeListener
174 Map<String, String> externalIds = new HashMap<>();
175 externalIds.put("attached-mac", portInfo.mac);
176 externalIds.put("iface-id", portId);
177 southboundUtils.addTerminationPoint(bridge, portInfo.name, portType, null, externalIds, portInfo.ofPort);
179 portInfoByName.put(portInfo.name, portInfo);
183 * Get the mac address for the n'th port created on this network (starts at 1).
184 * @param portNum index of port created
185 * @return the mac address
187 public String macFor(long portNum) {
188 return macPfx + String.format("%02x", 5 - portNum);
192 * Get the ip address for the n'th port created on this network (starts at 1).
193 * @param portNum index of port created
194 * @return the mac address
196 public String ipFor(long portNum) {
197 return ipPfx + portNum;