cloudstack/server/src/com/cloud/upgrade/dao/Upgrade304to305.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");
}
}
}