// 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.test; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Vector; import com.cloud.network.Networks.TrafficType; import com.cloud.utils.component.ComponentLocator; import com.cloud.utils.db.DB; import com.cloud.utils.db.Transaction; import com.cloud.utils.net.NetUtils; public class PodZoneConfig { public static void main(String[] args) { PodZoneConfig config = ComponentLocator.inject(PodZoneConfig.class); //config.run(args); System.exit(0); } public void savePod(boolean printOutput, long id, String name, long dcId, String gateway, String cidr, int vlanStart, int vlanEnd) { // Check that the cidr was valid if (!IPRangeConfig.validCIDR(cidr)) printError("Please enter a valid CIDR for pod: " + name); // Get the individual cidrAddress and cidrSize values String[] cidrPair = cidr.split("\\/"); String cidrAddress = cidrPair[0]; String cidrSize = cidrPair[1]; String sql = null; if (id != -1) sql = "INSERT INTO `cloud`.`host_pod_ref` (id, name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + id + "','" + name + "','" + dcId + "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')"; else sql = "INSERT INTO `cloud`.`host_pod_ref` (name, data_center_id, gateway, cidr_address, cidr_size) " + "VALUES ('" + name + "','" + dcId + "','" + gateway + "','" + cidrAddress + "','" + cidrSize + "')"; DatabaseConfig.saveSQL(sql, "Failed to save pod due to exception. Please contact Cloud Support."); if (printOutput) System.out.println("Successfuly saved pod."); } public void checkAllPodCidrSubnets() { Vector<Long> allZoneIDs = getAllZoneIDs(); for (Long dcId : allZoneIDs) { HashMap<Long, Vector<Object>> currentPodCidrSubnets = getCurrentPodCidrSubnets(dcId.longValue()); String result = checkPodCidrSubnets(dcId.longValue(), currentPodCidrSubnets); if (!result.equals("success")) printError(result); } } private String checkPodCidrSubnets(long dcId, HashMap<Long, Vector<Object>> currentPodCidrSubnets) { // DataCenterDao _dcDao = null; // final ComponentLocator locator = ComponentLocator.getLocator("management-server"); // _dcDao = locator.getDao(DataCenterDao.class); // For each pod, return an error if any of the following is true: // 1. The pod's CIDR subnet conflicts with the guest network subnet // 2. The pod's CIDR subnet conflicts with the CIDR subnet of any other pod String zoneName = PodZoneConfig.getZoneName(dcId); //get the guest network cidr and guest netmask from the zone // DataCenterVO dcVo = _dcDao.findById(dcId); String guestNetworkCidr = IPRangeConfig.getGuestNetworkCidr(dcId); if (guestNetworkCidr == null || guestNetworkCidr.isEmpty()) return "Please specify a valid guest cidr"; String[] cidrTuple = guestNetworkCidr.split("\\/"); String guestIpNetwork = NetUtils.getIpRangeStartIpFromCidr(cidrTuple[0], Long.parseLong(cidrTuple[1])); long guestCidrSize = Long.parseLong(cidrTuple[1]); // Iterate through all pods in this zone for (Long podId : currentPodCidrSubnets.keySet()) { String podName; if (podId.longValue() == -1) podName = "newPod"; else podName = PodZoneConfig.getPodName(podId.longValue(), dcId); Vector<Object> cidrPair = currentPodCidrSubnets.get(podId); String cidrAddress = (String) cidrPair.get(0); long cidrSize = ((Long) cidrPair.get(1)).longValue(); long cidrSizeToUse = -1; if (cidrSize < guestCidrSize) cidrSizeToUse = cidrSize; else cidrSizeToUse = guestCidrSize; String cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse); String guestSubnet = NetUtils.getCidrSubNet(guestIpNetwork, cidrSizeToUse); // Check that cidrSubnet does not equal guestSubnet if (cidrSubnet.equals(guestSubnet)) { if (podName.equals("newPod")) { return "The subnet of the pod you are adding conflicts with the subnet of the Guest IP Network. Please specify a different CIDR."; } else { return "Warning: The subnet of pod " + podName + " in zone " + zoneName + " conflicts with the subnet of the Guest IP Network. Please change either the pod's CIDR or the Guest IP Network's subnet, and re-run install-vmops-management."; } } // Iterate through the rest of the pods for (Long otherPodId : currentPodCidrSubnets.keySet()) { if (podId.equals(otherPodId)) continue; // Check that cidrSubnet does not equal otherCidrSubnet Vector<Object> otherCidrPair = currentPodCidrSubnets.get(otherPodId); String otherCidrAddress = (String) otherCidrPair.get(0); long otherCidrSize = ((Long) otherCidrPair.get(1)).longValue(); if (cidrSize < otherCidrSize) cidrSizeToUse = cidrSize; else cidrSizeToUse = otherCidrSize; cidrSubnet = NetUtils.getCidrSubNet(cidrAddress, cidrSizeToUse); String otherCidrSubnet = NetUtils.getCidrSubNet(otherCidrAddress, cidrSizeToUse); if (cidrSubnet.equals(otherCidrSubnet)) { String otherPodName = PodZoneConfig.getPodName(otherPodId.longValue(), dcId); if (podName.equals("newPod")) { return "The subnet of the pod you are adding conflicts with the subnet of pod " + otherPodName + " in zone " + zoneName + ". Please specify a different CIDR."; } else { return "Warning: The pods " + podName + " and " + otherPodName + " in zone " + zoneName + " have conflicting CIDR subnets. Please change the CIDR of one of these pods."; } } } } return "success"; } @DB protected HashMap<Long, Vector<Object>> getCurrentPodCidrSubnets(long dcId) { HashMap<Long, Vector<Object>> currentPodCidrSubnets = new HashMap<Long, Vector<Object>>(); String selectSql = "SELECT id, cidr_address, cidr_size FROM host_pod_ref WHERE data_center_id=" + dcId; Transaction txn = Transaction.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); while (rs.next()) { Long podId = rs.getLong("id"); String cidrAddress = rs.getString("cidr_address"); long cidrSize = rs.getLong("cidr_size"); Vector<Object> cidrPair = new Vector<Object>(); cidrPair.add(0, cidrAddress); cidrPair.add(1, new Long(cidrSize)); currentPodCidrSubnets.put(podId, cidrPair); } } catch (SQLException ex) { System.out.println(ex.getMessage()); printError("There was an issue with reading currently saved pod CIDR subnets. Please contact Cloud Support."); return null; } return currentPodCidrSubnets; } public void deletePod(String name, long dcId) { String sql = "DELETE FROM `cloud`.`host_pod_ref` WHERE name=\"" + name + "\" AND data_center_id=\"" + dcId + "\""; DatabaseConfig.saveSQL(sql, "Failed to delete pod due to exception. Please contact Cloud Support."); } public long getVlanDbId(String zone, String vlanId) { long zoneId = getZoneId(zone); return DatabaseConfig.getDatabaseValueLong("SELECT * FROM `cloud`.`vlan` WHERE data_center_id=\"" + zoneId + "\" AND vlan_id =\"" + vlanId + "\"", "id", "Unable to start DB connection to read vlan DB id. Please contact Cloud Support."); } public List<String> modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange, long networkId, long physicalNetworkId) { // Check if the zone is valid long zoneId = getZoneId(zone); if (zoneId == -1) return genReturnList("false", "Please specify a valid zone."); //check if physical network is valid long physicalNetworkDbId = checkPhysicalNetwork(physicalNetworkId); if (physicalNetworkId == -1) return genReturnList("false", "Please specify a valid physical network."); Long podId = pod!=null?getPodId(pod, zone):null; if (podId != null && podId == -1) return genReturnList("false", "Please specify a valid pod."); if (add) { // Make sure the gateway is valid if (!NetUtils.isValidIp(vlanGateway)) return genReturnList("false", "Please specify a valid gateway."); // Make sure the netmask is valid if (!NetUtils.isValidIp(vlanNetmask)) return genReturnList("false", "Please specify a valid netmask."); // Check if a vlan with the same vlanId already exists in the specified zone if (getVlanDbId(zone, vlanId) != -1) return genReturnList("false", "A VLAN with the specified VLAN ID already exists in zone " + zone + "."); /* // Check if another vlan in the same zone has the same subnet String newVlanSubnet = NetUtils.getSubNet(vlanGateway, vlanNetmask); List<VlanVO> vlans = _vlanDao.findByZone(zoneId); for (VlanVO vlan : vlans) { String currentVlanSubnet = NetUtils.getSubNet(vlan.getVlanGateway(), vlan.getVlanNetmask()); if (newVlanSubnet.equals(currentVlanSubnet)) return genReturnList("false", "The VLAN with ID " + vlan.getVlanId() + " in zone " + zone + " has the same subnet. Please specify a different gateway/netmask."); } */ // Everything was fine, so persist the VLAN saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange, networkId, physicalNetworkDbId); if (podId != null) { long vlanDbId = getVlanDbId(zone, vlanId); String sql = "INSERT INTO `cloud`.`pod_vlan_map` (pod_id, vlan_db_id) " + "VALUES ('" + podId + "','" + vlanDbId + "')"; DatabaseConfig.saveSQL(sql, "Failed to save pod_vlan_map due to exception vlanDbId=" + vlanDbId + ", podId=" + podId + ". Please contact Cloud Support."); } return genReturnList("true", "Successfully added VLAN."); } else { return genReturnList("false", "That operation is not suppored."); } /* else { // Check if a VLAN actually exists in the specified zone long vlanDbId = getVlanDbId(zone, vlanId); if (vlanDbId == -1) return genReturnList("false", "A VLAN with ID " + vlanId + " does not exist in zone " + zone); // Check if there are any public IPs that are in the specified vlan. List<IPAddressVO> ips = _publicIpAddressDao.listByVlanDbId(vlanDbId); if (ips.size() != 0) return genReturnList("false", "Please delete all IP addresses that are in VLAN " + vlanId + " before deleting the VLAN."); // Delete the vlan _vlanDao.delete(vlanDbId); return genReturnList("true", "Successfully deleted VLAN."); } */ } @DB public void saveZone(boolean printOutput, long id, String name, String dns1, String dns2, String dns3, String dns4, String guestNetworkCidr, String networkType) { if (printOutput) System.out.println("Saving zone, please wait..."); String columns = null; String values = null; if (id != -1) { columns = "(id, name"; values = "('" + id + "','" + name + "'"; } else { columns = "(name"; values = "('" + name + "'"; } if (dns1 != null) { columns += ", dns1"; values += ",'" + dns1 + "'"; } if (dns2 != null) { columns += ", dns2"; values += ",'" + dns2 + "'"; } if (dns3 != null) { columns += ", internal_dns1"; values += ",'" + dns3 + "'"; } if (dns4 != null) { columns += ", internal_dns2"; values += ",'" + dns4 + "'"; } if(guestNetworkCidr != null) { columns += ", guest_network_cidr"; values += ",'" + guestNetworkCidr + "'"; } if(networkType != null) { columns += ", networktype"; values += ",'" + networkType + "'"; } columns += ", uuid"; values += ", UUID()"; columns += ")"; values += ")"; String sql = "INSERT INTO `cloud`.`data_center` " + columns + " VALUES " + values; DatabaseConfig.saveSQL(sql, "Failed to save zone due to exception. Please contact Cloud Support."); if (printOutput) System.out.println("Successfully saved zone."); } @DB public void savePhysicalNetwork(boolean printOutput, long id, long dcId, int vnetStart, int vnetEnd) { if (printOutput) System.out.println("Saving physical network, please wait..."); String columns = null; String values = null; columns = "(id "; values = "('" + id + "'"; columns += ", name "; values += ",'physical network'"; columns += ", data_center_id "; values += ",'" + dcId + "'"; //save vnet information columns += ", vnet"; values += ",'" + vnetStart + "-" + vnetEnd + "'"; columns += ", state"; values += ", 'Enabled'"; columns += ", uuid"; values += ", UUID()"; columns += ")"; values += ")"; String sql = "INSERT INTO `cloud`.`physical_network` " + columns + " VALUES " + values; DatabaseConfig.saveSQL(sql, "Failed to save physical network due to exception. Please contact Cloud Support."); // Hardcode the vnet range to be the full range int begin = 0x64; int end = 64000; // If vnet arguments were passed in, use them if (vnetStart != -1 && vnetEnd != -1) { begin = vnetStart; end = vnetEnd; } String insertVnet = "INSERT INTO `cloud`.`op_dc_vnet_alloc` (vnet, data_center_id, physical_network_id) VALUES ( ?, ?, ?)"; Transaction txn = Transaction.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertVnet); for (int i = begin; i <= end; i++) { stmt.setString(1, Integer.toString(i)); stmt.setLong(2, dcId); stmt.setLong(3, id); stmt.addBatch(); } stmt.executeBatch(); } catch (SQLException ex) { printError("Error creating vnet for the physical network. Please contact Cloud Support."); } //add default traffic types //get default Xen network labels String defaultXenPrivateNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Management); String defaultXenPublicNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Public); String defaultXenStorageNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Storage); String defaultXenGuestNetworkLabel = getDefaultXenNetworkLabel(TrafficType.Guest); String insertTraficType = "INSERT INTO `cloud`.`physical_network_traffic_types` (physical_network_id, traffic_type, xen_network_label) VALUES ( ?, ?, ?)"; try { PreparedStatement stmt = txn.prepareAutoCloseStatement(insertTraficType); for (TrafficType traffic : TrafficType.values()) { if(traffic.equals(TrafficType.Control) || traffic.equals(TrafficType.Vpn) || traffic.equals(TrafficType.None)){ continue; } stmt.setLong(1, id); stmt.setString(2, traffic.toString()); if(traffic.equals(TrafficType.Public)){ stmt.setString(3, defaultXenPublicNetworkLabel); }else if(traffic.equals(TrafficType.Management)){ stmt.setString(3, defaultXenPrivateNetworkLabel); }else if(traffic.equals(TrafficType.Storage)){ stmt.setString(3, defaultXenStorageNetworkLabel); }else if(traffic.equals(TrafficType.Guest)){ stmt.setString(3, defaultXenGuestNetworkLabel); } stmt.addBatch(); } stmt.executeBatch(); } catch (SQLException ex) { printError("Error adding default traffic types for the physical network. Please contact Cloud Support."); } if (printOutput) System.out.println("Successfully saved physical network."); } private String getDefaultXenNetworkLabel(TrafficType trafficType){ String xenLabel = null; String configName = null; switch(trafficType){ case Public: configName = "xen.public.network.device"; break; case Guest: configName = "xen.guest.network.device"; break; case Storage: configName = "xen.storage.network.device1"; break; case Management: configName = "xen.private.network.device"; break; } if(configName != null){ xenLabel = getConfiguredValue(configName); } return xenLabel; } public static String getConfiguredValue(String configName) { return DatabaseConfig.getDatabaseValueString("SELECT value FROM `cloud`.`configuration` where name = \"" + configName + "\"","value", "Unable to start DB connection to read configuration. Please contact Cloud Support."); } public void deleteZone(String name) { String sql = "DELETE FROM `cloud`.`data_center` WHERE name=\"" + name + "\""; DatabaseConfig.saveSQL(sql, "Failed to delete zone due to exception. Please contact Cloud Support."); } public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange, long networkId, long physicalNetworkId) { String sql = "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description, network_id, physical_network_id) " + "VALUES ('" + vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange + "','" + networkId + "','" + physicalNetworkId + "')"; DatabaseConfig.saveSQL(sql, "Failed to save vlan due to exception. Please contact Cloud Support."); } public static long getPodId(String pod, String zone) { long dcId = getZoneId(zone); String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\""; String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support."; return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg); } public static long getPodId(String pod, long dcId) { String selectSql = "SELECT * FROM `cloud`.`host_pod_ref` WHERE name = \"" + pod + "\" AND data_center_id = \"" + dcId + "\""; String errorMsg = "Could not read pod ID fro mdatabase. Please contact Cloud Support."; return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg); } public static long getZoneId(String zone) { String selectSql = "SELECT * FROM `cloud`.`data_center` WHERE name = \"" + zone + "\""; String errorMsg = "Could not read zone ID from database. Please contact Cloud Support."; return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg); } public static long checkPhysicalNetwork(long physicalNetworkId) { String selectSql = "SELECT * FROM `cloud`.`physical_network` WHERE id = \"" + physicalNetworkId + "\""; String errorMsg = "Could not read physicalNetwork ID from database. Please contact Cloud Support."; return DatabaseConfig.getDatabaseValueLong(selectSql, "id", errorMsg); } @DB public Vector<Long> getAllZoneIDs() { Vector<Long> allZoneIDs = new Vector<Long>(); String selectSql = "SELECT id FROM data_center"; Transaction txn = Transaction.currentTxn(); try { PreparedStatement stmt = txn.prepareAutoCloseStatement(selectSql); ResultSet rs = stmt.executeQuery(); while (rs.next()) { Long dcId = rs.getLong("id"); allZoneIDs.add(dcId); } } catch (SQLException ex) { System.out.println(ex.getMessage()); printError("There was an issue with reading zone IDs. Please contact Cloud Support."); return null; } return allZoneIDs; } public static boolean validPod(String pod, String zone) { return (getPodId(pod, zone) != -1); } public static boolean validZone(String zone) { return (getZoneId(zone) != -1); } public static String getPodName(long podId, long dcId) { return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`host_pod_ref` WHERE id=" + podId + " AND data_center_id=" + dcId, "name", "Unable to start DB connection to read pod name. Please contact Cloud Support."); } public static String getZoneName(long dcId) { return DatabaseConfig.getDatabaseValueString("SELECT * FROM `cloud`.`data_center` WHERE id=" + dcId, "name", "Unable to start DB connection to read zone name. Please contact Cloud Support."); } private static void printError(String message) { DatabaseConfig.printError(message); } private List<String> genReturnList(String success, String message) { List<String> returnList = new ArrayList<String>(); returnList.add(0, success); returnList.add(1, message); return returnList; } }