Skip to content

Commit b54c0d5

Browse files
OSPF: WIP: adding dynamically routing capability to VPC
. 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 TODO: . CIDR selection functionality and UI . Marvin and unit tests
1 parent 8df8094 commit b54c0d5

File tree

70 files changed

+2267
-463
lines changed

Some content is hidden

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

70 files changed

+2267
-463
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: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
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.HashMap;
21+
import java.util.Map;
22+
23+
import com.cloud.exception.InvalidParameterValueException;
24+
import com.cloud.utils.net.NetUtils;
25+
26+
public class QuaggaZoneConfig {
27+
28+
private long zoneId;
29+
private String protocol;
30+
private String ospfArea;
31+
private String helloInterval;
32+
private String deadInterval;
33+
private String retransmitInterval;
34+
private String transitDelay;
35+
private String authentication;
36+
private String password;
37+
private String ospfSuperCIDR;
38+
private String enabled;
39+
40+
public static final String s_quaggaProtocol = "quaggaprotocol";
41+
public static final String s_ospfArea = "ospfarea";
42+
public static final String s_quaggaHelloInterval = "quaggahellointerval";
43+
public static final String s_quaggaDeadInterval = "quaggadeadinterval";
44+
public static final String s_quaggaRetransmitInterval = "quaggaretransmitinterval";
45+
public static final String s_quaggaTransitDelay = "quaggatransitdelay";
46+
public static final String s_quaggaAuthentication = "quaggaauthentication";
47+
public static final String s_ospfSuperCIDR = "ospfsupercidr";
48+
public static final String s_quaggaPassword = "quaggapassword";
49+
public static final String s_quaggaEnabled = "quaggaenabled";
50+
51+
public String getProtocol() {
52+
return protocol;
53+
}
54+
55+
public void setProtocol(String quaggaProtocol) {
56+
this.protocol = quaggaProtocol;
57+
}
58+
59+
public String getOspfArea() {
60+
return ospfArea;
61+
}
62+
63+
public void setOspfArea(String ospfArea) {
64+
this.ospfArea = ospfArea;
65+
}
66+
67+
public String getHelloInterval() {
68+
return helloInterval;
69+
}
70+
71+
public void setHelloInterval(String quaggaHelloInterval) {
72+
this.helloInterval = quaggaHelloInterval;
73+
}
74+
75+
public String getDeadInterval() {
76+
return deadInterval;
77+
}
78+
79+
public void setDeadInterval(String quaggaDeadInterval) {
80+
this.deadInterval = quaggaDeadInterval;
81+
}
82+
83+
public String getRetransmitInterval() {
84+
return retransmitInterval;
85+
}
86+
87+
public void setRetransmitInterval(String quaggaRetransmitInterval) {
88+
this.retransmitInterval = quaggaRetransmitInterval;
89+
}
90+
91+
public String getTransitDelay() {
92+
return transitDelay;
93+
}
94+
95+
public void setTransitDelay(String quaggaTransitDelay) {
96+
this.transitDelay = quaggaTransitDelay;
97+
}
98+
99+
public String getAuthentication() {
100+
return authentication;
101+
}
102+
103+
public void setAuthentication(String quaggaAuthentication) {
104+
this.authentication = quaggaAuthentication;
105+
}
106+
107+
public String getPassword() {
108+
return password;
109+
}
110+
111+
public void setPassword(String quaggaPassword) {
112+
this.password = quaggaPassword;
113+
}
114+
115+
public String getOspfSuperCIDR() {
116+
return ospfSuperCIDR;
117+
}
118+
119+
public void setOspfSuperCIDR(String ospfSuperCIDR) {
120+
this.ospfSuperCIDR = ospfSuperCIDR;
121+
}
122+
123+
public String getEnabled() {
124+
return enabled;
125+
}
126+
127+
public void setEnabled(String quaggaEnabled) {
128+
this.enabled = quaggaEnabled;
129+
}
130+
131+
public enum Params {
132+
QuaggaProtocol, OSPFArea, QuaggaHelloInterval, QuaggaDeadInterval, QuaggaRetransmitInterval, QuaggaTransitDelay, QuaggaAuthentication, OspfSuperCIDR, QuaggaPassword, QuaggaEnabled
133+
}
134+
135+
public enum QuaggaProtocol {
136+
Ospf, Bgp
137+
}
138+
139+
public enum QuaggaAuthetication {
140+
MD5, PlainText
141+
}
142+
143+
public QuaggaZoneConfig(final Map<String, String> details) {
144+
this.protocol = details.get(Params.QuaggaProtocol.name()) == null ? QuaggaProtocol.Ospf.name() : details.get(Params.QuaggaProtocol.name());
145+
this.ospfArea = details.get(Params.OSPFArea.name()) == null ? "0" : details.get(Params.OSPFArea.name());
146+
this.helloInterval = details.get(Params.QuaggaHelloInterval.name()) == null ? "10" : details.get(Params.QuaggaHelloInterval.name());
147+
this.deadInterval = details.get(Params.QuaggaDeadInterval.name()) == null ? "40" : details.get(Params.QuaggaDeadInterval.name());
148+
this.retransmitInterval = details.get(Params.QuaggaRetransmitInterval.name()) == null ? "5" : details.get(Params.QuaggaRetransmitInterval.name());
149+
this.transitDelay = details.get(Params.QuaggaTransitDelay.name()) == null ? "1" : details.get(Params.QuaggaTransitDelay.name());
150+
this.authentication = details.get(Params.QuaggaAuthentication.name()) == null ? QuaggaAuthetication.MD5.name() : details.get(Params.QuaggaAuthentication.name());
151+
this.password = details.get(Params.QuaggaPassword.name()) == null ? "" : details.get(Params.QuaggaPassword.name());
152+
this.ospfSuperCIDR = details.get(Params.OspfSuperCIDR.name()) == null ? "200.100.0.0/20" : details.get(Params.OspfSuperCIDR.name());
153+
this.enabled = details.get(Params.QuaggaEnabled.name()) == null ? "false" : details.get(Params.QuaggaEnabled.name());
154+
}
155+
156+
public QuaggaZoneConfig(final String protocol, final String ospfArea, final Short helloInterval, final Short deadInterval, final Short retransmitInterval,
157+
final Short transitDelay, final String authentication, final String quaggaPassword, final String superCIDR, final Boolean enabled) {
158+
this(new HashMap<String, String>());
159+
if (protocol != null) {
160+
if ((QuaggaProtocol.Ospf.name().equals(protocol) || QuaggaProtocol.Bgp.name().equals(protocol))) {
161+
this.protocol = protocol;
162+
} else {
163+
throw new InvalidParameterValueException("The quagga protocal can have values of Ospf or Bgp and not " + protocol);
164+
}
165+
}
166+
if (ospfArea != null) {
167+
this.ospfArea = ospfArea;
168+
}
169+
if (helloInterval != null) {
170+
this.helloInterval = helloInterval.toString();
171+
}
172+
if (deadInterval != null) {
173+
this.deadInterval = deadInterval.toString();
174+
}
175+
if (retransmitInterval != null) {
176+
this.retransmitInterval = retransmitInterval.toString();
177+
}
178+
if (transitDelay != null) {
179+
this.transitDelay = transitDelay.toString();
180+
}
181+
if (authentication != null) {
182+
if (QuaggaAuthetication.MD5.name().equals(authentication) || QuaggaAuthetication.PlainText.name().equals(authentication)) {
183+
this.authentication = authentication;
184+
} else {
185+
throw new InvalidParameterValueException("The quagga authentication can have values of MD5 or Plaintext and not " + protocol);
186+
}
187+
}
188+
if (quaggaPassword != null) {
189+
this.password = quaggaPassword;
190+
}
191+
if (superCIDR != null) {
192+
if (!NetUtils.isValidCIDR(superCIDR)) {
193+
throw new InvalidParameterValueException("The super CIDR is not a valid cidr " + superCIDR);
194+
} else {
195+
this.ospfSuperCIDR = superCIDR;
196+
}
197+
}
198+
if (enabled != null) {
199+
this.enabled = enabled.toString();
200+
}
201+
}
202+
203+
public Map<String, String> getQuaggaZoneDetails() {
204+
Map<String, String> details = new HashMap<String, String>();
205+
if (protocol != null) {
206+
if ((QuaggaProtocol.Ospf.name().equals(protocol) || QuaggaProtocol.Bgp.name().equals(protocol))) {
207+
details.put(Params.QuaggaProtocol.name(), protocol);
208+
} else {
209+
details.put(Params.QuaggaProtocol.name(), QuaggaProtocol.Ospf.name());
210+
}
211+
}
212+
if (ospfArea != null) {
213+
details.put(Params.OSPFArea.name(), ospfArea);
214+
}
215+
if (helloInterval != null) {
216+
details.put(Params.QuaggaHelloInterval.name(), helloInterval.toString());
217+
}
218+
if (deadInterval != null) {
219+
details.put(Params.QuaggaDeadInterval.name(), deadInterval.toString());
220+
}
221+
if (retransmitInterval != null) {
222+
details.put(Params.QuaggaRetransmitInterval.name(), retransmitInterval.toString());
223+
}
224+
if (transitDelay != null) {
225+
details.put(Params.QuaggaTransitDelay.name(), transitDelay.toString());
226+
}
227+
if (authentication != null) {
228+
if (QuaggaAuthetication.MD5.name().equals(authentication) || QuaggaAuthetication.PlainText.name().equals(authentication)) {
229+
details.put(Params.QuaggaAuthentication.name(), authentication);
230+
} else {
231+
details.put(Params.QuaggaAuthentication.name(), QuaggaAuthetication.MD5.name());
232+
}
233+
}
234+
if (password != null) {
235+
details.put(Params.QuaggaPassword.name(), password);
236+
}
237+
if (ospfSuperCIDR != null) {
238+
if (!NetUtils.isValidCIDR(ospfSuperCIDR)) {
239+
details.put(Params.OspfSuperCIDR.name(), "200.100.0.0/20");
240+
} else {
241+
details.put(Params.OspfSuperCIDR.name(), ospfSuperCIDR);
242+
}
243+
}
244+
if (enabled != null) {
245+
details.put(Params.QuaggaEnabled.name(), enabled.toString());
246+
}
247+
248+
return details;
249+
}
250+
251+
public Map<String, String> addQuaggaZoneDetails(final Map<String, String> details) {
252+
Map<String, String> quagga_details = getQuaggaZoneDetails();
253+
details.putAll(quagga_details);
254+
return details;
255+
}
256+
}

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: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
// under the License.
1717
package com.cloud.network.vpc;
1818

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

@@ -26,13 +25,11 @@ public interface VpcProvisioningService {
2625

2726
public VpcOffering getVpcOffering(long vpcOfferingId);
2827

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

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);
31+
Pair<List<? extends VpcOffering>, Integer> listVpcOfferings(Long id, String name, String displayText, List<String> supportedServicesStr, Boolean isDefault, String keyword,
32+
String state, Long startIndex, Long pageSizeVal);
3633

3734
/**
3835
* @param offId
@@ -49,4 +46,9 @@ Pair<List<? extends VpcOffering>,Integer> listVpcOfferings(Long id, String name,
4946
*/
5047
public VpcOffering updateVpcOffering(long vpcOffId, String vpcOfferingName, String displayText, String state);
5148

49+
Map<String, String> quaggaConfigUpdate(Long id, String protocol, String ospfArea, Short helloInterval, Short deadInterval, Short retransmitInterval, Short transitDelay,
50+
String authentication, String password, String superCIDR, Boolean enabled);
51+
52+
Map<String, String> quaggaConfig(Long id);
53+
5254
}

api/src/com/cloud/offering/NetworkOffering.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ public enum Detail {
5555
public final static String DefaultIsolatedNetworkOffering = "DefaultIsolatedNetworkOffering";
5656
public final static String DefaultSharedEIPandELBNetworkOffering = "DefaultSharedNetscalerEIPandELBNetworkOffering";
5757
public final static String DefaultIsolatedNetworkOfferingForVpcNetworks = "DefaultIsolatedNetworkOfferingForVpcNetworks";
58+
public final static String DefaultIsolatedDynamicRoutedNetworkOfferingForVpcNetworks = "DefaultIsolatedDynamicRoutedNetworkOfferingForVpcNetworks";
5859
public final static String DefaultIsolatedNetworkOfferingForVpcNetworksNoLB = "DefaultIsolatedNetworkOfferingForVpcNetworksNoLB";
5960
public final static String DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB = "DefaultIsolatedNetworkOfferingForVpcNetworksWithInternalLB";
6061

api/src/org/apache/cloudstack/api/ApiConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ public class ApiConstants {
622622
public static final String MAXCAPACITY = "maxcapacity";
623623
public static final String DISTRIBUTED_VPC_ROUTER = "distributedvpcrouter";
624624
public static final String REDUNDANT_VPC_ROUTER = "redundantvpcrouter";
625+
public static final String DYNAMICALLY_ROUTED_VPC_ROUTER = "dynamicallyroutedvpcrouter";
625626
public static final String READ_ONLY = "readonly";
626627
public static final String SUPPORTS_REGION_LEVEL_VPC = "supportsregionLevelvpc";
627628
public static final String SUPPORTS_STRECHED_L2_SUBNET = "supportsstrechedl2subnet";

0 commit comments

Comments
 (0)