diff --git a/api/src/com/cloud/api/ApiConstants.java b/api/src/com/cloud/api/ApiConstants.java index 34fc75071d9..419d577358a 100755 --- a/api/src/com/cloud/api/ApiConstants.java +++ b/api/src/com/cloud/api/ApiConstants.java @@ -360,6 +360,7 @@ public class ApiConstants { public static final String VPC_OFF_ID = "vpcofferingid"; public static final String NETWORK = "network"; public static final String VPC_ID = "vpcid"; + public static final String GATEWAY_ID = "gatewaycid"; public enum HostDetails { all, capacity, events, stats, min; diff --git a/api/src/com/cloud/api/ResponseGenerator.java b/api/src/com/cloud/api/ResponseGenerator.java index 2095f8fb5b2..5f79e197385 100755 --- a/api/src/com/cloud/api/ResponseGenerator.java +++ b/api/src/com/cloud/api/ResponseGenerator.java @@ -63,6 +63,7 @@ import com.cloud.api.response.ServiceOfferingResponse; import com.cloud.api.response.ServiceResponse; import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; import com.cloud.api.response.StorageNetworkIpRangeResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.api.response.SwiftResponse; @@ -112,6 +113,7 @@ import com.cloud.network.rules.StickinessPolicy; import com.cloud.network.security.SecurityGroup; import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityRule; +import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcOffering; import com.cloud.network.vpc.PrivateGateway; @@ -311,5 +313,11 @@ public interface ResponseGenerator { * @param result * @return */ - PrivateGatewayResponse createPrivateGatewayResponseResponse(PrivateGateway result); + PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result); + + /** + * @param result + * @return + */ + StaticRouteResponse createStaticRouteResponse(StaticRoute result); } diff --git a/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java index 8cb7a6d47de..4f0fe038e7e 100644 --- a/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java +++ b/api/src/com/cloud/api/commands/CreatePrivateGatewayCmd.java @@ -127,7 +127,7 @@ public class CreatePrivateGatewayCmd extends BaseAsyncCreateCmd { ResourceAllocationException, ResourceUnavailableException { PrivateGateway result = _vpcService.applyVpcGateway(getEntityId()); if (result != null) { - PrivateGatewayResponse response = _responseGenerator.createPrivateGatewayResponseResponse(result); + PrivateGatewayResponse response = _responseGenerator.createPrivateGatewayResponse(result); response.setResponseName(getCommandName()); this.setResponseObject(response); } else { diff --git a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java index 9006547673a..6b217757fbb 100644 --- a/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java +++ b/api/src/com/cloud/api/commands/ListPrivateGatewaysCmd.java @@ -80,7 +80,7 @@ public class ListPrivateGatewaysCmd extends BaseListCmd{ ListResponse response = new ListResponse(); List projectResponses = new ArrayList(); for (PrivateGateway gateway : gateways) { - PrivateGatewayResponse gatewayResponse = _responseGenerator.createPrivateGatewayResponseResponse(gateway); + PrivateGatewayResponse gatewayResponse = _responseGenerator.createPrivateGatewayResponse(gateway); projectResponses.add(gatewayResponse); } response.setResponses(projectResponses); diff --git a/api/src/com/cloud/api/response/StaticRouteResponse.java b/api/src/com/cloud/api/response/StaticRouteResponse.java new file mode 100644 index 00000000000..a77c71b25fd --- /dev/null +++ b/api/src/com/cloud/api/response/StaticRouteResponse.java @@ -0,0 +1,59 @@ +// 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.api.response; + +import com.cloud.api.ApiConstants; +import com.cloud.serializer.Param; +import com.cloud.utils.IdentityProxy; +import com.google.gson.annotations.SerializedName; + +/** + * @author Alena Prokharchyk + */ +@SuppressWarnings("unused") +public class StaticRouteResponse extends BaseResponse{ + @SerializedName(ApiConstants.ID) @Param(description="the ID of static route") + private IdentityProxy id = new IdentityProxy("static_routes"); + + @SerializedName(ApiConstants.STATE) @Param(description="the state of the static route") + private String state; + + @SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the static route belongs to") + private IdentityProxy vpcId = new IdentityProxy("vpc"); + + @SerializedName(ApiConstants.GATEWAY_ID) @Param(description="VPC gateway the route is created for") + private IdentityProxy gatewayId = new IdentityProxy("vpc_gateways"); + + @SerializedName(ApiConstants.CIDR) @Param(description="static route CIDR") + private String cidr; + + public void setId(Long id) { + this.id.setValue(id); + } + + public void setState(String state) { + this.state = state; + } + + public void setVpcId(Long vpcId) { + this.vpcId.setValue(vpcId); + } + + public void setGatewayId(Long gatewayId) { + this.gatewayId.setValue(gatewayId); + } + + public void setCidr(String cidr) { + this.cidr = cidr; + } +} diff --git a/api/src/com/cloud/network/vpc/StaticRoute.java b/api/src/com/cloud/network/vpc/StaticRoute.java new file mode 100644 index 00000000000..fee47ab71de --- /dev/null +++ b/api/src/com/cloud/network/vpc/StaticRoute.java @@ -0,0 +1,53 @@ +// 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 interface StaticRoute { + enum State { + Staged, // route been created but has never got through network rule conflict detection. Routes in this state can not be sent to VPC virtual router. + Add, // Add means the route has been created and has gone through network rule conflict detection. + Active, // Route has been sent to the VPC router and reported to be active. + Revoke // Revoke means this route has been revoked. If this route has been sent to the VPC router, the route will be deleted from database. + } + + /** + * @return + */ + long getVpcGatewayId(); + + /** + * @return + */ + String getCidr(); + + /** + * @return + */ + State getState(); + + /** + * @return + */ + Long getVpcId(); + + /** + * @return + */ + long getId(); + + +} diff --git a/client/tomcatconf/commands.properties.in b/client/tomcatconf/commands.properties.in index 748101e15c8..64f9415b475 100755 --- a/client/tomcatconf/commands.properties.in +++ b/client/tomcatconf/commands.properties.in @@ -356,7 +356,12 @@ createPrivateGateway=com.cloud.api.commands.CreatePrivateGatewayCmd;1 listPrivateGateways=com.cloud.api.commands.ListPrivateGatewaysCmd;1 deletePrivateGateway=com.cloud.api.commands.DeletePrivateGatewayCmd;1 -#### +#### Network ACL commands createNetworkACL=com.cloud.api.commands.CreateNetworkACLCmd;15 deleteNetworkACL=com.cloud.api.commands.DeleteNetworkACLCmd;15 listNetworkACLs=com.cloud.api.commands.ListNetworkACLsCmd;15 + +#### Static route commands +#createStaticRoute=com.cloud.api.commands.CreateStaticRouteCmd;15 +#deleteStaticRoute=com.cloud.api.commands.DeleteStaticRouteCmd;15 +#listStaticRoutes=com.cloud.api.commands.ListStaticRoutesCmd;15 diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 52712e6cdb1..d01213e9099 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -80,6 +80,7 @@ import com.cloud.api.response.ServiceOfferingResponse; import com.cloud.api.response.ServiceResponse; import com.cloud.api.response.SnapshotPolicyResponse; import com.cloud.api.response.SnapshotResponse; +import com.cloud.api.response.StaticRouteResponse; import com.cloud.api.response.StorageNetworkIpRangeResponse; import com.cloud.api.response.StoragePoolResponse; import com.cloud.api.response.SwiftResponse; @@ -148,9 +149,10 @@ import com.cloud.network.security.SecurityGroupRules; import com.cloud.network.security.SecurityGroupVO; import com.cloud.network.security.SecurityRule; import com.cloud.network.security.SecurityRule.SecurityRuleType; +import com.cloud.network.vpc.PrivateGateway; +import com.cloud.network.vpc.StaticRoute; import com.cloud.network.vpc.Vpc; import com.cloud.network.vpc.VpcOffering; -import com.cloud.network.vpc.PrivateGateway; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; import com.cloud.offering.ServiceOffering; @@ -3530,7 +3532,7 @@ public class ApiResponseHelper implements ResponseGenerator { } @Override - public PrivateGatewayResponse createPrivateGatewayResponseResponse(PrivateGateway result) { + public PrivateGatewayResponse createPrivateGatewayResponse(PrivateGateway result) { PrivateGatewayResponse response = new PrivateGatewayResponse(); response.setId(result.getId()); response.setVlan(result.getVlanTag()); @@ -3547,4 +3549,23 @@ public class ApiResponseHelper implements ResponseGenerator { return response; } + + @Override + public StaticRouteResponse createStaticRouteResponse(StaticRoute result) { + StaticRouteResponse response = new StaticRouteResponse(); + response.setId(result.getId()); + response.setVpcId(result.getVpcId()); + response.setCidr(result.getCidr()); + + StaticRoute.State state = result.getState(); + String stateToSet = state.toString(); + if (state.equals(FirewallRule.State.Revoke)) { + stateToSet = "Deleting"; + } + response.setState(stateToSet); + response.setObjectName("staticroute"); + + return response; + } + } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 34cc29a56ee..fce05842dd1 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -1891,6 +1891,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian List routerGuestNtwkIds = _routerDao.getRouterNetworks(router.getId()); for (Long guestNetworkId : routerGuestNtwkIds) { if (reprogramGuestNtwks) { + finalizeIpAssocForNetwork(cmds, router, provider, guestNetworkId); finalizeNetworkRulesForNetwork(cmds, router, provider, guestNetworkId); } @@ -1952,40 +1953,16 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian protected void finalizeNetworkRulesForNetwork(Commands cmds, DomainRouterVO router, Provider provider, Long guestNetworkId) { s_logger.debug("Resending ipAssoc, port forwarding, load balancing rules as a part of Virtual router start"); - long ownerId = router.getAccountId(); - final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); - List allPublicIps = new ArrayList(); - if (userIps != null && !userIps.isEmpty()) { - for (IPAddressVO userIp : userIps) { - PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), - NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); - allPublicIps.add(publicIp); - } - } - - //Get public Ips that should be handled by router - Network network = _networkDao.findById(guestNetworkId); - Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); - Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); - // Only cover virtual router for now, if ELB use it this need to be modified - - ArrayList publicIps = providerToIpList.get(provider); - - s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); - - if (!publicIps.isEmpty()) { + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { List vpns = new ArrayList(); List pfRules = new ArrayList(); List staticNatFirewallRules = new ArrayList(); List staticNats = new ArrayList(); List firewallRules = new ArrayList(); - // Re-apply public ip addresses - should come before PF/LB/VPN - if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { - createAssociateIPCommands(router, publicIps, cmds, 0); - } - //Get information about all the rules (StaticNats and StaticNatRules; PFVPN to reapply on domR start) for (PublicIp ip : publicIps) { if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.PortForwarding, provider)) { @@ -2031,7 +2008,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian if (!pfRules.isEmpty()) { createApplyPortForwardingRulesCommands(pfRules, router, cmds, guestNetworkId); } - + // Re-apply static nat rules s_logger.debug("Found " + staticNatFirewallRules.size() + " static nat rule(s) to apply as a part of domR " + router + " start."); if (!staticNatFirewallRules.isEmpty()) { @@ -2039,7 +2016,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian for (FirewallRule rule : staticNatFirewallRules) { staticNatRules.add(_rulesMgr.buildStaticNatRule(rule, false)); } - createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); + createApplyStaticNatRulesCommands(staticNatRules, router, cmds, guestNetworkId); } // Re-apply vpn rules @@ -2069,6 +2046,43 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian } } + protected ArrayList finalizeIpAssocForNetwork(Commands cmds, DomainRouterVO router, Provider provider, + Long guestNetworkId) { + + ArrayList publicIps = getPublicIpsToApply(router, provider, guestNetworkId); + + if (publicIps != null && !publicIps.isEmpty()) { + s_logger.debug("Found " + publicIps.size() + " ip(s) to apply as a part of domR " + router + " start."); + // Re-apply public ip addresses - should come before PF/LB/VPN + if (_networkMgr.isProviderSupportServiceInNetwork(guestNetworkId, Service.Firewall, provider)) { + createAssociateIPCommands(router, publicIps, cmds, 0); + } + } + return publicIps; + } + + protected ArrayList getPublicIpsToApply(DomainRouterVO router, Provider provider, Long guestNetworkId) { + long ownerId = router.getAccountId(); + final List userIps = _networkMgr.listPublicIpsAssignedToGuestNtwk(ownerId, guestNetworkId, null); + List allPublicIps = new ArrayList(); + if (userIps != null && !userIps.isEmpty()) { + for (IPAddressVO userIp : userIps) { + PublicIp publicIp = new PublicIp(userIp, _vlanDao.findById(userIp.getVlanId()), + NetUtils.createSequenceBasedMacAddress(userIp.getMacAddress())); + allPublicIps.add(publicIp); + } + } + + //Get public Ips that should be handled by router + Network network = _networkDao.findById(guestNetworkId); + Map> ipToServices = _networkMgr.getIpToServices(allPublicIps, false, false); + Map> providerToIpList = _networkMgr.getProviderToIpList(network, ipToServices); + // Only cover virtual router for now, if ELB use it this need to be modified + + ArrayList publicIps = providerToIpList.get(provider); + return publicIps; + } + @Override public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { diff --git a/server/src/com/cloud/network/rules/FirewallRuleVO.java b/server/src/com/cloud/network/rules/FirewallRuleVO.java index a9834ec3371..76b5b6bc7f5 100644 --- a/server/src/com/cloud/network/rules/FirewallRuleVO.java +++ b/server/src/com/cloud/network/rules/FirewallRuleVO.java @@ -32,7 +32,6 @@ import javax.persistence.Transient; import com.cloud.api.Identity; import com.cloud.network.dao.FirewallRulesCidrsDaoImpl; -import com.cloud.network.rules.FirewallRule.TrafficType; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.GenericDao; import com.cloud.utils.net.NetUtils; diff --git a/server/src/com/cloud/network/vpc/StaticRouteVO.java b/server/src/com/cloud/network/vpc/StaticRouteVO.java new file mode 100644 index 00000000000..3b58c358202 --- /dev/null +++ b/server/src/com/cloud/network/vpc/StaticRouteVO.java @@ -0,0 +1,104 @@ +// 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; + +import java.util.Date; +import java.util.UUID; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; + +import com.cloud.api.Identity; +import com.cloud.utils.db.GenericDao; + +/** + * @author Alena Prokharchyk + */ + +@Entity +@Table(name="static_routes") +public class StaticRouteVO implements Identity, StaticRoute{ + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + long id; + + @Column(name="uuid") + String uuid; + + @Column(name="vpc_gateway_id", updatable=false) + long vpcGatewayId; + + @Column(name="cidr") + private String cidr; + + @Enumerated(value=EnumType.STRING) + @Column(name="state") + State state; + + @Column(name="vpc_id") + private Long vpcId; + + @Column(name=GenericDao.CREATED_COLUMN) + Date created; + + /** + * @param vpcGatewayId + * @param cidr + * @param vpcId + */ + public StaticRouteVO(long vpcGatewayId, String cidr, Long vpcId) { + super(); + this.vpcGatewayId = vpcGatewayId; + this.cidr = cidr; + this.state = State.Staged; + this.vpcId = vpcId; + this.uuid = UUID.randomUUID().toString(); + } + + @Override + public long getVpcGatewayId() { + return vpcGatewayId; + } + + @Override + public String getCidr() { + return cidr; + } + + @Override + public State getState() { + return state; + } + + @Override + public Long getVpcId() { + return vpcId; + } + + @Override + public String getUuid() { + return this.uuid; + } + + @Override + public long getId() { + return id; + } +} \ No newline at end of file diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 88c2e38681c..c7f2cefd11f 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -2235,5 +2235,20 @@ CREATE TABLE `cloud`.`private_ip_address` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +CREATE TABLE `cloud`.`static_routes` ( + `id` bigint unsigned NOT NULL auto_increment COMMENT 'id', + `uuid` varchar(40), + `vpc_gateway_id` bigint unsigned COMMENT 'id of the corresponding ip address', + `cidr` varchar(18) COMMENT 'cidr for the static route', + `state` char(32) NOT NULL COMMENT 'current state of this rule', + `vpc_id` bigint unsigned COMMENT 'vpc the firewall rule is associated with', + `created` datetime COMMENT 'Date created', + PRIMARY KEY (`id`), + CONSTRAINT `fk_static_routes__vpc_gateway_id` FOREIGN KEY(`vpc_gateway_id`) REFERENCES `vpc_gateways`(`id`) ON DELETE CASCADE, + CONSTRAINT `fk_static_routes__vpc_id` FOREIGN KEY (`vpc_id`) REFERENCES `vpc`(`id`) ON DELETE CASCADE, + CONSTRAINT `uc_static_routes__uuid` UNIQUE (`uuid`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + + SET foreign_key_checks = 1;