Skip to content

Commit d7b3da7

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
1 parent a15a8f9 commit d7b3da7

File tree

82 files changed

+3393
-526
lines changed

Some content is hidden

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

82 files changed

+3393
-526
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: 3 additions & 1 deletion
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

@@ -243,7 +245,7 @@ public enum State {
243245

244246
Allocated("Indicates the network configuration is in allocated but not setup"), Setup("Indicates the network configuration is setup"), Implementing(
245247
"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");
248+
"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: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
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+
30+
public class QuaggaZoneConfig {
31+
32+
private long zoneId;
33+
private String protocol;
34+
private String ospfArea;
35+
private String helloInterval;
36+
private String deadInterval;
37+
private String retransmitInterval;
38+
private String transitDelay;
39+
private String authentication;
40+
private String password;
41+
private String[] ospfSuperCIDRList;
42+
private String enabled;
43+
44+
public static final String s_quaggaProtocol = "quaggaprotocol";
45+
public static final String s_ospfArea = "ospfarea";
46+
public static final String s_quaggaHelloInterval = "quaggahellointerval";
47+
public static final String s_quaggaDeadInterval = "quaggadeadinterval";
48+
public static final String s_quaggaRetransmitInterval = "quaggaretransmitinterval";
49+
public static final String s_quaggaTransitDelay = "quaggatransitdelay";
50+
public static final String s_quaggaAuthentication = "quaggaauthentication";
51+
public static final String s_ospfSuperCIDR = "ospfsupercidr";
52+
public static final String s_quaggaPassword = "quaggapassword";
53+
public static final String s_quaggaEnabled = "quaggaenabled";
54+
55+
public String getProtocol() {
56+
return protocol;
57+
}
58+
59+
public void setProtocol(String quaggaProtocol) {
60+
this.protocol = quaggaProtocol;
61+
}
62+
63+
public String getOspfArea() {
64+
return ospfArea;
65+
}
66+
67+
public void setOspfArea(String ospfArea) {
68+
this.ospfArea = ospfArea;
69+
}
70+
71+
public String getHelloInterval() {
72+
return helloInterval;
73+
}
74+
75+
public void setHelloInterval(String quaggaHelloInterval) {
76+
this.helloInterval = quaggaHelloInterval;
77+
}
78+
79+
public String getDeadInterval() {
80+
return deadInterval;
81+
}
82+
83+
public void setDeadInterval(String quaggaDeadInterval) {
84+
this.deadInterval = quaggaDeadInterval;
85+
}
86+
87+
public String getRetransmitInterval() {
88+
return retransmitInterval;
89+
}
90+
91+
public void setRetransmitInterval(String quaggaRetransmitInterval) {
92+
this.retransmitInterval = quaggaRetransmitInterval;
93+
}
94+
95+
public String getTransitDelay() {
96+
return transitDelay;
97+
}
98+
99+
public void setTransitDelay(String quaggaTransitDelay) {
100+
this.transitDelay = quaggaTransitDelay;
101+
}
102+
103+
public String getAuthentication() {
104+
return authentication;
105+
}
106+
107+
public void setAuthentication(String quaggaAuthentication) {
108+
this.authentication = quaggaAuthentication;
109+
}
110+
111+
public String getPassword() {
112+
return password;
113+
}
114+
115+
public void setPassword(String quaggaPassword) {
116+
this.password = quaggaPassword;
117+
}
118+
119+
public String[] getOspfSuperCIDR() {
120+
return ospfSuperCIDRList;
121+
}
122+
123+
public void setOspfSuperCIDR(String[] ospfSuperCIDR) {
124+
this.ospfSuperCIDRList = ospfSuperCIDR;
125+
}
126+
127+
public String getEnabled() {
128+
return enabled;
129+
}
130+
131+
public void setEnabled(String quaggaEnabled) {
132+
this.enabled = quaggaEnabled;
133+
}
134+
135+
public enum Params {
136+
QuaggaProtocol, OSPFArea, QuaggaHelloInterval, QuaggaDeadInterval, QuaggaRetransmitInterval, QuaggaTransitDelay, QuaggaAuthentication, OspfSuperCIDR, QuaggaPassword, QuaggaEnabled
137+
}
138+
139+
public enum QuaggaProtocol {
140+
Ospf, Bgp
141+
}
142+
143+
public enum QuaggaAuthetication {
144+
MD5, PlainText
145+
}
146+
147+
public QuaggaZoneConfig() {
148+
}
149+
150+
public void setDefaultValues(final Map<String, String> details) {
151+
this.protocol = details.get(Params.QuaggaProtocol.name()) == null ? QuaggaProtocol.Ospf.name() : details.get(Params.QuaggaProtocol.name());
152+
this.ospfArea = details.get(Params.OSPFArea.name()) == null ? "0" : details.get(Params.OSPFArea.name());
153+
this.helloInterval = details.get(Params.QuaggaHelloInterval.name()) == null ? "10" : details.get(Params.QuaggaHelloInterval.name());
154+
this.deadInterval = details.get(Params.QuaggaDeadInterval.name()) == null ? "40" : details.get(Params.QuaggaDeadInterval.name());
155+
this.retransmitInterval = details.get(Params.QuaggaRetransmitInterval.name()) == null ? "5" : details.get(Params.QuaggaRetransmitInterval.name());
156+
this.transitDelay = details.get(Params.QuaggaTransitDelay.name()) == null ? "1" : details.get(Params.QuaggaTransitDelay.name());
157+
this.authentication = details.get(Params.QuaggaAuthentication.name()) == null ? QuaggaAuthetication.MD5.name() : details.get(Params.QuaggaAuthentication.name());
158+
this.password = details.get(Params.QuaggaPassword.name()) == null ? "" : details.get(Params.QuaggaPassword.name());
159+
String cidr_list = details.get(Params.OspfSuperCIDR.name()) == null ? "200.100.0.0/20" : details.get(Params.OspfSuperCIDR.name());
160+
this.ospfSuperCIDRList = cidr_list.split(",");
161+
this.enabled = details.get(Params.QuaggaEnabled.name()) == null ? "false" : details.get(Params.QuaggaEnabled.name());
162+
}
163+
164+
public void setValues(final String protocol, final String ospfArea, final Short helloInterval, final Short deadInterval, final Short retransmitInterval,
165+
final Short transitDelay, final String authentication, final String quaggaPassword, final String superCIDRList, final Boolean enabled) {
166+
if (protocol != null) {
167+
if ((QuaggaProtocol.Ospf.name().equals(protocol) || QuaggaProtocol.Bgp.name().equals(protocol))) {
168+
this.protocol = protocol;
169+
} else {
170+
throw new InvalidParameterValueException("The quagga protocal can have values of Ospf or Bgp and not " + protocol);
171+
}
172+
}
173+
if (ospfArea != null) {
174+
this.ospfArea = ospfArea;
175+
}
176+
if (helloInterval != null) {
177+
this.helloInterval = helloInterval.toString();
178+
}
179+
if (deadInterval != null) {
180+
this.deadInterval = deadInterval.toString();
181+
}
182+
if (retransmitInterval != null) {
183+
this.retransmitInterval = retransmitInterval.toString();
184+
}
185+
if (transitDelay != null) {
186+
this.transitDelay = transitDelay.toString();
187+
}
188+
if (authentication != null) {
189+
if (QuaggaAuthetication.MD5.name().equals(authentication) || QuaggaAuthetication.PlainText.name().equals(authentication)) {
190+
this.authentication = authentication;
191+
} else {
192+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or Plaintext and not " + protocol);
193+
}
194+
}
195+
if (quaggaPassword != null) {
196+
this.password = quaggaPassword;
197+
}
198+
if (superCIDRList != null) {
199+
String[] cidr_list = superCIDRList.split(",");
200+
for (String cidr : cidr_list) {
201+
if (!NetUtils.isValidCIDR(cidr)) {
202+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + cidr);
203+
}
204+
}
205+
if (!NetUtils.cidrListConsistency(cidr_list)) {
206+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(cidr_list));
207+
}
208+
this.ospfSuperCIDRList = cidr_list;
209+
}
210+
if (enabled != null) {
211+
this.enabled = enabled.toString();
212+
}
213+
}
214+
215+
public void setValues(Map<String, String> details) {
216+
String protocol = details.get(Params.QuaggaProtocol.name());
217+
String ospfArea = details.get(Params.OSPFArea.name());
218+
String helloInterval = details.get(Params.QuaggaHelloInterval.name());
219+
String deadInterval = details.get(Params.QuaggaDeadInterval.name());
220+
String retransmitInterval = details.get(Params.QuaggaRetransmitInterval.name());
221+
String transitDelay = details.get(Params.QuaggaTransitDelay.name());
222+
String authentication = details.get(Params.QuaggaAuthentication.name());
223+
String quaggaPassword = details.get(Params.QuaggaPassword.name());
224+
String superCIDRList = details.get(Params.OspfSuperCIDR.name());
225+
String enabled = details.get(Params.QuaggaEnabled.name());
226+
227+
if (protocol != null) {
228+
if ((QuaggaProtocol.Ospf.name().equals(protocol) || QuaggaProtocol.Bgp.name().equals(protocol))) {
229+
this.protocol = protocol;
230+
} else {
231+
throw new InvalidParameterValueException("The quagga protocal can have values of Ospf or Bgp and not " + protocol);
232+
}
233+
}
234+
if (ospfArea != null) {
235+
this.ospfArea = ospfArea;
236+
}
237+
if (helloInterval != null) {
238+
this.helloInterval = helloInterval.toString();
239+
}
240+
if (deadInterval != null) {
241+
this.deadInterval = deadInterval.toString();
242+
}
243+
if (retransmitInterval != null) {
244+
this.retransmitInterval = retransmitInterval.toString();
245+
}
246+
if (transitDelay != null) {
247+
this.transitDelay = transitDelay.toString();
248+
}
249+
if (authentication != null) {
250+
if (QuaggaAuthetication.MD5.name().equals(authentication) || QuaggaAuthetication.PlainText.name().equals(authentication)) {
251+
this.authentication = authentication;
252+
} else {
253+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or Plaintext and not " + protocol);
254+
}
255+
}
256+
if (quaggaPassword != null) {
257+
this.password = quaggaPassword;
258+
}
259+
if (superCIDRList != null) {
260+
String[] cidr_list = superCIDRList.split(",");
261+
for (String cidr : cidr_list) {
262+
if (!NetUtils.isValidCIDR(cidr)) {
263+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + cidr);
264+
}
265+
}
266+
if (!NetUtils.cidrListConsistency(cidr_list)) {
267+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(cidr_list));
268+
}
269+
this.ospfSuperCIDRList = cidr_list;
270+
}
271+
if (enabled != null) {
272+
this.enabled = enabled.toString();
273+
}
274+
}
275+
276+
public Map<String, String> getValues() {
277+
Map<String, String> details = new HashMap<String, String>();
278+
if (protocol != null) {
279+
if ((QuaggaProtocol.Ospf.name().equals(protocol) || QuaggaProtocol.Bgp.name().equals(protocol))) {
280+
details.put(Params.QuaggaProtocol.name(), protocol);
281+
} else {
282+
details.put(Params.QuaggaProtocol.name(), QuaggaProtocol.Ospf.name());
283+
}
284+
}
285+
if (ospfArea != null) {
286+
details.put(Params.OSPFArea.name(), ospfArea);
287+
}
288+
if (helloInterval != null) {
289+
details.put(Params.QuaggaHelloInterval.name(), helloInterval.toString());
290+
}
291+
if (deadInterval != null) {
292+
details.put(Params.QuaggaDeadInterval.name(), deadInterval.toString());
293+
}
294+
if (retransmitInterval != null) {
295+
details.put(Params.QuaggaRetransmitInterval.name(), retransmitInterval.toString());
296+
}
297+
if (transitDelay != null) {
298+
details.put(Params.QuaggaTransitDelay.name(), transitDelay.toString());
299+
}
300+
if (authentication != null) {
301+
if (QuaggaAuthetication.MD5.name().equals(authentication) || QuaggaAuthetication.PlainText.name().equals(authentication)) {
302+
details.put(Params.QuaggaAuthentication.name(), authentication);
303+
} else {
304+
details.put(Params.QuaggaAuthentication.name(), QuaggaAuthetication.MD5.name());
305+
}
306+
}
307+
if (password != null) {
308+
details.put(Params.QuaggaPassword.name(), password);
309+
}
310+
if (!ArrayUtils.isEmpty(ospfSuperCIDRList)) {
311+
for (String cidr : ospfSuperCIDRList) {
312+
if (!NetUtils.isValidCIDR(cidr)) {
313+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + cidr);
314+
}
315+
}
316+
if (!NetUtils.cidrListConsistency(ospfSuperCIDRList)) {
317+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(ospfSuperCIDRList));
318+
}
319+
details.put(Params.OspfSuperCIDR.name(), StringUtils.join(ospfSuperCIDRList, ','));
320+
321+
} else {
322+
details.put(Params.OspfSuperCIDR.name(), "200.100.0.0/20");
323+
}
324+
if (enabled != null) {
325+
details.put(Params.QuaggaEnabled.name(), enabled.toString());
326+
}
327+
328+
return details;
329+
}
330+
331+
}

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)