mirror of https://github.com/apache/cloudstack.git
323 lines
15 KiB
Java
323 lines
15 KiB
Java
/*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.*/
|
|
|
|
|
|
package com.cloud.upgrade.dao;
|
|
|
|
import java.io.File;
|
|
import java.sql.Connection;
|
|
import java.sql.PreparedStatement;
|
|
import java.sql.ResultSet;
|
|
import java.sql.SQLException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
import org.apache.log4j.Logger;
|
|
|
|
import com.cloud.utils.exception.CloudRuntimeException;
|
|
import com.cloud.utils.script.Script;
|
|
|
|
public class Upgrade304to305 extends Upgrade30xBase implements DbUpgrade {
|
|
final static Logger s_logger = Logger.getLogger(Upgrade304to305.class);
|
|
|
|
@Override
|
|
public String[] getUpgradableVersionRange() {
|
|
return new String[] { "3.0.4", "3.0.5" };
|
|
}
|
|
|
|
@Override
|
|
public String getUpgradedVersion() {
|
|
return "3.0.5";
|
|
}
|
|
|
|
@Override
|
|
public boolean supportsRollingUpgrade() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public File[] getPrepareScripts() {
|
|
String script = Script.findScript("", "db/schema-304to305.sql");
|
|
if (script == null) {
|
|
throw new CloudRuntimeException("Unable to find db/schema-304to305.sql");
|
|
}
|
|
|
|
return new File[] { new File(script) };
|
|
}
|
|
|
|
@Override
|
|
public void performDataMigration(Connection conn) {
|
|
addHostDetailsUniqueKey(conn);
|
|
addVpcProvider(conn);
|
|
updateRouterNetworkRef(conn);
|
|
correctNetworkUsingExternalDevices(conn);
|
|
}
|
|
|
|
@Override
|
|
public File[] getCleanupScripts() {
|
|
String script = Script.findScript("", "db/schema-304to305-cleanup.sql");
|
|
if (script == null) {
|
|
throw new CloudRuntimeException("Unable to find db/schema-304to305-cleanup.sql");
|
|
}
|
|
|
|
return new File[] { new File(script) };
|
|
}
|
|
|
|
private void addVpcProvider(Connection conn){
|
|
//Encrypt config params and change category to Hidden
|
|
s_logger.debug("Adding vpc provider to all physical networks in the system");
|
|
PreparedStatement pstmt = null;
|
|
ResultSet rs = null;
|
|
try {
|
|
pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`physical_network` WHERE removed is NULL");
|
|
rs = pstmt.executeQuery();
|
|
while (rs.next()) {
|
|
Long pNtwkId = rs.getLong(1);
|
|
|
|
//insert provider
|
|
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`physical_network_service_providers` " +
|
|
"(`physical_network_id`, `provider_name`, `state`, `vpn_service_provided`, `dhcp_service_provided`, " +
|
|
"`dns_service_provided`, `gateway_service_provided`, `firewall_service_provided`, `source_nat_service_provided`," +
|
|
" `load_balance_service_provided`, `static_nat_service_provided`, `port_forwarding_service_provided`," +
|
|
" `user_data_service_provided`, `security_group_service_provided`) " +
|
|
"VALUES (?, 'VpcVirtualRouter', 'Enabled', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0)");
|
|
|
|
pstmt.setLong(1, pNtwkId);
|
|
pstmt.executeUpdate();
|
|
|
|
//get provider id
|
|
pstmt = conn.prepareStatement("SELECT id FROM `cloud`.`physical_network_service_providers` " +
|
|
"WHERE physical_network_id=? and provider_name='VpcVirtualRouter'");
|
|
pstmt.setLong(1, pNtwkId);
|
|
ResultSet rs1 = pstmt.executeQuery();
|
|
rs1.next();
|
|
long providerId = rs1.getLong(1);
|
|
|
|
//insert VR element
|
|
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`virtual_router_providers` (`nsp_id`, `type`, `enabled`) " +
|
|
"VALUES (?, 'VPCVirtualRouter', 1)");
|
|
pstmt.setLong(1, providerId);
|
|
pstmt.executeUpdate();
|
|
|
|
s_logger.debug("Added VPC Virtual router provider for physical network id=" + pNtwkId);
|
|
|
|
}
|
|
} catch (SQLException e) {
|
|
throw new CloudRuntimeException("Unable add VPC physical network service provider ", e);
|
|
} finally {
|
|
try {
|
|
if (rs != null) {
|
|
rs.close();
|
|
}
|
|
|
|
if (pstmt != null) {
|
|
pstmt.close();
|
|
}
|
|
} catch (SQLException e) {
|
|
}
|
|
}
|
|
s_logger.debug("Done adding VPC physical network service providers to all physical networks");
|
|
}
|
|
|
|
private void updateRouterNetworkRef(Connection conn){
|
|
//Encrypt config params and change category to Hidden
|
|
s_logger.debug("Updating router network ref");
|
|
PreparedStatement pstmt = null;
|
|
ResultSet rs = null;
|
|
try {
|
|
pstmt = conn.prepareStatement("SELECT d.id, d.network_id FROM `cloud`.`domain_router` d, `cloud`.`vm_instance` v " +
|
|
"WHERE d.id=v.id AND v.removed is NULL");
|
|
rs = pstmt.executeQuery();
|
|
while (rs.next()) {
|
|
Long routerId = rs.getLong(1);
|
|
Long networkId = rs.getLong(2);
|
|
|
|
//get the network type
|
|
pstmt = conn.prepareStatement("SELECT guest_type from `cloud`.`networks` where id=?");
|
|
pstmt.setLong(1, networkId);
|
|
ResultSet rs1 = pstmt.executeQuery();
|
|
rs1.next();
|
|
String networkType = rs1.getString(1);
|
|
|
|
//insert the reference
|
|
pstmt = conn.prepareStatement("INSERT INTO `cloud`.`router_network_ref` (router_id, network_id, guest_type) " +
|
|
"VALUES (?, ?, ?)");
|
|
|
|
pstmt.setLong(1, routerId);
|
|
pstmt.setLong(2, networkId);
|
|
pstmt.setString(3, networkType);
|
|
pstmt.executeUpdate();
|
|
|
|
s_logger.debug("Added reference for router id=" + routerId + " and network id=" + networkId);
|
|
|
|
}
|
|
} catch (SQLException e) {
|
|
throw new CloudRuntimeException("Failed to update the router/network reference ", e);
|
|
} finally {
|
|
try {
|
|
if (rs != null) {
|
|
rs.close();
|
|
}
|
|
|
|
if (pstmt != null) {
|
|
pstmt.close();
|
|
}
|
|
} catch (SQLException e) {
|
|
}
|
|
}
|
|
s_logger.debug("Done updating router/network references");
|
|
}
|
|
|
|
private void addHostDetailsUniqueKey(Connection conn) {
|
|
s_logger.debug("Checking if host_details unique key exists, if not we will add it");
|
|
PreparedStatement pstmt = null;
|
|
ResultSet rs = null;
|
|
try {
|
|
pstmt = conn.prepareStatement("SHOW INDEX FROM `cloud`.`host_details` WHERE KEY_NAME = 'uk_host_id_name'");
|
|
rs = pstmt.executeQuery();
|
|
if (rs.next()) {
|
|
s_logger.debug("Unique key already exists on host_details - not adding new one");
|
|
}else{
|
|
//add the key
|
|
PreparedStatement pstmtUpdate = conn.prepareStatement("ALTER TABLE `cloud`.`host_details` ADD CONSTRAINT UNIQUE KEY `uk_host_id_name` (`host_id`, `name`)");
|
|
pstmtUpdate.executeUpdate();
|
|
s_logger.debug("Unique key did not exist on host_details - added new one");
|
|
pstmtUpdate.close();
|
|
}
|
|
} catch (SQLException e) {
|
|
throw new CloudRuntimeException("Failed to check/update the host_details unique key ", e);
|
|
} finally {
|
|
try {
|
|
if (rs != null) {
|
|
rs.close();
|
|
}
|
|
|
|
if (pstmt != null) {
|
|
pstmt.close();
|
|
}
|
|
} catch (SQLException e) {
|
|
}
|
|
}
|
|
}
|
|
|
|
// ensure that networks using external load balancer/firewall in 2.2.14 or prior releases deployments has entry
|
|
// in network_external_lb_device_map and network_external_firewall_device_map
|
|
private void correctNetworkUsingExternalDevices(Connection conn) {
|
|
//Get zones to upgrade
|
|
List<Long> zoneIds = new ArrayList<Long>();
|
|
PreparedStatement pstmt = null;
|
|
PreparedStatement pstmtUpdate = null;
|
|
ResultSet rs = null;
|
|
long networkOfferingId, networkId;
|
|
long f5DeviceId, f5HostId;
|
|
long srxDevivceId, srxHostId;
|
|
|
|
try {
|
|
pstmt = conn.prepareStatement("select id from `cloud`.`data_center` where lb_provider='F5BigIp' or firewall_provider='JuniperSRX' or gateway_provider='JuniperSRX'");
|
|
rs = pstmt.executeQuery();
|
|
while (rs.next()) {
|
|
zoneIds.add(rs.getLong(1));
|
|
}
|
|
} catch (SQLException e) {
|
|
throw new CloudRuntimeException("Unable to create network to LB & firewalla device mapping for networks that use them", e);
|
|
}
|
|
|
|
if (zoneIds.size() == 0) {
|
|
return; // no zones using F5 and SRX devices so return
|
|
}
|
|
|
|
// find the default network offering created for external devices during upgrade from 2.2.14
|
|
try {
|
|
pstmt = conn.prepareStatement("select id from `cloud`.`network_offerings` where unique_name='Isolated with external providers' ");
|
|
rs = pstmt.executeQuery();
|
|
if (rs.first()) {
|
|
networkOfferingId = rs.getLong(1);
|
|
} else {
|
|
throw new CloudRuntimeException("Cannot upgrade as there is no 'Isolated with external providers' network offering crearted .");
|
|
}
|
|
} catch (SQLException e) {
|
|
throw new CloudRuntimeException("Unable to create network to LB & firewalla device mapping for networks that use them", e);
|
|
}
|
|
|
|
for (Long zoneId : zoneIds) {
|
|
try {
|
|
// find the F5 device id in the zone
|
|
pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalLoadBalancer' AND removed IS NULL");
|
|
pstmt.setLong(1, zoneId);
|
|
rs = pstmt.executeQuery();
|
|
if (rs.first()) {
|
|
f5HostId = networkOfferingId = rs.getLong(1);
|
|
} else {
|
|
throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device found in data center " + zoneId);
|
|
}
|
|
pstmt = conn.prepareStatement("SELECT id FROM external_load_balancer_devices WHERE host_id=?");
|
|
pstmt.setLong(1, f5HostId);
|
|
rs = pstmt.executeQuery();
|
|
if (rs.first()) {
|
|
f5DeviceId = networkOfferingId = rs.getLong(1);
|
|
} else {
|
|
throw new CloudRuntimeException("Cannot upgrade as there is no F5 load balancer device with host ID " + f5HostId + " found in external_load_balancer_device");
|
|
}
|
|
|
|
// find the SRX device id in the zone
|
|
pstmt = conn.prepareStatement("SELECT id FROM host WHERE data_center_id=? AND type = 'ExternalFirewall' AND removed IS NULL");
|
|
pstmt.setLong(1, zoneId);
|
|
rs = pstmt.executeQuery();
|
|
if (rs.first()) {
|
|
srxHostId = rs.getLong(1);
|
|
} else {
|
|
throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found in data center " + zoneId);
|
|
}
|
|
pstmt = conn.prepareStatement("SELECT id FROM external_firewall_devices WHERE host_id=?");
|
|
pstmt.setLong(1, srxHostId);
|
|
rs = pstmt.executeQuery();
|
|
if (rs.first()) {
|
|
srxDevivceId = rs.getLong(1);
|
|
} else {
|
|
throw new CloudRuntimeException("Cannot upgrade as there is no SRX firewall device found with host ID " + srxHostId + " found in external_firewall_devices");
|
|
}
|
|
|
|
// check if network any uses F5 or SRX devices in the zone
|
|
pstmt = conn.prepareStatement("select id from `cloud`.`networks` where guest_type='Virtual' and data_center_id=? and network_offering_id=? and removed IS NULL");
|
|
pstmt.setLong(1, zoneId);
|
|
pstmt.setLong(2, networkOfferingId);
|
|
rs = pstmt.executeQuery();
|
|
while (rs.next()) {
|
|
// get the network Id
|
|
networkId = rs.getLong(1);
|
|
|
|
// add mapping for the network in network_external_lb_device_map
|
|
String insertLbMapping = "INSERT INTO `cloud`.`network_external_lb_device_map` (uuid, network_id, external_load_balancer_device_id,) VALUES ( ?, ?, ?)";
|
|
pstmtUpdate = conn.prepareStatement(insertLbMapping);
|
|
pstmtUpdate.setString(1, UUID.randomUUID().toString());
|
|
pstmtUpdate.setLong(2, networkId);
|
|
pstmtUpdate.setLong(3, f5DeviceId);
|
|
pstmtUpdate.executeUpdate();
|
|
s_logger.debug("Successfully added entry in network_external_lb_device_map for network " + networkId + " and F5 device ID " + f5DeviceId);
|
|
|
|
// add mapping for the network in network_external_firewall_device_map
|
|
String insertFwMapping = "INSERT INTO `cloud`.`network_external_firewall_device_map` (uuid, network_id, external_firewall_device_id,) VALUES ( ?, ?, ?)";
|
|
pstmtUpdate = conn.prepareStatement(insertFwMapping);
|
|
pstmtUpdate.setString(1, UUID.randomUUID().toString());
|
|
pstmtUpdate.setLong(2, networkId);
|
|
pstmtUpdate.setLong(3, srxDevivceId);
|
|
pstmtUpdate.executeUpdate();
|
|
s_logger.debug("Successfully added entry in network_external_firewall_device_map for network " + networkId + " and SRX device ID " + srxDevivceId);
|
|
}
|
|
} catch (SQLException e) {
|
|
|
|
}
|
|
s_logger.info("Successfully upgraded network using F5 and SRX devices to have a entry in the network_external_lb_device_map and network_external_firewall_device_map");
|
|
}
|
|
}
|
|
}
|