Skip to content

Commit 95f2b5a

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 2b4b8aa commit 95f2b5a

File tree

97 files changed

+5461
-825
lines changed

Some content is hidden

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

97 files changed

+5461
-825
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: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
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.cloudstack.utils.net.cidr.CIDR;
25+
import org.apache.cloudstack.utils.net.cidr.CIDRException;
26+
import org.apache.cloudstack.utils.net.cidr.CIDRFactory;
27+
import org.apache.commons.lang.ArrayUtils;
28+
import org.apache.commons.lang.StringUtils;
29+
30+
import com.cloud.exception.InvalidParameterValueException;
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(String str) {
62+
this.protocol = str == null ? Protocol.OSPF : Protocol.valueOf(str);
63+
}
64+
65+
public String getOspfArea() {
66+
return ospfArea;
67+
}
68+
69+
public void setOspfArea(String ospfArea) {
70+
this.ospfArea = ospfArea == null ? "0" : ospfArea;
71+
}
72+
73+
public Short getHelloInterval() {
74+
return helloInterval;
75+
}
76+
77+
public void setHelloInterval(String string) {
78+
this.helloInterval = string == null ? 10 : Short.valueOf(string);
79+
if (this.helloInterval > 65535 || this.helloInterval < 1) {
80+
throw new IllegalArgumentException("The value of hello interval should be from 1 to 65535 and now " + this.helloInterval);
81+
}
82+
}
83+
84+
public Short getDeadInterval() {
85+
return deadInterval;
86+
}
87+
88+
public void setDeadInterval(String deadInterval) {
89+
this.deadInterval = deadInterval == null ? 40 : Short.valueOf(deadInterval);
90+
if (this.deadInterval > 65535 || this.helloInterval < 1) {
91+
throw new IllegalArgumentException("The value of dead interval should be from 1 to 65535 and now " + this.deadInterval);
92+
}
93+
}
94+
95+
public Short getRetransmitInterval() {
96+
return retransmitInterval;
97+
}
98+
99+
public void setRetransmitInterval(String retransmitInterval) {
100+
this.retransmitInterval = retransmitInterval == null ? 5 : Short.valueOf(retransmitInterval);
101+
if (this.retransmitInterval > 65535 || this.retransmitInterval < 1) {
102+
throw new IllegalArgumentException("The value of retransmit interval should be from 1 to 65535 and now " + this.retransmitInterval);
103+
}
104+
}
105+
106+
public Short getTransitDelay() {
107+
return transitDelay;
108+
}
109+
110+
public void setTransitDelay(String transitDelay) {
111+
this.transitDelay = transitDelay == null ? 1 : Short.valueOf(transitDelay);
112+
if (this.transitDelay > 65535 || this.transitDelay < 1) {
113+
throw new IllegalArgumentException("The value of transit rDelay should be from 1 to 65535 and now " + this.retransmitInterval);
114+
}
115+
}
116+
117+
public Authentication getAuthentication() {
118+
return authentication;
119+
}
120+
121+
public void setAuthentication(String authentication) {
122+
this.authentication = authentication == null ? Authentication.MD5 : Authentication.valueOf(authentication);
123+
}
124+
125+
public String getPassword() {
126+
return password = password == null ? "" : password;
127+
}
128+
129+
public void setPassword(String password) {
130+
this.password = password;
131+
}
132+
133+
public CIDR[] getSuperCIDR() {
134+
return superCIDRList;
135+
}
136+
137+
public void setSuperCIDR(String superCIDR) throws CIDRException {
138+
this.superCIDRList = superCIDR == null ? new CIDR[0] : CIDRFactory.convertToCIDR(superCIDR.split(","));
139+
}
140+
141+
public Boolean getEnabled() {
142+
return enabled;
143+
}
144+
145+
public void setEnabled(String enabled) {
146+
this.enabled = enabled == null ? Boolean.FALSE : Boolean.valueOf(enabled);
147+
}
148+
149+
public enum Params {
150+
PROTOCOL, AREA, HELLO_INTERVAL, DEAD_INTERVAL, RETRANSMIT_INTERVAL, TRANSIT_DELAY, AUTHENTICATION, SUPER_CIDR, PASSWORD, ENABLED
151+
}
152+
153+
public enum Protocol {
154+
OSPF
155+
}
156+
157+
public enum Authentication {
158+
MD5, PLAIN_TEXT
159+
}
160+
161+
public OSPFZoneConfig(final Map<String, String> details) {
162+
this.setProtocol(details.get(Params.PROTOCOL.name()));
163+
this.setOspfArea(details.get(Params.AREA.name()));
164+
this.setHelloInterval(details.get(Params.HELLO_INTERVAL.name()));
165+
this.setDeadInterval(details.get(Params.DEAD_INTERVAL.name()));
166+
this.setRetransmitInterval(details.get(Params.RETRANSMIT_INTERVAL.name()));
167+
this.setTransitDelay(details.get(Params.TRANSIT_DELAY.name()));
168+
this.setAuthentication(details.get(Params.AUTHENTICATION.name()));
169+
this.setPassword(details.get(Params.PASSWORD.name()));
170+
String cidrStr = details.get(Params.SUPER_CIDR.name());
171+
if (cidrStr != null && ! cidrStr.isEmpty()){
172+
try {
173+
this.setSuperCIDR(cidrStr);
174+
} catch (CIDRException e) {
175+
throw new InvalidParameterValueException("The supercidr in zone config is bad " + cidrStr);
176+
}
177+
}
178+
this.setEnabled(details.get(Params.ENABLED.name()));
179+
}
180+
181+
public void setValues(final String protocol, final String ospfArea, final Short helloInterval, final Short deadInterval, final Short retransmitInterval,
182+
final Short transitDelay, final String authentication, final String quaggaPassword, final String superCIDRList, final Boolean enabled) throws CIDRException {
183+
if (protocol != null) {
184+
if ((Protocol.OSPF.name().equals(protocol))) {
185+
this.protocol = Protocol.valueOf(protocol);
186+
} else {
187+
throw new InvalidParameterValueException("The quagga protocal can have values of OSPF only " + protocol);
188+
}
189+
}
190+
if (ospfArea != null) {
191+
this.ospfArea = ospfArea;
192+
}
193+
if (helloInterval != null) {
194+
this.helloInterval = helloInterval;
195+
}
196+
if (deadInterval != null) {
197+
this.deadInterval = deadInterval;
198+
}
199+
if (retransmitInterval != null) {
200+
this.retransmitInterval = retransmitInterval;
201+
}
202+
if (transitDelay != null) {
203+
this.transitDelay = transitDelay;
204+
}
205+
if (authentication != null) {
206+
if (Authentication.MD5.name().equals(authentication) || Authentication.PLAIN_TEXT.name().equals(authentication)) {
207+
this.authentication = Authentication.valueOf(authentication);
208+
} else {
209+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or PLAIN_TEXT and not " + protocol);
210+
}
211+
}
212+
if (quaggaPassword != null) {
213+
this.password = quaggaPassword;
214+
}
215+
if (superCIDRList != null) {
216+
this.superCIDRList = CIDRFactory.getCIDRList(superCIDRList);
217+
}
218+
if (enabled != null) {
219+
this.enabled = enabled;
220+
}
221+
}
222+
223+
224+
public Map<String, String> getValues() throws CIDRException {
225+
Map<String, String> details = new HashMap<String, String>();
226+
if (protocol != null) {
227+
if ((Protocol.OSPF.name().equals(protocol))) {
228+
details.put(Params.PROTOCOL.name(), protocol.name());
229+
} else {
230+
details.put(Params.PROTOCOL.name(), Protocol.OSPF.name());
231+
}
232+
}
233+
if (ospfArea != null) {
234+
details.put(Params.AREA.name(), ospfArea);
235+
}
236+
if (helloInterval != null) {
237+
details.put(Params.HELLO_INTERVAL.name(), helloInterval.toString());
238+
}
239+
if (deadInterval != null) {
240+
details.put(Params.DEAD_INTERVAL.name(), deadInterval.toString());
241+
}
242+
if (retransmitInterval != null) {
243+
details.put(Params.RETRANSMIT_INTERVAL.name(), retransmitInterval.toString());
244+
}
245+
if (transitDelay != null) {
246+
details.put(Params.TRANSIT_DELAY.name(), transitDelay.toString());
247+
}
248+
if (authentication != null) {
249+
if (Authentication.MD5.name().equals(authentication) || Authentication.PLAIN_TEXT.name().equals(authentication)) {
250+
details.put(Params.AUTHENTICATION.name(), authentication.name());
251+
} else {
252+
details.put(Params.AUTHENTICATION.name(), Authentication.MD5.name());
253+
}
254+
}
255+
if (password != null) {
256+
details.put(Params.PASSWORD.name(), password);
257+
}
258+
if (!ArrayUtils.isEmpty(superCIDRList)) {
259+
if (!CIDRFactory.cidrListConsistency(superCIDRList)) {
260+
throw new InvalidParameterValueException("The cidr list is not consistent " + Arrays.toString(superCIDRList));
261+
}
262+
details.put(Params.SUPER_CIDR.name(), StringUtils.join(superCIDRList, ','));
263+
264+
} else {
265+
details.put(Params.SUPER_CIDR.name(), "");
266+
}
267+
if (enabled != null) {
268+
details.put(Params.ENABLED.name(), enabled.toString());
269+
}
270+
271+
return details;
272+
}
273+
274+
@Override
275+
public String toString() {
276+
return "OSPFZoneConfig [zoneId=" + zoneId + ", protocol=" + protocol + ", ospfArea=" + ospfArea + ", helloInterval=" + helloInterval + ", deadInterval=" + deadInterval
277+
+ ", retransmitInterval=" + retransmitInterval + ", transitDelay=" + transitDelay + ", authentication=" + authentication + ", password=" + password
278+
+ ", superCIDRList=" + Arrays.toString(superCIDRList) + ", enabled=" + enabled + "]";
279+
}
280+
}

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
*

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,22 @@
1616
// under the License.
1717
package com.cloud.network.vpc;
1818

19-
2019
import java.util.List;
2120
import java.util.Map;
2221

22+
import org.apache.cloudstack.utils.net.cidr.CIDRException;
23+
2324
import com.cloud.utils.Pair;
2425

2526
public interface VpcProvisioningService {
2627

2728
public VpcOffering getVpcOffering(long vpcOfferingId);
2829

29-
public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices,
30-
Map<String, List<String>> serviceProviders,
31-
Map serviceCapabilitystList,
32-
Long serviceOfferingId);
30+
public VpcOffering createVpcOffering(String name, String displayText, List<String> supportedServices, Map<String, List<String>> serviceProviders, Map serviceCapabilitystList,
31+
Long serviceOfferingId);
3332

34-
Pair<List<? extends VpcOffering>,Integer> listVpcOfferings(Long id, String name, String displayText, List<String> supportedServicesStr, Boolean isDefault, String keyword,
35-
String state, Long startIndex, Long pageSizeVal);
33+
Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(Long id, String name, String displayText, List<String> supportedServicesStr, Boolean isDefault, String keyword,
34+
String state, Long startIndex, Long pageSizeVal);
3635

3736
/**
3837
* @param offId
@@ -49,4 +48,9 @@ Pair<List<? extends VpcOffering>,Integer> listVpcOfferings(Long id, String name,
4948
*/
5049
public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state);
5150

51+
Map<String, String> updateQuaggaConfig(Long id, String protocol, String ospfArea, Short helloInterval, Short deadInterval, Short retransmitInterval, Short transitDelay,
52+
String authentication, String password, String superCIDR, Boolean enabled) throws CIDRException;
53+
54+
Map<String, String> quaggaConfig(Long id);
55+
5256
}

0 commit comments

Comments
 (0)