VPC: implementation for Add/delete/list StaticRoute. Agent implementation is yet to be done

This commit is contained in:
Alena Prokharchyk 2012-06-26 11:10:55 -07:00
parent ce876e24de
commit 1a232171eb
20 changed files with 572 additions and 47 deletions

View File

@ -0,0 +1,35 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.agent.api.routing;
import com.cloud.agent.api.Answer;
/**
* @author Alena Prokharchyk
*/
public class SetStaticRouteAnswer extends Answer{
String[] results;
protected SetStaticRouteAnswer() {
}
public SetStaticRouteAnswer(SetStaticRouteCommand cmd, boolean success, String[] results) {
super(cmd, success, null);
assert (cmd.getStaticRoutes().length == results.length) : "Static routes and their results should be the same length";
this.results = results;
}
public String[] getResults() {
return results;
}
}

View File

@ -0,0 +1,35 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.agent.api.routing;
import java.util.List;
import com.cloud.network.vpc.StaticRouteProfile;
/**
* @author Alena Prokharchyk
*/
public class SetStaticRouteCommand extends NetworkElementCommand{
StaticRouteProfile[] staticRoutes;
protected SetStaticRouteCommand() {
}
public SetStaticRouteCommand(List<StaticRouteProfile> staticRoutes) {
this.staticRoutes = staticRoutes.toArray(new StaticRouteProfile[staticRoutes.size()]);
}
public StaticRouteProfile[] getStaticRoutes() {
return staticRoutes;
}
}

View File

@ -28,6 +28,7 @@ import com.cloud.event.EventTypes;
import com.cloud.exception.InvalidParameterValueException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.user.UserContext;
@ -91,7 +92,7 @@ public class CreateStaticRouteCmd extends BaseAsyncCreateCmd{
}
@Override
public void execute() {
public void execute() throws ResourceUnavailableException {
boolean success = false;
StaticRoute route = _entityMgr.findById(StaticRoute.class, getEntityId());
try {

View File

@ -21,7 +21,7 @@ import com.google.gson.annotations.SerializedName;
* @author Alena Prokharchyk
*/
@SuppressWarnings("unused")
public class StaticRouteResponse extends BaseResponse{
public class StaticRouteResponse extends BaseResponse implements ControlledEntityResponse{
@SerializedName(ApiConstants.ID) @Param(description="the ID of static route")
private IdentityProxy id = new IdentityProxy("static_routes");
@ -36,6 +36,24 @@ public class StaticRouteResponse extends BaseResponse{
@SerializedName(ApiConstants.CIDR) @Param(description="static route CIDR")
private String cidr;
@SerializedName(ApiConstants.ACCOUNT)
@Param(description = "the account associated with the static route")
private String accountName;
@SerializedName(ApiConstants.PROJECT_ID) @Param(description="the project id of the static route")
private IdentityProxy projectId = new IdentityProxy("projects");
@SerializedName(ApiConstants.PROJECT) @Param(description="the project name of the static route")
private String projectName;
@SerializedName(ApiConstants.DOMAIN_ID)
@Param(description = "the ID of the domain associated with the static route")
private IdentityProxy domainId = new IdentityProxy("domain");
@SerializedName(ApiConstants.DOMAIN)
@Param(description = "the domain associated with the static route")
private String domainName;
public void setId(Long id) {
this.id.setValue(id);
@ -56,4 +74,29 @@ public class StaticRouteResponse extends BaseResponse{
public void setCidr(String cidr) {
this.cidr = cidr;
}
@Override
public void setAccountName(String accountName) {
this.accountName = accountName;
}
@Override
public void setDomainId(Long domainId) {
this.domainId.setValue(domainId);
}
@Override
public void setDomainName(String domainName) {
this.domainName = domainName;
}
@Override
public void setProjectId(Long projectId) {
this.projectId.setValue(projectId);
}
@Override
public void setProjectName(String projectName) {
this.projectName = projectName;
}
}

View File

@ -292,5 +292,5 @@ public class VolumeResponse extends BaseResponse implements ControlledEntityResp
@Override
public void setProjectName(String projectName) {
this.projectName = projectName;
}
}
}

View File

@ -12,6 +12,7 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.element;
import java.util.List;
import com.cloud.deploy.DeployDestination;
@ -20,7 +21,7 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientNetworkCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
import com.cloud.vm.ReservationContext;
@ -48,5 +49,5 @@ public interface VpcProvider extends NetworkElement{
boolean deletePrivateGateway(PrivateGateway privateGateway) throws ConcurrentOperationException, ResourceUnavailableException;
boolean applyStaticRoutes(Vpc vpc, List<? extends StaticRoute> routes) throws ResourceUnavailableException;
boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException;
}

View File

@ -0,0 +1,97 @@
// Copyright 2012 Citrix Systems, Inc. Licensed under the
// Apache License, Version 2.0 (the "License"); you may not use this
// file except in compliance with the License. Citrix Systems, Inc.
// reserves all rights not expressly granted by the License.
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.vpc;
/**
* @author Alena Prokharchyk
*/
public class StaticRouteProfile implements StaticRoute{
private long id;
private String cidr;
private long accountId;
private long domainId;
private long gatewayId;
private StaticRoute.State state;
private long vpcId;
String vlanTag;
String gateway;
String netmask;
String ipAddress;
public StaticRouteProfile(StaticRoute staticRoute, PrivateGateway gateway) {
this.id = staticRoute.getId();
this.cidr = staticRoute.getCidr();
this.accountId = staticRoute.getAccountId();
this.domainId = staticRoute.getDomainId();
this.gatewayId = staticRoute.getVpcGatewayId();
this.state = staticRoute.getState();
this.vpcId = staticRoute.getVpcId();
this.vlanTag = gateway.getVlanTag();
this.gateway = gateway.getGateway();
this.netmask = gateway.getNetmask();
this.ipAddress = gateway.getIp4Address();
}
@Override
public long getAccountId() {
return accountId;
}
@Override
public long getDomainId() {
return domainId;
}
@Override
public long getVpcGatewayId() {
return gatewayId;
}
@Override
public String getCidr() {
return cidr;
}
@Override
public State getState() {
return state;
}
@Override
public Long getVpcId() {
return vpcId;
}
@Override
public long getId() {
return id;
}
public String getVlanTag() {
return vlanTag;
}
public String getIp4Address() {
return ipAddress;
}
public String getGateway() {
return gateway;
}
public String getNetmask() {
return netmask;
}
}

View File

@ -189,14 +189,16 @@ public interface VpcService {
/**
* @param vpcId
* @return
* @throws ResourceUnavailableException
*/
public boolean applyStaticRoutes(long vpcId);
public boolean applyStaticRoutes(long vpcId) throws ResourceUnavailableException;
/**
* @param routeId
* @return TODO
* @throws ResourceUnavailableException
*/
public boolean revokeStaticRoute(long routeId);
public boolean revokeStaticRoute(long routeId) throws ResourceUnavailableException;
/**
* @param gatewayId

View File

@ -156,6 +156,8 @@ import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
import com.cloud.agent.api.routing.SetSourceNatCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.routing.SetStaticRouteAnswer;
import com.cloud.agent.api.routing.SetStaticRouteCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
@ -542,12 +544,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((SetNetworkACLCommand) cmd);
} else if (clazz == SetPortForwardingRulesVpcCommand.class) {
return execute((SetPortForwardingRulesVpcCommand) cmd);
} else if (clazz == SetStaticRouteCommand.class) {
return execute((SetStaticRouteCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
}
protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException {
if (name != null) {
if (s_logger.isDebugEnabled()) {
@ -7125,4 +7128,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
//TODO - add implementation
return null;
}
private SetStaticRouteAnswer execute(SetStaticRouteCommand cmd) {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -3563,6 +3563,8 @@ public class ApiResponseHelper implements ResponseGenerator {
stateToSet = "Deleting";
}
response.setState(stateToSet);
populateAccount(response, result.getAccountId());
populateDomain(response, result.getDomainId());
response.setObjectName("staticroute");
return response;

View File

@ -32,19 +32,19 @@ import com.cloud.network.Network;
import com.cloud.network.Network.Capability;
import com.cloud.network.Network.Provider;
import com.cloud.network.Network.Service;
import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
import com.cloud.network.NetworkService;
import com.cloud.network.PublicIpAddress;
import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
import com.cloud.network.router.VirtualRouter;
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
import com.cloud.network.rules.FirewallRule;
import com.cloud.network.rules.NetworkACL;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.VpcGateway;
import com.cloud.network.vpc.VpcManager;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.offering.NetworkOffering;
import com.cloud.utils.component.Inject;
import com.cloud.utils.exception.CloudRuntimeException;
@ -119,7 +119,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
@Override
public boolean shutdownVpc(Vpc vpc) throws ConcurrentOperationException, ResourceUnavailableException {
List<DomainRouterVO> routers = _routerDao.listRoutersByVpcId(vpc.getId());
List<DomainRouterVO> routers = _routerDao.listByVpcId(vpc.getId());
if (routers == null || routers.isEmpty()) {
return true;
}
@ -228,7 +228,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
return success;
}
List<? extends VirtualRouter> routers = _routerDao.listRoutersByVpcId(vpcId);
List<? extends VirtualRouter> routers = _routerDao.listByVpcId(vpcId);
for (VirtualRouter router : routers) {
//1) Check if router is already a part of the network
if (!_ntwkService.isVmPartOfNetwork(router.getId(), network.getId())) {
@ -256,7 +256,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
return success;
}
List<? extends VirtualRouter> routers = _routerDao.listRoutersByVpcId(vpcId);
List<? extends VirtualRouter> routers = _routerDao.listByVpcId(vpcId);
for (VirtualRouter router : routers) {
//1) Check if router is already a part of the network
if (!_ntwkService.isVmPartOfNetwork(router.getId(), config.getId())) {
@ -403,12 +403,20 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
return VirtualRouterProviderType.VPCVirtualRouter;
}
/* (non-Javadoc)
* @see com.cloud.network.element.VpcProvider#applyStaticRoutes(com.cloud.network.vpc.Vpc, java.util.List)
*/
@Override
public boolean applyStaticRoutes(Vpc vpc, List<? extends StaticRoute> routes) throws ResourceUnavailableException {
// TODO Auto-generated method stub
return false;
public boolean applyStaticRoutes(Vpc vpc, List<StaticRouteProfile> routes) throws ResourceUnavailableException {
List<DomainRouterVO> routers = _routerDao.listByVpcId(vpc.getId());
if (routers == null || routers.isEmpty()) {
s_logger.debug("Virtual router elemnt doesn't need to static routes on the backend; virtual " +
"router doesn't exist in the vpc " + vpc);
return true;
}
if (!_vpcRouterMgr.applyStaticRoutes(routes, routers)) {
throw new CloudRuntimeException("Failed to apply static routes in vpc " + vpc);
} else {
s_logger.debug("Applied static routes on vpc " + vpc);
return true;
}
}
}

View File

@ -277,16 +277,16 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
if (!oneOfRulesIsFirewall) {
if (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() != Purpose.StaticNat) {
throw new NetworkRuleConflictException("There is 1 to 1 Nat rule specified for the ip address id="
+ newRule.getSourceIpAddressId());
+ newRule.getSourceIpAddressId());
} else if (rule.getPurpose() != Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat) {
throw new NetworkRuleConflictException("There is already firewall rule specified for the ip address id="
+ newRule.getSourceIpAddressId());
+ newRule.getSourceIpAddressId());
}
}
if (rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
throw new NetworkRuleConflictException("New rule is for a different network than what's specified in rule "
+ rule.getXid());
+ rule.getXid());
}
if (newRule.getProtocol().equalsIgnoreCase(NetUtils.ICMP_PROTO) && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol())) {
@ -302,14 +302,20 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma
if (!notNullPorts) {
continue;
} else if (!oneOfRulesIsFirewall && !(bothRulesFirewall && !duplicatedCidrs)
&& ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue())
|| (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue())
|| (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue())
|| (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
&& ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue()
&& rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue())
|| (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue()
&& rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue())
|| (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue()
&& newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue())
|| (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue()
&& newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) {
// we allow port forwarding rules with the same parameters but different protocols
boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat && !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding
&& !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
boolean allowStaticNat = (rule.getPurpose() == Purpose.StaticNat && newRule.getPurpose() == Purpose.StaticNat
&& !newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()));
if (!(allowPf || allowStaticNat || oneOfRulesIsFirewall)) {
throw new NetworkRuleConflictException("The range specified, " + newRule.getSourcePortStart() + "-" + newRule.getSourcePortEnd() + ", conflicts with rule " + rule.getId()

View File

@ -22,6 +22,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.network.Network;
import com.cloud.network.VpcVirtualNetworkApplianceService;
import com.cloud.network.rules.NetworkACL;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.user.Account;
@ -75,4 +76,12 @@ public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplian
*/
boolean destroyPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException;
/**
* @param routes
* @param routers
* @return
* @throws ResourceUnavailableException
*/
boolean applyStaticRoutes(List<StaticRouteProfile> routes, List<DomainRouterVO> routers) throws ResourceUnavailableException;
}

View File

@ -35,6 +35,7 @@ import com.cloud.agent.api.routing.IpAssocVpcCommand;
import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.SetNetworkACLCommand;
import com.cloud.agent.api.routing.SetSourceNatCommand;
import com.cloud.agent.api.routing.SetStaticRouteCommand;
import com.cloud.agent.api.to.IpAddressTO;
import com.cloud.agent.api.to.NetworkACLTO;
import com.cloud.agent.api.to.NicTO;
@ -72,6 +73,7 @@ import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.firewall.NetworkACLService;
import com.cloud.network.rules.NetworkACL;
import com.cloud.network.vpc.PrivateGateway;
import com.cloud.network.vpc.StaticRouteProfile;
import com.cloud.network.vpc.Vpc;
import com.cloud.network.vpc.Dao.VpcDao;
import com.cloud.network.vpc.Dao.VpcOfferingDao;
@ -183,7 +185,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
long dcId = dest.getDataCenter().getId();
DeploymentPlan plan = new DataCenterDeployment(dcId);
List<DomainRouterVO> routers = _routerDao.listRoutersByVpcId(vpcId);
List<DomainRouterVO> routers = _routerDao.listByVpcId(vpcId);
return new Pair<DeploymentPlan, List<DomainRouterVO>>(plan, routers);
}
@ -668,7 +670,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
}
protected boolean sendNetworkACLs(VirtualRouter router, List<NetworkACL> rules, long guestNetworkId) throws ResourceUnavailableException {
protected boolean sendNetworkACLs(VirtualRouter router, List<NetworkACL> rules, long guestNetworkId)
throws ResourceUnavailableException {
Commands cmds = new Commands(OnError.Continue);
createNetworkACLsCommands(rules, router, cmds, guestNetworkId);
return sendCommandsToRouter(router, cmds);
@ -936,4 +939,37 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
}
}
}
@Override
public boolean applyStaticRoutes(List<StaticRouteProfile> staticRoutes, List<DomainRouterVO> routers) throws ResourceUnavailableException {
if (staticRoutes == null || staticRoutes.isEmpty()) {
s_logger.debug("No static routes to apply");
return true;
}
//send commands to only one router as there is only one in the VPC
return sendStaticRoutes(staticRoutes, routers.get(0));
}
protected boolean sendStaticRoutes(List<StaticRouteProfile> staticRoutes, DomainRouterVO router)
throws ResourceUnavailableException {
Commands cmds = new Commands(OnError.Continue);
createStaticRouteCommands(staticRoutes, router, cmds);
return sendCommandsToRouter(router, cmds);
}
/**
* @param staticRoutes
* @param router
* @param cmds
*/
private void createStaticRouteCommands(List<StaticRouteProfile> staticRoutes, DomainRouterVO router, Commands cmds) {
SetStaticRouteCommand cmd = new SetStaticRouteCommand(staticRoutes);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn());
cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
cmds.addCommand(cmd);
}
}

View File

@ -12,6 +12,9 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.vpc.Dao;
import java.util.List;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.StaticRouteVO;
import com.cloud.utils.db.GenericDao;
@ -19,5 +22,10 @@ import com.cloud.utils.db.GenericDao;
* @author Alena Prokharchyk
*/
public interface StaticRouteDao extends GenericDao<StaticRouteVO, Long>{
boolean setStateToAdd(StaticRouteVO rule);
List<? extends StaticRoute> listByGatewayIdAndNotRevoked(long gatewayId);
List<? extends StaticRoute> listByVpcId(long vpcId);
}

View File

@ -12,11 +12,17 @@
// Automatically generated by addcopyright.py at 04/03/2012
package com.cloud.network.vpc.Dao;
import java.util.List;
import javax.ejb.Local;
import com.cloud.network.vpc.StaticRoute;
import com.cloud.network.vpc.StaticRouteVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
/**
* @author Alena Prokharchyk
@ -25,5 +31,50 @@ import com.cloud.utils.db.GenericDaoBase;
@Local(value = StaticRouteDao.class)
@DB(txn = false)
public class StaticRouteDaoImpl extends GenericDaoBase<StaticRouteVO, Long> implements StaticRouteDao{
protected final SearchBuilder<StaticRouteVO> AllFieldsSearch;
protected final SearchBuilder<StaticRouteVO> NotRevokedSearch;
protected StaticRouteDaoImpl() {
super();
AllFieldsSearch = createSearchBuilder();
AllFieldsSearch.and("gatewayId", AllFieldsSearch.entity().getVpcGatewayId(), Op.EQ);
AllFieldsSearch.and("vpcId", AllFieldsSearch.entity().getVpcId(), Op.EQ);
AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), Op.EQ);
AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), Op.EQ);
AllFieldsSearch.done();
NotRevokedSearch = createSearchBuilder();
NotRevokedSearch.and("gatewayId", NotRevokedSearch.entity().getVpcGatewayId(), Op.EQ);
NotRevokedSearch.and("state", NotRevokedSearch.entity().getState(), Op.NEQ);
NotRevokedSearch.done();
}
@Override
public boolean setStateToAdd(StaticRouteVO rule) {
SearchCriteria<StaticRouteVO> sc = AllFieldsSearch.create();
sc.setParameters("id", rule.getId());
sc.setParameters("state", StaticRoute.State.Staged);
rule.setState(StaticRoute.State.Add);
return update(rule, sc) > 0;
}
@Override
public List<? extends StaticRoute> listByGatewayIdAndNotRevoked(long gatewayId) {
SearchCriteria<StaticRouteVO> sc = NotRevokedSearch.create();
sc.setParameters("gatewayId", gatewayId);
sc.setParameters("state", StaticRoute.State.Revoke);
return listBy(sc);
}
@Override
public List<? extends StaticRoute> listByVpcId(long vpcId) {
SearchCriteria<StaticRouteVO> sc = AllFieldsSearch.create();
sc.setParameters("vpcId", vpcId);
return listBy(sc);
}
}

View File

@ -72,13 +72,17 @@ public class StaticRouteVO implements Identity, StaticRoute{
* @param vpcGatewayId
* @param cidr
* @param vpcId
* @param accountId TODO
* @param domainId TODO
*/
public StaticRouteVO(long vpcGatewayId, String cidr, Long vpcId) {
public StaticRouteVO(long vpcGatewayId, String cidr, Long vpcId, long accountId, long domainId) {
super();
this.vpcGatewayId = vpcGatewayId;
this.cidr = cidr;
this.state = State.Staged;
this.vpcId = vpcId;
this.accountId = accountId;
this.domainId = domainId;
this.uuid = UUID.randomUUID().toString();
}
@ -121,4 +125,15 @@ public class StaticRouteVO implements Identity, StaticRoute{
public long getDomainId() {
return domainId;
}
public void setState(State state) {
this.state = state;
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder("StaticRoute[");
buf.append(uuid).append("|").append(cidr).append("|").append(vpcGatewayId).append("]");
return buf.toString();
}
}

View File

@ -77,6 +77,7 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.net.NetUtils;
import com.cloud.vm.DomainRouterVO;
import com.cloud.vm.ReservationContext;
@ -611,7 +612,6 @@ public class VpcManagerImpl implements VpcManager, Manager{
sb.and("state", sb.entity().getState(), SearchCriteria.Op.EQ);
sb.and("restartRequired", sb.entity().isRestartRequired(), SearchCriteria.Op.EQ);
// now set the SC criteria...
SearchCriteria<VpcVO> sc = sb.create();
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
@ -796,7 +796,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
try {
//1) CIDR is required
//1) CIDR is required
if (cidr == null) {
throw new InvalidParameterValueException("Gateway/netmask are required when create network for VPC");
}
@ -930,7 +930,7 @@ public class VpcManagerImpl implements VpcManager, Manager{
@Override
public List<DomainRouterVO> getVpcRouters(long vpcId) {
return _routerDao.listRoutersByVpcId(vpcId);
return _routerDao.listByVpcId(vpcId);
}
@Override
@ -1110,26 +1110,193 @@ public class VpcManagerImpl implements VpcManager, Manager{
}
@Override
public boolean applyStaticRoutes(long vpcId) {
// TODO Auto-generated method stub
return false;
public boolean applyStaticRoutes(long vpcId) throws ResourceUnavailableException {
Account caller = UserContext.current().getCaller();
List<? extends StaticRoute> routes = _staticRouteDao.listByVpcId(vpcId);
return applyStaticRoutes(routes, caller);
}
protected boolean applyStaticRoutes(List<? extends StaticRoute> routes, Account caller) throws ResourceUnavailableException {
boolean success = true;
List<StaticRouteProfile> staticRouteProfiles = new ArrayList<StaticRouteProfile>(routes.size());
Map<Long, PrivateGateway> gatewayMap = new HashMap<Long, PrivateGateway>();
for (StaticRoute route : routes) {
PrivateGateway gateway = gatewayMap.get(route.getVpcGatewayId());
if (gateway == null) {
gateway = getVpcPrivateGateway(route.getVpcGatewayId());
gatewayMap.put(gateway.getId(), gateway);
}
staticRouteProfiles.add(new StaticRouteProfile(route, gateway));
}
if (!applyStaticRoutes(staticRouteProfiles)) {
s_logger.warn("Routes are not completely applied");
return false;
} else {
for (StaticRoute route : routes) {
if (route.getState() == StaticRoute.State.Revoke) {
_staticRouteDao.remove(route.getId());
} else if (route.getState() == StaticRoute.State.Add) {
StaticRouteVO ruleVO = _staticRouteDao.findById(route.getId());
ruleVO.setState(StaticRoute.State.Active);
_staticRouteDao.update(ruleVO.getId(), ruleVO);
}
}
}
return success;
}
protected boolean applyStaticRoutes(List<StaticRouteProfile> routes) throws ResourceUnavailableException{
if (routes.isEmpty()) {
s_logger.debug("No static routes to apply");
return true;
}
Vpc vpc = getVpc(routes.get(0).getVpcId());
s_logger.debug("Applying static routes for vpc " + vpc);
if (getVpcElement().applyStaticRoutes(vpc, routes)) {
s_logger.debug("Applied static routes for vpc " + vpc);
} else {
s_logger.warn("Failed to apply static routes for vpc " + vpc);
return false;
}
return true;
}
@Override
public boolean revokeStaticRoute(long routeId) {
// TODO Auto-generated method stub
return false;
public boolean revokeStaticRoute(long routeId) throws ResourceUnavailableException {
Account caller = UserContext.current().getCaller();
StaticRouteVO route = _staticRouteDao.findById(routeId);
if (route == null) {
throw new InvalidParameterValueException("Unable to find static route by id");
}
_accountMgr.checkAccess(caller, null, false, route);
revokeStaticRoute(route, caller);
return applyStaticRoutes(route.getVpcId());
}
@Override
@DB
public StaticRoute createStaticRoute(long gatewayId, String cidr) throws NetworkRuleConflictException {
// TODO Auto-generated method stub
return null;
Account caller = UserContext.current().getCaller();
//parameters validation
PrivateGateway gateway = getVpcPrivateGateway(gatewayId);
if (gateway == null) {
throw new InvalidParameterValueException("Invalid gateway id is given");
}
Vpc vpc = getVpc(gateway.getVpcId());
_accountMgr.checkAccess(caller, null, false, vpc);
if (!NetUtils.isValidCIDR(cidr)){
throw new InvalidParameterValueException("Invalid format for cidr " + cidr);
}
//TODO - check cidr for the conflicts
Transaction txn = Transaction.currentTxn();
txn.start();
StaticRouteVO newRoute = new StaticRouteVO(gateway.getId(), cidr, vpc.getId(), vpc.getAccountId(), vpc.getDomainId());
s_logger.debug("Adding static route " + newRoute);
newRoute = _staticRouteDao.persist(newRoute);
detectRoutesConflict(newRoute);
if (!_staticRouteDao.setStateToAdd(newRoute)) {
throw new CloudRuntimeException("Unable to update the state to add for " + newRoute);
}
UserContext.current().setEventDetails("Static route Id: " + newRoute.getId());
txn.commit();
return newRoute;
}
@Override
public List<? extends StaticRoute> listStaticRoutes(ListStaticRoutesCmd cmd) {
// TODO Auto-generated method stub
return null;
Long id = cmd.getId();
Long gatewayId = cmd.getGatewayId();
Long vpcId = cmd.getVpcId();
Long domainId = cmd.getDomainId();
Boolean isRecursive = cmd.isRecursive();
Boolean listAll = cmd.listAll();
String accountName = cmd.getAccountName();
Account caller = UserContext.current().getCaller();
List<Long> permittedAccounts = new ArrayList<Long>();
Ternary<Long, Boolean, ListProjectResourcesCriteria> domainIdRecursiveListProject = new Ternary<Long, Boolean,
ListProjectResourcesCriteria>(domainId, isRecursive, null);
_accountMgr.buildACLSearchParameters(caller, id, accountName, null, permittedAccounts, domainIdRecursiveListProject,
listAll, false);
domainId = domainIdRecursiveListProject.first();
isRecursive = domainIdRecursiveListProject.second();
ListProjectResourcesCriteria listProjectResourcesCriteria = domainIdRecursiveListProject.third();
Filter searchFilter = new Filter(StaticRouteVO.class, "created", false, cmd.getStartIndex(), cmd.getPageSizeVal());
SearchBuilder<StaticRouteVO> sb = _staticRouteDao.createSearchBuilder();
_accountMgr.buildACLSearchBuilder(sb, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
sb.and("id", sb.entity().getId(), SearchCriteria.Op.EQ);
sb.and("vpcId", sb.entity().getVpcId(), SearchCriteria.Op.EQ);
sb.and("vpcGatewayId", sb.entity().getVpcGatewayId(), SearchCriteria.Op.EQ);
SearchCriteria<StaticRouteVO> sc = sb.create();
_accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria);
if (id != null) {
sc.addAnd("id", Op.EQ, id);
}
if (vpcId != null) {
sc.addAnd("vpcId", Op.EQ, vpcId);
}
if (gatewayId != null) {
sc.addAnd("vpcGatewayId", Op.EQ, vpcId);
}
return _staticRouteDao.search(sc, searchFilter);
}
protected void detectRoutesConflict(StaticRoute newRoute) throws NetworkRuleConflictException {
List<? extends StaticRoute> routes = _staticRouteDao.listByGatewayIdAndNotRevoked(newRoute.getVpcGatewayId());
assert (routes.size() >= 1) : "For static routes, we now always first persist the route and then check for " +
"network conflicts so we should at least have one rule at this point.";
for (StaticRoute route : routes) {
if (route.getId() == newRoute.getId()) {
continue; // Skips my own route.
}
if (NetUtils.isNetworksOverlap(route.getCidr(), newRoute.getCidr())) {
throw new NetworkRuleConflictException("New static route cidr conflicts with existing route " + route);
}
}
}
protected void revokeStaticRoute(StaticRouteVO route, Account caller) {
s_logger.debug("Revoking static route " + route);
if (caller != null) {
_accountMgr.checkAccess(caller, null, false, route);
}
if (route.getState() == StaticRoute.State.Staged) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found a static route that is still in stage state so just removing it: " + route);
}
_staticRouteDao.remove(route.getId());
} else if (route.getState() == StaticRoute.State.Add || route.getState() == StaticRoute.State.Active) {
route.setState(StaticRoute.State.Revoke);
_staticRouteDao.update(route.getId(), route);
}
}
}

View File

@ -110,7 +110,7 @@ public interface DomainRouterDao extends GenericDao<DomainRouterVO, Long> {
* @param vpcId
* @return
*/
List<DomainRouterVO> listRoutersByVpcId(long vpcId);
List<DomainRouterVO> listByVpcId(long vpcId);
/**
* @param routerId

View File

@ -303,7 +303,7 @@ public class DomainRouterDaoImpl extends GenericDaoBase<DomainRouterVO, Long> im
}
@Override
public List<DomainRouterVO> listRoutersByVpcId(long vpcId) {
public List<DomainRouterVO> listByVpcId(long vpcId) {
SearchCriteria<DomainRouterVO> sc = VpcSearch.create();
sc.setParameters("vpcId", vpcId);
sc.setParameters("role", Role.VIRTUAL_ROUTER);