/**
 * Show server provisioning page
 */
function nocprovisioning_provision($params)
{
    try {
        /* against XSS attacks */
        if ($_SERVER['REQUEST_METHOD'] == "POST" && $_POST['nps_nonce'] != $_SESSION['nps_nonce']) {
            throw new Exception('Nonce value does not match');
        }
        if ($params[NOCPS_CONFIG_ENABLE_PROVISIONING] != 'on') {
            throw new Exception('Not allowed');
        }
        $api = nocprovisioning_api($params);
        $ip = nocprovisioning_getServerIP($params["serviceid"]);
        $mac = nocprovisioning_getServerMAC($params["serviceid"]);
        $error = "";
        if (!empty($_POST['profile'])) {
            /* Never trust user input. Double check if profile is not blacklisted */
            $whitelist = array_filter(explode(' ', $params[NOCPS_CONFIG_WHITELIST]));
            $blacklist = array_filter(explode(' ', $params[NOCPS_CONFIG_BLACKLIST]));
            $profile = $api->getProfile(intval($_POST['profile']));
            $profileid = intval($_POST['profile']);
            $tags = explode(' ', $profile['data']['tags']);
            if (count($whitelist) && !in_array($profileid, $whitelist) && count(array_intersect($tags, $whitelist)) == 0) {
                throw new Exception("Profile is not on whitelist");
            } else {
                if (count($blacklist) && (in_array($profileid, $blacklist) || count(array_intersect($tags, $blacklist)))) {
                    throw new Exception("Profile is on blacklist");
                }
            }
            /* --- */
            if (empty($params[NOCPS_CONFIG_REQUIRE_IPMIPASSWORD])) {
                $rebootmethod = 'auto';
                $ipmipassword = '';
                /* use password stored in db */
            } else {
                if (empty($_POST['ipmipassword'])) {
                    throw new Exception("Enter your server's IPMI password");
                }
                $rebootmethod = 'ipmi';
                $ipmipassword = $_POST['ipmipassword'];
            }
            /* Provision server */
            lg_debug("password : "******"rootpassword"]);
            lg_debug("password2: " . $_POST["rootpassword2"]);
            $result = $api->provisionHost(array("mac" => $mac, "hostname" => $_POST["hostname"], "profile" => $profileid, "rootpassword" => $_POST["rootpassword"], "rootpassword2" => $_POST["rootpassword2"], "adminuser" => $_POST["adminuser"], "userpassword" => $_POST["userpassword"], "userpassword2" => $_POST["userpassword2"], "disk_addon" => $_POST["disklayout"], "packages_addon" => $_POST["packageselection"], "extra_addon1" => $_POST["extra1"], "extra_addon2" => $_POST["extra2"], "rebootmethod" => $rebootmethod, "ipmipassword" => $ipmipassword));
            if ($result['success']) {
                $n = $profile['data']['name'];
                if ($_POST['disklayout']) {
                    $n .= '+' . $_POST['disklayout'];
                }
                if ($_POST['packages_addon']) {
                    $n .= '+' . $_POST['packages_addon'];
                }
                if ($_POST['extra1']) {
                    $n .= '+' . $_POST['extra1'];
                }
                if ($_POST['extra2']) {
                    $n .= '+' . $_POST['extra2'];
                }
                nocprovisioning_log("Provisioning server - Profile '{$n}' - MAC {$mac}", $params);
            } else {
                /* input validation error */
                foreach ($result['errors'] as $field => $msg) {
                    $error .= $field . ': ' . htmlentities($msg) . '<br>';
                }
                lg_err("Error trying to provision - " . str_replace("<br>", " - ", $error));
                // nocprovisioning_log("Error trying to provision - ".str_replace("<br>", " - ", $error), $params);
            }
        } else {
            if (!empty($_POST['cancelprovisioning'])) {
                /* Cancel provisioning */
                $api->cancelProvisioning($mac);
                nocprovisioning_log("Cancelled provisioning - MAC {$mac}", $params);
            }
        }
        $status = $api->getProvisioningStatusByServer($mac);
        if ($status) {
            /* Host is already being provisioned */
            return array('templatefile' => 'provision-status', 'vars' => array('ip' => $ip, 'mac' => $mac, 'serviceid' => $params["serviceid"], 'nonce' => $_SESSION['nps_nonce'], 'status' => $status));
        } else {
            $profiles = $api->getProfileNames(0, 1000);
            $addons = $api->getProfileAddonNames(0, 1000);
            /* Check profile against white- and blacklist */
            $whitelist = array_filter(explode(' ', $params[NOCPS_CONFIG_WHITELIST]));
            $blacklist = array_filter(explode(' ', $params[NOCPS_CONFIG_BLACKLIST]));
            foreach ($profiles['data'] as $k => $profile) {
                $tags = explode(' ', $profile['tags']);
                /* Check wheter the profile ID or any of its tags are on the whitelist */
                if (count($whitelist) && !in_array($profile['id'], $whitelist) && count(array_intersect($tags, $whitelist)) == 0) {
                    /* not on whitelist, remove */
                    unset($profiles['data'][$k]);
                } else {
                    if (count($blacklist) && (in_array($profile['id'], $blacklist) || count(array_intersect($tags, $blacklist)))) {
                        /* on blacklist, remove */
                        unset($profiles['data'][$k]);
                    }
                }
            }
            /* --- */
            require_once 'Zend/Json.php';
            return array('templatefile' => 'provision', 'vars' => array('ip' => $ip, 'mac' => $mac, 'serviceid' => $params["serviceid"], 'nonce' => $_SESSION['nps_nonce'], 'profiles' => $profiles['data'], 'addons_json' => Zend_Json::encode($addons['data']), 'profiles_json' => Zend_Json::encode(array_values($profiles['data'])), 'error' => $error, 'ask_ipmi_password' => !empty($params[NOCPS_CONFIG_REQUIRE_IPMIPASSWORD])));
        }
    } catch (Exception $e) {
        nocprovisioning_log("Provisioning error - " . $e->getMessage(), $params);
        die('<b>Error: </b>' . $e->getMessage());
    }
}
function nocps_define_citrix_vm($nocps_api, $vm_name, $vm_description, $ram_amount, $disk_size, $vcore_count)
{
    # ram_mount = needed ram in MB
    # disk_size = needed disk_size in MB
    $servers = nocps_get_citrix_servers($nocps_api);
    $target_server = "";
    foreach ($servers as $index => $data) {
        $free_ram = nocps_get_free_ram($nocps_api, $data["id"], $data["servername"], $data["address"]);
        $free_disk_space = nocps_get_free_disk_space($nocps_api, $data["id"], $data["servername"], $data["address"]);
        $total_cores = nocps_get_core_count($nocps_api, $data["id"], $data["servername"], $data["address"]);
        lg_debug("free_ram        of server: {$free_ram}        reqd ram:        {$ram_amount}");
        lg_debug("free_disk space of server: {$free_disk_space} reqd disk space: {$disk_size}");
        if ($free_ram >= $ram_amount and $free_disk_space >= $disk_size and $total_cores >= $vcore_count) {
            lg_info("Got Server " . $data["servername"] . " for new VM {$vm_name} with {$ram_amount} MB RAM, {$disk_size} MB Disk size and {$vcore_count} VCores");
            $target_server = $data;
            break;
        }
    }
    if ($target_server) {
        $ip = nocps_get_free_ip_address($nocps_api);
        if ($ip[0] == "No IPs avalable") {
            lg_err("No IPs available in NOC-PS");
            return "No IPs available";
        } else {
            $subnet = $ip[1];
            $ip = $ip[0];
            lg_info("Got new IP address {$ip}");
            lg_debug("Creating new VM");
            lg_debug2("Subnet: {$subnet}");
            lg_debug2("ip: {$ip}");
            lg_debug2("vm_name: {$vm_name}");
            lg_debug2("vm_description: {$vm_description}");
            lg_debug2("module: " . $target_server["id"]);
            lg_debug2("memory: {$ram_amount}");
            lg_debug2("disk_size: {$disk_size}");
            lg_debug2("network: " . nocps_get_citrix_first_nic($nocps_api, $target_server["id"]));
            try {
                $result = $nocps_api->addVM(array("subnet" => $subnet, "ip" => $ip, "numips" => 1, "hostname" => $vm_name, "description" => $vm_description, "module" => $target_server["id"], "memory" => $ram_amount, "disk" => $disk_size, "diskstore" => "Local storage", "network" => nocps_get_citrix_first_nic($nocps_api, $target_server["id"])));
            } catch (exception $e) {
                lg_err("Error from XenServer while creating new VM, Please check xensource.log");
                return "Error: from XenServer while Creating VM";
            }
        }
        if (is_array($result) and $result["success"] == "1") {
            $mac = $result["mac"];
            lg_info("VM-Setup Phase 1 - successful");
            if ($vcore_count > 1) {
                citrix_set_vcore_count($target_server["servername"], $vm_name, $vcore_count);
            }
            return "NEWIP {$ip}";
        } else {
            lg_err("VM-Setup failed, unknown error");
            lg_err("success: " . $result["success"]);
            $lines = print_r($result, true);
            if (is_array($lines)) {
                foreach ($lines as $ind => $text) {
                    lg_info($ind . " " . $text);
                }
            }
            return "Error: VM Setup Failed, unknown Error";
        }
    } else {
        lg_err("VM-Setup failed, No Server with enough resources for this VM available");
        return "Error: No Server has enough resources for this VM";
    }
}