Skip to content

Commit 1d2fd10

Browse files
OSPF: Adding dynamically routing capability to VPC by configuring quagga
on VR . Added zone level quagga/ospf config API and UI as addtional tab on zone . Added service offering with ospf . Added service offering for the tier guest network for VPC . Modified system vm template so that quagga is pre-installed . Added various configuration files that are required by Quagga . Added marvin tests for new APIs and unit test . Send quagga config from the server if VPC and tier are dynamically routed . Configure quagga when a VM of the tier is created/destroyed . Added necessary scritps on the vpc router to enable and configure quagga and iptable rules . Multiple Cidr management and netmask based cidr allocation . Added unit tests for cidr management . New dialog for create dynamic VPC and netmask as a field . Marvin tests to test dynmaic vpc service offering . Marvin tests to test dynamic network offering . Converting String based CIDR representation to InetAddress and mask based CIDR object representation that is implemented for ipv4 and with ipv6 placeholder.
1 parent d518b61 commit 1d2fd10

File tree

87 files changed

+4318
-814
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+4318
-814
lines changed

api/src/com/cloud/dc/DataCenter.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,4 +81,6 @@ public enum NetworkType {
8181
String getZoneToken();
8282

8383
boolean isLocalStorageEnabled();
84+
85+
boolean isDynamicRoutingEnabled();
8486
}

api/src/com/cloud/network/Network.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public static class Service {
5959
public static final Service SecurityGroup = new Service("SecurityGroup");
6060
public static final Service NetworkACL = new Service("NetworkACL", Capability.SupportedProtocols);
6161
public static final Service Connectivity = new Service("Connectivity", Capability.DistributedRouter, Capability.RegionLevelVpc, Capability.StretchedL2Subnet);
62+
public static final Service VPCDynamicRouting = new Service("VPCDynamicRouting");
6263

6364
private final String name;
6465
private final Capability[] caps;
@@ -213,6 +214,7 @@ public static class Capability {
213214
public static final Capability DistributedRouter = new Capability("DistributedRouter");
214215
public static final Capability StretchedL2Subnet = new Capability("StretchedL2Subnet");
215216
public static final Capability RegionLevelVpc = new Capability("RegionLevelVpc");
217+
public static final Capability VPCDynamicRouting = new Capability("VPCDynamicRouting");
216218

217219
private final String name;
218220

@@ -241,9 +243,9 @@ enum Event {
241243

242244
public enum State {
243245

244-
Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"), Implementing(
245-
"Indicates the network configuration is being implemented"), Implemented("Indicates the network configuration is in use"), Shutdown(
246-
"Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed");
246+
Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"),
247+
Implementing("Indicates the network configuration is being implemented"), Implemented("Indicates the network configuration is in use"),
248+
Shutdown("Indicates the network configuration is being destroyed"), Destroy("Indicates that the network is destroyed");
247249

248250
protected static final StateMachine2<State, Network.Event, Network> s_fsm = new StateMachine2<State, Network.Event, Network>();
249251

api/src/com/cloud/network/PhysicalNetworkServiceProvider.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,6 @@ public enum State {
6767
String getUuid();
6868

6969
boolean isNetworkAclServiceProvided();
70+
71+
boolean isDynamicRoutingProvided();
7072
}
Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
// Licensed to the Apache Software Foundation (ASF) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The ASF licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package com.cloud.network.vpc;
19+
20+
import java.util.Arrays;
21+
import java.util.HashMap;
22+
import java.util.Map;
23+
24+
import org.apache.commons.lang.ArrayUtils;
25+
import org.apache.commons.lang.StringUtils;
26+
27+
import com.cloud.exception.InvalidParameterValueException;
28+
import com.cloud.utils.net.NetUtils;
29+
import com.cloud.utils.net.cidr.BadCIDRException;
30+
import com.cloud.utils.net.cidr.CIDR;
31+
32+
public class OSPFZoneConfig {
33+
34+
private long zoneId;
35+
private Protocol protocol;
36+
private String ospfArea;
37+
private Short helloInterval;
38+
private Short deadInterval;
39+
private Short retransmitInterval;
40+
private Short transitDelay;
41+
private Authentication authentication;
42+
private String password;
43+
private CIDR[] superCIDRList;
44+
private Boolean enabled;
45+
46+
public static final String s_protocol = "protocol";
47+
public static final String s_area = "area";
48+
public static final String s_helloInterval = "hellointerval";
49+
public static final String s_deadInterval = "deadinterval";
50+
public static final String s_retransmitInterval = "retransmitinterval";
51+
public static final String s_transitDelay = "transitdelay";
52+
public static final String s_authentication = "authentication";
53+
public static final String s_superCIDR = "supercidr";
54+
public static final String s_password = "password";
55+
public static final String s_enabled = "enabled";
56+
57+
public Protocol getProtocol() {
58+
return protocol;
59+
}
60+
61+
public void setProtocol(Protocol protocol) {
62+
this.protocol = protocol;
63+
}
64+
65+
public String getOspfArea() {
66+
return ospfArea;
67+
}
68+
69+
public void setOspfArea(String ospfArea) {
70+
this.ospfArea = ospfArea;
71+
}
72+
73+
public Short getHelloInterval() {
74+
return helloInterval;
75+
}
76+
77+
public void setHelloInterval(Short helloInterval) {
78+
this.helloInterval = helloInterval;
79+
}
80+
81+
public Short getDeadInterval() {
82+
return deadInterval;
83+
}
84+
85+
public void setDeadInterval(Short deadInterval) {
86+
this.deadInterval = deadInterval;
87+
}
88+
89+
public Short getRetransmitInterval() {
90+
return retransmitInterval;
91+
}
92+
93+
public void setRetransmitInterval(Short retransmitInterval) {
94+
this.retransmitInterval = retransmitInterval;
95+
}
96+
97+
public Short getTransitDelay() {
98+
return transitDelay;
99+
}
100+
101+
public void setTransitDelay(Short transitDelay) {
102+
this.transitDelay = transitDelay;
103+
}
104+
105+
public Authentication getAuthentication() {
106+
return authentication;
107+
}
108+
109+
public void setAuthentication(Authentication authentication) {
110+
this.authentication = authentication;
111+
}
112+
113+
public String getPassword() {
114+
return password;
115+
}
116+
117+
public void setPassword(String password) {
118+
this.password = password;
119+
}
120+
121+
public CIDR[] getSuperCIDR() {
122+
return superCIDRList;
123+
}
124+
125+
public void setSuperCIDR(CIDR[] superCIDR) {
126+
this.superCIDRList = superCIDR;
127+
}
128+
129+
public Boolean getEnabled() {
130+
return enabled;
131+
}
132+
133+
public void setEnabled(Boolean enabled) {
134+
this.enabled = enabled;
135+
}
136+
137+
public enum Params {
138+
PROTOCOL, AREA, HELLO_INTERVAL, DEAD_INTERVAL, RETRANSMIT_INTERVAL, TRANSIT_DELAY, AUTHENTICATION, SUPER_CIDR, PASSWORD, ENABLED
139+
}
140+
141+
public enum Protocol {
142+
OSPF
143+
}
144+
145+
public enum Authentication {
146+
MD5, PLAIN_TEXT
147+
}
148+
149+
public OSPFZoneConfig() {
150+
}
151+
152+
public void setDefaultValues(final Map<String, String> details) throws BadCIDRException {
153+
this.protocol = details.get(Params.PROTOCOL.name()) == null ? Protocol.OSPF : Protocol.valueOf(details.get(Params.PROTOCOL.name()));
154+
this.ospfArea = details.get(Params.AREA.name()) == null ? "0" : details.get(Params.AREA.name());
155+
this.helloInterval = Short.valueOf(details.get(Params.HELLO_INTERVAL.name()) == null ? "10" : details.get(Params.HELLO_INTERVAL.name()));
156+
this.deadInterval = Short.valueOf(details.get(Params.DEAD_INTERVAL.name()) == null ? "40" : details.get(Params.DEAD_INTERVAL.name()));
157+
this.retransmitInterval = Short.valueOf(details.get(Params.RETRANSMIT_INTERVAL.name()) == null ? "5" : details.get(Params.RETRANSMIT_INTERVAL.name()));
158+
this.transitDelay = Short.valueOf(details.get(Params.TRANSIT_DELAY.name()) == null ? "1" : details.get(Params.TRANSIT_DELAY.name()));
159+
this.authentication = details.get(Params.AUTHENTICATION.name()) == null ? Authentication.MD5 : Authentication.valueOf(details.get(Params.AUTHENTICATION.name()));
160+
this.password = details.get(Params.PASSWORD.name()) == null ? "" : details.get(Params.PASSWORD.name());
161+
this.superCIDRList = details.get(Params.SUPER_CIDR.name()) == null ? new CIDR[0] : NetUtils.convertToCIDR(details.get(Params.SUPER_CIDR.name()).split(","));
162+
this.enabled = details.get(Params.ENABLED.name()) == null ? Boolean.FALSE : Boolean.valueOf(details.get(Params.ENABLED.name()));
163+
}
164+
165+
public void setValues(final String protocol, final String ospfArea, final Short helloInterval, final Short deadInterval, final Short retransmitInterval,
166+
final Short transitDelay, final String authentication, final String quaggaPassword, final String superCIDRList, final Boolean enabled) throws BadCIDRException {
167+
if (protocol != null) {
168+
if ((Protocol.OSPF.name().equals(protocol))) {
169+
this.protocol = Protocol.valueOf(protocol);
170+
} else {
171+
throw new InvalidParameterValueException("The quagga protocal can have values of OSPF only " + protocol);
172+
}
173+
}
174+
if (ospfArea != null) {
175+
this.ospfArea = ospfArea;
176+
}
177+
if (helloInterval != null) {
178+
this.helloInterval = helloInterval;
179+
}
180+
if (deadInterval != null) {
181+
this.deadInterval = deadInterval;
182+
}
183+
if (retransmitInterval != null) {
184+
this.retransmitInterval = retransmitInterval;
185+
}
186+
if (transitDelay != null) {
187+
this.transitDelay = transitDelay;
188+
}
189+
if (authentication != null) {
190+
if (Authentication.MD5.name().equals(authentication) || Authentication.PLAIN_TEXT.name().equals(authentication)) {
191+
this.authentication = Authentication.valueOf(authentication);
192+
} else {
193+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or PLAIN_TEXT and not " + protocol);
194+
}
195+
}
196+
if (quaggaPassword != null) {
197+
this.password = quaggaPassword;
198+
}
199+
if (superCIDRList != null) {
200+
String[] cidr_list = superCIDRList.split(",");
201+
for (String cidr : cidr_list) {
202+
if (!NetUtils.isValidCIDR(cidr)) {
203+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + cidr);
204+
}
205+
}
206+
CIDR[] v_cidr = NetUtils.convertToCIDR(cidr_list);
207+
if (!NetUtils.cidrListConsistency(v_cidr)) {
208+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(cidr_list));
209+
}
210+
this.superCIDRList = v_cidr;
211+
}
212+
if (enabled != null) {
213+
this.enabled = enabled;
214+
}
215+
}
216+
217+
public void setValues(Map<String, String> details) throws BadCIDRException {
218+
Protocol protocol = Protocol.valueOf(details.get(Params.PROTOCOL.name()));
219+
String ospfArea = details.get(Params.AREA.name());
220+
Short helloInterval = Short.valueOf(details.get(Params.HELLO_INTERVAL.name()));
221+
Short deadInterval = Short.valueOf(details.get(Params.DEAD_INTERVAL.name()));
222+
Short retransmitInterval = Short.valueOf(details.get(Params.RETRANSMIT_INTERVAL.name()));
223+
Short transitDelay = Short.valueOf(details.get(Params.TRANSIT_DELAY.name()));
224+
Authentication authentication = Authentication.valueOf(details.get(Params.AUTHENTICATION.name()));
225+
String quaggaPassword = details.get(Params.PASSWORD.name());
226+
String superCIDRList = details.get(Params.SUPER_CIDR.name());
227+
Boolean enabled = Boolean.valueOf(details.get(Params.ENABLED.name()));
228+
229+
if (protocol != null) {
230+
if (Protocol.OSPF == protocol) {
231+
this.protocol = protocol;
232+
} else {
233+
throw new InvalidParameterValueException("The quagga protocal can have values of OSPF " + protocol);
234+
}
235+
}
236+
if (ospfArea != null) {
237+
this.ospfArea = ospfArea;
238+
}
239+
if (helloInterval != null) {
240+
this.helloInterval = helloInterval;
241+
}
242+
if (deadInterval != null) {
243+
this.deadInterval = deadInterval;
244+
}
245+
if (retransmitInterval != null) {
246+
this.retransmitInterval = retransmitInterval;
247+
}
248+
if (transitDelay != null) {
249+
this.transitDelay = transitDelay;
250+
}
251+
if (authentication != null) {
252+
if (Authentication.MD5 == authentication || Authentication.PLAIN_TEXT == authentication) {
253+
this.authentication = authentication;
254+
} else {
255+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or PLAIN_TEXT and not " + authentication);
256+
}
257+
}
258+
if (quaggaPassword != null) {
259+
this.password = quaggaPassword;
260+
}
261+
if (superCIDRList != null) {
262+
String[] cidr_list = superCIDRList.split(",");
263+
for (String cidr : cidr_list) {
264+
if (!NetUtils.isValidCIDR(cidr)) {
265+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + cidr);
266+
}
267+
}
268+
CIDR[] v_cidr = NetUtils.convertToCIDR(cidr_list);
269+
if (!NetUtils.cidrListConsistency(v_cidr)) {
270+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(cidr_list));
271+
}
272+
this.superCIDRList = v_cidr;
273+
}
274+
if (enabled != null) {
275+
this.enabled = enabled;
276+
}
277+
}
278+
279+
public Map<String, String> getValues() throws BadCIDRException {
280+
Map<String, String> details = new HashMap<String, String>();
281+
if (protocol != null) {
282+
if ((Protocol.OSPF.name().equals(protocol))) {
283+
details.put(Params.PROTOCOL.name(), protocol.name());
284+
} else {
285+
details.put(Params.PROTOCOL.name(), Protocol.OSPF.name());
286+
}
287+
}
288+
if (ospfArea != null) {
289+
details.put(Params.AREA.name(), ospfArea);
290+
}
291+
if (helloInterval != null) {
292+
details.put(Params.HELLO_INTERVAL.name(), helloInterval.toString());
293+
}
294+
if (deadInterval != null) {
295+
details.put(Params.DEAD_INTERVAL.name(), deadInterval.toString());
296+
}
297+
if (retransmitInterval != null) {
298+
details.put(Params.RETRANSMIT_INTERVAL.name(), retransmitInterval.toString());
299+
}
300+
if (transitDelay != null) {
301+
details.put(Params.TRANSIT_DELAY.name(), transitDelay.toString());
302+
}
303+
if (authentication != null) {
304+
if (Authentication.MD5.name().equals(authentication) || Authentication.PLAIN_TEXT.name().equals(authentication)) {
305+
details.put(Params.AUTHENTICATION.name(), authentication.name());
306+
} else {
307+
details.put(Params.AUTHENTICATION.name(), Authentication.MD5.name());
308+
}
309+
}
310+
if (password != null) {
311+
details.put(Params.PASSWORD.name(), password);
312+
}
313+
if (!ArrayUtils.isEmpty(superCIDRList)) {
314+
if (!NetUtils.cidrListConsistency(superCIDRList)) {
315+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(superCIDRList));
316+
}
317+
details.put(Params.SUPER_CIDR.name(), StringUtils.join(superCIDRList, ','));
318+
319+
} else {
320+
details.put(Params.SUPER_CIDR.name(), "200.100.0.0/20");
321+
}
322+
if (enabled != null) {
323+
details.put(Params.ENABLED.name(), enabled.toString());
324+
}
325+
326+
return details;
327+
}
328+
329+
}

api/src/com/cloud/network/vpc/Vpc.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,5 @@ public enum State {
8787
* @return true if VPC spans multiple zones in the region
8888
*/
8989
boolean isRegionLevelVpc();
90+
9091
}

api/src/com/cloud/network/vpc/VpcOffering.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
import org.apache.cloudstack.api.InternalIdentity;
2121

2222
public interface VpcOffering extends InternalIdentity, Identity {
23+
2324
public enum State {
2425
Disabled, Enabled
2526
}
2627

2728
public static final String defaultVPCOfferingName = "Default VPC offering";
2829
public static final String defaultVPCNSOfferingName = "Default VPC offering with Netscaler";
2930
public static final String redundantVPCOfferingName = "Redundant VPC offering";
31+
public static final String routedVPCOfferingName = "Default Dynamically Routed VPC offering";
3032

3133
/**
3234
*

0 commit comments

Comments
 (0)