private void setupPhysicalNetworks()

in engine/schema/src/main/java/com/cloud/upgrade/dao/Upgrade2214to30.java [113:368]


    private void setupPhysicalNetworks(Connection conn) {
        /**
         * for each zone:
         * add a p.network, use zone.vnet and zone.type
         * add default traffic types, pnsp and virtual router element in enabled state
         * set p.network.id in op_dc_vnet and vlan and user_ip_address
         * list guest networks for the zone, set p.network.id
         *
         * for cases where network_tags are used for multiple guest networks:
         * - figure out distinct tags
         * - create physical network per tag
         * - create traffic types and set the tag to xen_network_label
         * - add physical network id  to networks, vlan, user_ip_address for networks belonging to this tag
         */
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<PreparedStatement> pstmt2Close = new ArrayList<PreparedStatement>();
        PreparedStatement pstmtUpdate = null;
        try {
            // Load all DataCenters

            String xenPublicLabel = getNetworkLabelFromConfig(conn, "xen.public.network.device");
            String xenPrivateLabel = getNetworkLabelFromConfig(conn, "xen.private.network.device");
            String xenStorageLabel = getNetworkLabelFromConfig(conn, "xen.storage.network.device1");
            String xenGuestLabel = getNetworkLabelFromConfig(conn, "xen.guest.network.device");

            String kvmPublicLabel = getNetworkLabelFromConfig(conn, "kvm.public.network.device");
            String kvmPrivateLabel = getNetworkLabelFromConfig(conn, "kvm.private.network.device");
            String kvmGuestLabel = getNetworkLabelFromConfig(conn, "kvm.guest.network.device");

            String vmwarePublicLabel = getNetworkLabelFromConfig(conn, "vmware.public.vswitch");
            String vmwarePrivateLabel = getNetworkLabelFromConfig(conn, "vmware.private.vswitch");
            String vmwareGuestLabel = getNetworkLabelFromConfig(conn, "vmware.guest.vswitch");

            pstmt = conn.prepareStatement("SELECT id, domain_id, networktype, vnet, name, removed FROM `cloud`.`data_center`");
            pstmt2Close.add(pstmt);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                long zoneId = rs.getLong(1);
                Long domainId = rs.getLong(2);
                String networkType = rs.getString(3);
                String vnet = rs.getString(4);
                String zoneName = rs.getString(5);
                String removed = rs.getString(6);

                //set uuid for the zone
                String uuid = UUID.randomUUID().toString();
                String updateUuid = "UPDATE `cloud`.`data_center` SET uuid = ? WHERE id = ?";
                pstmtUpdate = conn.prepareStatement(updateUuid);
                pstmtUpdate.setString(1, uuid);
                pstmtUpdate.setLong(2, zoneId);
                pstmtUpdate.executeUpdate();
                pstmtUpdate.close();

                //check if public network needs to be created
                boolean crtPbNtwk = false;
                pstmt = conn.prepareStatement("SELECT * FROM `cloud`.`networks` where traffic_type=\"public\" and data_center_id=?");
                pstmt2Close.add(pstmt);
                pstmt.setLong(1, zoneId);
                ResultSet rs1 = pstmt.executeQuery();
                if (rs1.next()) {
                    crtPbNtwk = true;
                }

                //check if there are multiple guest networks configured using network_tags
                PreparedStatement pstmt2 =
                    conn.prepareStatement("SELECT distinct tag FROM `cloud`.`network_tags` t JOIN `cloud`.`networks` n ON t.network_id = n.id WHERE n.data_center_id = ? and n.removed IS NULL");
                pstmt2Close.add(pstmt2);
                pstmt2.setLong(1, zoneId);
                ResultSet rsTags = pstmt2.executeQuery();
                if (rsTags.next()) {
                    logger.debug("Network tags are not empty, might have to create more than one physical network...");
                    //make sure setup does not use guest vnets

                    if (vnet != null) {
                        //check if any vnet is allocated and guest networks are using vnets.
                        PreparedStatement pstmt4 =
                            conn.prepareStatement("SELECT v.* FROM `cloud`.`op_dc_vnet_alloc` v JOIN `cloud`.`networks` n ON CONCAT('vlan://' , v.vnet) = " +
                                "n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.removed IS NULL");
                        pstmt2Close.add(pstmt4);
                        pstmt4.setLong(1, zoneId);
                        ResultSet rsVNet = pstmt4.executeQuery();

                        if (rsVNet.next()) {
                            String message = "Cannot upgrade. Your setup has multiple Physical Networks and is using guest "
                                + "Vnet that is assigned wrongly. To upgrade, first correct the setup by doing the following: \n"
                                + "1. Please rollback to your 2.2.14 setup\n"
                                + "2. Please stop all VMs using isolated(virtual) networks through CloudStack\n"
                                + "3. Run following query to find if any networks still have nics allocated:\n\t"
                                + "a) check if any virtual guest networks still have allocated nics by running:\n\t"
                                + "SELECT DISTINCT op.id from `cloud`.`op_networks` op JOIN `cloud`.`networks` n on "
                                + "op.id=n.id WHERE nics_count != 0 AND guest_type = 'Virtual';\n\t"
                                + "b) If this returns any networkd ids, then ensure that all VMs are stopped, no new VM is being started, and then shutdown management server\n\t"
                                + "c) Clean up the nics count for the 'virtual' network id's returned in step (a) by running this:\n\t"
                                + "UPDATE `cloud`.`op_networks` SET nics_count = 0 WHERE  id = <enter id of virtual network>\n\t"
                                + "d) Restart management server and wait for all networks to shutdown. [Networks shutdown will be "
                                + "determined by network.gc.interval and network.gc.wait seconds] \n"
                                + "4. Please ensure all networks are shutdown and all guest Vnet's are free.\n"
                                + "5. Run upgrade. This will allocate all your guest vnet range to first physical network.  \n"
                                + "6. Reconfigure the vnet ranges for each physical network as desired by using updatePhysicalNetwork API \n"
                                + "7. Start all your VMs";

                            logger.error(message);

                            throw new CloudRuntimeException(
                                "Cannot upgrade this setup since it uses guest vnet and will have multiple physical networks. Please check the logs for details on how to proceed");
                        }
                        rsVNet.close();

                        //Clean up any vnets that have no live networks/nics
                        pstmt4 =
                            conn.prepareStatement("SELECT v.id, v.vnet, v.reservation_id FROM `cloud`.`op_dc_vnet_alloc` v LEFT JOIN networks n ON CONCAT('vlan://' , v.vnet) = n.broadcast_uri WHERE v.taken IS NOT NULL AND v.data_center_id = ? AND n.broadcast_uri IS NULL AND n.removed IS NULL");
                        pstmt2Close.add(pstmt4);
                        pstmt4.setLong(1, zoneId);
                        rsVNet = pstmt4.executeQuery();
                        while (rsVNet.next()) {
                            Long vnet_id = rsVNet.getLong(1);
                            String vnetValue = rsVNet.getString(2);
                            String reservationId = rsVNet.getString(3);
                            //does this vnet have any nic associated?
                            PreparedStatement pstmt5 = conn.prepareStatement("SELECT id, instance_id FROM `cloud`.`nics` where broadcast_uri = ? and removed IS NULL");
                            pstmt2Close.add(pstmt5);
                            String uri = "vlan://" + vnetValue;
                            pstmt5.setString(1, uri);
                            ResultSet rsNic = pstmt5.executeQuery();
                            Long nic_id = rsNic.getLong(1);
                            Long instance_id = rsNic.getLong(2);
                            if (rsNic.next()) {
                                throw new CloudRuntimeException("Cannot upgrade. Please cleanup the guest vnet: " + vnetValue + " , it is being used by nic_id: " +
                                    nic_id + " , instance_id: " + instance_id);
                            }

                            //free this vnet
                            String freeVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET account_id = NULL, taken = NULL, reservation_id = NULL WHERE id = ?";
                            pstmtUpdate = conn.prepareStatement(freeVnet);
                            pstmtUpdate.setLong(1, vnet_id);
                            pstmtUpdate.executeUpdate();
                            pstmtUpdate.close();
                        }
                    }

                    boolean isFirstPhysicalNtwk = true;
                    do {
                        //create one physical network per tag
                        String guestNetworkTag = rsTags.getString(1);
                        long physicalNetworkId = addPhysicalNetworkToZone(conn, zoneId, zoneName, networkType, (isFirstPhysicalNtwk) ? vnet : null, domainId);
                        //add Traffic types
                        if (isFirstPhysicalNtwk) {
                            if (crtPbNtwk) {
                                addTrafficType(conn, physicalNetworkId, "Public", xenPublicLabel, kvmPublicLabel, vmwarePublicLabel);
                            } else {
                                logger.debug("Skip adding public traffic type to zone id=" + zoneId);
                            }
                            addTrafficType(conn, physicalNetworkId, "Management", xenPrivateLabel, kvmPrivateLabel, vmwarePrivateLabel);
                            addTrafficType(conn, physicalNetworkId, "Storage", xenStorageLabel, null, null);
                        }
                        addTrafficType(conn, physicalNetworkId, "Guest", guestNetworkTag, kvmGuestLabel, vmwareGuestLabel);
                        addDefaultVRProvider(conn, physicalNetworkId, zoneId);
                        addDefaultSGProvider(conn, physicalNetworkId, zoneId, networkType, false);
                        //for all networks with this tag, add physical_network_id

                        PreparedStatement pstmt3 = conn.prepareStatement("SELECT network_id FROM `cloud`.`network_tags` where tag= ?");
                        pstmt3.setString(1,guestNetworkTag);
                        ResultSet rsNet = pstmt3.executeQuery();
                        logger.debug("Adding PhysicalNetwork to VLAN");
                        logger.debug("Adding PhysicalNetwork to user_ip_address");
                        logger.debug("Adding PhysicalNetwork to networks");
                        while (rsNet.next()) {
                            Long networkId = rsNet.getLong(1);
                            addPhysicalNtwk_To_Ntwk_IP_Vlan(conn, physicalNetworkId, networkId);
                        }
                        pstmt3.close();

                        // add the reference to this physical network for the default public network entries in vlan / user_ip_address tables
                        // add first physicalNetworkId to op_dc_vnet_alloc for this zone - just a placeholder since direct networking don't need this
                        if (isFirstPhysicalNtwk) {
                            logger.debug("Adding PhysicalNetwork to default Public network entries in vlan and user_ip_address");
                            pstmt3 = conn.prepareStatement("SELECT id FROM `cloud`.`networks` where traffic_type = 'Public' and data_center_id = " + zoneId);
                            ResultSet rsPubNet = pstmt3.executeQuery();
                            if (rsPubNet.next()) {
                                Long publicNetworkId = rsPubNet.getLong(1);
                                addPhysicalNtwk_To_Ntwk_IP_Vlan(conn, physicalNetworkId, publicNetworkId);
                            }
                            pstmt3.close();

                            logger.debug("Adding PhysicalNetwork to op_dc_vnet_alloc");
                            String updateVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
                            pstmtUpdate = conn.prepareStatement(updateVnet);
                            pstmtUpdate.executeUpdate();
                            pstmtUpdate.close();
                        }

                        isFirstPhysicalNtwk = false;
                    } while (rsTags.next());
                    pstmt2.close();
                } else {
                    //default to one physical network
                    long physicalNetworkId = addPhysicalNetworkToZone(conn, zoneId, zoneName, networkType, vnet, domainId);
                    // add traffic types
                    if (crtPbNtwk) {
                        addTrafficType(conn, physicalNetworkId, "Public", xenPublicLabel, kvmPublicLabel, vmwarePublicLabel);
                    } else {
                        logger.debug("Skip adding public traffic type to zone id=" + zoneId);
                    }
                    addTrafficType(conn, physicalNetworkId, "Management", xenPrivateLabel, kvmPrivateLabel, vmwarePrivateLabel);
                    addTrafficType(conn, physicalNetworkId, "Storage", xenStorageLabel, null, null);
                    addTrafficType(conn, physicalNetworkId, "Guest", xenGuestLabel, kvmGuestLabel, vmwareGuestLabel);
                    addDefaultVRProvider(conn, physicalNetworkId, zoneId);
                    addDefaultSGProvider(conn, physicalNetworkId, zoneId, networkType, false);

                    // add physicalNetworkId to op_dc_vnet_alloc for this zone
                    logger.debug("Adding PhysicalNetwork to op_dc_vnet_alloc");
                    String updateVnet = "UPDATE `cloud`.`op_dc_vnet_alloc` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
                    pstmtUpdate = conn.prepareStatement(updateVnet);
                    pstmtUpdate.executeUpdate();
                    pstmtUpdate.close();

                    // add physicalNetworkId to vlan for this zone
                    logger.debug("Adding PhysicalNetwork to VLAN");
                    String updateVLAN = "UPDATE `cloud`.`vlan` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
                    pstmtUpdate = conn.prepareStatement(updateVLAN);
                    pstmtUpdate.executeUpdate();
                    pstmtUpdate.close();

                    // add physicalNetworkId to user_ip_address for this zone
                    logger.debug("Adding PhysicalNetwork to user_ip_address");
                    String updateUsrIp = "UPDATE `cloud`.`user_ip_address` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId;
                    pstmtUpdate = conn.prepareStatement(updateUsrIp);
                    pstmtUpdate.executeUpdate();
                    pstmtUpdate.close();

                    // add physicalNetworkId to guest networks for this zone
                    logger.debug("Adding PhysicalNetwork to networks");
                    String updateNet =
                        "UPDATE `cloud`.`networks` SET physical_network_id = " + physicalNetworkId + " WHERE data_center_id = " + zoneId + " AND traffic_type = 'Guest'";
                    pstmtUpdate = conn.prepareStatement(updateNet);
                    pstmtUpdate.executeUpdate();
                    pstmtUpdate.close();

                    //mark this physical network as removed if the zone is removed.
                    if (removed != null) {
                        pstmtUpdate = conn.prepareStatement("UPDATE `cloud`.`physical_network` SET removed = now() WHERE id = ?");
                        pstmtUpdate.setLong(1, physicalNetworkId);
                        pstmtUpdate.executeUpdate();
                        pstmtUpdate.close();
                    }
                }

            }
        } catch (SQLException e) {
            throw new CloudRuntimeException("Exception while adding PhysicalNetworks", e);
        } finally {
            TransactionLegacy.closePstmts(pstmt2Close);
        }

    }