diff --git a/api/src/com/cloud/network/RemoteAccessVpn.java b/api/src/com/cloud/network/RemoteAccessVpn.java index 1b463309a5f..058b2f486e6 100644 --- a/api/src/com/cloud/network/RemoteAccessVpn.java +++ b/api/src/com/cloud/network/RemoteAccessVpn.java @@ -17,8 +17,10 @@ package com.cloud.network; import org.apache.cloudstack.acl.ControlledEntity; +import org.apache.cloudstack.api.Identity; +import org.apache.cloudstack.api.InternalIdentity; -public interface RemoteAccessVpn extends ControlledEntity { +public interface RemoteAccessVpn extends ControlledEntity, InternalIdentity, Identity { enum State { Added, Running, diff --git a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java index bfd2c892ca1..d637da638ac 100644 --- a/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java +++ b/api/src/com/cloud/network/vpn/RemoteAccessVpnService.java @@ -45,6 +45,6 @@ public interface RemoteAccessVpnService { List listRemoteAccessVpns(long networkId); - RemoteAccessVpn getRemoteAccessVpn(long vpnId); + RemoteAccessVpn getRemoteAccessVpn(long vpnAddrId); } diff --git a/api/src/com/cloud/server/ResourceTag.java b/api/src/com/cloud/server/ResourceTag.java index ee56748640c..9006e305d81 100644 --- a/api/src/com/cloud/server/ResourceTag.java +++ b/api/src/com/cloud/server/ResourceTag.java @@ -38,7 +38,8 @@ public interface ResourceTag extends ControlledEntity, Identity, InternalIdentit Vpc, NetworkACL, StaticRoute, - VMSnapshot + VMSnapshot, + RemoteAccessVpn } /** diff --git a/api/src/org/apache/cloudstack/api/BaseCmd.java b/api/src/org/apache/cloudstack/api/BaseCmd.java index 8b7f43fd104..7ccb72e8fb9 100644 --- a/api/src/org/apache/cloudstack/api/BaseCmd.java +++ b/api/src/org/apache/cloudstack/api/BaseCmd.java @@ -28,7 +28,6 @@ import java.util.regex.Pattern; import javax.inject.Inject; import org.apache.cloudstack.query.QueryService; -import org.apache.cloudstack.region.RegionService; import org.apache.cloudstack.usage.UsageService; import org.apache.log4j.Logger; diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java index 7ddd7952172..5b1c5c6b4e6 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/DeleteRemoteAccessVpnCmd.java @@ -63,7 +63,7 @@ public class DeleteRemoteAccessVpnCmd extends BaseAsyncCmd { @Override public long getEntityOwnerId() { if (ownerId == null) { - RemoteAccessVpn vpnEntity = _entityMgr.findById(RemoteAccessVpn.class, publicIpId); + RemoteAccessVpn vpnEntity = _ravService.getRemoteAccessVpn(publicIpId); if(vpnEntity != null) return vpnEntity.getAccountId(); diff --git a/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java b/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java index 7db56630bc0..5e08bca6af2 100644 --- a/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java +++ b/api/src/org/apache/cloudstack/api/response/RemoteAccessVpnResponse.java @@ -57,6 +57,9 @@ public class RemoteAccessVpnResponse extends BaseResponse implements ControlledE @SerializedName(ApiConstants.STATE) @Param(description="the state of the rule") private String state; + + @SerializedName(ApiConstants.ID) @Param(description="the id of the remote access vpn") + private String id; public void setPublicIp(String publicIp) { this.publicIp = publicIp; @@ -100,5 +103,9 @@ public class RemoteAccessVpnResponse extends BaseResponse implements ControlledE public void setProjectName(String projectName) { this.projectName = projectName; } + + public void setId(String id) { + this.id = id; + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index ec809091f23..d350de2dfdd 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -1191,6 +1191,7 @@ public class ApiResponseHelper implements ResponseGenerator { populateOwner(vpnResponse, vpn); vpnResponse.setState(vpn.getState().toString()); + vpnResponse.setId(vpn.getUuid()); vpnResponse.setObjectName("remoteaccessvpn"); return vpnResponse; diff --git a/server/src/com/cloud/network/dao/RemoteAccessVpnVO.java b/server/src/com/cloud/network/dao/RemoteAccessVpnVO.java index 478decfe47b..2e8ee912464 100644 --- a/server/src/com/cloud/network/dao/RemoteAccessVpnVO.java +++ b/server/src/com/cloud/network/dao/RemoteAccessVpnVO.java @@ -16,13 +16,16 @@ // under the License. package com.cloud.network.dao; +import java.util.UUID; + import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import com.cloud.network.RemoteAccessVpn; -import com.cloud.network.RemoteAccessVpn.State; @Entity @Table(name=("remote_access_vpn")) @@ -36,7 +39,6 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn { @Column(name="domain_id") private long domainId; - @Id @Column(name="vpn_server_addr_id") private long serverAddressId; @@ -51,8 +53,18 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn { @Column(name="state") private State state; + + @Id + @GeneratedValue(strategy=GenerationType.IDENTITY) + @Column(name="id") + private long id; + + @Column(name="uuid") + private String uuid; - public RemoteAccessVpnVO() { } + public RemoteAccessVpnVO() { + this.uuid = UUID.randomUUID().toString(); + } public RemoteAccessVpnVO(long accountId, long domainId, long networkId, long publicIpId, String localIp, String ipRange, String presharedKey) { this.accountId = accountId; @@ -63,6 +75,7 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn { this.domainId = domainId; this.networkId = networkId; this.state = State.Added; + this.uuid = UUID.randomUUID().toString(); } @Override @@ -116,4 +129,14 @@ public class RemoteAccessVpnVO implements RemoteAccessVpn { public long getNetworkId() { return networkId; } + + @Override + public long getId() { + return id; + } + + @Override + public String getUuid() { + return uuid; + } } diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 78168b0b1a7..67c94fca030 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -303,8 +303,6 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V @Inject VpnUserDao _vpnUsersDao; @Inject - RemoteAccessVpnDao _remoteAccessVpnDao; - @Inject RulesManager _rulesMgr; @Inject NetworkDao _networkDao; @@ -2346,7 +2344,7 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V } if (_networkModel.isProviderSupportServiceInNetwork(guestNetworkId, Service.Vpn, provider)) { - RemoteAccessVpn vpn = _vpnDao.findById(ip.getId()); + RemoteAccessVpn vpn = _vpnDao.findByPublicIpAddress(ip.getId()); if (vpn != null) { vpns.add(vpn); } diff --git a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java index d64a0212b46..673535aaa42 100755 --- a/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/RemoteAccessVpnManagerImpl.java @@ -108,6 +108,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc SearchBuilder VpnSearch; @Override + @DB public RemoteAccessVpn createRemoteAccessVpn(long publicIpId, String ipRange, boolean openFirewall, long networkId) throws NetworkRuleConflictException { UserContext ctx = UserContext.current(); @@ -183,10 +184,17 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc long startIp = NetUtils.ip2Long(range[0]); String newIpRange = NetUtils.long2Ip(++startIp) + "-" + range[1]; String sharedSecret = PasswordGenerator.generatePresharedKey(_pskLength); + + Transaction txn = Transaction.currentTxn(); + txn.start(); + _rulesMgr.reservePorts(ipAddr, NetUtils.UDP_PROTO, Purpose.Vpn, openFirewall, caller, NetUtils.VPN_PORT, NetUtils.VPN_L2TP_PORT, NetUtils.VPN_NATT_PORT); vpnVO = new RemoteAccessVpnVO(ipAddr.getAccountId(), ipAddr.getDomainId(), ipAddr.getAssociatedWithNetworkId(), publicIpId, range[0], newIpRange, sharedSecret); - return _remoteAccessVpnDao.persist(vpnVO); + RemoteAccessVpn vpn = _remoteAccessVpnDao.persist(vpnVO); + + txn.commit(); + return vpn; } private void validateRemoteAccessVpnConfiguration() throws ConfigurationException { @@ -217,7 +225,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc @Override @DB public void destroyRemoteAccessVpn(long ipId, Account caller) throws ResourceUnavailableException { - RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(ipId); + RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipId); if (vpn == null) { s_logger.debug("vpn id=" + ipId + " does not exists "); return; @@ -228,7 +236,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc Network network = _networkMgr.getNetwork(vpn.getNetworkId()); vpn.setState(RemoteAccessVpn.State.Removed); - _remoteAccessVpnDao.update(vpn.getServerAddressId(), vpn); + _remoteAccessVpnDao.update(vpn.getId(), vpn); boolean success = false; @@ -273,7 +281,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc if (success) { try { txn.start(); - _remoteAccessVpnDao.remove(ipId); + _remoteAccessVpnDao.remove(vpn.getId()); // Stop billing of VPN users when VPN is removed. VPN_User_ADD events will be generated when VPN is created again List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); for(VpnUserVO user : vpnUsers){ @@ -363,18 +371,16 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } @Override @DB - public RemoteAccessVpnVO startRemoteAccessVpn(long vpnId, boolean openFirewall) throws ResourceUnavailableException { + public RemoteAccessVpnVO startRemoteAccessVpn(long ipAddressId, boolean openFirewall) throws ResourceUnavailableException { Account caller = UserContext.current().getCaller(); - RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findById(vpnId); + RemoteAccessVpnVO vpn = _remoteAccessVpnDao.findByPublicIpAddress(ipAddressId); if (vpn == null) { - throw new InvalidParameterValueException("Unable to find your vpn: " + vpnId); + throw new InvalidParameterValueException("Unable to find your vpn: " + ipAddressId); } _accountMgr.checkAccess(caller, null, true, vpn); - - Network network = _networkMgr.getNetwork(vpn.getNetworkId()); boolean started = false; @@ -399,7 +405,7 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc Transaction txn = Transaction.currentTxn(); txn.start(); vpn.setState(RemoteAccessVpn.State.Running); - _remoteAccessVpnDao.update(vpn.getServerAddressId(), vpn); + _remoteAccessVpnDao.update(vpn.getId(), vpn); // Start billing of existing VPN users in ADD and Active state List vpnUsers = _vpnUsersDao.listByAccount(vpn.getAccountId()); @@ -607,8 +613,8 @@ public class RemoteAccessVpnManagerImpl extends ManagerBase implements RemoteAcc } @Override - public RemoteAccessVpn getRemoteAccessVpn(long vpnId) { - return _remoteAccessVpnDao.findById(vpnId); + public RemoteAccessVpn getRemoteAccessVpn(long vpnAddrId) { + return _remoteAccessVpnDao.findByPublicIpAddress(vpnAddrId); } public List getRemoteAccessVPNServiceProviders() { diff --git a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java index 06756b617eb..20fccee2cc0 100644 --- a/server/src/com/cloud/tags/TaggedResourceManagerImpl.java +++ b/server/src/com/cloud/tags/TaggedResourceManagerImpl.java @@ -25,13 +25,10 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; -import org.apache.cloudstack.api.command.user.tag.ListTagsCmd; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; - import com.cloud.api.query.dao.ResourceTagJoinDao; -import com.cloud.api.query.vo.ResourceTagJoinVO; import com.cloud.domain.Domain; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; @@ -46,7 +43,6 @@ import com.cloud.network.rules.dao.PortForwardingRulesDao; import com.cloud.network.security.dao.SecurityGroupDao; import com.cloud.network.vpc.dao.StaticRouteDao; import com.cloud.network.vpc.dao.VpcDao; -import com.cloud.projects.Project.ListProjectResourcesCriteria; import com.cloud.projects.dao.ProjectDao; import com.cloud.server.ResourceTag; import com.cloud.server.ResourceTag.TaggedResourceType; @@ -60,12 +56,9 @@ import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.utils.Pair; -import com.cloud.utils.Ternary; -import com.cloud.utils.component.Manager; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.db.DB; import com.cloud.utils.db.DbUtil; -import com.cloud.utils.db.Filter; import com.cloud.utils.db.GenericDao; import com.cloud.utils.db.SearchBuilder; import com.cloud.utils.db.SearchCriteria; @@ -143,6 +136,7 @@ public class TaggedResourceManagerImpl extends ManagerBase implements TaggedReso _daoMap.put(TaggedResourceType.NetworkACL, _firewallDao); _daoMap.put(TaggedResourceType.StaticRoute, _staticRouteDao); _daoMap.put(TaggedResourceType.VMSnapshot, _vmSnapshotDao); + _daoMap.put(TaggedResourceType.RemoteAccessVpn, _vpnDao); return true; } diff --git a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java index f210dc17de0..d26da4dc916 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade410to420.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade410to420.java @@ -17,9 +17,6 @@ package com.cloud.upgrade.dao; -import com.cloud.utils.exception.CloudRuntimeException; -import com.cloud.utils.script.Script; - import java.io.File; import java.sql.Connection; import java.sql.PreparedStatement; @@ -29,6 +26,9 @@ import java.util.UUID; import org.apache.log4j.Logger; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.utils.script.Script; + public class Upgrade410to420 implements DbUpgrade { final static Logger s_logger = Logger.getLogger(Upgrade410to420.class); @@ -61,6 +61,7 @@ public class Upgrade410to420 implements DbUpgrade { public void performDataMigration(Connection conn) { upgradeVmwareLabels(conn); createPlaceHolderNics(conn); + updateRemoteAccessVpn(conn); PreparedStatement sql = null; try { sql = conn.prepareStatement("update vm_template set image_data_store_id = 1 where type = 'SYSTEM' or type = 'BUILTIN'"); @@ -196,4 +197,38 @@ public class Upgrade410to420 implements DbUpgrade { } } } + + + private void updateRemoteAccessVpn(Connection conn) { + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + pstmt = conn.prepareStatement("SELECT vpn_server_addr_id FROM `cloud`.`remote_access_vpn`"); + rs = pstmt.executeQuery(); + long id=1; + while (rs.next()) { + String uuid = UUID.randomUUID().toString(); + Long ipId = rs.getLong(1); + pstmt = conn.prepareStatement("UPDATE `cloud`.`remote_access_vpn` set uuid=?, id=? where vpn_server_addr_id=?"); + pstmt.setString(1, uuid); + pstmt.setLong(2, id); + pstmt.setLong(3, ipId); + pstmt.executeUpdate(); + id++; + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to update id/uuid of remote_access_vpn table", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + } } diff --git a/setup/db/db/schema-410to420-cleanup.sql b/setup/db/db/schema-410to420-cleanup.sql index 51970b21b89..187076ff984 100644 --- a/setup/db/db/schema-410to420-cleanup.sql +++ b/setup/db/db/schema-410to420-cleanup.sql @@ -19,3 +19,10 @@ -- Schema cleanup from 4.1.0 to 4.2.0; --; +#have to drop the foreign key in order to delete primary key; will re-insert the foreign key later +ALTER TABLE remote_access_vpn DROP foreign key `fk_remote_access_vpn__vpn_server_addr_id`; +ALTER TABLE remote_access_vpn DROP primary key; +ALTER TABLE remote_access_vpn ADD primary key (`id`); +ALTER TABLE remote_access_vpn ADD CONSTRAINT `fk_remote_access_vpn__vpn_server_addr_id` FOREIGN KEY (`vpn_server_addr_id`) REFERENCES `user_ip_address` (`id`); + + diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index f1e24fa1010..53f3c44529f 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -390,3 +390,6 @@ CREATE VIEW `cloud`.`account_view` AS `cloud`.`async_job` ON async_job.instance_id = account.id and async_job.instance_type = 'Account' and async_job.job_status = 0; + +ALTER TABLE remote_access_vpn ADD COLUMN `id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT COMMENT 'id'; +ALTER TABLE remote_access_vpn ADD COLUMN `uuid` varchar(40) UNIQUE;