93844d0a695d778d5696322f781fe0b4e003e035
[netvirt.git] / utils / netvirt-it-utils / src / main / java / org / opendaylight / netvirt / utils / netvirt / it / utils / NeutronNetItUtil.java
1 /*
2  * Copyright (c) 2016 Red Hat, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netvirt.utils.netvirt.it.utils;
10
11 import java.io.IOException;
12 import java.util.HashMap;
13 import java.util.Map;
14 import java.util.UUID;
15
16 import com.google.common.collect.Maps;
17 import org.junit.Assert;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
20 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
21 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSubnet;
22 import org.opendaylight.netvirt.utils.neutron.utils.NeutronUtils;
23 import org.opendaylight.ovsdb.utils.southbound.utils.SouthboundUtils;
24 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
25
26 /**
27  * A utility class used in integration tests that need to create neutron networks with some ports.
28  * Please see NetvirtIT#testNeutronNet for an example of how this class is used
29  */
30 public class NeutronNetItUtil {
31
32     public final String tenantId;
33     public final String id;
34     public final String subnetId;
35     public NeutronNetwork neutronNetwork;
36     public NeutronSubnet neutronSubnet;
37     public String segId = "100";
38     public String macPfx;
39     public String ipPfx;
40     public String cidr;
41
42     public SouthboundUtils southboundUtils;
43     public NeutronUtils neutronUtils;
44
45     /**
46      * Information about a port created using createPort() - fields should be pretty self explanatory
47      */
48     public class PortInfo {
49         public PortInfo(String name, long ofPort) {
50             this.name = name;
51             this.ofPort = ofPort;
52             this.ip = ipFor(ofPort);
53             this.mac = macFor(ofPort);
54         }
55
56         public String name;
57         public NeutronPort neutronPort;
58         public String ip;
59         public String mac;
60         public long ofPort;
61     }
62
63     /**
64      * Maps port names (the ones you pass in to createPort() to their PortInfo objects
65      */
66     public Map<String, PortInfo> portInfoByName = new HashMap<String, PortInfo>();
67
68     /**
69      * Construct a new NeutronNetItUtil.
70      * @param southboundUtils used to create termination points
71      * @param tenantId tenant ID
72      */
73     public NeutronNetItUtil(SouthboundUtils southboundUtils, String tenantId) {
74         this(southboundUtils, tenantId, "101", "f4:00:00:0f:00:", "10.0.0.", "10.0.0.0/24");
75     }
76
77     /**
78      * Construct a new NeutronNetItUtil.
79      * @param southboundUtils used to create termination points
80      * @param tenantId tenant ID
81      * @param segId the segmentation id to use for the neutron network
82      * @param macPfx the first characters of the mac addresses generated for ports. Format is "f7:00:00:0f:00:"
83      * @param ipPfx the first characters of the ip addresses generated for ports. Format is "10.0.0."
84      * @param cidr the cidr for this network, e.g., "10.0.0.0/24"
85      */
86     public NeutronNetItUtil(SouthboundUtils southboundUtils, String tenantId,
87                             String segId, String macPfx, String ipPfx, String cidr) {
88         this.tenantId = tenantId;
89         this.segId = segId;
90         this.macPfx = macPfx;
91         this.ipPfx = ipPfx;
92         this.cidr = cidr;
93
94         this.id = UUID.randomUUID().toString();
95         this.subnetId = UUID.randomUUID().toString();
96
97         this.southboundUtils = southboundUtils;
98         neutronUtils = new NeutronUtils();
99         neutronNetwork = null;
100         neutronSubnet = null;
101     }
102
103     /**
104      * Create the network and subnet.
105      */
106     public void create() {
107         neutronNetwork = neutronUtils.createNeutronNetwork(id, tenantId, "vxlan", segId);
108         neutronSubnet = neutronUtils.createNeutronSubnet(subnetId, tenantId, id, "10.0.0.0/24");
109     }
110
111     /**
112      * Clean up all created neutron objects.
113      */
114     public void destroy() {
115         for (PortInfo portInfo : portInfoByName.values()) {
116             neutronUtils.removeNeutronPort(portInfo.neutronPort.getID());
117         }
118         //TODO: probably more polite to clean up everything else as well...
119         //TODO: for now just assume that the docker image will be recreated
120         //TODO: before each test
121         portInfoByName.clear();
122
123         if (neutronSubnet != null) {
124             neutronUtils.removeNeutronSubnet(neutronSubnet.getID());
125             neutronSubnet = null;
126         }
127
128         if (neutronNetwork != null) {
129             neutronUtils.removeNeutronNetwork(neutronNetwork.getID());
130             neutronNetwork = null;
131         }
132     }
133
134     /**
135      * Create a port on the network. The deviceOwner will be set to "compute:None".
136      * @param bridge bridge where the port will be created on OVS
137      * @param portName name for this port
138      * @throws InterruptedException if we're interrupted while waiting for objects to be created
139      */
140     public void createPort(Node bridge, String portName) throws InterruptedException, IOException {
141         createPort(bridge, portName, "compute:None");
142     }
143
144     /**
145      * Create a port on the network. The deviceOwner will be set to "compute:None".
146      * @param bridge bridge where the port will be created on OVS
147      * @param portName name for this port
148      * @param owner deviceOwner, e.g., "network:dhcp"
149      * @param secGroups Optional NeutronSecurityGroup objects see NeutronUtils.createNeutronSecurityGroup()
150      * @throws InterruptedException if we're interrupted while waiting for objects to be created
151      */
152     public void createPort(Node bridge, String portName, String owner, NeutronSecurityGroup... secGroups)
153                                                                             throws InterruptedException, IOException {
154         PortInfo portInfo = buildPortInfo(portName);
155         doCreatePort(bridge, portInfo, owner, "internal", secGroups);
156     }
157
158     protected PortInfo buildPortInfo(String portName) {
159         Assert.assertFalse("Can't have two ports with the same name", portInfoByName.containsKey(portName));
160
161         long idx = portInfoByName.size() + 1;
162         Assert.assertTrue(idx < 256);
163         return new PortInfo(portName, idx);
164     }
165
166     protected void doCreatePort(Node bridge, PortInfo portInfo, String owner,
167                                 String portType, NeutronSecurityGroup ... secGroups) throws InterruptedException {
168
169         String portId = UUID.randomUUID().toString();
170         portInfo.neutronPort = neutronUtils.createNeutronPort(
171                 id, subnetId, portId, owner, portInfo.ip, portInfo.mac, secGroups);
172
173         //TBD: Use NotifyingDataChangeListener
174         Thread.sleep(1000);
175
176         Map<String, String> externalIds = Maps.newHashMap();
177         externalIds.put("attached-mac", portInfo.mac);
178         externalIds.put("iface-id", portId);
179         southboundUtils.addTerminationPoint(bridge, portInfo.name, portType, null, externalIds, portInfo.ofPort);
180
181         portInfoByName.put(portInfo.name, portInfo);
182     }
183
184     /**
185      * Get the mac address for the n'th port created on this network (starts at 1).
186      * @param portNum index of port created
187      * @return the mac address
188      */
189     public String macFor(long portNum) {
190         return macPfx + String.format("%02x", 5 - portNum);
191     }
192
193     /**
194      * Get the ip address for the n'th port created on this network (starts at 1).
195      * @param portNum index of port created
196      * @return the mac address
197      */
198     public String ipFor(long portNum) {
199         return ipPfx + portNum;
200     }
201 }
202